@softize/opus 23.0.0 → 24.0.1
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 +99 -0
- package/bin/cli.mjs +2 -0
- package/bin/lib/check.mjs +241 -42
- package/bin/lib/copy.mjs +16 -34
- package/docs/adr/0023-surfaces-share-one-anatomy-and-two-layouts.md +6 -0
- package/docs/adr/0039-filter-presentation-is-independent-from-filter-type.md +3 -3
- package/docs/adr/0040-tabs-use-a-single-navigation-presentation.md +5 -6
- package/docs/adr/0042-toggle-group-shares-the-grouped-control-grammar.md +79 -0
- package/docs/adr/0043-neutral-surfaces-and-interactions-use-opaque-role-tokens.md +73 -0
- package/docs/adr/0044-neutral-appearance-derives-from-bounded-axes-per-mode.md +133 -0
- package/docs/adr/0045-surface-replaces-content-and-card.md +230 -0
- package/docs/adr/0046-structural-body-owns-content-rhythm.md +103 -0
- package/docs/adr/0047-pane-is-only-a-split-layout-unit.md +71 -0
- package/docs/adr/0048-modal-intro-separates-content-from-chrome.md +34 -0
- package/docs/adr/0049-inline-navigation-groups-with-the-heading.md +95 -0
- package/package.json +5 -1
- package/registry/skills/build-opus-ui/SKILL.md +11 -11
- package/registry/skills/build-opus-ui/references/evaluations.md +10 -9
- package/registry/skills/build-opus-ui/references/ui-patterns.md +17 -16
- package/registry/templates/app/src/App.tsx +24 -12
- package/src/ui/appearance.ts +149 -0
- package/src/ui/components/patterns/action-form-card.tsx +46 -33
- package/src/ui/components/patterns/action-list-dialog.tsx +2 -4
- package/src/ui/components/patterns/confirm.tsx +3 -1
- package/src/ui/components/patterns/fill-region.ts +8 -7
- package/src/ui/components/patterns/form-dialog.tsx +1 -3
- package/src/ui/components/patterns/form.tsx +8 -7
- package/src/ui/components/patterns/list.tsx +15 -19
- package/src/ui/components/patterns/page.tsx +15 -11
- package/src/ui/components/patterns/pane.tsx +9 -240
- package/src/ui/components/patterns/presentation.tsx +14 -14
- package/src/ui/components/patterns/sidebar.tsx +7 -17
- package/src/ui/components/patterns/split.tsx +111 -59
- package/src/ui/components/patterns/{surface-header.tsx → structural-header.tsx} +90 -27
- package/src/ui/components/patterns/structural-media.tsx +26 -0
- package/src/ui/components/patterns/surface-anatomy.ts +71 -61
- package/src/ui/components/patterns/surface-assistant.tsx +2 -4
- package/src/ui/components/patterns/surface.tsx +620 -0
- package/src/ui/components/patterns/trigger.tsx +11 -9
- package/src/ui/components/primitives/ask.tsx +155 -83
- package/src/ui/components/primitives/button.tsx +11 -9
- package/src/ui/components/primitives/checkbox.tsx +8 -8
- package/src/ui/components/primitives/command.tsx +1 -1
- package/src/ui/components/primitives/composer.tsx +47 -45
- package/src/ui/components/primitives/detail.tsx +9 -2
- package/src/ui/components/primitives/dialog.tsx +60 -26
- package/src/ui/components/primitives/drawer.tsx +58 -12
- package/src/ui/components/primitives/icon-picker.tsx +90 -73
- package/src/ui/components/primitives/input-group.tsx +35 -28
- package/src/ui/components/primitives/input-otp.tsx +16 -16
- package/src/ui/components/primitives/input.tsx +20 -10
- package/src/ui/components/primitives/item.tsx +9 -12
- package/src/ui/components/primitives/menu.tsx +44 -65
- package/src/ui/components/primitives/metric-card.tsx +75 -59
- package/src/ui/components/primitives/radio-group.tsx +9 -9
- package/src/ui/components/primitives/select.tsx +344 -209
- package/src/ui/components/primitives/switch.tsx +10 -10
- package/src/ui/components/primitives/table.tsx +29 -24
- package/src/ui/components/primitives/tabs.tsx +4 -2
- package/src/ui/components/primitives/textarea.tsx +6 -6
- package/src/ui/components/primitives/toggle-group-context.ts +24 -0
- package/src/ui/components/primitives/toggle-group.tsx +116 -74
- package/src/ui/components/primitives/toggle.tsx +82 -16
- package/src/ui/docs/DocBrowser.tsx +77 -69
- package/src/ui/docs/content/action-form-card.md +9 -9
- package/src/ui/docs/content/action-list.md +76 -70
- package/src/ui/docs/content/action-view.md +33 -18
- package/src/ui/docs/content/button.md +1 -1
- package/src/ui/docs/content/communication.md +1 -1
- package/src/ui/docs/content/compositions.md +479 -0
- package/src/ui/docs/content/customization.md +64 -11
- package/src/ui/docs/content/detail.md +8 -6
- package/src/ui/docs/content/dialog.md +105 -60
- package/src/ui/docs/content/drawer.md +68 -22
- package/src/ui/docs/content/field.md +14 -15
- package/src/ui/docs/content/icon-tile.md +14 -13
- package/src/ui/docs/content/page.md +44 -34
- package/src/ui/docs/content/pane.md +42 -290
- package/src/ui/docs/content/presentation.md +3 -3
- package/src/ui/docs/content/separator.md +6 -6
- package/src/ui/docs/content/sidebar.md +68 -266
- package/src/ui/docs/content/skeleton.md +20 -18
- package/src/ui/docs/content/split.md +14 -14
- package/src/ui/docs/content/surface.md +513 -0
- package/src/ui/docs/content/tabs.md +20 -20
- package/src/ui/docs/content/toggle.md +117 -65
- package/src/ui/docs/content/tokens.md +124 -40
- package/src/ui/docs/registry.tsx +10 -6
- package/src/ui/index.ts +30 -27
- package/src/ui/meta.ts +15 -27
- package/src/ui/react.tsx +40 -43
- package/src/ui/theme.css +311 -64
- package/src/ui/components/patterns/content-header.tsx +0 -528
- package/src/ui/components/patterns/surface-media.tsx +0 -69
- package/src/ui/components/primitives/card.tsx +0 -191
- package/src/ui/docs/content/card.md +0 -292
- package/src/ui/docs/content/content.md +0 -275
package/src/ui/theme.css
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
*
|
|
7
7
|
* ── DIVERGÊNCIAS DECLARADAS vs shadcn upstream (regra: o que não está aqui é DRIFT
|
|
8
8
|
* e deve ser sincronizado; ver skill `build-opus-ui`) ─────────────────────────────
|
|
9
|
-
* 1. Formato HSL nos tokens (upstream migrou pra oklch) — legibilidade/ferramentas
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* 1. Formato HSL nos tokens (upstream migrou pra oklch) — legibilidade/ferramentas nossas.
|
|
10
|
+
* 2. Hierarquia de superfície nos dois temas: canvas, superfície elevada, controle e estados
|
|
11
|
+
* neutros têm valores opacos por papel (ADR 0043), sem depender do fundo ancestral. A escala
|
|
12
|
+
* neutra é derivada de quatro eixos de aparência por modo (ADR 0044); os presets reproduzem
|
|
13
|
+
* os valores calibrados e o app personaliza por custom property.
|
|
13
14
|
* 3. Radius mapeado (xs a 2xl em @theme inline) preservando o sentido pré-v4 dos
|
|
14
15
|
* utilitários `rounded-*` — neutraliza o rename do v4 e mantém a escala monotônica.
|
|
15
16
|
* 4. Escala shadow-* recomposta diretamente em duas camadas claras, difusas e com spread
|
|
@@ -18,10 +19,10 @@
|
|
|
18
19
|
* canvas quase-branco; superfícies elevadas usam a mesma borda real dos demais papéis.
|
|
19
20
|
* 6. Radius base em 0.75rem — identidade mais arredondada; os componentes continuam usando
|
|
20
21
|
* diretamente a escala Tailwind, sem tokens por papel (ver docs/radius-scale.md).
|
|
21
|
-
* Tudo o mais (
|
|
22
|
+
* Tudo o mais (semânticas e contratos das primitives) segue o upstream.
|
|
22
23
|
*/
|
|
23
|
-
@import
|
|
24
|
-
@import
|
|
24
|
+
@import "tailwindcss";
|
|
25
|
+
@import "tw-animate-css";
|
|
25
26
|
@plugin '@tailwindcss/typography';
|
|
26
27
|
|
|
27
28
|
/* dark por classe (v4 é CSS-first) */
|
|
@@ -31,20 +32,112 @@
|
|
|
31
32
|
/* Scrollbars e controles NATIVOS (date picker, autofill…) seguem o tema — sem
|
|
32
33
|
isto o browser assume light e pinta scrollbar branca no dark. */
|
|
33
34
|
color-scheme: light;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
|
|
36
|
+
/* ── Aparência (ADR 0044) ──────────────────────────────────────────────────────────
|
|
37
|
+
Quatro eixos inteiros de 0 a 100, declarados por modo. Estes são os presets: com eles a
|
|
38
|
+
escala neutra abaixo reproduz exatamente os valores calibrados do tema. O consumidor
|
|
39
|
+
sobrescreve `--appearance-light-*` e `--appearance-dark-*` (inline em <html>, por exemplo)
|
|
40
|
+
e remove a propriedade para voltar ao preset; `@softize/opus/ui/appearance` publica nomes e
|
|
41
|
+
presets. `--neutral-hue` é identidade do app — o matiz que a intensidade aplica aos
|
|
42
|
+
neutros — e não um eixo. Primary e contextos semânticos não participam desta derivação.
|
|
43
|
+
|
|
44
|
+
Os limites protegem o tema calibrado. Contraste e contraste entre camadas partem do preset
|
|
45
|
+
e só ampliam as separações. O brilho move as superfícies dentro de uma faixa em que o texto
|
|
46
|
+
secundário compensa a mudança. Nenhuma combinação de 0 a 100 fica abaixo do preset em
|
|
47
|
+
separação entre papéis nem em contraste do texto sobre as superfícies em repouso. */
|
|
48
|
+
--appearance-light-color-intensity: 0;
|
|
49
|
+
--appearance-light-contrast: 0;
|
|
50
|
+
--appearance-light-surface-brightness: 100;
|
|
51
|
+
--appearance-light-layer-contrast: 0;
|
|
52
|
+
--appearance-dark-color-intensity: 0;
|
|
53
|
+
--appearance-dark-contrast: 0;
|
|
54
|
+
--appearance-dark-surface-brightness: 50;
|
|
55
|
+
--appearance-dark-layer-contrast: 0;
|
|
56
|
+
--neutral-hue: 220;
|
|
57
|
+
|
|
58
|
+
/* Eixos ativos no modo claro. */
|
|
59
|
+
--appearance-color-intensity: var(--appearance-light-color-intensity);
|
|
60
|
+
--appearance-contrast: var(--appearance-light-contrast);
|
|
61
|
+
--appearance-surface-brightness: var(--appearance-light-surface-brightness);
|
|
62
|
+
--appearance-layer-contrast: var(--appearance-light-layer-contrast);
|
|
63
|
+
|
|
64
|
+
/* Escala neutra derivada (luminosidade em número, 0 a 100). No claro a superfície elevada
|
|
65
|
+
parte do branco; o canvas desce dela conforme o contraste entre camadas e o controle fica
|
|
66
|
+
entre os dois. Estados neutros, muted e bordas descem a partir do canvas — a superfície
|
|
67
|
+
mais escura — na direção do texto, em passos que o contraste amplia. O texto secundário
|
|
68
|
+
recebe só uma fração da saturação e escurece junto com as superfícies e com a intensidade,
|
|
69
|
+
para que nem o ajuste nem o matiz escolhido pelo app reduzam a leitura. */
|
|
70
|
+
--neutral-saturation: calc(var(--appearance-color-intensity) * 0.2%);
|
|
71
|
+
--neutral-text-saturation: calc(var(--appearance-color-intensity) * 0.08%);
|
|
72
|
+
--neutral-step: calc(1 + var(--appearance-contrast) * 0.01);
|
|
73
|
+
--neutral-layer-l: calc(95 + var(--appearance-surface-brightness) * 0.05);
|
|
74
|
+
--neutral-canvas-l: calc(
|
|
75
|
+
var(--neutral-layer-l) - 2.5 - var(--appearance-layer-contrast) * 0.025
|
|
76
|
+
);
|
|
77
|
+
--neutral-control-l: calc(
|
|
78
|
+
var(--neutral-canvas-l) + 1 + var(--appearance-layer-contrast) * 0.01
|
|
79
|
+
);
|
|
80
|
+
--neutral-muted-l: calc(var(--neutral-canvas-l) - 1.4 * var(--neutral-step));
|
|
81
|
+
--neutral-hover-l: calc(var(--neutral-canvas-l) - 2 * var(--neutral-step));
|
|
82
|
+
--neutral-selected-l: calc(var(--neutral-canvas-l) - 5 * var(--neutral-step));
|
|
83
|
+
--neutral-pressed-l: calc(
|
|
84
|
+
var(--neutral-canvas-l) - 6.5 * var(--neutral-step)
|
|
85
|
+
);
|
|
86
|
+
--neutral-line-l: calc(var(--neutral-canvas-l) - 5 * var(--neutral-step));
|
|
87
|
+
--neutral-ring-l: calc(var(--neutral-line-l) - 6.5 * var(--neutral-step));
|
|
88
|
+
--neutral-muted-foreground-l: calc(
|
|
89
|
+
45.1 - (96.1 - var(--neutral-muted-l)) * 0.8 -
|
|
90
|
+
var(--appearance-color-intensity) * 0.04
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
--background: hsl(
|
|
94
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
95
|
+
calc(var(--neutral-canvas-l) * 1%)
|
|
96
|
+
);
|
|
97
|
+
--foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 3.9%);
|
|
98
|
+
--card: hsl(
|
|
99
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
100
|
+
calc(var(--neutral-layer-l) * 1%)
|
|
101
|
+
);
|
|
102
|
+
--card-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 3.9%);
|
|
103
|
+
--control: hsl(
|
|
104
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
105
|
+
calc(var(--neutral-control-l) * 1%)
|
|
106
|
+
);
|
|
107
|
+
--interaction-hover: hsl(
|
|
108
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
109
|
+
calc(var(--neutral-hover-l) * 1%)
|
|
110
|
+
);
|
|
111
|
+
--interaction-selected: hsl(
|
|
112
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
113
|
+
calc(var(--neutral-selected-l) * 1%)
|
|
114
|
+
);
|
|
115
|
+
--interaction-pressed: hsl(
|
|
116
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
117
|
+
calc(var(--neutral-pressed-l) * 1%)
|
|
118
|
+
);
|
|
119
|
+
--popover: hsl(
|
|
120
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
121
|
+
calc(var(--neutral-layer-l) * 1%)
|
|
122
|
+
);
|
|
123
|
+
--popover-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 3.9%);
|
|
40
124
|
--primary: hsl(0 0% 9%);
|
|
41
125
|
--primary-foreground: hsl(0 0% 98%);
|
|
42
|
-
--secondary: hsl(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
--
|
|
47
|
-
--
|
|
126
|
+
--secondary: hsl(
|
|
127
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
128
|
+
calc(var(--neutral-muted-l) * 1%)
|
|
129
|
+
);
|
|
130
|
+
--secondary-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 9%);
|
|
131
|
+
--muted: hsl(
|
|
132
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
133
|
+
calc(var(--neutral-muted-l) * 1%)
|
|
134
|
+
);
|
|
135
|
+
--muted-foreground: hsl(
|
|
136
|
+
var(--neutral-hue) var(--neutral-text-saturation)
|
|
137
|
+
calc(var(--neutral-muted-foreground-l) * 1%)
|
|
138
|
+
);
|
|
139
|
+
--accent: var(--interaction-hover);
|
|
140
|
+
--accent-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 9%);
|
|
48
141
|
--destructive: hsl(0 84.2% 60.2%);
|
|
49
142
|
--destructive-foreground: hsl(0 0% 98%);
|
|
50
143
|
/* Contextos semânticos (ADR 0006): família independente do tratamento
|
|
@@ -58,7 +151,11 @@
|
|
|
58
151
|
--context-primary-foreground: var(--primary-foreground);
|
|
59
152
|
--context-primary-subtle: color-mix(in oklab, var(--primary) 8%, transparent);
|
|
60
153
|
--context-primary-emphasis: var(--foreground);
|
|
61
|
-
--context-primary-border: color-mix(
|
|
154
|
+
--context-primary-border: color-mix(
|
|
155
|
+
in oklab,
|
|
156
|
+
var(--primary) 25%,
|
|
157
|
+
transparent
|
|
158
|
+
);
|
|
62
159
|
/* info/success/warning: base, foreground, subtle e border (12 tokens) valem nos dois temas
|
|
63
160
|
de propósito — são cores saturadas com alpha, que já se assentam sobre qualquer canvas;
|
|
64
161
|
só `*-emphasis` (texto sobre o popover) precisa clarear no escuro, e é redefinido em .dark. */
|
|
@@ -79,35 +176,119 @@
|
|
|
79
176
|
--context-warning-border: hsl(38 92% 50% / 0.35);
|
|
80
177
|
--context-danger: var(--destructive);
|
|
81
178
|
--context-danger-foreground: var(--destructive-foreground);
|
|
82
|
-
--context-danger-subtle: color-mix(
|
|
179
|
+
--context-danger-subtle: color-mix(
|
|
180
|
+
in oklab,
|
|
181
|
+
var(--destructive) 10%,
|
|
182
|
+
transparent
|
|
183
|
+
);
|
|
83
184
|
--context-danger-emphasis: hsl(0 72% 45%);
|
|
84
|
-
--context-danger-border: color-mix(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
--
|
|
185
|
+
--context-danger-border: color-mix(
|
|
186
|
+
in oklab,
|
|
187
|
+
var(--destructive) 35%,
|
|
188
|
+
transparent
|
|
189
|
+
);
|
|
190
|
+
--border: hsl(
|
|
191
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
192
|
+
calc(var(--neutral-line-l) * 1%)
|
|
193
|
+
);
|
|
194
|
+
--input: hsl(
|
|
195
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
196
|
+
calc(var(--neutral-line-l) * 1%)
|
|
197
|
+
);
|
|
198
|
+
/* O aro acompanha a borda e o contraste escolhidos, preservando o degrau do preset. */
|
|
199
|
+
--ring: hsl(
|
|
200
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
201
|
+
calc(var(--neutral-ring-l) * 1%)
|
|
202
|
+
);
|
|
90
203
|
--radius: 0.75rem;
|
|
91
204
|
}
|
|
92
205
|
|
|
93
206
|
.dark {
|
|
94
207
|
color-scheme: dark;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
--
|
|
100
|
-
--
|
|
101
|
-
|
|
102
|
-
|
|
208
|
+
|
|
209
|
+
/* Eixos ativos no modo escuro. */
|
|
210
|
+
--appearance-color-intensity: var(--appearance-dark-color-intensity);
|
|
211
|
+
--appearance-contrast: var(--appearance-dark-contrast);
|
|
212
|
+
--appearance-surface-brightness: var(--appearance-dark-surface-brightness);
|
|
213
|
+
--appearance-layer-contrast: var(--appearance-dark-layer-contrast);
|
|
214
|
+
|
|
215
|
+
/* No escuro o brilho leva o canvas do preto, em 0, até um escuro suave, em 100. Elevação com
|
|
216
|
+
contraste de verdade (dialog e card "sobem" da página): a camada sobe do canvas conforme o
|
|
217
|
+
contraste entre camadas e o controle fica entre os dois. Estados neutros, muted e bordas
|
|
218
|
+
sobem a partir da camada — a superfície mais clara — na direção do texto. Mesmos papéis do
|
|
219
|
+
claro, direção invertida. O texto secundário clareia quando as superfícies sobem acima do
|
|
220
|
+
preset e nunca escurece abaixo dele. */
|
|
221
|
+
--neutral-saturation: calc(var(--appearance-color-intensity) * 0.2%);
|
|
222
|
+
--neutral-text-saturation: calc(var(--appearance-color-intensity) * 0.08%);
|
|
223
|
+
--neutral-step: calc(1 + var(--appearance-contrast) * 0.006);
|
|
224
|
+
--neutral-canvas-l: calc(var(--appearance-surface-brightness) * 0.078);
|
|
225
|
+
--neutral-layer-l: calc(
|
|
226
|
+
var(--neutral-canvas-l) + 6.1 + var(--appearance-layer-contrast) * 0.03
|
|
227
|
+
);
|
|
228
|
+
--neutral-control-l: calc(
|
|
229
|
+
var(--neutral-canvas-l) + 3.8 + var(--appearance-layer-contrast) * 0.018
|
|
230
|
+
);
|
|
231
|
+
--neutral-muted-l: calc(var(--neutral-layer-l) + 4.9 * var(--neutral-step));
|
|
232
|
+
--neutral-hover-l: calc(var(--neutral-layer-l) + 4.9 * var(--neutral-step));
|
|
233
|
+
--neutral-selected-l: calc(
|
|
234
|
+
var(--neutral-layer-l) + 8.5 * var(--neutral-step)
|
|
235
|
+
);
|
|
236
|
+
--neutral-pressed-l: calc(var(--neutral-layer-l) + 11 * var(--neutral-step));
|
|
237
|
+
--neutral-line-l: calc(var(--neutral-layer-l) + 6.5 * var(--neutral-step));
|
|
238
|
+
--neutral-ring-l: calc(var(--neutral-line-l) + 19.5 * var(--neutral-step));
|
|
239
|
+
--neutral-muted-foreground-l: calc(
|
|
240
|
+
63.9 + max(0, var(--neutral-muted-l) - 14.9) * 1.6 +
|
|
241
|
+
var(--appearance-color-intensity) * 0.04
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
--background: hsl(
|
|
245
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
246
|
+
calc(var(--neutral-canvas-l) * 1%)
|
|
247
|
+
);
|
|
248
|
+
--foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 98%);
|
|
249
|
+
--card: hsl(
|
|
250
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
251
|
+
calc(var(--neutral-layer-l) * 1%)
|
|
252
|
+
);
|
|
253
|
+
--card-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 98%);
|
|
254
|
+
--control: hsl(
|
|
255
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
256
|
+
calc(var(--neutral-control-l) * 1%)
|
|
257
|
+
);
|
|
258
|
+
--interaction-hover: hsl(
|
|
259
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
260
|
+
calc(var(--neutral-hover-l) * 1%)
|
|
261
|
+
);
|
|
262
|
+
--interaction-selected: hsl(
|
|
263
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
264
|
+
calc(var(--neutral-selected-l) * 1%)
|
|
265
|
+
);
|
|
266
|
+
--interaction-pressed: hsl(
|
|
267
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
268
|
+
calc(var(--neutral-pressed-l) * 1%)
|
|
269
|
+
);
|
|
270
|
+
--popover: hsl(
|
|
271
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
272
|
+
calc(var(--neutral-layer-l) * 1%)
|
|
273
|
+
);
|
|
274
|
+
--popover-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 98%);
|
|
103
275
|
--primary: hsl(0 0% 98%);
|
|
104
276
|
--primary-foreground: hsl(0 0% 9%);
|
|
105
|
-
--secondary: hsl(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
--
|
|
110
|
-
--
|
|
277
|
+
--secondary: hsl(
|
|
278
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
279
|
+
calc(var(--neutral-muted-l) * 1%)
|
|
280
|
+
);
|
|
281
|
+
--secondary-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 98%);
|
|
282
|
+
--muted: hsl(
|
|
283
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
284
|
+
calc(var(--neutral-muted-l) * 1%)
|
|
285
|
+
);
|
|
286
|
+
--muted-foreground: hsl(
|
|
287
|
+
var(--neutral-hue) var(--neutral-text-saturation)
|
|
288
|
+
calc(var(--neutral-muted-foreground-l) * 1%)
|
|
289
|
+
);
|
|
290
|
+
--accent: var(--interaction-hover);
|
|
291
|
+
--accent-foreground: hsl(var(--neutral-hue) var(--neutral-saturation) 98%);
|
|
111
292
|
/* Vermelho CLARO no escuro (era 30.6% — calibrado só pra FUNDO, com texto branco).
|
|
112
293
|
Como o menu/alert/field/erros usam `text-destructive` como FOREGROUND, o valor
|
|
113
294
|
escuro dava ~1,7:1 sobre o popover — ilegível. ~58% passa o AA como texto, o mesmo
|
|
@@ -119,10 +300,18 @@
|
|
|
119
300
|
--context-success-emphasis: hsl(142 69% 58%);
|
|
120
301
|
--context-warning-emphasis: hsl(43 96% 56%);
|
|
121
302
|
--context-danger-emphasis: hsl(0 91% 71%);
|
|
122
|
-
--border: hsl(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
303
|
+
--border: hsl(
|
|
304
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
305
|
+
calc(var(--neutral-line-l) * 1%)
|
|
306
|
+
);
|
|
307
|
+
--input: hsl(
|
|
308
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
309
|
+
calc(var(--neutral-line-l) * 1%)
|
|
310
|
+
);
|
|
311
|
+
--ring: hsl(
|
|
312
|
+
var(--neutral-hue) var(--neutral-saturation)
|
|
313
|
+
calc(var(--neutral-ring-l) * 1%)
|
|
314
|
+
);
|
|
126
315
|
}
|
|
127
316
|
|
|
128
317
|
/* Syntax highlighting (CodeBlock via prism-react-renderer): paleta calma mapeada por CSS
|
|
@@ -156,6 +345,10 @@
|
|
|
156
345
|
--color-foreground: var(--foreground);
|
|
157
346
|
--color-card: var(--card);
|
|
158
347
|
--color-card-foreground: var(--card-foreground);
|
|
348
|
+
--color-control: var(--control);
|
|
349
|
+
--color-interaction-hover: var(--interaction-hover);
|
|
350
|
+
--color-interaction-selected: var(--interaction-selected);
|
|
351
|
+
--color-interaction-pressed: var(--interaction-pressed);
|
|
159
352
|
--color-popover: var(--popover);
|
|
160
353
|
--color-popover-foreground: var(--popover-foreground);
|
|
161
354
|
--color-primary: var(--primary);
|
|
@@ -211,14 +404,38 @@
|
|
|
211
404
|
|
|
212
405
|
/* Escala Tailwind, com receita direta para o compilador preservar modifiers `/opacity`.
|
|
213
406
|
`light-dark()` mantém o peso adequado em cada tema sem uma variável intermediária. */
|
|
214
|
-
--shadow-2xs: 0 0.0625rem 0.125rem -0.0625rem
|
|
215
|
-
|
|
216
|
-
--shadow-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
--shadow-
|
|
407
|
+
--shadow-2xs: 0 0.0625rem 0.125rem -0.0625rem
|
|
408
|
+
light-dark(rgb(15 15 15 / 0.03), rgb(0 0 0 / 0.12));
|
|
409
|
+
--shadow-xs:
|
|
410
|
+
0 0.0625rem 0.125rem -0.0625rem
|
|
411
|
+
light-dark(rgb(15 15 15 / 0.025), rgb(0 0 0 / 0.12)),
|
|
412
|
+
0 0.125rem 0.25rem -0.125rem
|
|
413
|
+
light-dark(rgb(15 15 15 / 0.035), rgb(0 0 0 / 0.18));
|
|
414
|
+
--shadow-sm:
|
|
415
|
+
0 0.125rem 0.25rem -0.125rem
|
|
416
|
+
light-dark(rgb(15 15 15 / 0.025), rgb(0 0 0 / 0.16)),
|
|
417
|
+
0 0.25rem 0.5rem -0.25rem
|
|
418
|
+
light-dark(rgb(15 15 15 / 0.04), rgb(0 0 0 / 0.28));
|
|
419
|
+
--shadow:
|
|
420
|
+
0 0.125rem 0.375rem -0.125rem
|
|
421
|
+
light-dark(rgb(15 15 15 / 0.03), rgb(0 0 0 / 0.16)),
|
|
422
|
+
0 0.375rem 0.875rem -0.375rem
|
|
423
|
+
light-dark(rgb(15 15 15 / 0.05), rgb(0 0 0 / 0.29));
|
|
424
|
+
--shadow-md:
|
|
425
|
+
0 0.25rem 0.5rem -0.25rem
|
|
426
|
+
light-dark(rgb(15 15 15 / 0.03), rgb(0 0 0 / 0.16)),
|
|
427
|
+
0 0.625rem 1.75rem -0.5rem
|
|
428
|
+
light-dark(rgb(15 15 15 / 0.065), rgb(0 0 0 / 0.3));
|
|
429
|
+
--shadow-lg:
|
|
430
|
+
0 0.375rem 1rem -0.375rem
|
|
431
|
+
light-dark(rgb(15 15 15 / 0.03), rgb(0 0 0 / 0.18)),
|
|
432
|
+
0 1.125rem 3rem -0.75rem light-dark(rgb(15 15 15 / 0.07), rgb(0 0 0 / 0.3));
|
|
433
|
+
--shadow-xl:
|
|
434
|
+
0 0.5rem 1.5rem -0.625rem light-dark(rgb(15 15 15 / 0.04), rgb(0 0 0 / 0.2)),
|
|
435
|
+
0 1.5rem 4rem -1.125rem light-dark(rgb(15 15 15 / 0.08), rgb(0 0 0 / 0.34));
|
|
436
|
+
--shadow-2xl:
|
|
437
|
+
0 0.75rem 2rem -0.875rem light-dark(rgb(15 15 15 / 0.05), rgb(0 0 0 / 0.22)),
|
|
438
|
+
0 2rem 5.5rem -1.5rem light-dark(rgb(15 15 15 / 0.1), rgb(0 0 0 / 0.38));
|
|
222
439
|
}
|
|
223
440
|
|
|
224
441
|
/* Base canônica do consumidor — vem DAQUI, não do entry de cada app. Tailwind v4
|
|
@@ -261,7 +478,12 @@
|
|
|
261
478
|
}
|
|
262
479
|
:root:is(:hover, :focus, :focus-within),
|
|
263
480
|
:root *:is(:hover, :focus, :focus-within) {
|
|
264
|
-
scrollbar-color: color-mix(
|
|
481
|
+
scrollbar-color: color-mix(
|
|
482
|
+
in srgb,
|
|
483
|
+
var(--muted-foreground) 35%,
|
|
484
|
+
transparent
|
|
485
|
+
)
|
|
486
|
+
transparent;
|
|
265
487
|
}
|
|
266
488
|
:root::-webkit-scrollbar,
|
|
267
489
|
:root *::-webkit-scrollbar {
|
|
@@ -281,7 +503,11 @@
|
|
|
281
503
|
}
|
|
282
504
|
:root:is(:hover, :focus, :focus-within)::-webkit-scrollbar-thumb,
|
|
283
505
|
:root *:is(:hover, :focus, :focus-within)::-webkit-scrollbar-thumb {
|
|
284
|
-
background-color: color-mix(
|
|
506
|
+
background-color: color-mix(
|
|
507
|
+
in srgb,
|
|
508
|
+
var(--muted-foreground) 35%,
|
|
509
|
+
transparent
|
|
510
|
+
);
|
|
285
511
|
}
|
|
286
512
|
}
|
|
287
513
|
|
|
@@ -311,19 +537,28 @@
|
|
|
311
537
|
* O guard [class~='not-prose'] espelha o escopo do plugin typography: sem ele a
|
|
312
538
|
* regra custom vaza pra dentro do not-prose (o CodeBlock ganhava uma SEGUNDA
|
|
313
539
|
* borda no <pre>, colada na do contêiner — a "borda duplicada"). */
|
|
314
|
-
.prose
|
|
540
|
+
.prose
|
|
541
|
+
:where(code):not(
|
|
542
|
+
:where(pre code, [class~="not-prose"], [class~="not-prose"] *)
|
|
543
|
+
) {
|
|
315
544
|
border-radius: calc(var(--radius) - 0.25rem);
|
|
316
545
|
background: var(--muted);
|
|
317
546
|
padding: 0.125rem 0.375rem;
|
|
318
547
|
font-weight: 400;
|
|
319
548
|
}
|
|
320
|
-
.prose
|
|
321
|
-
|
|
549
|
+
.prose
|
|
550
|
+
:where(code):not(
|
|
551
|
+
:where(pre code, [class~="not-prose"], [class~="not-prose"] *)
|
|
552
|
+
)::before,
|
|
553
|
+
.prose
|
|
554
|
+
:where(code):not(
|
|
555
|
+
:where(pre code, [class~="not-prose"], [class~="not-prose"] *)
|
|
556
|
+
)::after {
|
|
322
557
|
content: none;
|
|
323
558
|
}
|
|
324
559
|
|
|
325
560
|
/* Code block = superfície da casa (borda + bg muted) — só o <pre> CRU do prose. */
|
|
326
|
-
.prose :where(pre):not(:where([class~=
|
|
561
|
+
.prose :where(pre):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
|
|
327
562
|
border: 1px solid var(--border); /* px: hairline do bloco de código — 1 pixel físico, não escala. */
|
|
328
563
|
}
|
|
329
564
|
|
|
@@ -347,11 +582,15 @@
|
|
|
347
582
|
justify-content: center;
|
|
348
583
|
}
|
|
349
584
|
|
|
350
|
-
.toaster
|
|
585
|
+
.toaster
|
|
586
|
+
.opus-toast[data-sonner-toast]
|
|
587
|
+
.opus-toast-close[data-close-button]:focus-visible {
|
|
351
588
|
box-shadow: 0 0 0 0.125rem color-mix(in srgb, var(--ring) 50%, transparent);
|
|
352
589
|
}
|
|
353
590
|
|
|
354
|
-
.toaster
|
|
591
|
+
.toaster
|
|
592
|
+
.opus-toast[data-sonner-toast]
|
|
593
|
+
.opus-toast-close[data-close-button][data-disabled="true"] {
|
|
355
594
|
pointer-events: none;
|
|
356
595
|
opacity: 0.5;
|
|
357
596
|
}
|
|
@@ -367,15 +606,23 @@
|
|
|
367
606
|
background: var(--popover);
|
|
368
607
|
color: var(--muted-foreground);
|
|
369
608
|
outline: none;
|
|
370
|
-
transition:
|
|
609
|
+
transition:
|
|
610
|
+
color 150ms,
|
|
611
|
+
background-color 150ms,
|
|
612
|
+
box-shadow 150ms;
|
|
371
613
|
}
|
|
372
614
|
|
|
373
|
-
.toaster
|
|
615
|
+
.toaster
|
|
616
|
+
.opus-toast[data-sonner-toast]
|
|
617
|
+
.opus-toast-close[data-close-button]:hover {
|
|
374
618
|
background: var(--accent);
|
|
375
619
|
color: var(--accent-foreground);
|
|
376
620
|
}
|
|
377
621
|
|
|
378
|
-
.toaster
|
|
622
|
+
.toaster
|
|
623
|
+
.opus-toast[data-sonner-toast]
|
|
624
|
+
.opus-toast-close[data-close-button]
|
|
625
|
+
svg {
|
|
379
626
|
width: 1rem;
|
|
380
627
|
height: 1rem;
|
|
381
628
|
}
|