@inchurch/matcha-theme 22.38.2 → 22.38.4
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/abstracts/_colors.scss +291 -291
- package/abstracts/_elevation.scss +108 -108
- package/abstracts/_functions.scss +321 -321
- package/abstracts/_media-breakpoint.scss +26 -26
- package/abstracts/_theme-api.scss +224 -224
- package/abstracts/_typography.scss +128 -128
- package/base/_reset.scss +487 -487
- package/components/app-page-header.scss +260 -260
- package/components/matcha-accordion.scss +297 -297
- package/components/matcha-audio-player.scss +31 -31
- package/components/matcha-autocomplete.scss +145 -145
- package/components/matcha-avatar.scss +426 -426
- package/components/matcha-badge.scss +120 -120
- package/components/matcha-breadcrumb.scss +231 -231
- package/components/matcha-button-toggle.scss +484 -484
- package/components/matcha-buttons.scss +973 -973
- package/components/matcha-calendar.scss +253 -253
- package/components/matcha-cards.scss +212 -212
- package/components/matcha-chart-card.scss +53 -53
- package/components/matcha-checkbox.scss +266 -266
- package/components/matcha-chip.scss +311 -311
- package/components/matcha-color-pick.scss +34 -34
- package/components/matcha-command-palette.scss +316 -316
- package/components/matcha-crop.scss +419 -419
- package/components/matcha-date.scss +81 -81
- package/components/matcha-divider.scss +100 -100
- package/components/matcha-draggable.scss +23 -23
- package/components/matcha-drawer.scss +376 -376
- package/components/matcha-drop-image.scss +14 -14
- package/components/matcha-drop-list.scss +430 -430
- package/components/matcha-emoji.scss +69 -69
- package/components/matcha-empty-state.scss +230 -230
- package/components/matcha-file-uploader.scss +650 -637
- package/components/matcha-flag.scss +103 -103
- package/components/matcha-footer.scss +91 -91
- package/components/matcha-form-field.scss +883 -883
- package/components/matcha-form-section.scss +100 -100
- package/components/matcha-header.scss +135 -135
- package/components/matcha-highlight.scss +164 -164
- package/components/matcha-hint-text.scss +90 -90
- package/components/matcha-horizontal-tree.scss +247 -247
- package/components/matcha-icon.scss +111 -111
- package/components/matcha-image.scss +60 -60
- package/components/matcha-list.scss +211 -211
- package/components/matcha-menu.scss +99 -99
- package/components/matcha-modal.scss +210 -210
- package/components/matcha-nav.scss +770 -770
- package/components/matcha-notification.scss +417 -417
- package/components/matcha-option.scss +170 -170
- package/components/matcha-page-builder.scss +4196 -4196
- package/components/matcha-paginator.scss +699 -699
- package/components/matcha-panel.scss +216 -216
- package/components/matcha-period.scss +174 -174
- package/components/matcha-profile-card.scss +50 -50
- package/components/matcha-progress-bar.scss +355 -355
- package/components/matcha-radio.scss +325 -325
- package/components/matcha-ripple.scss +7 -7
- package/components/matcha-scrollbar.scss +33 -33
- package/components/matcha-scrollbox-shadow.scss +120 -120
- package/components/matcha-section.scss +102 -102
- package/components/matcha-select-multiple.scss +56 -56
- package/components/matcha-select.scss +629 -629
- package/components/matcha-skeleton.scss +182 -182
- package/components/matcha-slide-toggle.scss +369 -369
- package/components/matcha-slider.scss +285 -285
- package/components/matcha-snack-bar.scss +259 -259
- package/components/matcha-spin.scss +164 -164
- package/components/matcha-spinner.scss +97 -97
- package/components/matcha-stepper.scss +376 -376
- package/components/matcha-table-cell.scss +107 -107
- package/components/matcha-table.scss +722 -722
- package/components/matcha-tabs.scss +642 -642
- package/components/matcha-text-editor.scss +111 -111
- package/components/matcha-time.scss +33 -33
- package/components/matcha-timepicker.scss +13 -13
- package/components/matcha-toolbar.scss +366 -366
- package/components/matcha-tooltip.scss +235 -235
- package/components/matcha-tree-view.scss +636 -636
- package/layout/matcha-page-layout.scss +778 -778
- package/main.scss +334 -334
- package/package.json +1 -1
- package/tokens/_animations-tokens.scss +37 -37
- package/tokens/_breakpoints-tokens.scss +35 -35
- package/tokens/_color-tokens.scss +288 -288
- package/tokens/_elevation-tokens.scss +33 -33
- package/tokens/_emit-tokens.scss +329 -329
- package/tokens/_material-palette.scss +1149 -1149
- package/tokens/_primitives.scss +98 -98
- package/tokens/_semantic-aliases.scss +120 -120
- package/tokens/_spacing-tokens.scss +94 -94
- package/tokens/_static-tokens.scss +137 -137
- package/tokens/_typography-tokens.scss +65 -65
- package/vendors/charts.scss +90 -90
|
@@ -1,770 +1,770 @@
|
|
|
1
|
-
@use "sass:map";
|
|
2
|
-
|
|
3
|
-
// =============================================================================
|
|
4
|
-
// matcha-nav.scss — Navigation system (nav-item, nav-rail, nav-panel, command-palette)
|
|
5
|
-
// =============================================================================
|
|
6
|
-
|
|
7
|
-
// ── Nav Item ─────────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
// Host: wrapper estrutural. Não tem padding/bg — só layout column pra empilhar
|
|
10
|
-
// row + children. Permite que o consumer aninhe nav-items sem quebrar o layout.
|
|
11
|
-
.matcha-nav-item {
|
|
12
|
-
position: relative;
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
align-items: stretch;
|
|
16
|
-
width: 100%;
|
|
17
|
-
text-decoration: none;
|
|
18
|
-
color: inherit;
|
|
19
|
-
user-select: none;
|
|
20
|
-
// Reset pra <button>/<a> caso o host venha como esses elementos.
|
|
21
|
-
appearance: none;
|
|
22
|
-
border: 0;
|
|
23
|
-
background: transparent;
|
|
24
|
-
font: inherit;
|
|
25
|
-
text-align: start;
|
|
26
|
-
outline: none;
|
|
27
|
-
|
|
28
|
-
&.matcha-nav-item--disabled {
|
|
29
|
-
pointer-events: none;
|
|
30
|
-
cursor: default;
|
|
31
|
-
|
|
32
|
-
.matcha-nav-item__row {
|
|
33
|
-
cursor: default;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Focus-visible no host (keyboard) → repassa pro __row (visual).
|
|
38
|
-
&:focus-visible .matcha-nav-item__row {
|
|
39
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
40
|
-
outline-offset: calc(-1 * var(--matcha-state-focus-ring-width, 2px));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Row: o "botão" visível do nav-item — Figma DSV3 1:1.
|
|
45
|
-
// Expansível: pad 8/12, gap 8, radius md (4px), body-md (14/20 regular)
|
|
46
|
-
// Indentado: pad 6/8/24, gap 8, radius sm (2px), body-sm (12/16 regular)
|
|
47
|
-
// Ativo: bg accent/alpha + border-inline-start 3px accent + label medium 500
|
|
48
|
-
// Hover: bg accent/surface-hover
|
|
49
|
-
// Expandido: bg accent/surface-pressed
|
|
50
|
-
//
|
|
51
|
-
// box-sizing: border-box + border-inline-start: 3px solid accent (no Ativo)
|
|
52
|
-
// gera shift de 3px no content (Padrão @12 → Ativo @15) — literal Figma.
|
|
53
|
-
.matcha-nav-item__row {
|
|
54
|
-
display: flex;
|
|
55
|
-
flex-direction: row;
|
|
56
|
-
align-items: center;
|
|
57
|
-
gap: var(--matcha-space-100, 8px);
|
|
58
|
-
padding-block: var(--matcha-space-100, 8px);
|
|
59
|
-
padding-inline: var(--matcha-space-150, 12px);
|
|
60
|
-
border-radius: var(--matcha-radius-md, 4px);
|
|
61
|
-
border: 0;
|
|
62
|
-
background: transparent;
|
|
63
|
-
cursor: pointer;
|
|
64
|
-
// O row é <a> quando o item tem [routerLink]/[href] — sem este reset a âncora
|
|
65
|
-
// traz sublinhado e a cor de link do browser. As demais regras já eram agnósticas
|
|
66
|
-
// de tag (border: 0, background: transparent atendiam o <button>).
|
|
67
|
-
text-decoration: none;
|
|
68
|
-
color: inherit;
|
|
69
|
-
width: 100%;
|
|
70
|
-
box-sizing: border-box;
|
|
71
|
-
transition: background-color var(--matcha-duration-instant, 80ms) ease,
|
|
72
|
-
border-color var(--matcha-duration-instant, 80ms) ease;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.matcha-nav-item__icon {
|
|
76
|
-
flex-shrink: 0;
|
|
77
|
-
width: 20px;
|
|
78
|
-
height: 20px;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.matcha-nav-item__label {
|
|
82
|
-
flex: 1;
|
|
83
|
-
font-size: var(--matcha-text-body-md, 14px);
|
|
84
|
-
font-weight: 400;
|
|
85
|
-
line-height: 20px;
|
|
86
|
-
overflow: hidden;
|
|
87
|
-
text-overflow: ellipsis;
|
|
88
|
-
white-space: nowrap;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Badge — Figma DSV3 spec (matcha/badge variant Label/Danger):
|
|
92
|
-
// padding 2/8, gap 4, radius pill (9999), bg feedback/danger, caption (11/14, letter 0.3).
|
|
93
|
-
// Em Ativo, font-weight medium 500 (Figma).
|
|
94
|
-
.matcha-nav-item__badge {
|
|
95
|
-
flex-shrink: 0;
|
|
96
|
-
display: inline-flex;
|
|
97
|
-
align-items: center;
|
|
98
|
-
justify-content: center;
|
|
99
|
-
padding: var(--matcha-space-025, 2px) var(--matcha-space-100, 8px);
|
|
100
|
-
gap: var(--matcha-space-050, 4px);
|
|
101
|
-
border-radius: var(--matcha-radius-pill, 9999px);
|
|
102
|
-
font-family: var(--matcha-font-family);
|
|
103
|
-
font-size: var(--matcha-text-p-tiny, 11px);
|
|
104
|
-
line-height: var(--matcha-leading-p-tiny, 14px);
|
|
105
|
-
letter-spacing: var(--matcha-letter-spacing-caption, 0.3px);
|
|
106
|
-
font-weight: 400;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Contador de itens da seção (drawer header) — número discreto à direita do label.
|
|
110
|
-
.matcha-nav-item__count {
|
|
111
|
-
flex-shrink: 0;
|
|
112
|
-
font-family: var(--matcha-font-family);
|
|
113
|
-
font-size: 11px;
|
|
114
|
-
font-weight: 600;
|
|
115
|
-
line-height: 16px;
|
|
116
|
-
letter-spacing: 0.4px;
|
|
117
|
-
color: var(--matcha-color-text-secondary);
|
|
118
|
-
opacity: 0.7;
|
|
119
|
-
margin-left: auto;
|
|
120
|
-
margin-right: 4px;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Chevron — SVG matcha-icon variant=right (fixo). Rotaciona 90° via CSS quando
|
|
124
|
-
// item está expandido. Easing-emphasized (Material 3 spring) pra rotação smooth.
|
|
125
|
-
.matcha-nav-item__chevron {
|
|
126
|
-
flex-shrink: 0;
|
|
127
|
-
width: 16px;
|
|
128
|
-
height: 16px;
|
|
129
|
-
opacity: 0.5;
|
|
130
|
-
transition: transform var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
131
|
-
transform: rotate(0deg);
|
|
132
|
-
|
|
133
|
-
.matcha-nav-item--expanded & {
|
|
134
|
-
transform: rotate(90deg);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Indented variant (subitem) — Figma DSV3: só label, padding 6/8/24, radius sm.
|
|
139
|
-
.matcha-nav-item--indented .matcha-nav-item__row {
|
|
140
|
-
padding-block: var(--matcha-space-075, 6px);
|
|
141
|
-
padding-inline: var(--matcha-space-300, 24px) var(--matcha-space-100, 8px);
|
|
142
|
-
border-radius: var(--matcha-radius-sm, 2px);
|
|
143
|
-
|
|
144
|
-
.matcha-nav-item__label {
|
|
145
|
-
font-size: var(--matcha-text-body-sm, 12px);
|
|
146
|
-
line-height: 16px;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Esconde slots não-canônicos do indentado (Figma só permite label).
|
|
150
|
-
.matcha-nav-item__icon,
|
|
151
|
-
.matcha-nav-item__badge,
|
|
152
|
-
.matcha-nav-item__chevron {
|
|
153
|
-
display: none;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Children container (nav-items aninhados quando pai está expandido).
|
|
158
|
-
// Flex column garante que filhos empilhem verticalmente, NÃO inline com o row.
|
|
159
|
-
// Gap 4px igual ao items slot do panel — mantém rítmo visual consistente.
|
|
160
|
-
// Margin-top 4px separa o primeiro filho do row do pai.
|
|
161
|
-
//
|
|
162
|
-
// Animation: fade + slight slide-down ao montar (cada vez que *ngIf entra).
|
|
163
|
-
// Duration fast 200ms easing-emphasized — entra suave, não abrupto.
|
|
164
|
-
.matcha-nav-item__children {
|
|
165
|
-
display: flex;
|
|
166
|
-
flex-direction: column;
|
|
167
|
-
align-items: stretch;
|
|
168
|
-
gap: var(--matcha-space-050, 4px);
|
|
169
|
-
margin-top: var(--matcha-space-050, 4px);
|
|
170
|
-
width: 100%;
|
|
171
|
-
animation: matcha-nav-item-children-in
|
|
172
|
-
var(--matcha-duration-fast, 200ms)
|
|
173
|
-
var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
@keyframes matcha-nav-item-children-in {
|
|
177
|
-
from { opacity: 0; transform: translateY(-4px); }
|
|
178
|
-
to { opacity: 1; transform: translateY(0); }
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// ── Nav Rail (72px sidebar — Figma DSV3 1:1 com matcha/nav-rail) ────────────
|
|
182
|
-
|
|
183
|
-
.matcha-nav-rail {
|
|
184
|
-
// Wrapper externo: 72px wide, full height.
|
|
185
|
-
// Bg surface/bg (1 nível abaixo do panel) — cria depth tonal sutil sem
|
|
186
|
-
// precisar de border ou shadow. Pattern canônico de DS modernos (Slack,
|
|
187
|
-
// VS Code, Linear): rail "recuado" + panel "elevado". Hierarquia Z via tom.
|
|
188
|
-
display: flex;
|
|
189
|
-
flex-direction: column;
|
|
190
|
-
align-items: center;
|
|
191
|
-
width: 72px;
|
|
192
|
-
height: 100%;
|
|
193
|
-
flex-shrink: 0;
|
|
194
|
-
box-sizing: border-box;
|
|
195
|
-
overflow: hidden;
|
|
196
|
-
padding: 0;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.matcha-nav-rail__header {
|
|
200
|
-
// Figma: 72×56, padding 4/0, flex row center.
|
|
201
|
-
display: flex;
|
|
202
|
-
flex-direction: row;
|
|
203
|
-
align-items: center;
|
|
204
|
-
justify-content: center;
|
|
205
|
-
width: 100%;
|
|
206
|
-
height: var(--matcha-grid-header-height, 56px);
|
|
207
|
-
padding: var(--matcha-space-050, 4px) 0;
|
|
208
|
-
flex-shrink: 0;
|
|
209
|
-
box-sizing: border-box;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.matcha-nav-rail__modules {
|
|
213
|
-
// Figma: padding 12/0, gap 4, flex column center.
|
|
214
|
-
display: flex;
|
|
215
|
-
flex-direction: column;
|
|
216
|
-
align-items: center;
|
|
217
|
-
gap: var(--matcha-space-050, 4px);
|
|
218
|
-
padding: var(--matcha-space-150, 12px) 0;
|
|
219
|
-
flex: 1;
|
|
220
|
-
width: 100%;
|
|
221
|
-
box-sizing: border-box;
|
|
222
|
-
overflow-y: auto;
|
|
223
|
-
overflow-x: hidden;
|
|
224
|
-
|
|
225
|
-
// Hide scrollbar but keep scroll
|
|
226
|
-
scrollbar-width: none;
|
|
227
|
-
&::-webkit-scrollbar { display: none; }
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Module button — Figma: 44×44 (touch target), radius 12, sem padding.
|
|
231
|
-
// Suporta tanto o atributo de slot (consumer projeta com `matcha-nav-rail-module`)
|
|
232
|
-
// quanto a classe BEM (caso consumer use `.matcha-nav-rail__module` diretamente).
|
|
233
|
-
[matcha-nav-rail-module],
|
|
234
|
-
.matcha-nav-rail__module {
|
|
235
|
-
display: flex;
|
|
236
|
-
align-items: center;
|
|
237
|
-
justify-content: center;
|
|
238
|
-
width: 44px;
|
|
239
|
-
height: 44px;
|
|
240
|
-
padding: 0;
|
|
241
|
-
border: 0;
|
|
242
|
-
background: transparent;
|
|
243
|
-
border-radius: var(--matcha-radius-xl, 12px);
|
|
244
|
-
cursor: pointer;
|
|
245
|
-
flex-shrink: 0;
|
|
246
|
-
position: relative;
|
|
247
|
-
// Reset pra <button>
|
|
248
|
-
appearance: none;
|
|
249
|
-
font: inherit;
|
|
250
|
-
color: inherit;
|
|
251
|
-
transition: background-color var(--matcha-duration-instant, 80ms) ease,
|
|
252
|
-
color var(--matcha-duration-instant, 80ms) ease;
|
|
253
|
-
|
|
254
|
-
// Focus-visible — keyboard nav.
|
|
255
|
-
&:focus-visible {
|
|
256
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
257
|
-
outline-offset: var(--matcha-state-focus-ring-offset, 2px);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Desabilitado — irmão do .matcha-nav-item--disabled (mesma dupla
|
|
261
|
-
// pointer-events/cursor aqui; a cor fica no mixin de tema). Cobre as 3 formas:
|
|
262
|
-
// o `disabled` nativo do <button>, o atributo em elemento que não é button
|
|
263
|
-
// (o slot aceita <a>) e o aria-disabled de quem precisa manter o foco.
|
|
264
|
-
// Sem isto, um módulo desabilitado renderiza IDÊNTICO ao habilitado e o
|
|
265
|
-
// usuário clica sem entender por que nada acontece.
|
|
266
|
-
&:disabled,
|
|
267
|
-
&[disabled],
|
|
268
|
-
&[aria-disabled="true"] {
|
|
269
|
-
cursor: default;
|
|
270
|
-
pointer-events: none;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// ── Nav Rail labeled (84px — nome do módulo embaixo do ícone) ───────────────
|
|
275
|
-
// Variante ativada por `<matcha-nav-rail labeled>`. O slot do label fica oculto
|
|
276
|
-
// por padrão, então o consumer mantém o <span> no template e só alterna a flag.
|
|
277
|
-
// Header fica de fora do resize: o hamburger não recebe label (56px fixos).
|
|
278
|
-
|
|
279
|
-
.matcha-nav-rail [matcha-nav-rail-module-label],
|
|
280
|
-
.matcha-nav-rail .matcha-nav-rail__module-label {
|
|
281
|
-
display: none;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
.matcha-nav-rail--labeled {
|
|
285
|
-
width: 84px;
|
|
286
|
-
|
|
287
|
-
.matcha-nav-rail__modules,
|
|
288
|
-
.matcha-nav-rail__footer {
|
|
289
|
-
[matcha-nav-rail-module],
|
|
290
|
-
.matcha-nav-rail__module {
|
|
291
|
-
flex-direction: column;
|
|
292
|
-
gap: var(--matcha-space-050, 4px);
|
|
293
|
-
width: 76px;
|
|
294
|
-
height: auto;
|
|
295
|
-
min-height: 64px;
|
|
296
|
-
padding-block: var(--matcha-space-075, 6px);
|
|
297
|
-
padding-inline: var(--matcha-space-050, 4px);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
[matcha-nav-rail-module-label],
|
|
301
|
-
.matcha-nav-rail__module-label {
|
|
302
|
-
// -webkit-box + line-clamp: 2 linhas máx com ellipsis. Nome longo
|
|
303
|
-
// ("Configurações") quebra em vez de estourar os 76px do botão.
|
|
304
|
-
display: -webkit-box;
|
|
305
|
-
-webkit-box-orient: vertical;
|
|
306
|
-
-webkit-line-clamp: 2;
|
|
307
|
-
overflow: hidden;
|
|
308
|
-
max-width: 100%;
|
|
309
|
-
font-family: var(--matcha-font-family);
|
|
310
|
-
font-size: var(--matcha-text-2xs, 10px);
|
|
311
|
-
line-height: var(--matcha-leading-p-tiny, 14px);
|
|
312
|
-
letter-spacing: var(--matcha-letter-spacing-caption, 0.3px);
|
|
313
|
-
font-weight: 400;
|
|
314
|
-
text-align: center;
|
|
315
|
-
overflow-wrap: break-word;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
.matcha-nav-rail__footer {
|
|
321
|
-
// Figma: padding 8/0, flex column center.
|
|
322
|
-
display: flex;
|
|
323
|
-
flex-direction: column;
|
|
324
|
-
align-items: center;
|
|
325
|
-
width: 100%;
|
|
326
|
-
padding: var(--matcha-space-100, 8px) 0;
|
|
327
|
-
flex-shrink: 0;
|
|
328
|
-
box-sizing: border-box;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
.matcha-nav-rail__divider {
|
|
332
|
-
// Figma: 28×1, bg surface/border (rgba(255,255,255,0.12) dark).
|
|
333
|
-
// Sem opacity extra — token já tem 12% built-in.
|
|
334
|
-
flex-shrink: 0;
|
|
335
|
-
width: 28px;
|
|
336
|
-
height: 1px;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// ── Nav Panel (216px sub-panel — Figma DSV3 1:1 com matcha/nav-panel) ───────
|
|
340
|
-
// Estrutura: header (title-row) → divider 192×1 → items slot.
|
|
341
|
-
// Bg surface/card · só border-right (não border completa) · width 216 fixa.
|
|
342
|
-
|
|
343
|
-
.matcha-nav-panel {
|
|
344
|
-
display: flex;
|
|
345
|
-
flex-direction: column;
|
|
346
|
-
align-items: stretch;
|
|
347
|
-
width: 216px;
|
|
348
|
-
height: 100%;
|
|
349
|
-
box-sizing: border-box;
|
|
350
|
-
padding: 0;
|
|
351
|
-
overflow: hidden;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Header — Figma: padding 20/20/16/20, gap 16.
|
|
355
|
-
// Logical properties pra suporte RTL automático.
|
|
356
|
-
// Aceita slot custom via [matcha-nav-panel-header] OU default title-row.
|
|
357
|
-
.matcha-nav-panel__header {
|
|
358
|
-
display: flex;
|
|
359
|
-
flex-direction: column;
|
|
360
|
-
align-items: flex-start;
|
|
361
|
-
gap: var(--matcha-space-200, 16px);
|
|
362
|
-
padding-block-start: var(--matcha-space-250, 20px);
|
|
363
|
-
padding-block-end: var(--matcha-space-200, 16px);
|
|
364
|
-
padding-inline: var(--matcha-space-250, 20px);
|
|
365
|
-
width: 100%;
|
|
366
|
-
box-sizing: border-box;
|
|
367
|
-
flex-shrink: 0;
|
|
368
|
-
|
|
369
|
-
// Default title-row some quando consumer projeta slot custom
|
|
370
|
-
// (priority pro custom, sem precisar de boolean prop).
|
|
371
|
-
&:has([matcha-nav-panel-header]) .matcha-nav-panel__title-row--default {
|
|
372
|
-
display: none;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// Title row — Figma: padding 0, gap 8, body-md regular 14/20.
|
|
377
|
-
.matcha-nav-panel__title-row {
|
|
378
|
-
display: flex;
|
|
379
|
-
flex-direction: row;
|
|
380
|
-
align-items: center;
|
|
381
|
-
gap: var(--matcha-space-100, 8px);
|
|
382
|
-
width: 100%;
|
|
383
|
-
height: 20px;
|
|
384
|
-
min-width: 0;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
.matcha-nav-panel__title-icon {
|
|
388
|
-
flex-shrink: 0;
|
|
389
|
-
width: 16px;
|
|
390
|
-
height: 16px;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
.matcha-nav-panel__title {
|
|
394
|
-
flex: 1;
|
|
395
|
-
font-family: var(--matcha-font-family);
|
|
396
|
-
font-size: var(--matcha-text-body-md, 14px);
|
|
397
|
-
font-weight: 400;
|
|
398
|
-
line-height: 20px;
|
|
399
|
-
overflow: hidden;
|
|
400
|
-
text-overflow: ellipsis;
|
|
401
|
-
white-space: nowrap;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Divider — Figma: 192×1 (= 216 - 12 - 12 padding sides), sibling do header.
|
|
405
|
-
// Centrado via margin auto.
|
|
406
|
-
.matcha-nav-panel__divider {
|
|
407
|
-
flex-shrink: 0;
|
|
408
|
-
width: 192px;
|
|
409
|
-
height: 1px;
|
|
410
|
-
margin: 0 auto;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Items slot — Figma: padding 12 (todos lados), gap 4, scroll vertical.
|
|
414
|
-
.matcha-nav-panel__items {
|
|
415
|
-
display: flex;
|
|
416
|
-
flex-direction: column;
|
|
417
|
-
align-items: stretch;
|
|
418
|
-
gap: var(--matcha-space-050, 4px);
|
|
419
|
-
padding: var(--matcha-space-150, 12px);
|
|
420
|
-
flex: 1;
|
|
421
|
-
width: 100%;
|
|
422
|
-
box-sizing: border-box;
|
|
423
|
-
overflow-y: auto;
|
|
424
|
-
overflow-x: hidden;
|
|
425
|
-
|
|
426
|
-
// Hide scrollbar mas mantém scroll funcional.
|
|
427
|
-
scrollbar-width: thin;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// ── Command Palette ──────────────────────────────────────────────────────────
|
|
431
|
-
// Estilos do command-palette movidos pra matcha-command-palette.scss (canônico).
|
|
432
|
-
// Mantido aqui só o reduced-motion das outras nav classes.
|
|
433
|
-
|
|
434
|
-
@media (prefers-reduced-motion: reduce) {
|
|
435
|
-
.matcha-nav-item,
|
|
436
|
-
.matcha-nav-rail__module {
|
|
437
|
-
animation: none;
|
|
438
|
-
transition: none;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// ── Forced colors (Windows High Contrast) ──────────────────────────────────
|
|
443
|
-
// Bgs translúcidos (accent-surface-hover, accent-alpha) somem em high-contrast.
|
|
444
|
-
// Usa system colors (Highlight, SelectedItem, CanvasText) sempre visíveis.
|
|
445
|
-
@media (forced-colors: active) {
|
|
446
|
-
// ── Nav Item ──
|
|
447
|
-
.matcha-nav-item {
|
|
448
|
-
forced-color-adjust: none;
|
|
449
|
-
|
|
450
|
-
&.matcha-nav-item--active > .matcha-nav-item__row {
|
|
451
|
-
background: Highlight;
|
|
452
|
-
color: HighlightText;
|
|
453
|
-
border-inline-start: 3px solid Highlight;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
&:not(.matcha-nav-item--disabled):not(.matcha-nav-item--active) > .matcha-nav-item__row:hover,
|
|
457
|
-
&.matcha-nav-item--expanded:not(.matcha-nav-item--active) > .matcha-nav-item__row {
|
|
458
|
-
background: SelectedItem;
|
|
459
|
-
color: SelectedItemText;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
&:focus-visible .matcha-nav-item__row {
|
|
463
|
-
outline-color: CanvasText;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// ── Nav Rail ──
|
|
468
|
-
.matcha-nav-rail {
|
|
469
|
-
border-inline-end-color: CanvasText;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
[matcha-nav-rail-module]:hover:not([aria-current]):not(.matcha-nav-rail__module--active),
|
|
473
|
-
.matcha-nav-rail__module:hover:not([aria-current]):not(.matcha-nav-rail__module--active) {
|
|
474
|
-
background: SelectedItem;
|
|
475
|
-
color: SelectedItemText;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
[matcha-nav-rail-module][aria-current],
|
|
479
|
-
[matcha-nav-rail-module].matcha-nav-rail__module--active,
|
|
480
|
-
.matcha-nav-rail__module--active {
|
|
481
|
-
background: Highlight;
|
|
482
|
-
color: HighlightText;
|
|
483
|
-
|
|
484
|
-
matcha-icon { color: HighlightText; }
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
.matcha-nav-rail__divider {
|
|
488
|
-
background-color: CanvasText;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// ── Nav Panel ──
|
|
492
|
-
.matcha-nav-panel {
|
|
493
|
-
border-color: CanvasText;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
.matcha-nav-panel__divider {
|
|
497
|
-
background-color: CanvasText;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// ── Command Palette: high-contrast em matcha-command-palette.scss ──
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// ── Nav Drawer ───────────────────────────────────────────────────────────────
|
|
504
|
-
// Navegação em drawer (Figma DSV3 node 19228:2014) — a forma da navegação quando
|
|
505
|
-
// não há espaço pro par rail + panel. Compõe matcha-drawer-container +
|
|
506
|
-
// matcha-drawer mode=over; aqui só a anatomia e o ritmo da árvore.
|
|
507
|
-
|
|
508
|
-
.matcha-nav-drawer {
|
|
509
|
-
// Cobre a viewport pra ancorar o backdrop do container (que é absolute/inset:0).
|
|
510
|
-
// Sem isso o scrim ficaria do tamanho do pai onde o drawer foi declarado.
|
|
511
|
-
position: fixed;
|
|
512
|
-
inset: 0;
|
|
513
|
-
z-index: var(--matcha-nav-drawer-z, 1000);
|
|
514
|
-
// Fechado não pode capturar clique da página que está por baixo.
|
|
515
|
-
pointer-events: none;
|
|
516
|
-
|
|
517
|
-
&.matcha-nav-drawer--opened {
|
|
518
|
-
pointer-events: auto;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// Contained — ancora no ancestral posicionado em vez da viewport. Preview e
|
|
522
|
-
// embed (playground da doc dentro de um frame de phone). Mesmo cenário que o
|
|
523
|
-
// matcha-drawer já reconhece no max-height do bottom sheet.
|
|
524
|
-
&.matcha-nav-drawer--contained {
|
|
525
|
-
position: absolute;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// O container tem bg opaco próprio (é feito pra envolver a app). Aqui ele é só
|
|
529
|
-
// âncora de posicionamento — opaco cobriria a página inteira mesmo fechado.
|
|
530
|
-
.matcha-drawer-container {
|
|
531
|
-
height: 100%;
|
|
532
|
-
background-color: transparent;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// Ritmo dos slots: a navegação define o próprio (Figma), não o padding 20/20
|
|
536
|
-
// genérico do drawer. As CSS vars existem pra isso — sem !important.
|
|
537
|
-
matcha-drawer {
|
|
538
|
-
--drawer-pad-x: var(--matcha-space-150, 12px);
|
|
539
|
-
--drawer-pad-y: var(--matcha-space-150, 12px);
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Header — brand à esquerda, close à direita (space-between vem do slot).
|
|
543
|
-
.matcha-nav-drawer__brand {
|
|
544
|
-
display: flex;
|
|
545
|
-
align-items: center;
|
|
546
|
-
min-width: 0;
|
|
547
|
-
gap: var(--matcha-space-100, 8px);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// Busca — largura total, logo abaixo do header e antes da árvore.
|
|
551
|
-
.matcha-nav-drawer__search {
|
|
552
|
-
display: block;
|
|
553
|
-
width: 100%;
|
|
554
|
-
flex-shrink: 0;
|
|
555
|
-
|
|
556
|
-
> * {
|
|
557
|
-
width: 100%;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Árvore de navegação.
|
|
562
|
-
.matcha-nav-drawer__items {
|
|
563
|
-
display: flex;
|
|
564
|
-
flex-direction: column;
|
|
565
|
-
align-items: stretch;
|
|
566
|
-
gap: var(--matcha-space-050, 4px);
|
|
567
|
-
width: 100%;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// Hierarquia de 3 níveis. O matcha-nav-item só tem UM flag de indentação
|
|
571
|
-
// (`indented`), reservado ao nível 3 — que também é o único que o Figma
|
|
572
|
-
// permite sem ícone/chevron. O recuo do nível 2 vem daqui, do container,
|
|
573
|
-
// pra não sobrecarregar o contrato público do nav-item nem mexer no desktop.
|
|
574
|
-
//
|
|
575
|
-
// 24px = ícone (16) + gap (8) do row do módulo. Isso alinha o label do filho
|
|
576
|
-
// com o label do pai, formando uma coluna de texto. Com menos que isso o filho
|
|
577
|
-
// renderiza à ESQUERDA do label do pai (o pai tem ícone, o filho não) e a
|
|
578
|
-
// hierarquia lê invertida. O nível 3 soma os 24 do `indented` por cima.
|
|
579
|
-
.matcha-nav-drawer__items > .matcha-nav-item > .matcha-nav-item__children {
|
|
580
|
-
padding-inline-start: var(--matcha-space-300, 24px);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Footer — lista de itens empilhada. O slot do drawer é feito pra botões de
|
|
584
|
-
// ação (row, alinhado à direita); a navegação precisa do oposto.
|
|
585
|
-
.matcha-drawer__slot--footer > * {
|
|
586
|
-
flex-direction: column;
|
|
587
|
-
align-items: stretch;
|
|
588
|
-
justify-content: flex-start;
|
|
589
|
-
gap: var(--matcha-space-025, 2px);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
.matcha-nav-drawer__footer {
|
|
593
|
-
display: flex;
|
|
594
|
-
flex-direction: column;
|
|
595
|
-
align-items: stretch;
|
|
596
|
-
gap: var(--matcha-space-025, 2px);
|
|
597
|
-
width: 100%;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
// O wrapper do slot existe sempre (é do template), então o :has() do drawer
|
|
601
|
-
// não consegue esconder o footer vazio sozinho — a checagem real é esta.
|
|
602
|
-
.matcha-drawer__slot--footer:not(:has(matcha-nav-drawer-footer)) {
|
|
603
|
-
display: none;
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// ── Print ──────────────────────────────────────────────────────────────────
|
|
608
|
-
// Convenção DS: chrome de navegação some em impressão — conteúdo full-page.
|
|
609
|
-
@media print {
|
|
610
|
-
.matcha-nav-rail,
|
|
611
|
-
.matcha-nav-panel,
|
|
612
|
-
.matcha-nav-drawer {
|
|
613
|
-
display: none !important;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// =============================================================================
|
|
618
|
-
// Theme mixin
|
|
619
|
-
// =============================================================================
|
|
620
|
-
|
|
621
|
-
@mixin matcha-nav-theme($theme) {
|
|
622
|
-
// ── Nav Item ── Figma DSV3 (node 14998:10045) — tokens accent diretos
|
|
623
|
-
// Bg/border/etc aplicados no .matcha-nav-item__row (não no host) — assim
|
|
624
|
-
// os filhos aninhados não herdam o bg do pai expandido/ativo.
|
|
625
|
-
.matcha-nav-item {
|
|
626
|
-
color: var(--matcha-color-text-primary);
|
|
627
|
-
|
|
628
|
-
.matcha-nav-item__label {
|
|
629
|
-
color: var(--matcha-color-text-primary);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
.matcha-nav-item__icon,
|
|
633
|
-
.matcha-nav-item__chevron {
|
|
634
|
-
color: var(--matcha-color-text-secondary);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// Hover — bg accent/surface-hover direto (Figma usa este token, não state-layer).
|
|
638
|
-
&:not(.matcha-nav-item--disabled):not(.matcha-nav-item--active) > .matcha-nav-item__row:hover {
|
|
639
|
-
background-color: var(--matcha-color-accent-surface-hover);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// Ativo — bg accent/alpha + border-inline-start 3px accent + label medium.
|
|
643
|
-
// 1:1 literal Figma. Aplicado no __row (não host) pra não vazar pros filhos.
|
|
644
|
-
&.matcha-nav-item--active > .matcha-nav-item__row {
|
|
645
|
-
background-color: var(--matcha-color-accent-alpha);
|
|
646
|
-
border-inline-start: 3px solid var(--matcha-color-accent);
|
|
647
|
-
|
|
648
|
-
.matcha-nav-item__label {
|
|
649
|
-
font-weight: var(--matcha-weight-medium, 500);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
.matcha-nav-item__badge {
|
|
653
|
-
font-weight: var(--matcha-weight-medium, 500);
|
|
654
|
-
color: var(--matcha-color-text-inverse, #1a1d21);
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// Expandido — pai com filhos abertos: bg accent/surface-pressed.
|
|
659
|
-
&.matcha-nav-item--expanded:not(.matcha-nav-item--active) > .matcha-nav-item__row {
|
|
660
|
-
background-color: var(--matcha-color-accent-surface-pressed);
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
// Badge — Figma DSV3 feedback/danger bg + danger-contrast fg (Padrão).
|
|
664
|
-
.matcha-nav-item__badge {
|
|
665
|
-
background: var(--matcha-color-feedback-danger);
|
|
666
|
-
color: var(--matcha-color-feedback-danger-contrast, rgba(0, 0, 0, 0.87));
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
// Disabled — texto/ícone caem pra disabled-fg.
|
|
670
|
-
&.matcha-nav-item--disabled {
|
|
671
|
-
.matcha-nav-item__label,
|
|
672
|
-
.matcha-nav-item__icon,
|
|
673
|
-
.matcha-nav-item__chevron {
|
|
674
|
-
color: var(--matcha-color-interaction-disabled-fg);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// Indented — placeholder pra futuras diferenças de tema (border já no base).
|
|
680
|
-
|
|
681
|
-
// ── Nav Rail (depth sutil — light/dark adaptativo) ──
|
|
682
|
-
// Bg = surface-bg (page layer) + 4% foreground overlay via color-mix.
|
|
683
|
-
// Cria tonal step VISIBLE em ambos modes:
|
|
684
|
-
// - Light: surface-bg #f1f4f1 + 4% fg #2a2d33 → ~#e8ebe7 (recesso vs page brighter)
|
|
685
|
-
// - Dark: surface-bg #111318 + 4% fg #e8eaed → ~#1a1c20 (peak vs page darker)
|
|
686
|
-
// Antes usava surface-card 85% transparente, que em light ficava imperceptível
|
|
687
|
-
// (surface-card ≈ surface-bg no zona do branco — humano não distingue ~7 units).
|
|
688
|
-
.matcha-nav-rail {
|
|
689
|
-
background-color: color-mix(
|
|
690
|
-
in srgb,
|
|
691
|
-
var(--matcha-color-surface-bg) 96%,
|
|
692
|
-
var(--matcha-color-fg) 4%
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
[matcha-nav-rail-module],
|
|
697
|
-
.matcha-nav-rail__module {
|
|
698
|
-
// Inactive: text-secondary no button + override no matcha-icon filho
|
|
699
|
-
// (matcha-icon tem regra global no theme com mesma especificidade,
|
|
700
|
-
// então precisa target explícito pra vencer no cascade).
|
|
701
|
-
color: var(--matcha-color-text-secondary);
|
|
702
|
-
|
|
703
|
-
matcha-icon {
|
|
704
|
-
color: var(--matcha-color-text-secondary);
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
// Hover (inactive): bg accent/surface-hover (state-layer canon Figma).
|
|
708
|
-
&:hover:not(.matcha-nav-rail__module--active):not([aria-current]) {
|
|
709
|
-
background-color: var(--matcha-color-accent-surface-hover);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// Active: bg accent/surface-hover + icon accent.
|
|
713
|
-
// Figma usa #161E12 (accent/surface-hover token), não accent/alpha.
|
|
714
|
-
// Aceita .--active class OU aria-current (pattern ARIA canônico).
|
|
715
|
-
&.matcha-nav-rail__module--active,
|
|
716
|
-
&[aria-current] {
|
|
717
|
-
background-color: var(--matcha-color-accent-surface-hover);
|
|
718
|
-
color: var(--matcha-color-accent);
|
|
719
|
-
|
|
720
|
-
matcha-icon {
|
|
721
|
-
color: var(--matcha-color-accent);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
// Labeled: ícone E label sobem pra accent (color herdado) + label medium,
|
|
725
|
-
// espelhando o nav-item ativo.
|
|
726
|
-
[matcha-nav-rail-module-label],
|
|
727
|
-
.matcha-nav-rail__module-label {
|
|
728
|
-
font-weight: var(--matcha-weight-medium, 500);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
// Desabilitado — mesmo token de cor do nav-item disabled, pra os dois
|
|
733
|
-
// estados lerem igual. Depois do bloco ativo de propósito: um módulo
|
|
734
|
-
// desabilitado não deve ficar com a cor de ativo.
|
|
735
|
-
&:disabled,
|
|
736
|
-
&[disabled],
|
|
737
|
-
&[aria-disabled="true"] {
|
|
738
|
-
color: var(--matcha-color-interaction-disabled-fg);
|
|
739
|
-
|
|
740
|
-
matcha-icon {
|
|
741
|
-
color: var(--matcha-color-interaction-disabled-fg);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
.matcha-nav-rail__divider {
|
|
747
|
-
background-color: var(--matcha-color-surface-border);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// ── Nav Panel (Figma DSV3 1:1) ──
|
|
751
|
-
// bg surface/card (1 step acima do rail). Sem shadow — só tonal hierarchy.
|
|
752
|
-
.matcha-nav-panel {
|
|
753
|
-
background-color: var(--matcha-color-surface-card);
|
|
754
|
-
border-right: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
.matcha-nav-panel__divider {
|
|
758
|
-
background-color: var(--matcha-color-surface-border);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
.matcha-nav-panel__title {
|
|
762
|
-
color: var(--matcha-color-text-primary);
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
.matcha-nav-panel__title-icon {
|
|
766
|
-
color: var(--matcha-color-text-secondary);
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
// ── Command Palette theme em matcha-command-palette.scss (canônico) ──
|
|
770
|
-
}
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// matcha-nav.scss — Navigation system (nav-item, nav-rail, nav-panel, command-palette)
|
|
5
|
+
// =============================================================================
|
|
6
|
+
|
|
7
|
+
// ── Nav Item ─────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
// Host: wrapper estrutural. Não tem padding/bg — só layout column pra empilhar
|
|
10
|
+
// row + children. Permite que o consumer aninhe nav-items sem quebrar o layout.
|
|
11
|
+
.matcha-nav-item {
|
|
12
|
+
position: relative;
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
align-items: stretch;
|
|
16
|
+
width: 100%;
|
|
17
|
+
text-decoration: none;
|
|
18
|
+
color: inherit;
|
|
19
|
+
user-select: none;
|
|
20
|
+
// Reset pra <button>/<a> caso o host venha como esses elementos.
|
|
21
|
+
appearance: none;
|
|
22
|
+
border: 0;
|
|
23
|
+
background: transparent;
|
|
24
|
+
font: inherit;
|
|
25
|
+
text-align: start;
|
|
26
|
+
outline: none;
|
|
27
|
+
|
|
28
|
+
&.matcha-nav-item--disabled {
|
|
29
|
+
pointer-events: none;
|
|
30
|
+
cursor: default;
|
|
31
|
+
|
|
32
|
+
.matcha-nav-item__row {
|
|
33
|
+
cursor: default;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Focus-visible no host (keyboard) → repassa pro __row (visual).
|
|
38
|
+
&:focus-visible .matcha-nav-item__row {
|
|
39
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
40
|
+
outline-offset: calc(-1 * var(--matcha-state-focus-ring-width, 2px));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Row: o "botão" visível do nav-item — Figma DSV3 1:1.
|
|
45
|
+
// Expansível: pad 8/12, gap 8, radius md (4px), body-md (14/20 regular)
|
|
46
|
+
// Indentado: pad 6/8/24, gap 8, radius sm (2px), body-sm (12/16 regular)
|
|
47
|
+
// Ativo: bg accent/alpha + border-inline-start 3px accent + label medium 500
|
|
48
|
+
// Hover: bg accent/surface-hover
|
|
49
|
+
// Expandido: bg accent/surface-pressed
|
|
50
|
+
//
|
|
51
|
+
// box-sizing: border-box + border-inline-start: 3px solid accent (no Ativo)
|
|
52
|
+
// gera shift de 3px no content (Padrão @12 → Ativo @15) — literal Figma.
|
|
53
|
+
.matcha-nav-item__row {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: row;
|
|
56
|
+
align-items: center;
|
|
57
|
+
gap: var(--matcha-space-100, 8px);
|
|
58
|
+
padding-block: var(--matcha-space-100, 8px);
|
|
59
|
+
padding-inline: var(--matcha-space-150, 12px);
|
|
60
|
+
border-radius: var(--matcha-radius-md, 4px);
|
|
61
|
+
border: 0;
|
|
62
|
+
background: transparent;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
// O row é <a> quando o item tem [routerLink]/[href] — sem este reset a âncora
|
|
65
|
+
// traz sublinhado e a cor de link do browser. As demais regras já eram agnósticas
|
|
66
|
+
// de tag (border: 0, background: transparent atendiam o <button>).
|
|
67
|
+
text-decoration: none;
|
|
68
|
+
color: inherit;
|
|
69
|
+
width: 100%;
|
|
70
|
+
box-sizing: border-box;
|
|
71
|
+
transition: background-color var(--matcha-duration-instant, 80ms) ease,
|
|
72
|
+
border-color var(--matcha-duration-instant, 80ms) ease;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.matcha-nav-item__icon {
|
|
76
|
+
flex-shrink: 0;
|
|
77
|
+
width: 20px;
|
|
78
|
+
height: 20px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.matcha-nav-item__label {
|
|
82
|
+
flex: 1;
|
|
83
|
+
font-size: var(--matcha-text-body-md, 14px);
|
|
84
|
+
font-weight: 400;
|
|
85
|
+
line-height: 20px;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
text-overflow: ellipsis;
|
|
88
|
+
white-space: nowrap;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Badge — Figma DSV3 spec (matcha/badge variant Label/Danger):
|
|
92
|
+
// padding 2/8, gap 4, radius pill (9999), bg feedback/danger, caption (11/14, letter 0.3).
|
|
93
|
+
// Em Ativo, font-weight medium 500 (Figma).
|
|
94
|
+
.matcha-nav-item__badge {
|
|
95
|
+
flex-shrink: 0;
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
padding: var(--matcha-space-025, 2px) var(--matcha-space-100, 8px);
|
|
100
|
+
gap: var(--matcha-space-050, 4px);
|
|
101
|
+
border-radius: var(--matcha-radius-pill, 9999px);
|
|
102
|
+
font-family: var(--matcha-font-family);
|
|
103
|
+
font-size: var(--matcha-text-p-tiny, 11px);
|
|
104
|
+
line-height: var(--matcha-leading-p-tiny, 14px);
|
|
105
|
+
letter-spacing: var(--matcha-letter-spacing-caption, 0.3px);
|
|
106
|
+
font-weight: 400;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Contador de itens da seção (drawer header) — número discreto à direita do label.
|
|
110
|
+
.matcha-nav-item__count {
|
|
111
|
+
flex-shrink: 0;
|
|
112
|
+
font-family: var(--matcha-font-family);
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
line-height: 16px;
|
|
116
|
+
letter-spacing: 0.4px;
|
|
117
|
+
color: var(--matcha-color-text-secondary);
|
|
118
|
+
opacity: 0.7;
|
|
119
|
+
margin-left: auto;
|
|
120
|
+
margin-right: 4px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Chevron — SVG matcha-icon variant=right (fixo). Rotaciona 90° via CSS quando
|
|
124
|
+
// item está expandido. Easing-emphasized (Material 3 spring) pra rotação smooth.
|
|
125
|
+
.matcha-nav-item__chevron {
|
|
126
|
+
flex-shrink: 0;
|
|
127
|
+
width: 16px;
|
|
128
|
+
height: 16px;
|
|
129
|
+
opacity: 0.5;
|
|
130
|
+
transition: transform var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
131
|
+
transform: rotate(0deg);
|
|
132
|
+
|
|
133
|
+
.matcha-nav-item--expanded & {
|
|
134
|
+
transform: rotate(90deg);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Indented variant (subitem) — Figma DSV3: só label, padding 6/8/24, radius sm.
|
|
139
|
+
.matcha-nav-item--indented .matcha-nav-item__row {
|
|
140
|
+
padding-block: var(--matcha-space-075, 6px);
|
|
141
|
+
padding-inline: var(--matcha-space-300, 24px) var(--matcha-space-100, 8px);
|
|
142
|
+
border-radius: var(--matcha-radius-sm, 2px);
|
|
143
|
+
|
|
144
|
+
.matcha-nav-item__label {
|
|
145
|
+
font-size: var(--matcha-text-body-sm, 12px);
|
|
146
|
+
line-height: 16px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Esconde slots não-canônicos do indentado (Figma só permite label).
|
|
150
|
+
.matcha-nav-item__icon,
|
|
151
|
+
.matcha-nav-item__badge,
|
|
152
|
+
.matcha-nav-item__chevron {
|
|
153
|
+
display: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Children container (nav-items aninhados quando pai está expandido).
|
|
158
|
+
// Flex column garante que filhos empilhem verticalmente, NÃO inline com o row.
|
|
159
|
+
// Gap 4px igual ao items slot do panel — mantém rítmo visual consistente.
|
|
160
|
+
// Margin-top 4px separa o primeiro filho do row do pai.
|
|
161
|
+
//
|
|
162
|
+
// Animation: fade + slight slide-down ao montar (cada vez que *ngIf entra).
|
|
163
|
+
// Duration fast 200ms easing-emphasized — entra suave, não abrupto.
|
|
164
|
+
.matcha-nav-item__children {
|
|
165
|
+
display: flex;
|
|
166
|
+
flex-direction: column;
|
|
167
|
+
align-items: stretch;
|
|
168
|
+
gap: var(--matcha-space-050, 4px);
|
|
169
|
+
margin-top: var(--matcha-space-050, 4px);
|
|
170
|
+
width: 100%;
|
|
171
|
+
animation: matcha-nav-item-children-in
|
|
172
|
+
var(--matcha-duration-fast, 200ms)
|
|
173
|
+
var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@keyframes matcha-nav-item-children-in {
|
|
177
|
+
from { opacity: 0; transform: translateY(-4px); }
|
|
178
|
+
to { opacity: 1; transform: translateY(0); }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ── Nav Rail (72px sidebar — Figma DSV3 1:1 com matcha/nav-rail) ────────────
|
|
182
|
+
|
|
183
|
+
.matcha-nav-rail {
|
|
184
|
+
// Wrapper externo: 72px wide, full height.
|
|
185
|
+
// Bg surface/bg (1 nível abaixo do panel) — cria depth tonal sutil sem
|
|
186
|
+
// precisar de border ou shadow. Pattern canônico de DS modernos (Slack,
|
|
187
|
+
// VS Code, Linear): rail "recuado" + panel "elevado". Hierarquia Z via tom.
|
|
188
|
+
display: flex;
|
|
189
|
+
flex-direction: column;
|
|
190
|
+
align-items: center;
|
|
191
|
+
width: 72px;
|
|
192
|
+
height: 100%;
|
|
193
|
+
flex-shrink: 0;
|
|
194
|
+
box-sizing: border-box;
|
|
195
|
+
overflow: hidden;
|
|
196
|
+
padding: 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.matcha-nav-rail__header {
|
|
200
|
+
// Figma: 72×56, padding 4/0, flex row center.
|
|
201
|
+
display: flex;
|
|
202
|
+
flex-direction: row;
|
|
203
|
+
align-items: center;
|
|
204
|
+
justify-content: center;
|
|
205
|
+
width: 100%;
|
|
206
|
+
height: var(--matcha-grid-header-height, 56px);
|
|
207
|
+
padding: var(--matcha-space-050, 4px) 0;
|
|
208
|
+
flex-shrink: 0;
|
|
209
|
+
box-sizing: border-box;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.matcha-nav-rail__modules {
|
|
213
|
+
// Figma: padding 12/0, gap 4, flex column center.
|
|
214
|
+
display: flex;
|
|
215
|
+
flex-direction: column;
|
|
216
|
+
align-items: center;
|
|
217
|
+
gap: var(--matcha-space-050, 4px);
|
|
218
|
+
padding: var(--matcha-space-150, 12px) 0;
|
|
219
|
+
flex: 1;
|
|
220
|
+
width: 100%;
|
|
221
|
+
box-sizing: border-box;
|
|
222
|
+
overflow-y: auto;
|
|
223
|
+
overflow-x: hidden;
|
|
224
|
+
|
|
225
|
+
// Hide scrollbar but keep scroll
|
|
226
|
+
scrollbar-width: none;
|
|
227
|
+
&::-webkit-scrollbar { display: none; }
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Module button — Figma: 44×44 (touch target), radius 12, sem padding.
|
|
231
|
+
// Suporta tanto o atributo de slot (consumer projeta com `matcha-nav-rail-module`)
|
|
232
|
+
// quanto a classe BEM (caso consumer use `.matcha-nav-rail__module` diretamente).
|
|
233
|
+
[matcha-nav-rail-module],
|
|
234
|
+
.matcha-nav-rail__module {
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
justify-content: center;
|
|
238
|
+
width: 44px;
|
|
239
|
+
height: 44px;
|
|
240
|
+
padding: 0;
|
|
241
|
+
border: 0;
|
|
242
|
+
background: transparent;
|
|
243
|
+
border-radius: var(--matcha-radius-xl, 12px);
|
|
244
|
+
cursor: pointer;
|
|
245
|
+
flex-shrink: 0;
|
|
246
|
+
position: relative;
|
|
247
|
+
// Reset pra <button>
|
|
248
|
+
appearance: none;
|
|
249
|
+
font: inherit;
|
|
250
|
+
color: inherit;
|
|
251
|
+
transition: background-color var(--matcha-duration-instant, 80ms) ease,
|
|
252
|
+
color var(--matcha-duration-instant, 80ms) ease;
|
|
253
|
+
|
|
254
|
+
// Focus-visible — keyboard nav.
|
|
255
|
+
&:focus-visible {
|
|
256
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
257
|
+
outline-offset: var(--matcha-state-focus-ring-offset, 2px);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Desabilitado — irmão do .matcha-nav-item--disabled (mesma dupla
|
|
261
|
+
// pointer-events/cursor aqui; a cor fica no mixin de tema). Cobre as 3 formas:
|
|
262
|
+
// o `disabled` nativo do <button>, o atributo em elemento que não é button
|
|
263
|
+
// (o slot aceita <a>) e o aria-disabled de quem precisa manter o foco.
|
|
264
|
+
// Sem isto, um módulo desabilitado renderiza IDÊNTICO ao habilitado e o
|
|
265
|
+
// usuário clica sem entender por que nada acontece.
|
|
266
|
+
&:disabled,
|
|
267
|
+
&[disabled],
|
|
268
|
+
&[aria-disabled="true"] {
|
|
269
|
+
cursor: default;
|
|
270
|
+
pointer-events: none;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ── Nav Rail labeled (84px — nome do módulo embaixo do ícone) ───────────────
|
|
275
|
+
// Variante ativada por `<matcha-nav-rail labeled>`. O slot do label fica oculto
|
|
276
|
+
// por padrão, então o consumer mantém o <span> no template e só alterna a flag.
|
|
277
|
+
// Header fica de fora do resize: o hamburger não recebe label (56px fixos).
|
|
278
|
+
|
|
279
|
+
.matcha-nav-rail [matcha-nav-rail-module-label],
|
|
280
|
+
.matcha-nav-rail .matcha-nav-rail__module-label {
|
|
281
|
+
display: none;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.matcha-nav-rail--labeled {
|
|
285
|
+
width: 84px;
|
|
286
|
+
|
|
287
|
+
.matcha-nav-rail__modules,
|
|
288
|
+
.matcha-nav-rail__footer {
|
|
289
|
+
[matcha-nav-rail-module],
|
|
290
|
+
.matcha-nav-rail__module {
|
|
291
|
+
flex-direction: column;
|
|
292
|
+
gap: var(--matcha-space-050, 4px);
|
|
293
|
+
width: 76px;
|
|
294
|
+
height: auto;
|
|
295
|
+
min-height: 64px;
|
|
296
|
+
padding-block: var(--matcha-space-075, 6px);
|
|
297
|
+
padding-inline: var(--matcha-space-050, 4px);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
[matcha-nav-rail-module-label],
|
|
301
|
+
.matcha-nav-rail__module-label {
|
|
302
|
+
// -webkit-box + line-clamp: 2 linhas máx com ellipsis. Nome longo
|
|
303
|
+
// ("Configurações") quebra em vez de estourar os 76px do botão.
|
|
304
|
+
display: -webkit-box;
|
|
305
|
+
-webkit-box-orient: vertical;
|
|
306
|
+
-webkit-line-clamp: 2;
|
|
307
|
+
overflow: hidden;
|
|
308
|
+
max-width: 100%;
|
|
309
|
+
font-family: var(--matcha-font-family);
|
|
310
|
+
font-size: var(--matcha-text-2xs, 10px);
|
|
311
|
+
line-height: var(--matcha-leading-p-tiny, 14px);
|
|
312
|
+
letter-spacing: var(--matcha-letter-spacing-caption, 0.3px);
|
|
313
|
+
font-weight: 400;
|
|
314
|
+
text-align: center;
|
|
315
|
+
overflow-wrap: break-word;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.matcha-nav-rail__footer {
|
|
321
|
+
// Figma: padding 8/0, flex column center.
|
|
322
|
+
display: flex;
|
|
323
|
+
flex-direction: column;
|
|
324
|
+
align-items: center;
|
|
325
|
+
width: 100%;
|
|
326
|
+
padding: var(--matcha-space-100, 8px) 0;
|
|
327
|
+
flex-shrink: 0;
|
|
328
|
+
box-sizing: border-box;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.matcha-nav-rail__divider {
|
|
332
|
+
// Figma: 28×1, bg surface/border (rgba(255,255,255,0.12) dark).
|
|
333
|
+
// Sem opacity extra — token já tem 12% built-in.
|
|
334
|
+
flex-shrink: 0;
|
|
335
|
+
width: 28px;
|
|
336
|
+
height: 1px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// ── Nav Panel (216px sub-panel — Figma DSV3 1:1 com matcha/nav-panel) ───────
|
|
340
|
+
// Estrutura: header (title-row) → divider 192×1 → items slot.
|
|
341
|
+
// Bg surface/card · só border-right (não border completa) · width 216 fixa.
|
|
342
|
+
|
|
343
|
+
.matcha-nav-panel {
|
|
344
|
+
display: flex;
|
|
345
|
+
flex-direction: column;
|
|
346
|
+
align-items: stretch;
|
|
347
|
+
width: 216px;
|
|
348
|
+
height: 100%;
|
|
349
|
+
box-sizing: border-box;
|
|
350
|
+
padding: 0;
|
|
351
|
+
overflow: hidden;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Header — Figma: padding 20/20/16/20, gap 16.
|
|
355
|
+
// Logical properties pra suporte RTL automático.
|
|
356
|
+
// Aceita slot custom via [matcha-nav-panel-header] OU default title-row.
|
|
357
|
+
.matcha-nav-panel__header {
|
|
358
|
+
display: flex;
|
|
359
|
+
flex-direction: column;
|
|
360
|
+
align-items: flex-start;
|
|
361
|
+
gap: var(--matcha-space-200, 16px);
|
|
362
|
+
padding-block-start: var(--matcha-space-250, 20px);
|
|
363
|
+
padding-block-end: var(--matcha-space-200, 16px);
|
|
364
|
+
padding-inline: var(--matcha-space-250, 20px);
|
|
365
|
+
width: 100%;
|
|
366
|
+
box-sizing: border-box;
|
|
367
|
+
flex-shrink: 0;
|
|
368
|
+
|
|
369
|
+
// Default title-row some quando consumer projeta slot custom
|
|
370
|
+
// (priority pro custom, sem precisar de boolean prop).
|
|
371
|
+
&:has([matcha-nav-panel-header]) .matcha-nav-panel__title-row--default {
|
|
372
|
+
display: none;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Title row — Figma: padding 0, gap 8, body-md regular 14/20.
|
|
377
|
+
.matcha-nav-panel__title-row {
|
|
378
|
+
display: flex;
|
|
379
|
+
flex-direction: row;
|
|
380
|
+
align-items: center;
|
|
381
|
+
gap: var(--matcha-space-100, 8px);
|
|
382
|
+
width: 100%;
|
|
383
|
+
height: 20px;
|
|
384
|
+
min-width: 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.matcha-nav-panel__title-icon {
|
|
388
|
+
flex-shrink: 0;
|
|
389
|
+
width: 16px;
|
|
390
|
+
height: 16px;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.matcha-nav-panel__title {
|
|
394
|
+
flex: 1;
|
|
395
|
+
font-family: var(--matcha-font-family);
|
|
396
|
+
font-size: var(--matcha-text-body-md, 14px);
|
|
397
|
+
font-weight: 400;
|
|
398
|
+
line-height: 20px;
|
|
399
|
+
overflow: hidden;
|
|
400
|
+
text-overflow: ellipsis;
|
|
401
|
+
white-space: nowrap;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Divider — Figma: 192×1 (= 216 - 12 - 12 padding sides), sibling do header.
|
|
405
|
+
// Centrado via margin auto.
|
|
406
|
+
.matcha-nav-panel__divider {
|
|
407
|
+
flex-shrink: 0;
|
|
408
|
+
width: 192px;
|
|
409
|
+
height: 1px;
|
|
410
|
+
margin: 0 auto;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Items slot — Figma: padding 12 (todos lados), gap 4, scroll vertical.
|
|
414
|
+
.matcha-nav-panel__items {
|
|
415
|
+
display: flex;
|
|
416
|
+
flex-direction: column;
|
|
417
|
+
align-items: stretch;
|
|
418
|
+
gap: var(--matcha-space-050, 4px);
|
|
419
|
+
padding: var(--matcha-space-150, 12px);
|
|
420
|
+
flex: 1;
|
|
421
|
+
width: 100%;
|
|
422
|
+
box-sizing: border-box;
|
|
423
|
+
overflow-y: auto;
|
|
424
|
+
overflow-x: hidden;
|
|
425
|
+
|
|
426
|
+
// Hide scrollbar mas mantém scroll funcional.
|
|
427
|
+
scrollbar-width: thin;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// ── Command Palette ──────────────────────────────────────────────────────────
|
|
431
|
+
// Estilos do command-palette movidos pra matcha-command-palette.scss (canônico).
|
|
432
|
+
// Mantido aqui só o reduced-motion das outras nav classes.
|
|
433
|
+
|
|
434
|
+
@media (prefers-reduced-motion: reduce) {
|
|
435
|
+
.matcha-nav-item,
|
|
436
|
+
.matcha-nav-rail__module {
|
|
437
|
+
animation: none;
|
|
438
|
+
transition: none;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// ── Forced colors (Windows High Contrast) ──────────────────────────────────
|
|
443
|
+
// Bgs translúcidos (accent-surface-hover, accent-alpha) somem em high-contrast.
|
|
444
|
+
// Usa system colors (Highlight, SelectedItem, CanvasText) sempre visíveis.
|
|
445
|
+
@media (forced-colors: active) {
|
|
446
|
+
// ── Nav Item ──
|
|
447
|
+
.matcha-nav-item {
|
|
448
|
+
forced-color-adjust: none;
|
|
449
|
+
|
|
450
|
+
&.matcha-nav-item--active > .matcha-nav-item__row {
|
|
451
|
+
background: Highlight;
|
|
452
|
+
color: HighlightText;
|
|
453
|
+
border-inline-start: 3px solid Highlight;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
&:not(.matcha-nav-item--disabled):not(.matcha-nav-item--active) > .matcha-nav-item__row:hover,
|
|
457
|
+
&.matcha-nav-item--expanded:not(.matcha-nav-item--active) > .matcha-nav-item__row {
|
|
458
|
+
background: SelectedItem;
|
|
459
|
+
color: SelectedItemText;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
&:focus-visible .matcha-nav-item__row {
|
|
463
|
+
outline-color: CanvasText;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// ── Nav Rail ──
|
|
468
|
+
.matcha-nav-rail {
|
|
469
|
+
border-inline-end-color: CanvasText;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
[matcha-nav-rail-module]:hover:not([aria-current]):not(.matcha-nav-rail__module--active),
|
|
473
|
+
.matcha-nav-rail__module:hover:not([aria-current]):not(.matcha-nav-rail__module--active) {
|
|
474
|
+
background: SelectedItem;
|
|
475
|
+
color: SelectedItemText;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
[matcha-nav-rail-module][aria-current],
|
|
479
|
+
[matcha-nav-rail-module].matcha-nav-rail__module--active,
|
|
480
|
+
.matcha-nav-rail__module--active {
|
|
481
|
+
background: Highlight;
|
|
482
|
+
color: HighlightText;
|
|
483
|
+
|
|
484
|
+
matcha-icon { color: HighlightText; }
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.matcha-nav-rail__divider {
|
|
488
|
+
background-color: CanvasText;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// ── Nav Panel ──
|
|
492
|
+
.matcha-nav-panel {
|
|
493
|
+
border-color: CanvasText;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.matcha-nav-panel__divider {
|
|
497
|
+
background-color: CanvasText;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// ── Command Palette: high-contrast em matcha-command-palette.scss ──
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// ── Nav Drawer ───────────────────────────────────────────────────────────────
|
|
504
|
+
// Navegação em drawer (Figma DSV3 node 19228:2014) — a forma da navegação quando
|
|
505
|
+
// não há espaço pro par rail + panel. Compõe matcha-drawer-container +
|
|
506
|
+
// matcha-drawer mode=over; aqui só a anatomia e o ritmo da árvore.
|
|
507
|
+
|
|
508
|
+
.matcha-nav-drawer {
|
|
509
|
+
// Cobre a viewport pra ancorar o backdrop do container (que é absolute/inset:0).
|
|
510
|
+
// Sem isso o scrim ficaria do tamanho do pai onde o drawer foi declarado.
|
|
511
|
+
position: fixed;
|
|
512
|
+
inset: 0;
|
|
513
|
+
z-index: var(--matcha-nav-drawer-z, 1000);
|
|
514
|
+
// Fechado não pode capturar clique da página que está por baixo.
|
|
515
|
+
pointer-events: none;
|
|
516
|
+
|
|
517
|
+
&.matcha-nav-drawer--opened {
|
|
518
|
+
pointer-events: auto;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Contained — ancora no ancestral posicionado em vez da viewport. Preview e
|
|
522
|
+
// embed (playground da doc dentro de um frame de phone). Mesmo cenário que o
|
|
523
|
+
// matcha-drawer já reconhece no max-height do bottom sheet.
|
|
524
|
+
&.matcha-nav-drawer--contained {
|
|
525
|
+
position: absolute;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// O container tem bg opaco próprio (é feito pra envolver a app). Aqui ele é só
|
|
529
|
+
// âncora de posicionamento — opaco cobriria a página inteira mesmo fechado.
|
|
530
|
+
.matcha-drawer-container {
|
|
531
|
+
height: 100%;
|
|
532
|
+
background-color: transparent;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Ritmo dos slots: a navegação define o próprio (Figma), não o padding 20/20
|
|
536
|
+
// genérico do drawer. As CSS vars existem pra isso — sem !important.
|
|
537
|
+
matcha-drawer {
|
|
538
|
+
--drawer-pad-x: var(--matcha-space-150, 12px);
|
|
539
|
+
--drawer-pad-y: var(--matcha-space-150, 12px);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Header — brand à esquerda, close à direita (space-between vem do slot).
|
|
543
|
+
.matcha-nav-drawer__brand {
|
|
544
|
+
display: flex;
|
|
545
|
+
align-items: center;
|
|
546
|
+
min-width: 0;
|
|
547
|
+
gap: var(--matcha-space-100, 8px);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Busca — largura total, logo abaixo do header e antes da árvore.
|
|
551
|
+
.matcha-nav-drawer__search {
|
|
552
|
+
display: block;
|
|
553
|
+
width: 100%;
|
|
554
|
+
flex-shrink: 0;
|
|
555
|
+
|
|
556
|
+
> * {
|
|
557
|
+
width: 100%;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Árvore de navegação.
|
|
562
|
+
.matcha-nav-drawer__items {
|
|
563
|
+
display: flex;
|
|
564
|
+
flex-direction: column;
|
|
565
|
+
align-items: stretch;
|
|
566
|
+
gap: var(--matcha-space-050, 4px);
|
|
567
|
+
width: 100%;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Hierarquia de 3 níveis. O matcha-nav-item só tem UM flag de indentação
|
|
571
|
+
// (`indented`), reservado ao nível 3 — que também é o único que o Figma
|
|
572
|
+
// permite sem ícone/chevron. O recuo do nível 2 vem daqui, do container,
|
|
573
|
+
// pra não sobrecarregar o contrato público do nav-item nem mexer no desktop.
|
|
574
|
+
//
|
|
575
|
+
// 24px = ícone (16) + gap (8) do row do módulo. Isso alinha o label do filho
|
|
576
|
+
// com o label do pai, formando uma coluna de texto. Com menos que isso o filho
|
|
577
|
+
// renderiza à ESQUERDA do label do pai (o pai tem ícone, o filho não) e a
|
|
578
|
+
// hierarquia lê invertida. O nível 3 soma os 24 do `indented` por cima.
|
|
579
|
+
.matcha-nav-drawer__items > .matcha-nav-item > .matcha-nav-item__children {
|
|
580
|
+
padding-inline-start: var(--matcha-space-300, 24px);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Footer — lista de itens empilhada. O slot do drawer é feito pra botões de
|
|
584
|
+
// ação (row, alinhado à direita); a navegação precisa do oposto.
|
|
585
|
+
.matcha-drawer__slot--footer > * {
|
|
586
|
+
flex-direction: column;
|
|
587
|
+
align-items: stretch;
|
|
588
|
+
justify-content: flex-start;
|
|
589
|
+
gap: var(--matcha-space-025, 2px);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.matcha-nav-drawer__footer {
|
|
593
|
+
display: flex;
|
|
594
|
+
flex-direction: column;
|
|
595
|
+
align-items: stretch;
|
|
596
|
+
gap: var(--matcha-space-025, 2px);
|
|
597
|
+
width: 100%;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// O wrapper do slot existe sempre (é do template), então o :has() do drawer
|
|
601
|
+
// não consegue esconder o footer vazio sozinho — a checagem real é esta.
|
|
602
|
+
.matcha-drawer__slot--footer:not(:has(matcha-nav-drawer-footer)) {
|
|
603
|
+
display: none;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// ── Print ──────────────────────────────────────────────────────────────────
|
|
608
|
+
// Convenção DS: chrome de navegação some em impressão — conteúdo full-page.
|
|
609
|
+
@media print {
|
|
610
|
+
.matcha-nav-rail,
|
|
611
|
+
.matcha-nav-panel,
|
|
612
|
+
.matcha-nav-drawer {
|
|
613
|
+
display: none !important;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// =============================================================================
|
|
618
|
+
// Theme mixin
|
|
619
|
+
// =============================================================================
|
|
620
|
+
|
|
621
|
+
@mixin matcha-nav-theme($theme) {
|
|
622
|
+
// ── Nav Item ── Figma DSV3 (node 14998:10045) — tokens accent diretos
|
|
623
|
+
// Bg/border/etc aplicados no .matcha-nav-item__row (não no host) — assim
|
|
624
|
+
// os filhos aninhados não herdam o bg do pai expandido/ativo.
|
|
625
|
+
.matcha-nav-item {
|
|
626
|
+
color: var(--matcha-color-text-primary);
|
|
627
|
+
|
|
628
|
+
.matcha-nav-item__label {
|
|
629
|
+
color: var(--matcha-color-text-primary);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.matcha-nav-item__icon,
|
|
633
|
+
.matcha-nav-item__chevron {
|
|
634
|
+
color: var(--matcha-color-text-secondary);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Hover — bg accent/surface-hover direto (Figma usa este token, não state-layer).
|
|
638
|
+
&:not(.matcha-nav-item--disabled):not(.matcha-nav-item--active) > .matcha-nav-item__row:hover {
|
|
639
|
+
background-color: var(--matcha-color-accent-surface-hover);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Ativo — bg accent/alpha + border-inline-start 3px accent + label medium.
|
|
643
|
+
// 1:1 literal Figma. Aplicado no __row (não host) pra não vazar pros filhos.
|
|
644
|
+
&.matcha-nav-item--active > .matcha-nav-item__row {
|
|
645
|
+
background-color: var(--matcha-color-accent-alpha);
|
|
646
|
+
border-inline-start: 3px solid var(--matcha-color-accent);
|
|
647
|
+
|
|
648
|
+
.matcha-nav-item__label {
|
|
649
|
+
font-weight: var(--matcha-weight-medium, 500);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
.matcha-nav-item__badge {
|
|
653
|
+
font-weight: var(--matcha-weight-medium, 500);
|
|
654
|
+
color: var(--matcha-color-text-inverse, #1a1d21);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Expandido — pai com filhos abertos: bg accent/surface-pressed.
|
|
659
|
+
&.matcha-nav-item--expanded:not(.matcha-nav-item--active) > .matcha-nav-item__row {
|
|
660
|
+
background-color: var(--matcha-color-accent-surface-pressed);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Badge — Figma DSV3 feedback/danger bg + danger-contrast fg (Padrão).
|
|
664
|
+
.matcha-nav-item__badge {
|
|
665
|
+
background: var(--matcha-color-feedback-danger);
|
|
666
|
+
color: var(--matcha-color-feedback-danger-contrast, rgba(0, 0, 0, 0.87));
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Disabled — texto/ícone caem pra disabled-fg.
|
|
670
|
+
&.matcha-nav-item--disabled {
|
|
671
|
+
.matcha-nav-item__label,
|
|
672
|
+
.matcha-nav-item__icon,
|
|
673
|
+
.matcha-nav-item__chevron {
|
|
674
|
+
color: var(--matcha-color-interaction-disabled-fg);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Indented — placeholder pra futuras diferenças de tema (border já no base).
|
|
680
|
+
|
|
681
|
+
// ── Nav Rail (depth sutil — light/dark adaptativo) ──
|
|
682
|
+
// Bg = surface-bg (page layer) + 4% foreground overlay via color-mix.
|
|
683
|
+
// Cria tonal step VISIBLE em ambos modes:
|
|
684
|
+
// - Light: surface-bg #f1f4f1 + 4% fg #2a2d33 → ~#e8ebe7 (recesso vs page brighter)
|
|
685
|
+
// - Dark: surface-bg #111318 + 4% fg #e8eaed → ~#1a1c20 (peak vs page darker)
|
|
686
|
+
// Antes usava surface-card 85% transparente, que em light ficava imperceptível
|
|
687
|
+
// (surface-card ≈ surface-bg no zona do branco — humano não distingue ~7 units).
|
|
688
|
+
.matcha-nav-rail {
|
|
689
|
+
background-color: color-mix(
|
|
690
|
+
in srgb,
|
|
691
|
+
var(--matcha-color-surface-bg) 96%,
|
|
692
|
+
var(--matcha-color-fg) 4%
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
[matcha-nav-rail-module],
|
|
697
|
+
.matcha-nav-rail__module {
|
|
698
|
+
// Inactive: text-secondary no button + override no matcha-icon filho
|
|
699
|
+
// (matcha-icon tem regra global no theme com mesma especificidade,
|
|
700
|
+
// então precisa target explícito pra vencer no cascade).
|
|
701
|
+
color: var(--matcha-color-text-secondary);
|
|
702
|
+
|
|
703
|
+
matcha-icon {
|
|
704
|
+
color: var(--matcha-color-text-secondary);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// Hover (inactive): bg accent/surface-hover (state-layer canon Figma).
|
|
708
|
+
&:hover:not(.matcha-nav-rail__module--active):not([aria-current]) {
|
|
709
|
+
background-color: var(--matcha-color-accent-surface-hover);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// Active: bg accent/surface-hover + icon accent.
|
|
713
|
+
// Figma usa #161E12 (accent/surface-hover token), não accent/alpha.
|
|
714
|
+
// Aceita .--active class OU aria-current (pattern ARIA canônico).
|
|
715
|
+
&.matcha-nav-rail__module--active,
|
|
716
|
+
&[aria-current] {
|
|
717
|
+
background-color: var(--matcha-color-accent-surface-hover);
|
|
718
|
+
color: var(--matcha-color-accent);
|
|
719
|
+
|
|
720
|
+
matcha-icon {
|
|
721
|
+
color: var(--matcha-color-accent);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Labeled: ícone E label sobem pra accent (color herdado) + label medium,
|
|
725
|
+
// espelhando o nav-item ativo.
|
|
726
|
+
[matcha-nav-rail-module-label],
|
|
727
|
+
.matcha-nav-rail__module-label {
|
|
728
|
+
font-weight: var(--matcha-weight-medium, 500);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// Desabilitado — mesmo token de cor do nav-item disabled, pra os dois
|
|
733
|
+
// estados lerem igual. Depois do bloco ativo de propósito: um módulo
|
|
734
|
+
// desabilitado não deve ficar com a cor de ativo.
|
|
735
|
+
&:disabled,
|
|
736
|
+
&[disabled],
|
|
737
|
+
&[aria-disabled="true"] {
|
|
738
|
+
color: var(--matcha-color-interaction-disabled-fg);
|
|
739
|
+
|
|
740
|
+
matcha-icon {
|
|
741
|
+
color: var(--matcha-color-interaction-disabled-fg);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.matcha-nav-rail__divider {
|
|
747
|
+
background-color: var(--matcha-color-surface-border);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// ── Nav Panel (Figma DSV3 1:1) ──
|
|
751
|
+
// bg surface/card (1 step acima do rail). Sem shadow — só tonal hierarchy.
|
|
752
|
+
.matcha-nav-panel {
|
|
753
|
+
background-color: var(--matcha-color-surface-card);
|
|
754
|
+
border-right: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.matcha-nav-panel__divider {
|
|
758
|
+
background-color: var(--matcha-color-surface-border);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.matcha-nav-panel__title {
|
|
762
|
+
color: var(--matcha-color-text-primary);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.matcha-nav-panel__title-icon {
|
|
766
|
+
color: var(--matcha-color-text-secondary);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// ── Command Palette theme em matcha-command-palette.scss (canônico) ──
|
|
770
|
+
}
|