ui-optago 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ui-optago.css ADDED
@@ -0,0 +1,1917 @@
1
+ /* ============================================================================
2
+ UI ÓPTAGO — Design System v1.0
3
+ CSS puro, sem dependências. Tema escuro por padrão.
4
+ Para tema claro: adicione a classe "light" ao <html> (o ui-optago.js
5
+ gerencia isso automaticamente via localStorage).
6
+
7
+ Convenção de nomes: todas as classes usam o prefixo "op-".
8
+ Estados usam "is-" (is-open, is-collapsed, is-active, is-error...).
9
+ ============================================================================ */
10
+
11
+ /* ----------------------------------------------------------------------------
12
+ 1. TOKENS (CSS Custom Properties)
13
+ ---------------------------------------------------------------------------- */
14
+ :root {
15
+ /* Marca */
16
+ --op-accent: #C0FF6B;
17
+ --op-accent-hover: #AEF552;
18
+ --op-accent-ink: #000000; /* texto sobre o verde-lima */
19
+
20
+ /* Cores semânticas */
21
+ --op-info: #3B82F6;
22
+ --op-success: #10B981;
23
+ --op-warning: #F59E0B;
24
+ --op-danger: #EF4444;
25
+
26
+ /* Superfícies — TEMA ESCURO (padrão) */
27
+ --op-bg: #050505;
28
+ --op-panel: #0A0A0A;
29
+ --op-panel-2: #111111;
30
+ --op-panel-3: #1A1A1A;
31
+ --op-border: #262626;
32
+ --op-border-2: #333333;
33
+ --op-text: #D5D5D5;
34
+ --op-strong: #FFFFFF;
35
+ --op-muted: #656565;
36
+
37
+ /* Botão primário (no escuro = verde-lima; no claro = quase-preto) */
38
+ --op-primary: var(--op-accent);
39
+ --op-primary-hover: var(--op-accent-hover);
40
+ --op-primary-ink: #000000;
41
+
42
+ /* Tipografia */
43
+ --op-font-display: "Chakra Petch", system-ui, sans-serif;
44
+ --op-font-sans: "Inter", system-ui, sans-serif;
45
+ --op-font-mono: "JetBrains Mono", ui-monospace, monospace;
46
+
47
+ /* Forma */
48
+ --op-radius-sm: 8px;
49
+ --op-radius: 12px;
50
+ --op-radius-lg: 16px;
51
+ --op-oct: polygon(29% 0%, 71% 0%, 100% 29%, 100% 71%, 71% 100%, 29% 100%, 0% 71%, 0% 29%);
52
+
53
+ /* Sombras */
54
+ --op-shadow-sm: 0 1px 2px rgba(0,0,0,.3);
55
+ --op-shadow: 0 8px 24px -8px rgba(0,0,0,.5);
56
+ --op-shadow-lg: 0 25px 50px -12px rgba(0,0,0,.6);
57
+ --op-shadow-side: -16px 0 40px rgba(0,0,0,.35);
58
+ --op-glow: 0 0 20px rgba(192,255,107,.35);
59
+ --op-glow-danger: 0 0 20px rgba(239,68,68,.35);
60
+ --op-glow-info: 0 0 20px rgba(59,130,246,.35);
61
+
62
+ /* Layout fixo */
63
+ --op-header-h: 56px;
64
+ --op-footer-h: 42px;
65
+ --op-sidebar-w: 260px;
66
+ --op-sidebar-w-collapsed: 4.5rem;
67
+
68
+ /* Transições */
69
+ --op-ease: cubic-bezier(.4, 0, .2, 1);
70
+ --op-spring: cubic-bezier(.16, 1, .3, 1);
71
+
72
+ color-scheme: dark;
73
+ }
74
+
75
+ /* Superfícies — TEMA CLARO */
76
+ html.light {
77
+ --op-bg: #EEF2F7;
78
+ --op-panel: #FFFFFF;
79
+ --op-panel-2: #F6F8FB;
80
+ --op-panel-3: #EDF1F6;
81
+ --op-border: #DFE6EE;
82
+ --op-border-2: #C6D2DF;
83
+ --op-text: #334155;
84
+ --op-strong: #0F172A;
85
+ --op-muted: #64748B;
86
+
87
+ --op-primary: #0F172A;
88
+ --op-primary-hover: #1E293B;
89
+ --op-primary-ink: #FFFFFF;
90
+
91
+ --op-shadow-sm: 0 1px 3px rgba(15,23,42,.08);
92
+ --op-shadow: 0 10px 30px -10px rgba(15,23,42,.16);
93
+ --op-shadow-lg: 0 30px 60px -15px rgba(15,23,42,.28);
94
+ --op-shadow-side: -16px 0 40px rgba(15,23,42,.10);
95
+ --op-glow: 0 4px 14px rgba(15,23,42,.25);
96
+
97
+ color-scheme: light;
98
+ }
99
+
100
+ /* Fundo do tema claro: gradiente suave com um toque de verde-lima no topo */
101
+ html.light body {
102
+ background:
103
+ radial-gradient(900px 420px at 75% -10%, rgba(192,255,107,.30) 0%, transparent 60%),
104
+ radial-gradient(700px 380px at 10% 110%, rgba(192,255,107,.14) 0%, transparent 60%),
105
+ linear-gradient(180deg, #F2F5F9 0%, #E9EEF5 100%);
106
+ }
107
+
108
+ /* ----------------------------------------------------------------------------
109
+ 2. RESET & BASE
110
+ ---------------------------------------------------------------------------- */
111
+ *, *::before, *::after { box-sizing: border-box; }
112
+
113
+ html { scroll-behavior: smooth; }
114
+
115
+ body {
116
+ margin: 0;
117
+ font-family: var(--op-font-sans);
118
+ font-size: 14px;
119
+ line-height: 1.6;
120
+ background: var(--op-bg);
121
+ color: var(--op-text);
122
+ -webkit-font-smoothing: antialiased;
123
+ transition: background-color .3s ease, color .3s ease;
124
+ }
125
+
126
+ ::selection { background: var(--op-accent); color: #000; }
127
+
128
+ h1, h2, h3, h4, h5, h6 {
129
+ font-family: var(--op-font-display);
130
+ font-weight: 700;
131
+ color: var(--op-strong);
132
+ line-height: 1.2;
133
+ margin: 0 0 .5em;
134
+ letter-spacing: -.02em;
135
+ }
136
+ h1 { font-size: 2.5rem; }
137
+ h2 { font-size: 1.75rem; }
138
+ h3 { font-size: 1.25rem; }
139
+ h4 { font-size: 1rem; }
140
+
141
+ p { margin: 0 0 1em; }
142
+ a { color: var(--op-accent); }
143
+ html.light a { color: #3F6212; }
144
+ code, kbd { font-family: var(--op-font-mono); font-size: .85em; }
145
+
146
+ kbd {
147
+ padding: 2px 7px;
148
+ background: var(--op-panel-3);
149
+ border: 1px solid var(--op-border-2);
150
+ border-bottom-width: 2px;
151
+ border-radius: 6px;
152
+ color: var(--op-strong);
153
+ font-weight: 600;
154
+ }
155
+
156
+ hr, .op-divider {
157
+ border: 0;
158
+ height: 1px;
159
+ background: var(--op-border);
160
+ margin: 1.5rem 0;
161
+ }
162
+
163
+ :focus-visible {
164
+ outline: 2px solid color-mix(in srgb, var(--op-accent) 80%, transparent);
165
+ outline-offset: 2px;
166
+ border-radius: 4px;
167
+ }
168
+ html.light :focus-visible {
169
+ outline-color: color-mix(in srgb, var(--op-info) 70%, transparent);
170
+ }
171
+
172
+ /* Scrollbar */
173
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
174
+ ::-webkit-scrollbar-track { background: transparent; }
175
+ ::-webkit-scrollbar-thumb {
176
+ background: var(--op-border);
177
+ border-radius: 10px;
178
+ border: 2px solid var(--op-bg);
179
+ }
180
+ ::-webkit-scrollbar-thumb:hover { background: var(--op-muted); }
181
+
182
+ /* Octógono da marca */
183
+ .op-oct { -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct); }
184
+
185
+ /* Fundo pontilhado decorativo */
186
+ .op-bg-pattern {
187
+ background-image: radial-gradient(var(--op-border) 1.5px, transparent 1.5px);
188
+ background-size: 32px 32px;
189
+ }
190
+
191
+ /* ----------------------------------------------------------------------------
192
+ 3. LAYOUT — app shell com header, footer e sidebar (direita) fixos.
193
+ Somente .op-main rola.
194
+
195
+ <body class="op-app">
196
+ <div class="op-app-body">
197
+ <header class="op-header">...</header>
198
+ <main class="op-main">...</main>
199
+ <footer class="op-footer">...</footer>
200
+ </div>
201
+ <aside class="op-sidebar" id="opSidebar">...</aside>
202
+ </body>
203
+ ---------------------------------------------------------------------------- */
204
+ .op-app {
205
+ display: flex;
206
+ height: 100vh;
207
+ height: 100dvh;
208
+ overflow: hidden;
209
+ }
210
+
211
+ .op-app-body {
212
+ flex: 1;
213
+ min-width: 0;
214
+ display: flex;
215
+ flex-direction: column;
216
+ position: relative;
217
+ }
218
+
219
+ /* Header */
220
+ .op-header {
221
+ position: relative;
222
+ height: var(--op-header-h);
223
+ flex-shrink: 0;
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: space-between;
227
+ gap: 1rem;
228
+ padding: 0 1.25rem;
229
+ border-bottom: 1px solid var(--op-border);
230
+ background: color-mix(in srgb, var(--op-panel) 85%, transparent);
231
+ backdrop-filter: blur(12px);
232
+ -webkit-backdrop-filter: blur(12px);
233
+ box-shadow: 0 8px 24px -12px rgba(0,0,0,.5);
234
+ z-index: 30;
235
+ }
236
+ /* filete de brilho verde-lima sob o header */
237
+ .op-header::after {
238
+ content: "";
239
+ position: absolute;
240
+ left: 0; right: 0; bottom: -1px;
241
+ height: 1px;
242
+ background: linear-gradient(90deg,
243
+ transparent 5%,
244
+ color-mix(in srgb, var(--op-accent) 55%, transparent) 50%,
245
+ transparent 95%);
246
+ pointer-events: none;
247
+ }
248
+ html.light .op-header { box-shadow: 0 8px 24px -14px rgba(15,23,42,.18); }
249
+ .op-header-group { display: flex; align-items: center; gap: .75rem; min-width: 0; }
250
+ .op-header-divider { width: 1px; height: 20px; background: var(--op-border-2); }
251
+
252
+ /* Logo / marca */
253
+ .op-brand { display: flex; align-items: center; gap: .625rem; }
254
+ .op-brand-mark {
255
+ width: 32px; height: 32px;
256
+ background: var(--op-accent);
257
+ -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
258
+ display: flex; align-items: center; justify-content: center;
259
+ flex-shrink: 0;
260
+ }
261
+ .op-brand-mark::after {
262
+ content: "";
263
+ width: 10px; height: 10px;
264
+ background: #000;
265
+ -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
266
+ }
267
+ html.light .op-brand-mark { background: #000; }
268
+ html.light .op-brand-mark::after { background: var(--op-accent); }
269
+ .op-brand-name {
270
+ font-family: var(--op-font-display);
271
+ font-weight: 700;
272
+ font-size: 1.25rem;
273
+ color: var(--op-strong);
274
+ letter-spacing: .02em;
275
+ }
276
+
277
+ /* Conteúdo rolável */
278
+ .op-main {
279
+ flex: 1;
280
+ overflow-y: auto;
281
+ padding: 2rem 1.5rem;
282
+ scroll-behavior: smooth;
283
+ position: relative;
284
+ z-index: 1; /* mantém o conteúdo acima dos .op-glow do fundo */
285
+ }
286
+ @media (min-width: 1024px) { .op-main { padding: 2.5rem; } }
287
+
288
+ .op-container { max-width: 1100px; margin: 0 auto; }
289
+
290
+ /* Footer */
291
+ .op-footer {
292
+ height: var(--op-footer-h);
293
+ flex-shrink: 0;
294
+ display: flex;
295
+ align-items: center;
296
+ justify-content: space-between;
297
+ gap: 1rem;
298
+ padding: 0 1.25rem;
299
+ border-top: 1px solid var(--op-border);
300
+ background: var(--op-panel);
301
+ font-family: var(--op-font-mono);
302
+ font-size: 11px;
303
+ color: var(--op-muted);
304
+ z-index: 30;
305
+ }
306
+
307
+ /* ----------------------------------------------------------------------------
308
+ 4. SIDEBAR (direita, colapsável)
309
+ ---------------------------------------------------------------------------- */
310
+ .op-sidebar {
311
+ width: var(--op-sidebar-w);
312
+ flex-shrink: 0;
313
+ display: flex;
314
+ flex-direction: column;
315
+ background: var(--op-panel);
316
+ border-left: 1px solid var(--op-border);
317
+ box-shadow: var(--op-shadow-side);
318
+ transition: width .3s var(--op-ease), transform .3s var(--op-ease);
319
+ z-index: 50;
320
+ }
321
+
322
+ .op-sidebar-header {
323
+ height: var(--op-header-h);
324
+ flex-shrink: 0;
325
+ display: flex;
326
+ align-items: center;
327
+ justify-content: space-between;
328
+ padding: 0 1rem;
329
+ border-bottom: 1px solid var(--op-border);
330
+ }
331
+
332
+ .op-sidebar-nav {
333
+ flex: 1;
334
+ overflow-y: auto;
335
+ overflow-x: visible;
336
+ padding: 1rem .75rem;
337
+ display: flex;
338
+ flex-direction: column;
339
+ gap: .25rem;
340
+ }
341
+
342
+ .op-sidebar-label {
343
+ padding: 0 .75rem;
344
+ margin: .5rem 0;
345
+ font-family: var(--op-font-mono);
346
+ font-size: 10px;
347
+ font-weight: 700;
348
+ text-transform: uppercase;
349
+ letter-spacing: .2em;
350
+ color: var(--op-muted);
351
+ white-space: nowrap;
352
+ }
353
+
354
+ .op-nav-item {
355
+ position: relative;
356
+ display: flex;
357
+ align-items: center;
358
+ gap: .75rem;
359
+ padding: .625rem .75rem;
360
+ border-radius: var(--op-radius);
361
+ color: var(--op-text);
362
+ text-decoration: none;
363
+ font-weight: 600;
364
+ font-size: .875rem;
365
+ white-space: nowrap;
366
+ transition: background .2s ease, color .2s ease;
367
+ }
368
+ .op-nav-item i { font-size: 1.25rem; flex-shrink: 0; }
369
+ .op-nav-item:hover {
370
+ background: color-mix(in srgb, var(--op-strong) 6%, transparent);
371
+ color: var(--op-strong);
372
+ }
373
+ .op-nav-item.is-active {
374
+ background: color-mix(in srgb, var(--op-accent) 12%, transparent);
375
+ color: var(--op-strong);
376
+ box-shadow: inset -3px 0 0 var(--op-accent);
377
+ }
378
+ html.light .op-nav-item.is-active { box-shadow: inset -3px 0 0 #84CC16; }
379
+ .op-nav-item.is-active i { color: var(--op-accent); }
380
+ html.light .op-nav-item.is-active i { color: #3F6212; }
381
+
382
+ /* Estado colapsado — só ícones */
383
+ .op-sidebar.is-collapsed { width: var(--op-sidebar-w-collapsed); }
384
+ .op-sidebar.is-collapsed .op-nav-text,
385
+ .op-sidebar.is-collapsed .op-sidebar-label,
386
+ .op-sidebar.is-collapsed .op-sidebar-header-text { display: none; }
387
+ .op-sidebar.is-collapsed .op-nav-item { justify-content: center; padding-left: 0; padding-right: 0; }
388
+
389
+ /* Tooltip do item (aparece à esquerda quando colapsada).
390
+ position:fixed — o JS calcula top/right no hover, pois o overflow-y:auto
391
+ da nav cortaria um tooltip posicionado com absolute. */
392
+ .op-nav-tooltip {
393
+ position: fixed;
394
+ translate: 0 -50%;
395
+ background: var(--op-strong);
396
+ color: var(--op-bg);
397
+ font-family: var(--op-font-mono);
398
+ font-size: 11px;
399
+ font-weight: 700;
400
+ padding: .375rem .75rem;
401
+ border-radius: var(--op-radius-sm);
402
+ box-shadow: var(--op-shadow);
403
+ white-space: nowrap;
404
+ visibility: hidden;
405
+ opacity: 0;
406
+ transform: translateX(-8px) scale(.95);
407
+ transform-origin: right center;
408
+ transition: all .2s var(--op-spring);
409
+ pointer-events: none;
410
+ z-index: 60;
411
+ }
412
+ .op-nav-tooltip::after {
413
+ content: "";
414
+ position: absolute;
415
+ left: 100%;
416
+ top: 50%;
417
+ translate: 0 -50%;
418
+ border: 5px solid transparent;
419
+ border-left-color: var(--op-strong);
420
+ }
421
+ .op-sidebar.is-collapsed .op-nav-item:hover .op-nav-tooltip {
422
+ visibility: visible;
423
+ opacity: 1;
424
+ transform: translateX(0) scale(1);
425
+ }
426
+
427
+ /* Sidebar mobile: vira drawer sobreposto */
428
+ .op-overlay {
429
+ position: fixed;
430
+ inset: 0;
431
+ background: rgba(0,0,0,.6);
432
+ backdrop-filter: blur(4px);
433
+ z-index: 40;
434
+ opacity: 0;
435
+ visibility: hidden;
436
+ transition: opacity .3s ease, visibility .3s ease;
437
+ }
438
+ .op-overlay.is-open { opacity: 1; visibility: visible; }
439
+
440
+ @media (max-width: 1023px) {
441
+ .op-sidebar {
442
+ position: fixed;
443
+ top: 0; right: 0; bottom: 0;
444
+ transform: translateX(100%);
445
+ box-shadow: var(--op-shadow-lg);
446
+ }
447
+ .op-sidebar.is-open { transform: translateX(0); }
448
+ .op-sidebar.is-collapsed { width: var(--op-sidebar-w); } /* colapso só no desktop */
449
+ .op-sidebar.is-collapsed .op-nav-text,
450
+ .op-sidebar.is-collapsed .op-sidebar-label,
451
+ .op-sidebar.is-collapsed .op-sidebar-header-text { display: block; }
452
+ .op-sidebar.is-collapsed .op-nav-item { justify-content: flex-start; padding: .625rem .75rem; }
453
+ }
454
+
455
+ /* ----------------------------------------------------------------------------
456
+ 5. BOTÕES
457
+ ---------------------------------------------------------------------------- */
458
+ .op-btn {
459
+ display: inline-flex;
460
+ align-items: center;
461
+ justify-content: center;
462
+ gap: .5rem;
463
+ padding: .625rem 1.25rem;
464
+ border: 1px solid transparent;
465
+ border-radius: var(--op-radius-sm);
466
+ font-family: var(--op-font-mono);
467
+ font-size: .75rem;
468
+ font-weight: 700;
469
+ text-transform: uppercase;
470
+ letter-spacing: .08em;
471
+ text-decoration: none;
472
+ cursor: pointer;
473
+ user-select: none;
474
+ white-space: nowrap;
475
+ transition: all .2s var(--op-ease);
476
+ }
477
+ .op-btn i { font-size: 1rem; }
478
+ .op-btn:hover { transform: translateY(-2px); }
479
+ .op-btn:active { transform: scale(.96); }
480
+ .op-btn:disabled, .op-btn.is-disabled {
481
+ opacity: .45;
482
+ pointer-events: none;
483
+ }
484
+
485
+ /* Variantes sólidas */
486
+ .op-btn-primary {
487
+ background: var(--op-primary);
488
+ color: var(--op-primary-ink);
489
+ box-shadow: 0 4px 14px color-mix(in srgb, var(--op-primary) 30%, transparent);
490
+ }
491
+ .op-btn-primary:hover { background: var(--op-primary-hover); box-shadow: var(--op-glow); }
492
+
493
+ .op-btn-success { background: var(--op-success); color: #fff; box-shadow: 0 4px 14px rgba(16,185,129,.25); }
494
+ .op-btn-success:hover { background: color-mix(in srgb, var(--op-success) 85%, #000); box-shadow: 0 0 20px rgba(16,185,129,.35); }
495
+
496
+ .op-btn-danger { background: var(--op-danger); color: #fff; box-shadow: 0 4px 14px rgba(239,68,68,.25); }
497
+ .op-btn-danger:hover { background: color-mix(in srgb, var(--op-danger) 85%, #000); box-shadow: var(--op-glow-danger); }
498
+
499
+ .op-btn-warning { background: var(--op-warning); color: #000; box-shadow: 0 4px 14px rgba(245,158,11,.25); }
500
+ .op-btn-warning:hover { background: color-mix(in srgb, var(--op-warning) 85%, #000); box-shadow: 0 0 20px rgba(245,158,11,.35); }
501
+
502
+ .op-btn-info { background: var(--op-info); color: #fff; box-shadow: 0 4px 14px rgba(59,130,246,.25); }
503
+ .op-btn-info:hover { background: color-mix(in srgb, var(--op-info) 85%, #000); box-shadow: var(--op-glow-info); }
504
+
505
+ /* Secundário (outline) */
506
+ .op-btn-secondary {
507
+ background: var(--op-panel-2);
508
+ border-color: var(--op-border-2);
509
+ color: var(--op-text);
510
+ }
511
+ .op-btn-secondary:hover { background: var(--op-panel-3); color: var(--op-strong); }
512
+
513
+ /* Ghost (fundo suave) */
514
+ .op-btn-ghost { background: transparent; color: var(--op-text); }
515
+ .op-btn-ghost:hover { background: color-mix(in srgb, var(--op-strong) 7%, transparent); color: var(--op-strong); }
516
+
517
+ .op-btn-ghost-info { background: color-mix(in srgb, var(--op-info) 12%, transparent); color: color-mix(in srgb, var(--op-info) 70%, var(--op-strong)); }
518
+ .op-btn-ghost-info:hover { background: color-mix(in srgb, var(--op-info) 22%, transparent); }
519
+ .op-btn-ghost-success { background: color-mix(in srgb, var(--op-success) 12%, transparent); color: color-mix(in srgb, var(--op-success) 70%, var(--op-strong)); }
520
+ .op-btn-ghost-success:hover { background: color-mix(in srgb, var(--op-success) 22%, transparent); }
521
+ .op-btn-ghost-danger { background: color-mix(in srgb, var(--op-danger) 12%, transparent); color: color-mix(in srgb, var(--op-danger) 70%, var(--op-strong)); }
522
+ .op-btn-ghost-danger:hover { background: color-mix(in srgb, var(--op-danger) 22%, transparent); }
523
+ .op-btn-ghost-warning { background: color-mix(in srgb, var(--op-warning) 14%, transparent); color: color-mix(in srgb, var(--op-warning) 70%, var(--op-strong)); }
524
+ .op-btn-ghost-warning:hover { background: color-mix(in srgb, var(--op-warning) 24%, transparent); }
525
+
526
+ /* Tamanhos */
527
+ .op-btn-sm { padding: .375rem .875rem; font-size: .6875rem; }
528
+ .op-btn-lg { padding: .875rem 1.75rem; font-size: .8125rem; }
529
+
530
+ /* Somente ícone */
531
+ .op-btn-icon {
532
+ padding: .625rem;
533
+ aspect-ratio: 1;
534
+ background: var(--op-panel-2);
535
+ border-color: var(--op-border);
536
+ color: var(--op-muted);
537
+ }
538
+ .op-btn-icon:hover { color: var(--op-strong); background: var(--op-panel-3); }
539
+ .op-btn-icon i { font-size: 1.125rem; }
540
+
541
+ /* Loading */
542
+ .op-btn.is-loading { pointer-events: none; opacity: .75; }
543
+ .op-btn.is-loading::before {
544
+ content: "";
545
+ width: 14px; height: 14px;
546
+ border: 2px solid currentColor;
547
+ border-top-color: transparent;
548
+ border-radius: 50%;
549
+ animation: op-spin .7s linear infinite;
550
+ }
551
+
552
+ /* Grupo de botões */
553
+ .op-btn-group { display: inline-flex; }
554
+ .op-btn-group .op-btn { border-radius: 0; }
555
+ .op-btn-group .op-btn:hover { transform: none; }
556
+ .op-btn-group .op-btn:first-child { border-radius: var(--op-radius-sm) 0 0 var(--op-radius-sm); }
557
+ .op-btn-group .op-btn:last-child { border-radius: 0 var(--op-radius-sm) var(--op-radius-sm) 0; }
558
+ .op-btn-group .op-btn-secondary + .op-btn-secondary { border-left-width: 0; }
559
+
560
+ /* ----------------------------------------------------------------------------
561
+ 6. BADGES
562
+ ---------------------------------------------------------------------------- */
563
+ .op-badge {
564
+ display: inline-flex;
565
+ align-items: center;
566
+ gap: .375rem;
567
+ padding: .1875rem .625rem;
568
+ border: 1px solid var(--op-border);
569
+ border-radius: 6px;
570
+ background: var(--op-panel-3);
571
+ color: var(--op-text);
572
+ font-family: var(--op-font-mono);
573
+ font-size: .6875rem;
574
+ font-weight: 700;
575
+ line-height: 1.6;
576
+ white-space: nowrap;
577
+ }
578
+ .op-badge-pill { border-radius: 999px; }
579
+
580
+ .op-badge-brand {
581
+ background: color-mix(in srgb, var(--op-accent) 10%, transparent);
582
+ border-color: color-mix(in srgb, var(--op-accent) 25%, transparent);
583
+ color: var(--op-accent);
584
+ }
585
+ html.light .op-badge-brand { color: #3F6212; background: #F3FFE0; border-color: #D4F7A5; }
586
+
587
+ .op-badge-info { background: color-mix(in srgb, var(--op-info) 14%, transparent); border-color: color-mix(in srgb, var(--op-info) 30%, transparent); color: color-mix(in srgb, var(--op-info) 65%, var(--op-strong)); }
588
+ .op-badge-success { background: color-mix(in srgb, var(--op-success) 14%, transparent); border-color: color-mix(in srgb, var(--op-success) 30%, transparent); color: color-mix(in srgb, var(--op-success) 65%, var(--op-strong)); }
589
+ .op-badge-warning { background: color-mix(in srgb, var(--op-warning) 14%, transparent); border-color: color-mix(in srgb, var(--op-warning) 30%, transparent); color: color-mix(in srgb, var(--op-warning) 65%, var(--op-strong)); }
590
+ .op-badge-danger { background: color-mix(in srgb, var(--op-danger) 14%, transparent); border-color: color-mix(in srgb, var(--op-danger) 30%, transparent); color: color-mix(in srgb, var(--op-danger) 65%, var(--op-strong)); }
591
+
592
+ /* Pontinho de status (com pulso opcional) */
593
+ .op-dot {
594
+ width: 7px; height: 7px;
595
+ border-radius: 50%;
596
+ background: currentColor;
597
+ flex-shrink: 0;
598
+ }
599
+ .op-dot-pulse { animation: op-pulse 1.6s ease-in-out infinite; }
600
+
601
+ /* ----------------------------------------------------------------------------
602
+ 7. ALERTAS
603
+ ---------------------------------------------------------------------------- */
604
+ .op-alert {
605
+ display: flex;
606
+ gap: .75rem;
607
+ padding: 1rem;
608
+ border: 1px solid var(--op-border);
609
+ border-radius: var(--op-radius);
610
+ background: var(--op-panel-2);
611
+ }
612
+ .op-alert > i { font-size: 1.25rem; flex-shrink: 0; margin-top: .125rem; }
613
+ .op-alert-title { font-family: var(--op-font-sans); font-weight: 700; font-size: .875rem; margin: 0 0 .125rem; }
614
+ .op-alert-text { font-size: .8125rem; margin: 0; opacity: .85; }
615
+ .op-alert-close {
616
+ margin-left: auto;
617
+ background: none; border: 0; cursor: pointer;
618
+ color: inherit; opacity: .6;
619
+ font-size: 1rem;
620
+ padding: .25rem;
621
+ border-radius: 6px;
622
+ transition: opacity .2s;
623
+ align-self: flex-start;
624
+ }
625
+ .op-alert-close:hover { opacity: 1; }
626
+
627
+ .op-alert-info { background: color-mix(in srgb, var(--op-info) 10%, transparent); border-color: color-mix(in srgb, var(--op-info) 25%, transparent); }
628
+ .op-alert-info > i, .op-alert-info .op-alert-title { color: color-mix(in srgb, var(--op-info) 60%, var(--op-strong)); }
629
+ .op-alert-success { background: color-mix(in srgb, var(--op-success) 10%, transparent); border-color: color-mix(in srgb, var(--op-success) 25%, transparent); }
630
+ .op-alert-success > i, .op-alert-success .op-alert-title { color: color-mix(in srgb, var(--op-success) 60%, var(--op-strong)); }
631
+ .op-alert-warning { background: color-mix(in srgb, var(--op-warning) 10%, transparent); border-color: color-mix(in srgb, var(--op-warning) 25%, transparent); }
632
+ .op-alert-warning > i, .op-alert-warning .op-alert-title { color: color-mix(in srgb, var(--op-warning) 60%, var(--op-strong)); }
633
+ .op-alert-danger { background: color-mix(in srgb, var(--op-danger) 10%, transparent); border-color: color-mix(in srgb, var(--op-danger) 25%, transparent); }
634
+ .op-alert-danger > i, .op-alert-danger .op-alert-title { color: color-mix(in srgb, var(--op-danger) 60%, var(--op-strong)); }
635
+
636
+ /* ----------------------------------------------------------------------------
637
+ 8. FORMULÁRIOS
638
+ ---------------------------------------------------------------------------- */
639
+ .op-field { display: flex; flex-direction: column; gap: .375rem; }
640
+
641
+ .op-label {
642
+ font-family: var(--op-font-mono);
643
+ font-size: .6875rem;
644
+ font-weight: 700;
645
+ text-transform: uppercase;
646
+ letter-spacing: .1em;
647
+ color: var(--op-muted);
648
+ }
649
+ .op-label .req { color: var(--op-danger); }
650
+
651
+ .op-help { font-size: .75rem; color: var(--op-muted); margin: 0; }
652
+ .op-help.is-error { color: var(--op-danger); }
653
+ .op-help.is-success { color: var(--op-success); }
654
+
655
+ .op-input, .op-select, .op-textarea {
656
+ width: 100%;
657
+ padding: .625rem .875rem;
658
+ background: var(--op-panel-2);
659
+ border: 1px solid var(--op-border-2);
660
+ border-radius: var(--op-radius-sm);
661
+ color: var(--op-strong);
662
+ font-family: var(--op-font-sans);
663
+ font-size: .875rem;
664
+ transition: border-color .2s, box-shadow .2s, background .2s;
665
+ }
666
+ .op-input::placeholder, .op-textarea::placeholder { color: var(--op-muted); }
667
+ .op-input:focus, .op-select:focus, .op-textarea:focus {
668
+ outline: none;
669
+ border-color: var(--op-accent);
670
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--op-accent) 20%, transparent);
671
+ }
672
+ html.light .op-input:focus, html.light .op-select:focus, html.light .op-textarea:focus {
673
+ border-color: var(--op-info);
674
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--op-info) 15%, transparent);
675
+ }
676
+ .op-input:disabled, .op-select:disabled, .op-textarea:disabled { opacity: .5; cursor: not-allowed; }
677
+
678
+ .op-textarea { resize: vertical; min-height: 90px; }
679
+
680
+ .op-select {
681
+ appearance: none;
682
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 256 256' fill='%23656565'%3E%3Cpath d='M213.7 101.7l-80 80a8.2 8.2 0 0 1-11.4 0l-80-80a8.1 8.1 0 0 1 11.4-11.4L128 164.7l74.3-74.4a8.1 8.1 0 0 1 11.4 11.4Z'/%3E%3C/svg%3E");
683
+ background-repeat: no-repeat;
684
+ background-position: right .875rem center;
685
+ padding-right: 2.5rem;
686
+ cursor: pointer;
687
+ }
688
+
689
+ /* Estados de validação */
690
+ .op-input.is-error, .op-select.is-error, .op-textarea.is-error {
691
+ border-color: var(--op-danger);
692
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--op-danger) 15%, transparent);
693
+ }
694
+ .op-input.is-success, .op-select.is-success, .op-textarea.is-success {
695
+ border-color: var(--op-success);
696
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--op-success) 15%, transparent);
697
+ }
698
+
699
+ /* Input com ícone */
700
+ .op-input-icon { position: relative; }
701
+ .op-input-icon > i {
702
+ position: absolute;
703
+ left: .875rem;
704
+ top: 50%;
705
+ translate: 0 -50%;
706
+ color: var(--op-muted);
707
+ font-size: 1.125rem;
708
+ pointer-events: none;
709
+ }
710
+ .op-input-icon .op-input { padding-left: 2.625rem; }
711
+
712
+ /* Input group (prefixo/sufixo) */
713
+ .op-input-group { display: flex; }
714
+ .op-input-group .op-input { border-radius: 0; }
715
+ .op-input-group > :first-child { border-radius: var(--op-radius-sm) 0 0 var(--op-radius-sm); }
716
+ .op-input-group > :last-child { border-radius: 0 var(--op-radius-sm) var(--op-radius-sm) 0; }
717
+ .op-input-addon {
718
+ display: flex; align-items: center;
719
+ padding: 0 .875rem;
720
+ background: var(--op-panel-3);
721
+ border: 1px solid var(--op-border-2);
722
+ color: var(--op-muted);
723
+ font-family: var(--op-font-mono);
724
+ font-size: .75rem;
725
+ font-weight: 600;
726
+ white-space: nowrap;
727
+ }
728
+ .op-input-group .op-input-addon:first-child { border-right: 0; }
729
+ .op-input-group .op-input-addon:last-child { border-left: 0; }
730
+
731
+ /* Checkbox & Radio */
732
+ .op-check {
733
+ display: inline-flex;
734
+ align-items: center;
735
+ gap: .625rem;
736
+ cursor: pointer;
737
+ font-size: .875rem;
738
+ color: var(--op-text);
739
+ user-select: none;
740
+ }
741
+ .op-check input[type="checkbox"], .op-check input[type="radio"] {
742
+ appearance: none;
743
+ width: 18px; height: 18px;
744
+ margin: 0;
745
+ border: 1.5px solid var(--op-border-2);
746
+ background: var(--op-panel-2);
747
+ cursor: pointer;
748
+ transition: all .2s var(--op-ease);
749
+ flex-shrink: 0;
750
+ display: grid;
751
+ place-content: center;
752
+ }
753
+ .op-check input[type="checkbox"] { border-radius: 5px; }
754
+ .op-check input[type="radio"] { border-radius: 50%; }
755
+ .op-check input:checked {
756
+ background: var(--op-accent);
757
+ border-color: var(--op-accent);
758
+ }
759
+ html.light .op-check input:checked { background: var(--op-primary); border-color: var(--op-primary); }
760
+ .op-check input[type="checkbox"]:checked::before {
761
+ content: "";
762
+ width: 10px; height: 10px;
763
+ background: var(--op-accent-ink);
764
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
765
+ }
766
+ html.light .op-check input[type="checkbox"]:checked::before { background: #fff; }
767
+ .op-check input[type="radio"]:checked::before {
768
+ content: "";
769
+ width: 8px; height: 8px;
770
+ border-radius: 50%;
771
+ background: var(--op-accent-ink);
772
+ }
773
+ html.light .op-check input[type="radio"]:checked::before { background: #fff; }
774
+ .op-check input:disabled { opacity: .4; cursor: not-allowed; }
775
+ .op-check input:disabled + span { opacity: .4; }
776
+
777
+ /* Switch */
778
+ .op-switch {
779
+ display: inline-flex;
780
+ align-items: center;
781
+ gap: .625rem;
782
+ cursor: pointer;
783
+ font-size: .875rem;
784
+ user-select: none;
785
+ }
786
+ .op-switch input {
787
+ appearance: none;
788
+ width: 40px; height: 22px;
789
+ margin: 0;
790
+ border-radius: 999px;
791
+ background: var(--op-panel-3);
792
+ border: 1px solid var(--op-border-2);
793
+ position: relative;
794
+ cursor: pointer;
795
+ transition: background .25s var(--op-ease), border-color .25s;
796
+ flex-shrink: 0;
797
+ }
798
+ .op-switch input::before {
799
+ content: "";
800
+ position: absolute;
801
+ top: 2px; left: 2px;
802
+ width: 16px; height: 16px;
803
+ border-radius: 50%;
804
+ background: var(--op-muted);
805
+ transition: all .25s var(--op-spring);
806
+ }
807
+ .op-switch input:checked {
808
+ background: var(--op-accent);
809
+ border-color: var(--op-accent);
810
+ }
811
+ html.light .op-switch input:checked { background: var(--op-primary); border-color: var(--op-primary); }
812
+ .op-switch input:checked::before {
813
+ left: 20px;
814
+ background: var(--op-accent-ink);
815
+ }
816
+ html.light .op-switch input:checked::before { background: #fff; }
817
+
818
+ /* Range */
819
+ .op-range {
820
+ appearance: none;
821
+ width: 100%;
822
+ height: 6px;
823
+ border-radius: 999px;
824
+ background: var(--op-panel-3);
825
+ border: 1px solid var(--op-border);
826
+ outline: none;
827
+ cursor: pointer;
828
+ }
829
+ .op-range::-webkit-slider-thumb {
830
+ appearance: none;
831
+ width: 18px; height: 18px;
832
+ border-radius: 50%;
833
+ background: var(--op-accent);
834
+ border: 2px solid var(--op-bg);
835
+ box-shadow: var(--op-shadow-sm);
836
+ transition: transform .15s;
837
+ }
838
+ html.light .op-range::-webkit-slider-thumb { background: var(--op-primary); }
839
+ .op-range::-webkit-slider-thumb:hover { transform: scale(1.2); }
840
+
841
+ /* ----------------------------------------------------------------------------
842
+ 9. TABELAS
843
+ ---------------------------------------------------------------------------- */
844
+ .op-table-wrap {
845
+ overflow-x: auto;
846
+ border: 1px solid var(--op-border);
847
+ border-radius: var(--op-radius);
848
+ background: var(--op-panel);
849
+ box-shadow: var(--op-shadow);
850
+ }
851
+ .op-table {
852
+ width: 100%;
853
+ border-collapse: collapse;
854
+ text-align: left;
855
+ font-size: .875rem;
856
+ }
857
+ .op-table thead tr {
858
+ background: var(--op-panel-2);
859
+ border-bottom: 1px solid var(--op-border);
860
+ }
861
+ .op-table th {
862
+ padding: .875rem 1.25rem;
863
+ font-family: var(--op-font-mono);
864
+ font-size: .6875rem;
865
+ font-weight: 700;
866
+ text-transform: uppercase;
867
+ letter-spacing: .15em;
868
+ color: var(--op-muted);
869
+ white-space: nowrap;
870
+ }
871
+ .op-table td { padding: .875rem 1.25rem; }
872
+ .op-table tbody tr { border-bottom: 1px solid var(--op-border); transition: background .15s; }
873
+ .op-table tbody tr:last-child { border-bottom: 0; }
874
+ .op-table-hover tbody tr:hover { background: color-mix(in srgb, var(--op-strong) 4%, transparent); }
875
+ .op-table-striped tbody tr:nth-child(odd) { background: color-mix(in srgb, var(--op-strong) 2.5%, transparent); }
876
+
877
+ /* ----------------------------------------------------------------------------
878
+ 10. CARDS
879
+ ---------------------------------------------------------------------------- */
880
+ .op-card {
881
+ background: var(--op-panel);
882
+ border: 1px solid var(--op-border);
883
+ border-radius: var(--op-radius-lg);
884
+ padding: 1.5rem;
885
+ box-shadow: var(--op-shadow);
886
+ transition: transform .25s var(--op-ease), box-shadow .25s, border-color .25s;
887
+ }
888
+ .op-card-hover:hover {
889
+ transform: translateY(-4px);
890
+ border-color: color-mix(in srgb, var(--op-accent) 30%, var(--op-border));
891
+ box-shadow: var(--op-shadow-lg), 0 0 24px color-mix(in srgb, var(--op-accent) 8%, transparent);
892
+ }
893
+
894
+ .op-card-icon {
895
+ width: 48px; height: 48px;
896
+ border-radius: var(--op-radius);
897
+ background: var(--op-panel-3);
898
+ border: 1px solid var(--op-border-2);
899
+ display: flex; align-items: center; justify-content: center;
900
+ font-size: 1.5rem;
901
+ color: var(--op-strong);
902
+ margin-bottom: 1rem;
903
+ transition: transform .25s var(--op-spring);
904
+ }
905
+ .op-card-hover:hover .op-card-icon { transform: scale(1.1); }
906
+
907
+ .op-card-title { font-size: 1.125rem; margin-bottom: .375rem; }
908
+ .op-card-text { font-size: .8125rem; color: var(--op-muted); line-height: 1.6; margin-bottom: 1rem; }
909
+
910
+ .op-card-link {
911
+ font-family: var(--op-font-mono);
912
+ font-size: .6875rem;
913
+ font-weight: 700;
914
+ text-transform: uppercase;
915
+ letter-spacing: .1em;
916
+ color: var(--op-accent);
917
+ text-decoration: none;
918
+ display: inline-flex;
919
+ align-items: center;
920
+ gap: .375rem;
921
+ transition: gap .2s;
922
+ }
923
+ html.light .op-card-link { color: #3F6212; }
924
+ .op-card-link:hover { gap: .625rem; }
925
+
926
+ /* Card de estatística (KPI) */
927
+ .op-stat { display: flex; flex-direction: column; gap: .25rem; }
928
+ .op-stat-label {
929
+ font-family: var(--op-font-mono);
930
+ font-size: .6875rem;
931
+ font-weight: 700;
932
+ text-transform: uppercase;
933
+ letter-spacing: .12em;
934
+ color: var(--op-muted);
935
+ }
936
+ .op-stat-value {
937
+ font-family: var(--op-font-display);
938
+ font-size: 2rem;
939
+ font-weight: 700;
940
+ color: var(--op-strong);
941
+ line-height: 1.1;
942
+ }
943
+ .op-stat-delta {
944
+ font-family: var(--op-font-mono);
945
+ font-size: .75rem;
946
+ font-weight: 600;
947
+ display: inline-flex;
948
+ align-items: center;
949
+ gap: .25rem;
950
+ }
951
+ .op-stat-delta.is-up { color: var(--op-success); }
952
+ .op-stat-delta.is-down { color: var(--op-danger); }
953
+
954
+ /* ----------------------------------------------------------------------------
955
+ 11. AVATAR
956
+ ---------------------------------------------------------------------------- */
957
+ .op-avatar {
958
+ width: 40px; height: 40px;
959
+ border-radius: 50%;
960
+ overflow: hidden;
961
+ background: var(--op-panel-3);
962
+ border: 1px solid var(--op-border-2);
963
+ display: inline-flex;
964
+ align-items: center;
965
+ justify-content: center;
966
+ font-family: var(--op-font-mono);
967
+ font-size: .75rem;
968
+ font-weight: 700;
969
+ color: var(--op-accent);
970
+ flex-shrink: 0;
971
+ }
972
+ html.light .op-avatar { color: #3F6212; }
973
+ .op-avatar img { width: 100%; height: 100%; object-fit: cover; }
974
+ .op-avatar-sm { width: 30px; height: 30px; font-size: .625rem; }
975
+ .op-avatar-lg { width: 56px; height: 56px; font-size: 1rem; }
976
+ .op-avatar-ring { border: 2px solid var(--op-accent); }
977
+ .op-avatar-group { display: inline-flex; }
978
+ .op-avatar-group .op-avatar { margin-left: -10px; border: 2px solid var(--op-panel); }
979
+ .op-avatar-group .op-avatar:first-child { margin-left: 0; }
980
+
981
+ /* ----------------------------------------------------------------------------
982
+ 12. PROGRESSO, SPINNERS & SKELETON
983
+ ---------------------------------------------------------------------------- */
984
+ .op-progress {
985
+ height: 10px;
986
+ background: var(--op-panel-3);
987
+ border: 1px solid var(--op-border);
988
+ border-radius: 999px;
989
+ overflow: hidden;
990
+ }
991
+ .op-progress-bar {
992
+ height: 100%;
993
+ background: var(--op-accent);
994
+ border-radius: 999px;
995
+ transition: width .6s var(--op-ease);
996
+ position: relative;
997
+ overflow: hidden;
998
+ }
999
+ html.light .op-progress-bar { background: var(--op-primary); }
1000
+ .op-progress-bar.is-animated::after {
1001
+ content: "";
1002
+ position: absolute;
1003
+ inset: 0;
1004
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,.35), transparent);
1005
+ animation: op-shimmer 1.6s ease-in-out infinite;
1006
+ }
1007
+ .op-progress-bar.is-info { background: var(--op-info); }
1008
+ .op-progress-bar.is-success { background: var(--op-success); }
1009
+ .op-progress-bar.is-warning { background: var(--op-warning); }
1010
+ .op-progress-bar.is-danger { background: var(--op-danger); }
1011
+
1012
+ .op-progress-header {
1013
+ display: flex;
1014
+ justify-content: space-between;
1015
+ margin-bottom: .5rem;
1016
+ font-family: var(--op-font-mono);
1017
+ font-size: .6875rem;
1018
+ font-weight: 700;
1019
+ }
1020
+ .op-progress-header .lbl { color: var(--op-muted); text-transform: uppercase; letter-spacing: .1em; }
1021
+ .op-progress-header .val { color: var(--op-strong); }
1022
+
1023
+ /* Spinner circular */
1024
+ .op-spinner {
1025
+ width: 24px; height: 24px;
1026
+ border: 2.5px solid var(--op-border-2);
1027
+ border-top-color: var(--op-accent);
1028
+ border-radius: 50%;
1029
+ animation: op-spin .7s linear infinite;
1030
+ display: inline-block;
1031
+ }
1032
+ html.light .op-spinner { border-top-color: var(--op-primary); }
1033
+ .op-spinner-sm { width: 16px; height: 16px; border-width: 2px; }
1034
+ .op-spinner-lg { width: 40px; height: 40px; border-width: 3px; }
1035
+
1036
+ /* Spinner de pontos */
1037
+ .op-spinner-dots { display: inline-flex; gap: .375rem; }
1038
+ .op-spinner-dots span {
1039
+ width: 9px; height: 9px;
1040
+ border-radius: 50%;
1041
+ background: var(--op-accent);
1042
+ animation: op-bounce 1s ease-in-out infinite;
1043
+ }
1044
+ html.light .op-spinner-dots span { background: var(--op-primary); }
1045
+ .op-spinner-dots span:nth-child(2) { animation-delay: .15s; }
1046
+ .op-spinner-dots span:nth-child(3) { animation-delay: .3s; }
1047
+
1048
+ /* Skeleton */
1049
+ .op-skeleton {
1050
+ background: var(--op-panel-3);
1051
+ border-radius: var(--op-radius-sm);
1052
+ position: relative;
1053
+ overflow: hidden;
1054
+ }
1055
+ .op-skeleton::after {
1056
+ content: "";
1057
+ position: absolute;
1058
+ inset: 0;
1059
+ background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--op-strong) 6%, transparent), transparent);
1060
+ animation: op-shimmer 1.5s ease-in-out infinite;
1061
+ }
1062
+ .op-skeleton-text { height: 12px; margin-bottom: .625rem; }
1063
+ .op-skeleton-circle { border-radius: 50%; }
1064
+
1065
+ /* ----------------------------------------------------------------------------
1066
+ 13. TABS
1067
+ ---------------------------------------------------------------------------- */
1068
+ .op-tabs {
1069
+ display: flex;
1070
+ gap: .25rem;
1071
+ border-bottom: 1px solid var(--op-border);
1072
+ overflow-x: auto;
1073
+ }
1074
+ .op-tab {
1075
+ padding: .625rem 1.125rem;
1076
+ background: none;
1077
+ border: 0;
1078
+ border-bottom: 2px solid transparent;
1079
+ margin-bottom: -1px;
1080
+ color: var(--op-muted);
1081
+ font-family: var(--op-font-mono);
1082
+ font-size: .75rem;
1083
+ font-weight: 700;
1084
+ text-transform: uppercase;
1085
+ letter-spacing: .08em;
1086
+ cursor: pointer;
1087
+ display: inline-flex;
1088
+ align-items: center;
1089
+ gap: .5rem;
1090
+ white-space: nowrap;
1091
+ transition: color .2s, border-color .2s;
1092
+ }
1093
+ .op-tab:hover { color: var(--op-text); }
1094
+ .op-tab.is-active {
1095
+ color: var(--op-strong);
1096
+ border-bottom-color: var(--op-accent);
1097
+ }
1098
+ html.light .op-tab.is-active { border-bottom-color: var(--op-primary); }
1099
+ .op-tab-panel { display: none; padding: 1.25rem 0; }
1100
+ .op-tab-panel.is-active { display: block; animation: op-fade-in .25s ease; }
1101
+
1102
+ /* Tabs estilo "pill" */
1103
+ .op-tabs-pills {
1104
+ display: inline-flex;
1105
+ gap: .25rem;
1106
+ padding: .25rem;
1107
+ background: var(--op-panel-2);
1108
+ border: 1px solid var(--op-border);
1109
+ border-radius: var(--op-radius);
1110
+ box-shadow: var(--op-shadow-sm);
1111
+ }
1112
+ .op-tabs-pills .op-tab {
1113
+ border: 0;
1114
+ margin: 0;
1115
+ border-radius: var(--op-radius-sm);
1116
+ padding: .5rem 1rem;
1117
+ }
1118
+ .op-tabs-pills .op-tab.is-active {
1119
+ background: var(--op-accent);
1120
+ color: var(--op-accent-ink);
1121
+ }
1122
+ html.light .op-tabs-pills .op-tab.is-active { background: var(--op-primary); color: var(--op-primary-ink); }
1123
+
1124
+ /* ----------------------------------------------------------------------------
1125
+ 14. ACCORDION (usa <details> nativo)
1126
+ ---------------------------------------------------------------------------- */
1127
+ .op-accordion {
1128
+ border: 1px solid var(--op-border);
1129
+ border-radius: var(--op-radius);
1130
+ overflow: hidden;
1131
+ background: var(--op-panel);
1132
+ box-shadow: var(--op-shadow);
1133
+ }
1134
+ .op-accordion details { border-bottom: 1px solid var(--op-border); }
1135
+ .op-accordion details:last-child { border-bottom: 0; }
1136
+ .op-accordion summary {
1137
+ padding: 1rem 1.25rem;
1138
+ cursor: pointer;
1139
+ list-style: none;
1140
+ display: flex;
1141
+ align-items: center;
1142
+ justify-content: space-between;
1143
+ gap: 1rem;
1144
+ font-weight: 700;
1145
+ font-size: .875rem;
1146
+ color: var(--op-strong);
1147
+ transition: background .2s;
1148
+ }
1149
+ .op-accordion summary::-webkit-details-marker { display: none; }
1150
+ .op-accordion summary::after {
1151
+ content: "";
1152
+ width: 8px; height: 8px;
1153
+ border-right: 2px solid var(--op-muted);
1154
+ border-bottom: 2px solid var(--op-muted);
1155
+ transform: rotate(45deg);
1156
+ transition: transform .25s var(--op-ease);
1157
+ flex-shrink: 0;
1158
+ }
1159
+ .op-accordion details[open] summary::after { transform: rotate(-135deg); }
1160
+ .op-accordion summary:hover { background: color-mix(in srgb, var(--op-strong) 4%, transparent); }
1161
+ .op-accordion-body {
1162
+ padding: 0 1.25rem 1.25rem;
1163
+ font-size: .8125rem;
1164
+ color: var(--op-muted);
1165
+ line-height: 1.7;
1166
+ }
1167
+
1168
+ /* ----------------------------------------------------------------------------
1169
+ 15. DROPDOWN
1170
+ ---------------------------------------------------------------------------- */
1171
+ .op-dropdown { position: relative; display: inline-block; }
1172
+ .op-menu {
1173
+ position: absolute;
1174
+ top: calc(100% + 8px);
1175
+ right: 0;
1176
+ min-width: 200px;
1177
+ background: var(--op-panel);
1178
+ border: 1px solid var(--op-border-2);
1179
+ border-radius: var(--op-radius);
1180
+ box-shadow: var(--op-shadow-lg);
1181
+ padding: .375rem;
1182
+ z-index: 80;
1183
+ opacity: 0;
1184
+ visibility: hidden;
1185
+ transform: translateY(-6px) scale(.98);
1186
+ transform-origin: top right;
1187
+ transition: all .2s var(--op-spring);
1188
+ }
1189
+ .op-dropdown.is-open .op-menu {
1190
+ opacity: 1;
1191
+ visibility: visible;
1192
+ transform: translateY(0) scale(1);
1193
+ }
1194
+ .op-menu-item {
1195
+ display: flex;
1196
+ align-items: center;
1197
+ gap: .625rem;
1198
+ width: 100%;
1199
+ padding: .5625rem .75rem;
1200
+ background: none;
1201
+ border: 0;
1202
+ border-radius: var(--op-radius-sm);
1203
+ color: var(--op-text);
1204
+ font-family: var(--op-font-sans);
1205
+ font-size: .8125rem;
1206
+ font-weight: 500;
1207
+ text-align: left;
1208
+ text-decoration: none;
1209
+ cursor: pointer;
1210
+ transition: background .15s, color .15s;
1211
+ }
1212
+ .op-menu-item i { font-size: 1rem; color: var(--op-muted); }
1213
+ .op-menu-item:hover { background: color-mix(in srgb, var(--op-strong) 6%, transparent); color: var(--op-strong); }
1214
+ .op-menu-item:hover i { color: var(--op-strong); }
1215
+ .op-menu-item.is-danger { color: var(--op-danger); }
1216
+ .op-menu-item.is-danger i { color: var(--op-danger); }
1217
+ .op-menu-item.is-danger:hover { background: color-mix(in srgb, var(--op-danger) 12%, transparent); color: var(--op-danger); }
1218
+ .op-menu-divider { height: 1px; background: var(--op-border); margin: .375rem .25rem; }
1219
+ .op-menu-label {
1220
+ padding: .375rem .75rem .125rem;
1221
+ font-family: var(--op-font-mono);
1222
+ font-size: .625rem;
1223
+ font-weight: 700;
1224
+ text-transform: uppercase;
1225
+ letter-spacing: .15em;
1226
+ color: var(--op-muted);
1227
+ }
1228
+
1229
+ /* ----------------------------------------------------------------------------
1230
+ 16. TOOLTIP (CSS puro via atributo data-op-tip)
1231
+ ---------------------------------------------------------------------------- */
1232
+ [data-op-tip] { position: relative; }
1233
+ [data-op-tip]::after {
1234
+ content: attr(data-op-tip);
1235
+ position: absolute;
1236
+ bottom: calc(100% + 10px);
1237
+ left: 50%;
1238
+ translate: -50% 0;
1239
+ background: var(--op-strong);
1240
+ color: var(--op-bg);
1241
+ font-family: var(--op-font-mono);
1242
+ font-size: 11px;
1243
+ font-weight: 700;
1244
+ padding: .375rem .75rem;
1245
+ border-radius: var(--op-radius-sm);
1246
+ white-space: nowrap;
1247
+ box-shadow: var(--op-shadow);
1248
+ opacity: 0;
1249
+ visibility: hidden;
1250
+ transform: translateY(4px);
1251
+ transition: all .2s var(--op-spring);
1252
+ pointer-events: none;
1253
+ z-index: 70;
1254
+ }
1255
+ [data-op-tip]::before {
1256
+ content: "";
1257
+ position: absolute;
1258
+ bottom: calc(100% + 2px);
1259
+ left: 50%;
1260
+ translate: -50% 0;
1261
+ border: 5px solid transparent;
1262
+ border-top-color: var(--op-strong);
1263
+ opacity: 0;
1264
+ visibility: hidden;
1265
+ transition: all .2s var(--op-spring);
1266
+ pointer-events: none;
1267
+ z-index: 70;
1268
+ }
1269
+ [data-op-tip]:hover::after, [data-op-tip]:hover::before {
1270
+ opacity: 1;
1271
+ visibility: visible;
1272
+ transform: translateY(0);
1273
+ }
1274
+
1275
+ /* Variante: tooltip abaixo do elemento (para itens colados no topo da tela) */
1276
+ .op-tip-bottom::after {
1277
+ bottom: auto;
1278
+ top: calc(100% + 10px);
1279
+ transform: translateY(-4px);
1280
+ }
1281
+ .op-tip-bottom::before {
1282
+ bottom: auto;
1283
+ top: calc(100% + 2px);
1284
+ border-top-color: transparent;
1285
+ border-bottom-color: var(--op-strong);
1286
+ }
1287
+
1288
+ /* ----------------------------------------------------------------------------
1289
+ 17. BREADCRUMB & PAGINAÇÃO
1290
+ ---------------------------------------------------------------------------- */
1291
+ .op-breadcrumb {
1292
+ display: flex;
1293
+ align-items: center;
1294
+ gap: .5rem;
1295
+ font-family: var(--op-font-mono);
1296
+ font-size: .75rem;
1297
+ list-style: none;
1298
+ padding: 0;
1299
+ margin: 0;
1300
+ flex-wrap: wrap;
1301
+ }
1302
+ .op-breadcrumb li { display: flex; align-items: center; gap: .5rem; }
1303
+ .op-breadcrumb li:not(:last-child)::after {
1304
+ content: "/";
1305
+ color: var(--op-border-2);
1306
+ }
1307
+ .op-breadcrumb a { color: var(--op-muted); text-decoration: none; transition: color .2s; }
1308
+ .op-breadcrumb a:hover { color: var(--op-strong); }
1309
+ .op-breadcrumb li:last-child { color: var(--op-accent); font-weight: 700; }
1310
+ html.light .op-breadcrumb li:last-child { color: #3F6212; }
1311
+
1312
+ .op-pagination { display: inline-flex; gap: .25rem; list-style: none; padding: 0; margin: 0; }
1313
+ .op-page {
1314
+ min-width: 36px; height: 36px;
1315
+ display: inline-flex;
1316
+ align-items: center;
1317
+ justify-content: center;
1318
+ padding: 0 .5rem;
1319
+ border: 1px solid var(--op-border);
1320
+ border-radius: var(--op-radius-sm);
1321
+ background: var(--op-panel-2);
1322
+ color: var(--op-text);
1323
+ font-family: var(--op-font-mono);
1324
+ font-size: .75rem;
1325
+ font-weight: 700;
1326
+ text-decoration: none;
1327
+ cursor: pointer;
1328
+ transition: all .2s;
1329
+ }
1330
+ .op-page:hover { border-color: var(--op-border-2); color: var(--op-strong); background: var(--op-panel-3); }
1331
+ .op-page.is-active {
1332
+ background: var(--op-accent);
1333
+ border-color: var(--op-accent);
1334
+ color: var(--op-accent-ink);
1335
+ }
1336
+ html.light .op-page.is-active { background: var(--op-primary); border-color: var(--op-primary); color: var(--op-primary-ink); }
1337
+ .op-page.is-disabled { opacity: .4; pointer-events: none; }
1338
+
1339
+ /* ----------------------------------------------------------------------------
1340
+ 18. MODAL
1341
+ ---------------------------------------------------------------------------- */
1342
+ .op-modal {
1343
+ position: fixed;
1344
+ inset: 0;
1345
+ z-index: 100;
1346
+ display: none;
1347
+ align-items: center;
1348
+ justify-content: center;
1349
+ padding: 1rem;
1350
+ background: rgba(0,0,0,.7);
1351
+ backdrop-filter: blur(6px);
1352
+ -webkit-backdrop-filter: blur(6px);
1353
+ }
1354
+ html.light .op-modal { background: rgba(15,23,42,.5); }
1355
+ .op-modal.is-open { display: flex; }
1356
+
1357
+ .op-modal-box {
1358
+ width: 100%;
1359
+ max-width: 520px;
1360
+ max-height: calc(100vh - 2rem);
1361
+ display: flex;
1362
+ flex-direction: column;
1363
+ background: var(--op-panel);
1364
+ border: 1px solid var(--op-border-2);
1365
+ border-radius: var(--op-radius-lg);
1366
+ box-shadow: var(--op-shadow-lg);
1367
+ overflow: hidden;
1368
+ }
1369
+ .op-modal-sm .op-modal-box { max-width: 400px; }
1370
+ .op-modal-lg .op-modal-box { max-width: 760px; }
1371
+
1372
+ .op-modal.is-open .op-modal-box { animation: op-modal-in .3s var(--op-spring); }
1373
+ .op-modal.is-closing .op-modal-box { animation: op-modal-out .2s ease-in forwards; }
1374
+
1375
+ .op-modal-header {
1376
+ display: flex;
1377
+ align-items: center;
1378
+ justify-content: space-between;
1379
+ gap: 1rem;
1380
+ padding: 1.25rem 1.5rem;
1381
+ border-bottom: 1px solid var(--op-border);
1382
+ background: var(--op-panel-2);
1383
+ }
1384
+ .op-modal-title {
1385
+ display: flex;
1386
+ align-items: center;
1387
+ gap: .75rem;
1388
+ font-family: var(--op-font-display);
1389
+ font-size: 1.25rem;
1390
+ font-weight: 700;
1391
+ color: var(--op-strong);
1392
+ margin: 0;
1393
+ }
1394
+ .op-modal-close {
1395
+ background: none;
1396
+ border: 0;
1397
+ color: var(--op-muted);
1398
+ font-size: 1.375rem;
1399
+ cursor: pointer;
1400
+ padding: .25rem;
1401
+ border-radius: var(--op-radius-sm);
1402
+ display: flex;
1403
+ transition: all .2s;
1404
+ }
1405
+ .op-modal-close:hover { color: var(--op-strong); background: color-mix(in srgb, var(--op-strong) 8%, transparent); }
1406
+ .op-modal-close:active { transform: scale(.9); }
1407
+
1408
+ .op-modal-body { padding: 1.5rem; overflow-y: auto; }
1409
+ .op-modal-footer {
1410
+ display: flex;
1411
+ justify-content: flex-end;
1412
+ gap: .75rem;
1413
+ padding: 1.25rem 1.5rem;
1414
+ border-top: 1px solid var(--op-border);
1415
+ background: var(--op-panel-2);
1416
+ }
1417
+
1418
+ /* ----------------------------------------------------------------------------
1419
+ 19. TOASTS (criados via OptagoUI.toast)
1420
+ ---------------------------------------------------------------------------- */
1421
+ .op-toast-container {
1422
+ position: fixed;
1423
+ top: 1.5rem;
1424
+ left: 50%;
1425
+ translate: -50% 0;
1426
+ z-index: 110;
1427
+ display: flex;
1428
+ flex-direction: column;
1429
+ align-items: center;
1430
+ gap: .625rem;
1431
+ pointer-events: none;
1432
+ width: min(420px, calc(100vw - 2rem));
1433
+ }
1434
+ .op-toast {
1435
+ pointer-events: auto;
1436
+ display: flex;
1437
+ align-items: center;
1438
+ gap: .75rem;
1439
+ width: 100%;
1440
+ padding: .875rem 1rem;
1441
+ background: var(--op-panel);
1442
+ border: 1px solid var(--op-border-2);
1443
+ border-radius: var(--op-radius);
1444
+ box-shadow: var(--op-shadow-lg);
1445
+ font-family: var(--op-font-mono);
1446
+ font-size: .8125rem;
1447
+ font-weight: 600;
1448
+ color: var(--op-strong);
1449
+ opacity: 0;
1450
+ transform: translateY(-16px) scale(.97);
1451
+ transition: all .3s var(--op-spring);
1452
+ }
1453
+ .op-toast.is-visible { opacity: 1; transform: translateY(0) scale(1); }
1454
+ .op-toast > span { flex: 1; }
1455
+ .op-toast-close {
1456
+ background: none;
1457
+ border: 0;
1458
+ color: var(--op-muted);
1459
+ font-size: 1.125rem;
1460
+ cursor: pointer;
1461
+ padding: .25rem;
1462
+ border-radius: 6px;
1463
+ display: flex;
1464
+ flex-shrink: 0;
1465
+ transition: color .2s, background .2s;
1466
+ }
1467
+ .op-toast-close:hover {
1468
+ color: var(--op-strong);
1469
+ background: color-mix(in srgb, var(--op-strong) 8%, transparent);
1470
+ }
1471
+ .op-toast-icon {
1472
+ width: 32px; height: 32px;
1473
+ border-radius: 50%;
1474
+ display: flex;
1475
+ align-items: center;
1476
+ justify-content: center;
1477
+ font-size: 1.125rem;
1478
+ flex-shrink: 0;
1479
+ border: 1px solid transparent;
1480
+ }
1481
+ .op-toast-info { border-color: color-mix(in srgb, var(--op-info) 35%, var(--op-border)); }
1482
+ .op-toast-info .op-toast-icon { background: color-mix(in srgb, var(--op-info) 15%, transparent); color: var(--op-info); border-color: color-mix(in srgb, var(--op-info) 30%, transparent); }
1483
+ .op-toast-success { border-color: color-mix(in srgb, var(--op-success) 35%, var(--op-border)); }
1484
+ .op-toast-success .op-toast-icon { background: color-mix(in srgb, var(--op-success) 15%, transparent); color: var(--op-success); border-color: color-mix(in srgb, var(--op-success) 30%, transparent); }
1485
+ .op-toast-warning { border-color: color-mix(in srgb, var(--op-warning) 35%, var(--op-border)); }
1486
+ .op-toast-warning .op-toast-icon { background: color-mix(in srgb, var(--op-warning) 15%, transparent); color: var(--op-warning); border-color: color-mix(in srgb, var(--op-warning) 30%, transparent); }
1487
+ .op-toast-danger { border-color: color-mix(in srgb, var(--op-danger) 35%, var(--op-border)); }
1488
+ .op-toast-danger .op-toast-icon { background: color-mix(in srgb, var(--op-danger) 15%, transparent); color: var(--op-danger); border-color: color-mix(in srgb, var(--op-danger) 30%, transparent); }
1489
+
1490
+ /* ----------------------------------------------------------------------------
1491
+ 20. BLOCO DE DEMONSTRAÇÃO (showcase: preview + copiar + ver código)
1492
+ ---------------------------------------------------------------------------- */
1493
+ .op-demo {
1494
+ background: var(--op-panel);
1495
+ border: 1px solid var(--op-border);
1496
+ border-radius: var(--op-radius-lg);
1497
+ overflow: hidden;
1498
+ box-shadow: var(--op-shadow);
1499
+ }
1500
+ .op-demo-preview {
1501
+ padding: 2rem;
1502
+ background:
1503
+ radial-gradient(color-mix(in srgb, var(--op-border) 55%, transparent) 1px, transparent 1px);
1504
+ background-size: 22px 22px;
1505
+ }
1506
+ .op-demo-bar {
1507
+ display: flex;
1508
+ justify-content: flex-end;
1509
+ gap: .5rem;
1510
+ padding: .625rem .875rem;
1511
+ border-top: 1px solid var(--op-border);
1512
+ background: var(--op-panel-2);
1513
+ }
1514
+ .op-demo-code {
1515
+ display: none;
1516
+ margin: 0;
1517
+ padding: 1.25rem;
1518
+ background: #0D1117;
1519
+ border-top: 1px solid var(--op-border);
1520
+ color: #A5D6FF;
1521
+ font-family: var(--op-font-mono);
1522
+ font-size: .75rem;
1523
+ line-height: 1.6;
1524
+ overflow-x: auto;
1525
+ tab-size: 2;
1526
+ white-space: pre;
1527
+ }
1528
+ .op-demo-code.is-visible { display: block; }
1529
+
1530
+ /* Cabeçalho de seção do showcase */
1531
+ .op-section-head {
1532
+ display: flex;
1533
+ align-items: center;
1534
+ gap: .75rem;
1535
+ padding-bottom: 1rem;
1536
+ margin-bottom: 1.5rem;
1537
+ border-bottom: 1px solid var(--op-border);
1538
+ }
1539
+ .op-section-head i {
1540
+ font-size: 1.375rem;
1541
+ color: var(--op-accent);
1542
+ width: 44px; height: 44px;
1543
+ display: flex;
1544
+ align-items: center;
1545
+ justify-content: center;
1546
+ background: color-mix(in srgb, var(--op-accent) 10%, transparent);
1547
+ -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
1548
+ flex-shrink: 0;
1549
+ }
1550
+ html.light .op-section-head i { color: #3F6212; background: #EDFBD4; }
1551
+ .op-section-head h2 { margin: 0; font-size: 1.5rem; }
1552
+
1553
+ /* ----------------------------------------------------------------------------
1554
+ 20b. GLOW — manchas de verde-lima desfocadas no fundo.
1555
+ Use dentro de um container com position:relative (ou no .op-app-body).
1556
+ O conteúdo por cima deve ter z-index maior (o .op-main já tem z-index:1).
1557
+ ---------------------------------------------------------------------------- */
1558
+ .op-glow {
1559
+ position: absolute;
1560
+ width: 460px;
1561
+ height: 340px;
1562
+ max-width: 70vw;
1563
+ background: var(--op-accent);
1564
+ opacity: .07;
1565
+ filter: blur(110px);
1566
+ border-radius: 50%;
1567
+ pointer-events: none;
1568
+ z-index: 0;
1569
+ }
1570
+ html.light .op-glow { opacity: .22; }
1571
+ .op-glow-info { background: var(--op-info); }
1572
+ html.light .op-glow-info { opacity: .14; }
1573
+ .op-glow-sm { width: 260px; height: 200px; }
1574
+ .op-glow-lg { width: 700px; height: 460px; }
1575
+ .op-glow-strong { opacity: .12; }
1576
+ html.light .op-glow-strong { opacity: .32; }
1577
+
1578
+ /* ----------------------------------------------------------------------------
1579
+ 20c. MODAIS — VARIANTES EXTRAS
1580
+ ---------------------------------------------------------------------------- */
1581
+ /* Drawer lateral (desliza da direita) */
1582
+ .op-modal-drawer { justify-content: flex-end; align-items: stretch; padding: 0; }
1583
+ .op-modal-drawer .op-modal-box {
1584
+ max-width: 440px;
1585
+ height: 100%;
1586
+ max-height: none;
1587
+ border-radius: 0;
1588
+ border-top: 0;
1589
+ border-bottom: 0;
1590
+ border-right: 0;
1591
+ }
1592
+ .op-modal-drawer .op-modal-body { flex: 1; }
1593
+ .op-modal-drawer.is-open .op-modal-box { animation: op-drawer-in .35s var(--op-spring); }
1594
+ .op-modal-drawer.is-closing .op-modal-box { animation: op-drawer-out .25s ease-in forwards; }
1595
+
1596
+ /* Modal centrado (confirmações e sucesso, sem header) */
1597
+ .op-modal-centered .op-modal-box { max-width: 400px; text-align: center; }
1598
+ .op-modal-centered .op-modal-body {
1599
+ padding: 2.25rem 1.75rem 1rem;
1600
+ display: flex;
1601
+ flex-direction: column;
1602
+ align-items: center;
1603
+ }
1604
+ .op-modal-centered .op-modal-footer {
1605
+ justify-content: center;
1606
+ border-top: 0;
1607
+ background: transparent;
1608
+ padding-top: .5rem;
1609
+ }
1610
+ .op-modal-icon {
1611
+ width: 68px; height: 68px;
1612
+ -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
1613
+ display: flex;
1614
+ align-items: center;
1615
+ justify-content: center;
1616
+ font-size: 2rem;
1617
+ margin-bottom: 1rem;
1618
+ }
1619
+ .op-modal-icon.is-success { background: color-mix(in srgb, var(--op-success) 15%, transparent); color: var(--op-success); }
1620
+ .op-modal-icon.is-danger { background: color-mix(in srgb, var(--op-danger) 15%, transparent); color: var(--op-danger); }
1621
+ .op-modal-icon.is-warning { background: color-mix(in srgb, var(--op-warning) 15%, transparent); color: var(--op-warning); }
1622
+ .op-modal-icon.is-brand { background: color-mix(in srgb, var(--op-accent) 14%, transparent); color: var(--op-accent); }
1623
+ html.light .op-modal-icon.is-brand { color: #3F6212; }
1624
+
1625
+ @keyframes op-drawer-in {
1626
+ from { transform: translateX(100%); }
1627
+ to { transform: translateX(0); }
1628
+ }
1629
+ @keyframes op-drawer-out {
1630
+ from { transform: translateX(0); }
1631
+ to { transform: translateX(100%); }
1632
+ }
1633
+
1634
+ /* ----------------------------------------------------------------------------
1635
+ 20d. TABS VERTICAIS
1636
+ ---------------------------------------------------------------------------- */
1637
+ .op-tabs-vertical { display: flex; gap: 1.5rem; align-items: flex-start; }
1638
+ .op-tabs-vertical .op-tabs-col {
1639
+ display: flex;
1640
+ flex-direction: column;
1641
+ gap: .25rem;
1642
+ min-width: 190px;
1643
+ flex-shrink: 0;
1644
+ }
1645
+ .op-tabs-col .op-tab {
1646
+ justify-content: flex-start;
1647
+ border: 0;
1648
+ margin: 0;
1649
+ border-radius: var(--op-radius-sm);
1650
+ padding: .625rem .875rem;
1651
+ text-align: left;
1652
+ }
1653
+ .op-tabs-col .op-tab.is-active {
1654
+ background: color-mix(in srgb, var(--op-accent) 12%, transparent);
1655
+ color: var(--op-strong);
1656
+ box-shadow: inset 3px 0 0 var(--op-accent);
1657
+ }
1658
+ html.light .op-tabs-col .op-tab.is-active { box-shadow: inset 3px 0 0 #84CC16; }
1659
+ .op-tabs-vertical .op-tab-panels { flex: 1; min-width: 0; }
1660
+ .op-tabs-vertical .op-tab-panel { padding: 0; }
1661
+ @media (max-width: 640px) {
1662
+ .op-tabs-vertical { flex-direction: column; }
1663
+ .op-tabs-vertical .op-tabs-col { flex-direction: row; flex-wrap: wrap; min-width: 0; }
1664
+ }
1665
+
1666
+ /* ----------------------------------------------------------------------------
1667
+ 20e. SKELETON — variações extras
1668
+ ---------------------------------------------------------------------------- */
1669
+ .op-skeleton-thumb { aspect-ratio: 16 / 9; width: 100%; border-radius: var(--op-radius); margin-bottom: 1rem; }
1670
+ .op-skeleton-title { height: 16px; width: 55%; margin-bottom: .75rem; }
1671
+ .op-skeleton-btn { height: 36px; width: 116px; }
1672
+ .op-skeleton-badge { height: 22px; width: 68px; border-radius: 999px; }
1673
+ .op-skeleton-row {
1674
+ display: flex;
1675
+ align-items: center;
1676
+ gap: .875rem;
1677
+ padding: .625rem 0;
1678
+ }
1679
+
1680
+ /* ----------------------------------------------------------------------------
1681
+ 20f. TIMELINE
1682
+ ---------------------------------------------------------------------------- */
1683
+ .op-timeline { position: relative; list-style: none; margin: 0; padding: 0 0 0 2rem; }
1684
+ .op-timeline::before {
1685
+ content: "";
1686
+ position: absolute;
1687
+ left: 7px;
1688
+ top: 6px;
1689
+ bottom: 6px;
1690
+ width: 2px;
1691
+ background: var(--op-border);
1692
+ }
1693
+ .op-timeline-item { position: relative; padding-bottom: 1.75rem; }
1694
+ .op-timeline-item:last-child { padding-bottom: 0; }
1695
+ .op-timeline-marker {
1696
+ position: absolute;
1697
+ left: -2rem;
1698
+ top: 3px;
1699
+ width: 16px; height: 16px;
1700
+ background: var(--op-border-2);
1701
+ -webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
1702
+ }
1703
+ .op-timeline-marker.is-brand { background: var(--op-accent); }
1704
+ .op-timeline-marker.is-success { background: var(--op-success); }
1705
+ .op-timeline-marker.is-warning { background: var(--op-warning); }
1706
+ .op-timeline-marker.is-danger { background: var(--op-danger); }
1707
+ .op-timeline-marker.is-info { background: var(--op-info); }
1708
+ .op-timeline-marker.is-pulse { animation: op-pulse 1.6s ease-in-out infinite; }
1709
+ .op-timeline-time {
1710
+ font-family: var(--op-font-mono);
1711
+ font-size: .6875rem;
1712
+ font-weight: 700;
1713
+ text-transform: uppercase;
1714
+ letter-spacing: .1em;
1715
+ color: var(--op-muted);
1716
+ display: block;
1717
+ margin-bottom: .125rem;
1718
+ }
1719
+ .op-timeline-title {
1720
+ font-weight: 700;
1721
+ font-size: .9375rem;
1722
+ color: var(--op-strong);
1723
+ margin: 0 0 .25rem;
1724
+ display: flex;
1725
+ align-items: center;
1726
+ gap: .5rem;
1727
+ flex-wrap: wrap;
1728
+ }
1729
+ .op-timeline-text { font-size: .8125rem; color: var(--op-muted); margin: 0; line-height: 1.6; }
1730
+
1731
+ /* ----------------------------------------------------------------------------
1732
+ 20g. TABULATOR — tema Óptago
1733
+ Aplicado quando a tabela é criada via OptagoUI.tabulator() (o JS injeta o
1734
+ CSS base do Tabulator ANTES deste arquivo, então estas regras vencem).
1735
+ ---------------------------------------------------------------------------- */
1736
+ .op-tabulator.tabulator {
1737
+ background: var(--op-panel);
1738
+ border: 1px solid var(--op-border);
1739
+ border-radius: var(--op-radius);
1740
+ box-shadow: var(--op-shadow);
1741
+ font-family: var(--op-font-sans);
1742
+ font-size: .875rem;
1743
+ overflow: hidden;
1744
+ }
1745
+ .op-tabulator.tabulator .tabulator-header {
1746
+ background: var(--op-panel-2);
1747
+ border-bottom: 1px solid var(--op-border);
1748
+ color: var(--op-muted);
1749
+ }
1750
+ .op-tabulator.tabulator .tabulator-header .tabulator-col {
1751
+ background: transparent;
1752
+ border-right: 1px solid var(--op-border);
1753
+ }
1754
+ .op-tabulator.tabulator .tabulator-header .tabulator-col:last-of-type { border-right: 0; }
1755
+ .op-tabulator.tabulator .tabulator-header .tabulator-col .tabulator-col-content { padding: .875rem 1rem; }
1756
+ .op-tabulator.tabulator .tabulator-header .tabulator-col-title {
1757
+ font-family: var(--op-font-mono);
1758
+ font-size: .6875rem;
1759
+ font-weight: 700;
1760
+ text-transform: uppercase;
1761
+ letter-spacing: .12em;
1762
+ color: var(--op-muted);
1763
+ }
1764
+ .op-tabulator.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
1765
+ background: var(--op-panel-3);
1766
+ }
1767
+ /* setas de ordenação */
1768
+ .op-tabulator.tabulator .tabulator-header .tabulator-col .tabulator-col-sorter .tabulator-arrow {
1769
+ border-bottom-color: var(--op-muted);
1770
+ }
1771
+ .op-tabulator.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="ascending"] .tabulator-col-sorter .tabulator-arrow {
1772
+ border-bottom-color: var(--op-accent);
1773
+ }
1774
+ .op-tabulator.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="descending"] .tabulator-col-sorter .tabulator-arrow {
1775
+ border-top-color: var(--op-accent);
1776
+ }
1777
+ html.light .op-tabulator.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="ascending"] .tabulator-col-sorter .tabulator-arrow { border-bottom-color: #65A30D; }
1778
+ html.light .op-tabulator.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="descending"] .tabulator-col-sorter .tabulator-arrow { border-top-color: #65A30D; }
1779
+
1780
+ .op-tabulator.tabulator .tabulator-tableholder { background: var(--op-panel); }
1781
+ .op-tabulator.tabulator .tabulator-tableholder .tabulator-table {
1782
+ background: transparent;
1783
+ color: var(--op-text);
1784
+ }
1785
+ .op-tabulator.tabulator .tabulator-row {
1786
+ background: transparent;
1787
+ border-bottom: 1px solid var(--op-border);
1788
+ color: var(--op-text);
1789
+ min-height: 0;
1790
+ }
1791
+ .op-tabulator.tabulator .tabulator-row .tabulator-cell {
1792
+ padding: .75rem 1rem;
1793
+ border-right: 0;
1794
+ }
1795
+ .op-tabulator.tabulator .tabulator-row.tabulator-row-even { background: color-mix(in srgb, var(--op-strong) 2.5%, transparent); }
1796
+ .op-tabulator.tabulator .tabulator-row.tabulator-selectable:hover {
1797
+ background: color-mix(in srgb, var(--op-accent) 6%, transparent);
1798
+ cursor: pointer;
1799
+ }
1800
+ .op-tabulator.tabulator .tabulator-row.tabulator-selected {
1801
+ background: color-mix(in srgb, var(--op-accent) 14%, transparent);
1802
+ }
1803
+ .op-tabulator.tabulator .tabulator-placeholder .tabulator-placeholder-contents {
1804
+ color: var(--op-muted);
1805
+ font-family: var(--op-font-mono);
1806
+ font-size: .8125rem;
1807
+ }
1808
+ /* rodapé / paginação */
1809
+ .op-tabulator.tabulator .tabulator-footer {
1810
+ background: var(--op-panel-2);
1811
+ border-top: 1px solid var(--op-border);
1812
+ color: var(--op-muted);
1813
+ padding: .5rem .75rem;
1814
+ }
1815
+ .op-tabulator.tabulator .tabulator-footer .tabulator-footer-contents { padding: 0; }
1816
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page-counter,
1817
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page-size {
1818
+ font-family: var(--op-font-mono);
1819
+ font-size: .6875rem;
1820
+ color: var(--op-muted);
1821
+ }
1822
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page-size {
1823
+ background: var(--op-panel);
1824
+ border: 1px solid var(--op-border-2);
1825
+ border-radius: 6px;
1826
+ color: var(--op-text);
1827
+ padding: .25rem .5rem;
1828
+ }
1829
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page {
1830
+ background: var(--op-panel);
1831
+ border: 1px solid var(--op-border);
1832
+ border-radius: var(--op-radius-sm);
1833
+ color: var(--op-text);
1834
+ font-family: var(--op-font-mono);
1835
+ font-size: .6875rem;
1836
+ font-weight: 700;
1837
+ padding: .3125rem .625rem;
1838
+ margin: 0 .125rem;
1839
+ transition: all .2s;
1840
+ }
1841
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
1842
+ background: var(--op-panel-3);
1843
+ border-color: var(--op-border-2);
1844
+ color: var(--op-strong);
1845
+ }
1846
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page.active {
1847
+ background: var(--op-accent);
1848
+ border-color: var(--op-accent);
1849
+ color: var(--op-accent-ink);
1850
+ }
1851
+ html.light .op-tabulator.tabulator .tabulator-footer .tabulator-page.active {
1852
+ background: var(--op-primary);
1853
+ border-color: var(--op-primary);
1854
+ color: var(--op-primary-ink);
1855
+ }
1856
+ .op-tabulator.tabulator .tabulator-footer .tabulator-page.disabled { opacity: .4; }
1857
+ /* barra de progresso interna usada em células formatadas */
1858
+ .op-tabulator .op-progress { min-width: 90px; }
1859
+
1860
+ /* ----------------------------------------------------------------------------
1861
+ 21. UTILITÁRIOS
1862
+ ---------------------------------------------------------------------------- */
1863
+ .op-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
1864
+ .op-stack { display: flex; flex-direction: column; gap: 1rem; }
1865
+ .op-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.25rem; }
1866
+ .op-grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.25rem; }
1867
+ .op-grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; }
1868
+
1869
+ /* Visível apenas no mobile (ex.: hamburguer que abre a sidebar) */
1870
+ .op-mobile-only { display: none !important; }
1871
+ @media (max-width: 1023px) { .op-mobile-only { display: inline-flex !important; } }
1872
+
1873
+ .op-text-muted { color: var(--op-muted); }
1874
+ .op-text-accent { color: var(--op-accent); }
1875
+ html.light .op-text-accent { color: #3F6212; }
1876
+ .op-text-mono { font-family: var(--op-font-mono); }
1877
+ .op-text-sm { font-size: .8125rem; }
1878
+ .op-text-xs { font-size: .6875rem; }
1879
+
1880
+ .op-mt-1 { margin-top: .5rem; } .op-mt-2 { margin-top: 1rem; } .op-mt-3 { margin-top: 1.5rem; } .op-mt-4 { margin-top: 2.5rem; }
1881
+ .op-mb-1 { margin-bottom: .5rem; } .op-mb-2 { margin-bottom: 1rem; } .op-mb-3 { margin-bottom: 1.5rem; } .op-mb-4 { margin-bottom: 2.5rem; }
1882
+
1883
+ /* ----------------------------------------------------------------------------
1884
+ 22. ANIMAÇÕES
1885
+ ---------------------------------------------------------------------------- */
1886
+ @keyframes op-spin { to { transform: rotate(360deg); } }
1887
+ @keyframes op-bounce {
1888
+ 0%, 100% { transform: translateY(0); }
1889
+ 50% { transform: translateY(-7px); }
1890
+ }
1891
+ @keyframes op-pulse {
1892
+ 0%, 100% { opacity: 1; }
1893
+ 50% { opacity: .35; }
1894
+ }
1895
+ @keyframes op-shimmer {
1896
+ from { transform: translateX(-100%); }
1897
+ to { transform: translateX(100%); }
1898
+ }
1899
+ @keyframes op-fade-in {
1900
+ from { opacity: 0; transform: translateY(4px); }
1901
+ to { opacity: 1; transform: translateY(0); }
1902
+ }
1903
+ @keyframes op-modal-in {
1904
+ from { opacity: 0; transform: scale(.95) translateY(12px); }
1905
+ to { opacity: 1; transform: scale(1) translateY(0); }
1906
+ }
1907
+ @keyframes op-modal-out {
1908
+ from { opacity: 1; transform: scale(1) translateY(0); }
1909
+ to { opacity: 0; transform: scale(.95) translateY(12px); }
1910
+ }
1911
+
1912
+ @media (prefers-reduced-motion: reduce) {
1913
+ *, *::before, *::after {
1914
+ animation-duration: .01ms !important;
1915
+ transition-duration: .01ms !important;
1916
+ }
1917
+ }