@salesforce/metadata-visualizer-web 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,724 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ **/
7
+
8
+ /* Light theme — VS Code "Light Modern" aligned, tuned so every meaningful
9
+ color clears its WCAG floor on a light canvas. This sheet declares the full
10
+ `--vscode-*` layer that vscode-design-system.css reads for its `--mv-*`
11
+ tokens; without it, a plain browser iframe falls to the base sheet's dark
12
+ fallbacks. Body text clears WCAG-AA (4.5:1) and every graphical color clears
13
+ WCAG 1.4.11 (3:1) on white. Ratios in the trailing comments are measured
14
+ with the WCAG 2.x relative-luminance formula (the same math the parity test
15
+ uses). Dark is NOT re-authored here — dark remains the base sheet's inline
16
+ fallbacks, so the default (no-theme) bundle stays byte-identical. */
17
+ :root {
18
+ /* ===== Canvas / shell ===== */
19
+ --vscode-editor-background: #ffffff;
20
+ --vscode-foreground: #3b3b3b; /* 11.2:1 on white — deliberately not pure black */
21
+ --vscode-descriptionForeground: #5f6368; /* 6.05:1 on white */
22
+ --vscode-disabledForeground: #a1a1a1; /* 2.58:1 — disabled text is WCAG-exempt, not asserted */
23
+
24
+ /* ===== Node / surface backgrounds (near-white so foreground stays >= 4.5:1) ===== */
25
+ --vscode-editorWidget-background: #f8f8f8;
26
+ --vscode-sideBar-background: #f8f8f8;
27
+ --vscode-panel-background: #ffffff;
28
+ --vscode-dropdown-background: #ffffff;
29
+ --vscode-input-background: #ffffff;
30
+ --vscode-minimap-background: #f8f8f8;
31
+ --vscode-widget-background: rgba(255, 255, 255, 0.9);
32
+
33
+ /* ===== Interactive / chrome (text pairs >= 4.5:1) ===== */
34
+ --vscode-textLink-foreground: #005fb8; /* 6.31:1 on white */
35
+ --vscode-textLink-activeForeground: #005fb8; /* 6.31:1 on white */
36
+ --vscode-button-background: #005fb8;
37
+ --vscode-button-foreground: #ffffff; /* 6.31:1 on the button background */
38
+ --vscode-button-secondaryBackground: #e5e5e5;
39
+ --vscode-button-secondaryForeground: #3b3b3b; /* 8.89:1 on the secondary background */
40
+ --vscode-badge-background: #005fb8;
41
+ --vscode-badge-foreground: #ffffff;
42
+ --vscode-list-activeSelectionBackground: #0060c0;
43
+ --vscode-list-activeSelectionForeground: #ffffff; /* 6.11:1 on the selection background */
44
+ --vscode-textPreformat-foreground: #0a5c79; /* 7.45:1 on white */
45
+ --vscode-focusBorder: #005fb8;
46
+
47
+ /* ===== Borders / separators (structural, visible on white) ===== */
48
+ --vscode-editorGroup-border: #d4d4d4;
49
+ --vscode-widget-border: #d4d4d4;
50
+ --vscode-panel-border: #d4d4d4;
51
+ --vscode-input-border: #d4d4d4;
52
+ --vscode-dropdown-border: #d4d4d4;
53
+ --vscode-editorRuler-foreground: #d4d4d4;
54
+ --vscode-contrastBorder: transparent; /* High-contrast mode only; stays transparent otherwise */
55
+
56
+ /* ===== Charts / accents / edges (>= 3:1 on white) =====
57
+ Darkened from the SLDS bright hues so they clear the non-text floor on a
58
+ light canvas. The bright #4bca81 / #fe9339 / #e4a201 fail 3:1 on white and
59
+ are intentionally NOT used. These feed accent, status, and ERD-edge tokens
60
+ that color meaningful non-text graphics. */
61
+ --vscode-charts-blue: #0b66c2; /* 5.69:1 on white */
62
+ --vscode-charts-green: #137a3c; /* 5.42:1 on white — darkened from the bright green */
63
+ --vscode-charts-red: #d13438; /* 4.93:1 on white */
64
+ --vscode-charts-orange: #b5620a; /* 4.45:1 on white — darkened from the bright orange */
65
+ --vscode-charts-yellow: #946a00; /* 4.86:1 on white — a dark amber; bright yellow cannot clear 3:1 */
66
+ --vscode-charts-purple: #8250df; /* 5.05:1 on white */
67
+ --vscode-charts-lines: #767676; /* 4.54:1 on white — edges are meaningful; a faint ruler line fails */
68
+
69
+ /* ===== Status / ANSI (graphical >= 3:1, error text >= 4.5:1) ===== */
70
+ --vscode-terminal-ansiGreen: #137a3c; /* 5.42:1 on white */
71
+ --vscode-terminal-ansiCyan: #0a7c8c; /* 4.91:1 on white */
72
+ --vscode-terminal-ansiYellow: #946a00; /* 4.86:1 on white */
73
+ --vscode-errorForeground: #c4291c; /* 5.70:1 on white */
74
+ --vscode-inputValidation-errorBackground: #fdedeb;
75
+ --vscode-inputValidation-errorBorder: #c4291c;
76
+
77
+ /* ===== Syntax primitives (rendered as text inside nodes on #f8f8f8) ===== */
78
+ --vscode-debugTokenExpression-string: #a31515; /* 7.39:1 on #f8f8f8 */
79
+ --vscode-debugTokenExpression-number: #0a7d33; /* 4.95:1 on #f8f8f8 */
80
+ --vscode-debugTokenExpression-boolean: #0000ff; /* 8.09:1 on #f8f8f8 */
81
+ --vscode-debugTokenExpression-name: #001080; /* 14.27:1 on #f8f8f8 */
82
+ --vscode-symbolIcon-propertyForeground: #3b3b3b;
83
+ --vscode-symbolIcon-classForeground: #9a6700; /* 4.58:1 on #f8f8f8 — class icon is graphical */
84
+
85
+ /* ===== Selection / hover tints ===== */
86
+ --vscode-editor-selectionBackground: rgba(0, 95, 184, 0.15);
87
+ --vscode-list-hoverBackground: #f0f0f0;
88
+ --vscode-scrollbarSlider-background: rgba(100, 100, 100, 0.4);
89
+ --vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);
90
+ --vscode-widget-shadow: rgba(0, 0, 0, 0.16);
91
+
92
+ /* ===== Fonts (environmental, not color — carried over from the base sheet's
93
+ own fallbacks so the light bundle stays self-contained and all vars are
94
+ declared for parity) ===== */
95
+ --vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
96
+ --vscode-editor-font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace;
97
+ --vscode-editor-font-size: 13px;
98
+ --vscode-editor-font-weight: 400;
99
+ }
100
+
101
+
102
+ /* ===== RESET & BASE STYLES ===== */
103
+
104
+ *,
105
+ *::before,
106
+ *::after {
107
+ box-sizing: border-box;
108
+ }
109
+
110
+ html,
111
+ body {
112
+ margin: 0;
113
+ padding: 0;
114
+ width: 100%;
115
+ height: 100%;
116
+ overflow-x: hidden;
117
+ }
118
+
119
+ body {
120
+ font-family: var(--vscode-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
121
+ font-size: var(--vscode-editor-font-size, 13px);
122
+ font-weight: var(--vscode-editor-font-weight, 400);
123
+ line-height: 1.4;
124
+ color: var(--vscode-foreground, #cccccc);
125
+ background: var(--vscode-editor-background, #1e1e1e);
126
+ -webkit-font-smoothing: antialiased;
127
+ -moz-osx-font-smoothing: grayscale;
128
+ }
129
+
130
+ h1, h2, h3, h4, h5, h6,
131
+ p, blockquote, pre,
132
+ dl, dd, ol, ul,
133
+ figure, hr {
134
+ margin: 0;
135
+ padding: 0;
136
+ }
137
+
138
+ ol, ul {
139
+ list-style: none;
140
+ }
141
+
142
+ img {
143
+ max-width: 100%;
144
+ height: auto;
145
+ display: block;
146
+ }
147
+
148
+ button, input, select, textarea {
149
+ font-family: inherit;
150
+ font-size: inherit;
151
+ line-height: inherit;
152
+ }
153
+
154
+ button {
155
+ background: transparent;
156
+ border: none;
157
+ cursor: pointer;
158
+ padding: 0;
159
+ }
160
+
161
+ a {
162
+ color: var(--vscode-textLink-foreground, #3794ff);
163
+ text-decoration: none;
164
+ }
165
+
166
+ a:hover {
167
+ color: var(--vscode-textLink-activeForeground, #3794ff);
168
+ text-decoration: underline;
169
+ }
170
+
171
+ :focus-visible {
172
+ outline: 2px solid var(--vscode-focusBorder, #007fd4);
173
+ outline-offset: 2px;
174
+ }
175
+
176
+ ::-webkit-scrollbar {
177
+ width: 10px;
178
+ height: 10px;
179
+ }
180
+
181
+ ::-webkit-scrollbar-track {
182
+ background: var(--vscode-scrollbarSlider-background, rgba(121, 121, 121, 0.4));
183
+ }
184
+
185
+ ::-webkit-scrollbar-thumb {
186
+ background: var(--vscode-scrollbarSlider-background, rgba(121, 121, 121, 0.4));
187
+ border-radius: 10px;
188
+ }
189
+
190
+ ::-webkit-scrollbar-thumb:hover {
191
+ background: var(--vscode-scrollbarSlider-hoverBackground, rgba(100, 100, 100, 0.7));
192
+ }
193
+
194
+ /* ===== DESIGN TOKENS ===== */
195
+
196
+ :root {
197
+ /* ===== 1. CANVAS & SHELL (Global Environment) ===== */
198
+ /* The immutable stage - ensures every visualization looks native to VS Code */
199
+
200
+ /* Canvas */
201
+ --mv-canvas-bg: var(--vscode-editor-background, #1e1e1e);
202
+ --mv-canvas-grid: var(--vscode-editorRuler-foreground, #e5e5e5);
203
+ --mv-minimap-bg: var(--vscode-minimap-background, #f0f0f0);
204
+
205
+ /* Chrome / Shell */
206
+ --mv-panel-bg: var(--vscode-editorWidget-background, #252526);
207
+ --mv-panel-border: var(--vscode-editorGroup-border, #454545);
208
+ --mv-panel-shadow: 0 4px 16px var(--vscode-widget-shadow, rgba(0, 0, 0, 0.36));
209
+
210
+ /* ===== 2. CORE ENTITIES (Node Contract) ===== */
211
+ /* Base tokens for all entity cards - ensures consistent elevation and behavior */
212
+
213
+ /* Node Base */
214
+ --mv-node-bg: var(--vscode-editorWidget-background, #252526);
215
+ --mv-node-border: var(--vscode-widget-border, #454545);
216
+ --mv-node-border-focus: var(--vscode-focusBorder, #007fd4);
217
+
218
+ --mv-node-bg-hover: var(--vscode-list-hoverBackground, #2a2d2e);
219
+ --mv-node-bg-selected: var(--vscode-list-activeSelectionBackground, #094771);
220
+ --mv-node-fg: var(--vscode-foreground, #cccccc);
221
+ --mv-node-fg-secondary: var(--vscode-descriptionForeground, #cccccc99);
222
+ --mv-node-fg-selected: var(--vscode-list-activeSelectionForeground, #ffffff);
223
+
224
+ --mv-edge-neutral: var(--vscode-charts-lines, #cccccc);
225
+ --mv-edge-active: var(--vscode-textLink-activeForeground, #3794ff);
226
+
227
+ /* ===== 3. SEMANTIC VARIANTS & SYNTAX ===== */
228
+
229
+ /* 3A. Functional Accents - The "Four Pillars" */
230
+ /* Teams must map their metadata concepts to these four categories */
231
+ --mv-accent-data: var(--vscode-charts-purple, #b180d7);
232
+ --mv-accent-logic: var(--vscode-charts-blue, #3794ff);
233
+ --mv-accent-ui: var(--vscode-charts-yellow, #ffb454);
234
+ --mv-accent-system: var(--vscode-charts-orange, #d18616);
235
+
236
+ /* Syntax Primitives */
237
+ --mv-syntax-string: var(--vscode-debugTokenExpression-string, #ce9178);
238
+ --mv-syntax-number: var(--vscode-debugTokenExpression-number, #b5cea8);
239
+ --mv-syntax-boolean: var(--vscode-debugTokenExpression-boolean, #569cd6);
240
+ --mv-syntax-property: var(--vscode-symbolIcon-propertyForeground, #cccccc);
241
+ --mv-syntax-class: var(--vscode-symbolIcon-classForeground, #ee9d28);
242
+
243
+
244
+ /* 3B. State Indicators - Universal Status */
245
+ /* Teams must use these for state indication - custom colors forbidden */
246
+ --mv-status-positive: var(--vscode-charts-green, #23d18b);
247
+ --mv-status-negative: var(--vscode-charts-red, #f14c4c);
248
+ --mv-status-warning: var(--vscode-charts-orange, #d18616);
249
+ --mv-status-info: var(--vscode-charts-blue, #3794ff);
250
+ --mv-status-neutral: var(--vscode-disabledForeground, #656565);
251
+
252
+ /* ===== 4. INTERNAL COMPONENT TOKENS ===== */
253
+ /* Standardized internal elements for within nodes */
254
+ --mv-marker-primary: var(--vscode-foreground, #cccccc);
255
+ --mv-marker-muted: var(--vscode-disabledForeground, #656565);
256
+ --mv-separator: var(--vscode-editorRuler-foreground, #e5e5ee);
257
+ --mv-region-zone: var(--vscode-editor-selectionBackground, rgba(38, 79, 120, 0.4));
258
+
259
+ /* ===== 5. ACCESSIBILITY (High Contrast) ===== */
260
+ /* Platform-enforced overrides for High Contrast mode */
261
+ --mv-hc-border: var(--vscode-contrastBorder, transparent);
262
+ --mv-hc-selection: var(--vscode-focusBorder, #007fd4);
263
+
264
+ /* ===== GENERAL PURPOSE TOKENS ===== */
265
+
266
+ /* Background Colors */
267
+ --mv-bg-primary: var(--vscode-editor-background, #1e1e1e);
268
+ --mv-bg-secondary: var(--vscode-sideBar-background, #252526);
269
+ --mv-bg-elevated: var(--vscode-dropdown-background, #3c3c3c);
270
+ --mv-bg-surface: var(--vscode-panel-background, #1e1e1e);
271
+ --mv-bg-surface-hover: var(--vscode-list-hoverBackground, #2a2d2e);
272
+ --mv-bg-input: var(--vscode-input-background, #3c3c3c);
273
+ --mv-bg-badge: var(--vscode-badge-background, #4d4d4d);
274
+ --mv-fg-badge: var(--vscode-badge-foreground, #ffffff);
275
+
276
+ /* Text Colors */
277
+ --mv-text-primary: var(--vscode-foreground, #cccccc);
278
+ --mv-text-secondary: var(--vscode-descriptionForeground, #999999);
279
+ --mv-text-muted: var(--vscode-disabledForeground, #656565);
280
+ --mv-text-inverse: var(--vscode-list-activeSelectionForeground, #ffffff);
281
+
282
+ /* Interactive Colors */
283
+ --mv-interactive-primary: var(--vscode-textLink-foreground, #3794ff);
284
+ --mv-interactive-primary-hover: var(--vscode-textLink-activeForeground, #3794ff);
285
+ --mv-interactive-secondary: var(--vscode-textPreformat-foreground, #d7ba7d);
286
+ --mv-interactive-focus: var(--vscode-button-background, #0e639c);
287
+ --mv-interactive-focus-border: var(--vscode-focusBorder, #007fd4);
288
+ --mv-button-primary-bg: var(--vscode-button-background, #0e639c);
289
+ --mv-button-primary-fg: var(--vscode-button-foreground, #ffffff);
290
+ --mv-button-secondary-bg: var(--vscode-button-secondaryBackground, #5f6a79);
291
+ --mv-button-secondary-fg: var(--vscode-button-secondaryForeground, #ffffff);
292
+
293
+ /* Border Colors */
294
+ --mv-border-default: var(--vscode-panel-border, #454545);
295
+ --mv-border-primary: var(--vscode-editorGroup-border, #454545);
296
+ --mv-border-hover: var(--vscode-list-hoverBackground, #2a2d2e);
297
+ --mv-border-input: var(--vscode-input-border, #454545);
298
+ --mv-border-focus: var(--vscode-focusBorder, #007fd4);
299
+ --mv-border-dropdown: var(--vscode-dropdown-border, #454545);
300
+
301
+ /* Status Colors */
302
+ --mv-status-error: var(--vscode-errorForeground, #f14c4c);
303
+ --mv-status-error-bg: var(--vscode-inputValidation-errorBackground, #5a1d1d);
304
+ --mv-status-error-border: var(--vscode-inputValidation-errorBorder, #be1100);
305
+ --mv-status-success: var(--vscode-terminal-ansiGreen, #23d18b);
306
+
307
+ /* Accent Colors */
308
+ --mv-accent-cyan: var(--vscode-terminal-ansiCyan, #11b7ee);
309
+ --mv-accent-cyan-light: var(--vscode-debugTokenExpression-name, #9cdcfe);
310
+ --mv-accent-yellow: var(--vscode-terminal-ansiYellow, #ffb454);
311
+
312
+ /* Shadows & Effects */
313
+ --mv-shadow-light: rgba(0, 0, 0, 0.1);
314
+ --mv-shadow-medium: rgba(0, 0, 0, 0.15);
315
+ --mv-shadow-heavy: rgba(0, 0, 0, 0.3);
316
+ --mv-shadow-text: rgba(0, 0, 0, 0.4);
317
+ --mv-bg-overlay: var(--vscode-widget-background, rgba(37, 37, 38, 0.8));
318
+
319
+ /* Typography */
320
+ --mv-font-family: var(--vscode-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
321
+ --mv-font-family-mono: var(--vscode-editor-font-family, 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace);
322
+ --mv-font-size-xs: 0.75rem;
323
+ --mv-font-size-sm: 0.875rem;
324
+ --mv-font-size-base: 1rem;
325
+ --mv-font-size-lg: 1.125rem;
326
+ --mv-font-size-xl: 1.25rem;
327
+ --mv-font-size-2xl: 1.5rem;
328
+ --mv-font-size-3xl: 1.875rem;
329
+ --mv-font-weight-normal: 400;
330
+ --mv-font-weight-medium: 500;
331
+ --mv-font-weight-semibold: 600;
332
+ --mv-font-weight-bold: 700;
333
+ --mv-line-height-tight: 1.25;
334
+ --mv-line-height-normal: 1.5;
335
+ --mv-line-height-relaxed: 1.75;
336
+
337
+ /* Spacing */
338
+ --mv-spacing-xs: 0.25rem;
339
+ --mv-spacing-sm: 0.5rem;
340
+ --mv-spacing-md: 1rem;
341
+ --mv-spacing-lg: 1.5rem;
342
+ --mv-spacing-xl: 2rem;
343
+ --mv-spacing-2xl: 3rem;
344
+ --mv-spacing-3xl: 4rem;
345
+
346
+ /* Shadows */
347
+ --mv-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
348
+ --mv-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
349
+ --mv-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
350
+ --mv-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
351
+
352
+ /* Border Radius */
353
+ --mv-radius-none: 0;
354
+ --mv-radius-sm: 0.125rem;
355
+ --mv-radius-md: 0.25rem;
356
+ --mv-radius-lg: 0.5rem;
357
+ --mv-radius-xl: 0.75rem;
358
+ --mv-radius-full: 9999px;
359
+
360
+ /* Transitions */
361
+ --mv-transition-fast: 150ms ease;
362
+ --mv-transition-base: 250ms ease;
363
+ --mv-transition-slow: 350ms ease;
364
+
365
+ /* Layout */
366
+ --mv-container-max-width: 1200px;
367
+ --mv-content-max-width: 65ch;
368
+ }
369
+
370
+ /* ===== UTILITY CLASSES ===== */
371
+
372
+ /* Layout */
373
+ .mv-container {
374
+ width: 100%;
375
+ max-width: var(--mv-container-max-width);
376
+ margin: 0 auto;
377
+ padding: var(--mv-spacing-lg);
378
+ }
379
+
380
+ .mv-container-full {
381
+ width: 100%;
382
+ padding: var(--mv-spacing-lg);
383
+ }
384
+
385
+ .mv-flex {
386
+ display: flex;
387
+ }
388
+
389
+ .mv-flex-col {
390
+ display: flex;
391
+ flex-direction: column;
392
+ }
393
+
394
+ .mv-items-center {
395
+ align-items: center;
396
+ }
397
+
398
+ .mv-justify-between {
399
+ justify-content: space-between;
400
+ }
401
+
402
+ .mv-justify-center {
403
+ justify-content: center;
404
+ }
405
+
406
+ .mv-grid {
407
+ display: grid;
408
+ }
409
+
410
+ .mv-grid-cols-2 {
411
+ grid-template-columns: repeat(2, 1fr);
412
+ }
413
+
414
+ .mv-grid-cols-3 {
415
+ grid-template-columns: repeat(3, 1fr);
416
+ }
417
+
418
+ .mv-grid-cols-4 {
419
+ grid-template-columns: repeat(4, 1fr);
420
+ }
421
+
422
+ /* Gap */
423
+ .mv-gap-xs { gap: var(--mv-spacing-xs); }
424
+ .mv-gap-sm { gap: var(--mv-spacing-sm); }
425
+ .mv-gap-md { gap: var(--mv-spacing-md); }
426
+ .mv-gap-lg { gap: var(--mv-spacing-lg); }
427
+
428
+ /* Padding */
429
+ .mv-p-xs { padding: var(--mv-spacing-xs); }
430
+ .mv-p-sm { padding: var(--mv-spacing-sm); }
431
+ .mv-p-md { padding: var(--mv-spacing-md); }
432
+ .mv-p-lg { padding: var(--mv-spacing-lg); }
433
+ .mv-px-sm { padding-left: var(--mv-spacing-sm); padding-right: var(--mv-spacing-sm); }
434
+ .mv-px-md { padding-left: var(--mv-spacing-md); padding-right: var(--mv-spacing-md); }
435
+ .mv-py-sm { padding-top: var(--mv-spacing-sm); padding-bottom: var(--mv-spacing-sm); }
436
+ .mv-py-md { padding-top: var(--mv-spacing-md); padding-bottom: var(--mv-spacing-md); }
437
+
438
+ /* Margins */
439
+ .mv-mb-sm { margin-bottom: var(--mv-spacing-sm); }
440
+ .mv-mb-md { margin-bottom: var(--mv-spacing-md); }
441
+ .mv-mb-lg { margin-bottom: var(--mv-spacing-lg); }
442
+ .mv-mt-sm { margin-top: var(--mv-spacing-sm); }
443
+ .mv-mt-md { margin-top: var(--mv-spacing-md); }
444
+
445
+ /* Typography */
446
+ .mv-text-xs {
447
+ font-size: var(--mv-font-size-xs);
448
+ line-height: var(--mv-line-height-normal);
449
+ }
450
+
451
+ .mv-text-sm {
452
+ font-size: var(--mv-font-size-sm);
453
+ line-height: var(--mv-line-height-normal);
454
+ }
455
+
456
+ .mv-text-base {
457
+ font-size: var(--mv-font-size-base);
458
+ line-height: var(--mv-line-height-normal);
459
+ }
460
+
461
+ .mv-text-lg {
462
+ font-size: var(--mv-font-size-lg);
463
+ line-height: var(--mv-line-height-normal);
464
+ }
465
+
466
+ .mv-text-xl {
467
+ font-size: var(--mv-font-size-xl);
468
+ line-height: var(--mv-line-height-tight);
469
+ }
470
+
471
+ .mv-text-2xl {
472
+ font-size: var(--mv-font-size-2xl);
473
+ line-height: var(--mv-line-height-tight);
474
+ }
475
+
476
+ .mv-font-medium { font-weight: var(--mv-font-weight-medium); }
477
+ .mv-font-semibold { font-weight: var(--mv-font-weight-semibold); }
478
+ .mv-font-bold { font-weight: var(--mv-font-weight-bold); }
479
+
480
+ .mv-text-primary { color: var(--mv-text-primary); }
481
+ .mv-text-secondary { color: var(--mv-text-secondary); }
482
+ .mv-text-muted { color: var(--mv-text-muted); }
483
+ .mv-text-error { color: var(--mv-status-error); }
484
+ .mv-text-warning { color: var(--mv-status-warning); }
485
+ .mv-text-success { color: var(--mv-status-success); }
486
+ .mv-text-info { color: var(--mv-status-info); }
487
+
488
+ .mv-text-center { text-align: center; }
489
+
490
+ /* ===== COMPONENTS ===== */
491
+
492
+ /* Cards */
493
+ .mv-card {
494
+ background: var(--mv-bg-surface);
495
+ border: 1px solid var(--mv-border-default);
496
+ border-radius: var(--mv-radius-lg);
497
+ padding: var(--mv-spacing-lg);
498
+ box-shadow: var(--mv-shadow-sm);
499
+ transition: box-shadow var(--mv-transition-base);
500
+ }
501
+
502
+ .mv-card:hover {
503
+ box-shadow: var(--mv-shadow-md);
504
+ }
505
+
506
+ .mv-card-elevated {
507
+ background: var(--mv-bg-elevated);
508
+ box-shadow: var(--mv-shadow-lg);
509
+ }
510
+
511
+ /* Headers */
512
+ .mv-header {
513
+ display: flex;
514
+ align-items: center;
515
+ justify-content: space-between;
516
+ padding: var(--mv-spacing-lg);
517
+ border-bottom: 1px solid var(--mv-border-default);
518
+ margin-bottom: var(--mv-spacing-lg);
519
+ }
520
+
521
+ .mv-header-title {
522
+ font-size: var(--mv-font-size-xl);
523
+ font-weight: var(--mv-font-weight-semibold);
524
+ color: var(--mv-text-primary);
525
+ margin: 0;
526
+ display: flex;
527
+ align-items: center;
528
+ gap: var(--mv-spacing-sm);
529
+ }
530
+
531
+ .mv-header-subtitle {
532
+ font-size: var(--mv-font-size-sm);
533
+ color: var(--mv-text-secondary);
534
+ margin-top: var(--mv-spacing-xs);
535
+ }
536
+
537
+ /* Buttons */
538
+ .mv-button {
539
+ display: inline-flex;
540
+ align-items: center;
541
+ justify-content: center;
542
+ gap: var(--mv-spacing-xs);
543
+ padding: var(--mv-spacing-sm) var(--mv-spacing-md);
544
+ border: none;
545
+ border-radius: var(--mv-radius-md);
546
+ font-family: var(--mv-font-family);
547
+ font-size: var(--mv-font-size-sm);
548
+ font-weight: var(--mv-font-weight-medium);
549
+ cursor: pointer;
550
+ transition: all var(--mv-transition-fast);
551
+ text-decoration: none;
552
+ }
553
+
554
+ .mv-button:focus-visible {
555
+ outline: 2px solid var(--mv-border-focus);
556
+ outline-offset: 2px;
557
+ }
558
+
559
+ .mv-button-primary {
560
+ background: var(--mv-button-primary-bg);
561
+ color: var(--mv-button-primary-fg);
562
+ }
563
+
564
+ .mv-button-primary:hover {
565
+ filter: brightness(1.1);
566
+ }
567
+
568
+ .mv-button-secondary {
569
+ background: var(--mv-button-secondary-bg);
570
+ color: var(--mv-button-secondary-fg);
571
+ }
572
+
573
+ .mv-button-outline {
574
+ background: transparent;
575
+ color: var(--mv-interactive-primary);
576
+ border: 1px solid var(--mv-border-default);
577
+ }
578
+
579
+ .mv-button-outline:hover {
580
+ background: var(--mv-bg-elevated);
581
+ }
582
+
583
+ .mv-button-sm {
584
+ padding: var(--mv-spacing-xs) var(--mv-spacing-sm);
585
+ font-size: var(--mv-font-size-xs);
586
+ }
587
+
588
+ /* Badges */
589
+ .mv-badge {
590
+ display: inline-flex;
591
+ align-items: center;
592
+ padding: var(--mv-spacing-xs) var(--mv-spacing-sm);
593
+ background: var(--mv-bg-elevated);
594
+ color: var(--mv-text-primary);
595
+ font-size: var(--mv-font-size-xs);
596
+ font-weight: var(--mv-font-weight-medium);
597
+ border-radius: var(--mv-radius-full);
598
+ border: 1px solid var(--mv-border-default);
599
+ }
600
+
601
+ .mv-badge-primary {
602
+ background: var(--mv-interactive-primary);
603
+ color: var(--mv-text-inverse);
604
+ border-color: var(--mv-interactive-primary);
605
+ }
606
+
607
+ .mv-badge-error {
608
+ background: var(--mv-status-error);
609
+ color: var(--mv-text-inverse);
610
+ border-color: var(--mv-status-error);
611
+ }
612
+
613
+ .mv-badge-warning {
614
+ background: var(--mv-status-warning);
615
+ color: var(--mv-text-inverse);
616
+ border-color: var(--mv-status-warning);
617
+ }
618
+
619
+ .mv-badge-success {
620
+ background: var(--mv-status-success);
621
+ color: var(--mv-text-inverse);
622
+ border-color: var(--mv-status-success);
623
+ }
624
+
625
+ .mv-badge-info {
626
+ background: var(--mv-status-info);
627
+ color: var(--mv-text-inverse);
628
+ border-color: var(--mv-status-info);
629
+ }
630
+
631
+ /* Status dots */
632
+ .mv-status-dot {
633
+ display: inline-block;
634
+ width: 8px;
635
+ height: 8px;
636
+ border-radius: var(--mv-radius-full);
637
+ background: var(--mv-text-muted);
638
+ }
639
+
640
+ .mv-status-dot-error { background: var(--mv-status-error); }
641
+ .mv-status-dot-warning { background: var(--mv-status-warning); }
642
+ .mv-status-dot-success { background: var(--mv-status-success); }
643
+ .mv-status-dot-info { background: var(--mv-status-info); }
644
+
645
+ /* Form elements */
646
+ .mv-input {
647
+ width: 100%;
648
+ padding: var(--mv-spacing-sm) var(--mv-spacing-md);
649
+ background: var(--mv-bg-input);
650
+ border: 1px solid var(--mv-border-input);
651
+ border-radius: var(--mv-radius-md);
652
+ color: var(--mv-text-primary);
653
+ font-family: var(--mv-font-family);
654
+ font-size: var(--mv-font-size-sm);
655
+ transition: border-color var(--mv-transition-fast);
656
+ }
657
+
658
+ .mv-input:focus {
659
+ outline: none;
660
+ border-color: var(--mv-border-focus);
661
+ }
662
+
663
+ .mv-input::placeholder {
664
+ color: var(--mv-text-muted);
665
+ }
666
+
667
+ /* Lists */
668
+ .mv-list {
669
+ display: flex;
670
+ flex-direction: column;
671
+ gap: var(--mv-spacing-xs);
672
+ }
673
+
674
+ .mv-list-item {
675
+ display: flex;
676
+ align-items: center;
677
+ gap: var(--mv-spacing-sm);
678
+ padding: var(--mv-spacing-sm);
679
+ border-radius: var(--mv-radius-md);
680
+ transition: background-color var(--mv-transition-fast);
681
+ }
682
+
683
+ .mv-list-item:hover {
684
+ background: var(--mv-bg-elevated);
685
+ }
686
+
687
+ /* Utilities */
688
+ .mv-hidden {
689
+ display: none !important;
690
+ }
691
+
692
+ .mv-truncate {
693
+ overflow: hidden;
694
+ text-overflow: ellipsis;
695
+ white-space: nowrap;
696
+ }
697
+
698
+ /* Loading spinner */
699
+ .mv-spinner {
700
+ display: inline-block;
701
+ width: 20px;
702
+ height: 20px;
703
+ border: 2px solid var(--mv-text-muted);
704
+ border-radius: 50%;
705
+ border-top-color: var(--mv-interactive-primary);
706
+ animation: mv-spin 1s ease-in-out infinite;
707
+ }
708
+
709
+ @keyframes mv-spin {
710
+ to { transform: rotate(360deg); }
711
+ }
712
+
713
+ /* Responsive */
714
+ @media (max-width: 768px) {
715
+ .mv-container {
716
+ padding: var(--mv-spacing-md);
717
+ }
718
+
719
+ .mv-grid-cols-2,
720
+ .mv-grid-cols-3,
721
+ .mv-grid-cols-4 {
722
+ grid-template-columns: 1fr;
723
+ }
724
+ }