Diff -- /var/www/vhosts/3dshawn.com/crm.3dshawn.com/assets/css/site.css
Diff

/var/www/vhosts/3dshawn.com/crm.3dshawn.com/assets/css/site.css

added on local at 2026-07-09 23:25:37

Added
+2374
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 77ea478cde56
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1/* =====================================================================
2 ContactForge — site.css
3 Dark, modern, "operations-grade" theme for the Customer Relationship
4 Platform. Electric cyan brand palette over deep navy surfaces, with
5 high-density data layouts for the CRM dashboard.
6===================================================================== */
7
8/* ---------------------------------------------------------------------
9 1. Design tokens
10--------------------------------------------------------------------- */
11:root {
12 /* Background scale — deepest at the page, ladders up for cards */
13 --col-bg: #050813;
14 --col-bg-2: #080c1a;
15 --col-surface-1: #0c1224;
16 --col-surface-2: #111a31;
17 --col-surface-3: #18243f;
18 --col-surface-4: #1f2e4f;
19 --col-border: #1c2a48;
20 --col-border-2: #283c66;
21
22 /* Brand — ContactForge electric cyan */
23 --col-brand: #06b6d4;
24 --col-brand-2: #67e8f9;
25 --col-accent: #5aa9ff;
26 --col-accent-deep: #0e7490;
27 --col-accent-bright:#67e8f9;
28 --col-accent-glow: rgba(6,182,212,0.35);
29
30 --col-violet: #7c3aed;
31 --col-violet-bright:#a78bfa;
32 --col-cyan: #06b6d4;
33 --col-cyan-bright: #67e8f9;
34 --col-pink: #ec4899;
35
36 /* Status colors */
37 --col-success: #22c55e;
38 --col-warning: #f59e0b;
39 --col-danger: #ef4444;
40 --col-info: #38bdf8;
41
42 /* Text */
43 --col-text: #e6ecf6;
44 --col-text-2: #a8b6d1;
45 --col-text-3: #6f7e9c;
46 --col-text-dim: #4a5878;
47 --col-white: #ffffff;
48
49 /* Gradients */
50 --grad-brand: linear-gradient(130deg, #06b6d4 0%, #67e8f9 100%);
51 --grad-brand-soft: linear-gradient(130deg, rgba(6,182,212,0.18) 0%, rgba(103,232,249,0.18) 100%);
52 --grad-cyan: linear-gradient(130deg, #06b6d4 0%, #67e8f9 100%);
53 --grad-success: linear-gradient(130deg, #16a34a 0%, #22c55e 100%);
54 --grad-card: linear-gradient(160deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.01) 100%);
55 --grad-border: linear-gradient(130deg, rgba(6,182,212,0.45), rgba(103,232,249,0.45));
56
57 /* Typography */
58 --font-display: 'Space Grotesk', 'Bebas Neue', system-ui, sans-serif;
59 --font-ui: 'Inter', 'Rajdhani', system-ui, sans-serif;
60 --font-mono: 'JetBrains Mono', 'Source Code Pro', monospace;
61
62 /* Spacing */
63 --space-2xs: 4px;
64 --space-xs: 6px;
65 --space-sm: 10px;
66 --space-md: 16px;
67 --space-lg: 24px;
68 --space-xl: 40px;
69 --space-2xl: 64px;
70 --space-3xl: 96px;
71
72 /* Radii */
73 --radius-xs: 4px;
74 --radius-sm: 6px;
75 --radius-md: 10px;
76 --radius-lg: 16px;
77 --radius-xl: 22px;
78 --radius-2xl: 28px;
79
80 /* Shadow */
81 --shadow-sm: 0 2px 8px rgba(0,0,0,0.35);
82 --shadow-md: 0 8px 24px rgba(0,0,0,0.45);
83 --shadow-lg: 0 18px 48px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.02);
84 --shadow-glow: 0 0 32px rgba(6,182,212,0.3);
85
86 /* Transitions */
87 --t-fast: 0.14s ease;
88 --t-med: 0.26s cubic-bezier(.4,0,.2,1);
89 --t-slow: 0.5s cubic-bezier(.4,0,.2,1);
90
91 /* Layout */
92 --sidebar-w: 240px;
93 --topbar-h: 64px;
94 --content-max: 1480px;
95}
96
97
98/* ---------------------------------------------------------------------
99 2. Reset
100--------------------------------------------------------------------- */
101*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
102html { font-size: 16px; scroll-behavior: smooth; }
103body {
104 background: var(--col-bg);
105 color: var(--col-text);
106 font-family: var(--font-ui);
107 font-weight: 400;
108 line-height: 1.55;
109 min-height: 100vh;
110 overflow-x: hidden;
111 -webkit-font-smoothing: antialiased;
112}
113a { color: inherit; text-decoration: none; }
114button { font-family: var(--font-ui); cursor: pointer; border: none; background: none; color: inherit; }
115img { max-width: 100%; display: block; }
116ul, ol { list-style: none; }
117input, textarea, select { font-family: var(--font-ui); }
118
119/* Background atmosphere — every page gets a subtle radial-gradient
120 wash so pure black never shows through. */
121body::before {
122 content: '';
123 position: fixed; inset: 0;
124 background:
125 radial-gradient(ellipse 1200px 700px at 8% -5%, rgba(6,182,212,0.10), transparent 60%),
126 radial-gradient(ellipse 900px 600px at 100% 30%, rgba(6,182,212,0.10), transparent 60%),
127 radial-gradient(ellipse 700px 400px at 50% 110%, rgba(6,182,212,0.08), transparent 60%);
128 pointer-events: none;
129 z-index: 0;
130}
131body > * { position: relative; z-index: 1; }
132
133
134/* ---------------------------------------------------------------------
135 3. Layout shell — sidebar + topbar + main
136--------------------------------------------------------------------- */
137.app {
138 display: grid;
139 grid-template-columns: var(--sidebar-w) 1fr;
140 min-height: 100vh;
141}
142
143.app-main {
144 display: flex;
145 flex-direction: column;
146 min-width: 0;
147}
148
149.app-content {
150 flex: 1;
151 padding: 24px 40px;
152 width: 100%;
153 /* No max-width cap -- main content fills the freed viewport space.
154 Pages with deliberately narrower content (sign-in, settings forms)
155 set their own max-width on their inner wrappers. */
156}
157
158
159/* ---------------------------------------------------------------------
160 4. Sidebar
161--------------------------------------------------------------------- */
162.sidebar {
163 background: linear-gradient(180deg, var(--col-surface-1) 0%, var(--col-bg-2) 100%);
164 border-right: 1px solid var(--col-border);
165 display: flex;
166 flex-direction: column;
167 position: sticky;
168 top: 0;
169 height: 100vh;
170}
171
172/* Diagonal shimmer (sidebar-glisten) -- ambient brand-tinted band sweeps
173 top-left -> bottom-right of the menu BG. Full recipe + bug list:
174 [[feedback-sidebar-glisten-recipe]] in user auto-memory. */
175.sidebar::before {
176 content: '';
177 position: absolute;
178 inset: 0;
179 pointer-events: none;
180 background: linear-gradient(
181 135deg,
182 transparent 30%,
183 rgba(150,200,255,0.07) 48%,
184 rgba(200,225,255,0.11) 52%,
185 transparent 70%
186 );
187 background-size: 250% 250%;
188 background-repeat: no-repeat;
189 background-position: 150% 150%;
190 animation: sidebar-glisten 14s linear infinite;
191 z-index: 0;
192}
193.sidebar > * { position: relative; z-index: 1; }
194@keyframes sidebar-glisten {
195 0% { background-position: 150% 150%; }
196 55% { background-position: -150% -150%; }
197 100% { background-position: -150% -150%; }
198}
199@media (prefers-reduced-motion: reduce) {
200 .sidebar::before { animation: none; opacity: 0; }
201}
202
203.sidebar-brand {
204 padding: var(--space-lg) var(--space-lg) var(--space-md);
205 border-bottom: 1px solid var(--col-border);
206 display: flex;
207 align-items: center;
208 gap: 12px;
209}
210.brand-mark {
211 width: 38px; height: 38px;
212 background: #083344;
213 border: 1px solid #fff;
214 border-radius: var(--radius-md);
215 display: inline-flex !important;
216 flex-direction: row !important;
217 flex-wrap: nowrap !important;
218 align-items: center;
219 justify-content: center;
220 gap: 1px;
221 letter-spacing: -0.5px;
222 line-height: 1;
223 white-space: nowrap;
224 color: #fff;
225 font-family: var(--font-display);
226 font-weight: 700;
227 font-size: 18px;
228 box-shadow: 0 6px 18px rgba(6, 182, 212, 0.55);
229 position: relative;
230}
231.brand-mark::after {
232 content: '';
233 position: absolute; inset: -2px;
234 border-radius: inherit;
235 background: #06b6d4;
236 filter: blur(12px);
237 opacity: 0.45;
238 z-index: -1;
239}
240.brand-text {
241 display: flex; flex-direction: column; line-height: 1;
242}
243.brand-name {
244 font-family: var(--font-display);
245 font-weight: 700;
246 font-size: 18px;
247 letter-spacing: 0.4px;
248 color: #fff;
249}
250.brand-sub {
251 font-size: 10px;
252 letter-spacing: 2px;
253 text-transform: uppercase;
254 color: var(--col-text-3);
255 margin-top: 4px;
256}
257
258.sidebar-nav {
259 flex: 1;
260 overflow-y: auto;
261 padding: var(--space-md) var(--space-sm);
262}
263.sidebar-section-label {
264 font-size: 13px;
265 font-weight: 800;
266 letter-spacing: 2px;
267 text-transform: uppercase;
268 color: var(--col-accent-bright);
269 padding: var(--space-md) var(--space-md) var(--space-xs);
270}
271.sidebar-link {
272 display: flex;
273 align-items: center;
274 gap: 12px;
275 padding: 9px 14px;
276 margin-bottom: 2px;
277 border-radius: var(--radius-md);
278 color: var(--col-text-2);
279 font-size: 14px;
280 font-weight: 500;
281 transition: background var(--t-fast), color var(--t-fast);
282 position: relative;
283}
284.sidebar-link svg { width: 18px; height: 18px; flex-shrink: 0; }
285.sidebar-link:hover {
286 background: var(--col-surface-2);
287 color: var(--col-text);
288}
289.sidebar-link.active {
290 background: linear-gradient(90deg, rgba(6,182,212,0.18), rgba(6,182,212,0.10));
291 color: #fff;
292 box-shadow: inset 0 0 0 1px rgba(6,182,212,0.25);
293}
294.sidebar-link.active::before {
295 content: '';
296 position: absolute;
297 left: -10px; top: 8px; bottom: 8px;
298 width: 3px;
299 border-radius: 0 4px 4px 0;
300 background: var(--grad-brand);
301 box-shadow: 0 0 12px var(--col-accent-glow);
302}
303.sidebar-link .badge {
304 margin-left: auto;
305 background: var(--col-accent);
306 color: #fff;
307 font-size: 10px;
308 font-weight: 700;
309 padding: 2px 7px;
310 border-radius: 5px;
311}
312
313.sidebar-foot {
314 padding: var(--space-md);
315 border-top: 1px solid var(--col-border);
316 display: flex;
317 align-items: center;
318 gap: 10px;
319}
320.user-chip {
321 display: flex; align-items: center; gap: 10px;
322 flex: 1; min-width: 0;
323}
324.user-avatar {
325 width: 34px; height: 34px;
326 border-radius: 50%;
327 background: var(--grad-brand);
328 display: grid; place-items: center;
329 font-weight: 700; font-size: 13px; color: #fff;
330 flex-shrink: 0;
331}
332.user-meta { min-width: 0; }
333.user-name { font-size: 13px; font-weight: 600; color: var(--col-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
334.user-tier { font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--col-cyan-bright); }
335
336
337/* ---------------------------------------------------------------------
338 5. Topbar
339--------------------------------------------------------------------- */
340.topbar {
341 height: var(--topbar-h);
342 border-bottom: 1px solid var(--col-border);
343 background: rgba(8, 12, 26, 0.7);
344 backdrop-filter: blur(12px);
345 -webkit-backdrop-filter: blur(12px);
346 display: flex;
347 align-items: center;
348 justify-content: space-between;
349 padding: 0 var(--space-xl);
350 position: sticky;
351 top: 0;
352 z-index: 150;
353}
354.topbar-title {
355 font-family: var(--font-display);
356 font-size: 18px;
357 font-weight: 600;
358 color: #fff;
359 letter-spacing: 0.3px;
360}
361.topbar-tools { display: flex; align-items: center; gap: 12px; }
362.search-box {
363 display: flex; align-items: center; gap: 8px;
364 background: var(--col-surface-2);
365 border: 1px solid var(--col-border);
366 border-radius: var(--radius-md);
367 padding: 7px 12px;
368 width: 375px;
369 color: var(--col-text-2);
370 transition: border-color var(--t-fast), background var(--t-fast);
371}
372.search-box:focus-within {
373 border-color: var(--col-accent);
374 background: var(--col-surface-1);
375}
376.search-box svg { width: 16px; height: 16px; opacity: 0.7; }
377.search-box input {
378 background: none; border: none; outline: none;
379 color: var(--col-text); font-size: 13px; flex: 1;
380}
381.search-box input::placeholder { color: var(--col-text-3); }
382.search-box .kbd {
383 font-family: var(--font-mono);
384 font-size: 11px;
385 background: var(--col-surface-3);
386 padding: 2px 6px;
387 border-radius: 4px;
388 color: var(--col-text-3);
389 border: 1px solid var(--col-border);
390 white-space: nowrap;
391 flex-shrink: 0;
392}
393
394.icon-btn {
395 width: 36px; height: 36px;
396 border-radius: var(--radius-md);
397 background: var(--col-surface-2);
398 border: 1px solid var(--col-border);
399 display: grid; place-items: center;
400 color: var(--col-text-2);
401 position: relative;
402 transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
403}
404.icon-btn:hover { background: var(--col-surface-3); color: var(--col-text); border-color: var(--col-border-2); }
405.icon-btn svg { width: 16px; height: 16px; }
406.icon-btn .dot {
407 position: absolute;
408 top: 7px; right: 7px;
409 width: 8px; height: 8px;
410 border-radius: 50%;
411 background: var(--col-danger);
412 box-shadow: 0 0 0 2px var(--col-surface-2);
413}
414
415
416/* ---------------------------------------------------------------------
417 6. Buttons
418--------------------------------------------------------------------- */
419.btn {
420 display: inline-flex; align-items: center; justify-content: center; gap: 8px;
421 padding: 10px 18px;
422 font-family: var(--font-ui);
423 font-size: 13px; font-weight: 600;
424 letter-spacing: 0.3px;
425 border-radius: var(--radius-md);
426 border: 1px solid transparent;
427 transition: transform var(--t-fast), background var(--t-fast), color var(--t-fast),
428 border-color var(--t-fast), box-shadow var(--t-fast);
429 cursor: pointer;
430 white-space: nowrap;
431}
432.btn svg { width: 15px; height: 15px; }
433.btn:active { transform: translateY(1px); }
434
435.btn-primary {
436 background: var(--grad-brand);
437 color: #fff;
438 box-shadow: 0 6px 16px rgba(6,182,212,0.35);
439}
440.btn-primary:hover { box-shadow: 0 8px 22px rgba(6,182,212,0.5); filter: brightness(1.08); }
441
442.btn-secondary {
443 background: var(--col-surface-2);
444 color: var(--col-text);
445 border-color: var(--col-border);
446}
447.btn-secondary:hover { background: var(--col-surface-3); border-color: var(--col-border-2); }
448
449.btn-ghost {
450 background: transparent;
451 color: var(--col-text-2);
452}
453.btn-ghost:hover { color: var(--col-text); background: var(--col-surface-2); }
454
455.btn-danger {
456 background: rgba(239,68,68,0.15);
457 color: var(--col-danger);
458 border-color: rgba(239,68,68,0.3);
459}
460.btn-danger:hover { background: rgba(239,68,68,0.25); }
461
462.btn-success {
463 background: rgba(34,197,94,0.16);
464 color: var(--col-success);
465 border-color: rgba(34,197,94,0.3);
466}
467
468.btn-sm { padding: 7px 12px; font-size: 12px; }
469.btn-lg { padding: 14px 28px; font-size: 14px; }
470.btn-block { width: 100%; }
471
472
473/* ---------------------------------------------------------------------
474 7. Cards
475--------------------------------------------------------------------- */
476.card {
477 background: var(--col-surface-1);
478 border: 1px solid var(--col-border);
479 border-radius: var(--radius-lg);
480 padding: var(--space-lg);
481 position: relative;
482}
483.card-elevated {
484 background: linear-gradient(160deg, var(--col-surface-1) 0%, var(--col-surface-2) 100%);
485 box-shadow: var(--shadow-md);
486}
487.card-glow {
488 position: relative;
489 overflow: hidden;
490}
491.card-glow::before {
492 content: '';
493 position: absolute;
494 inset: -1px;
495 border-radius: inherit;
496 background: var(--grad-border);
497 z-index: -1;
498 opacity: 0.55;
499}
500.card-glow::after {
501 content: '';
502 position: absolute;
503 inset: 0;
504 background: var(--col-surface-1);
505 border-radius: inherit;
506 z-index: -1;
507}
508
509.card-head {
510 display: flex; align-items: center; justify-content: space-between;
511 margin-bottom: var(--space-md);
512 gap: 12px;
513}
514.card-title {
515 font-family: var(--font-display);
516 font-size: 16px;
517 font-weight: 600;
518 color: var(--col-text);
519 display: flex; align-items: center; gap: 10px;
520}
521.card-title svg { width: 18px; height: 18px; color: var(--col-accent-bright); }
522.card-actions { display: flex; gap: 8px; }
523
524
525/* ---------------------------------------------------------------------
526 8. Page header
527--------------------------------------------------------------------- */
528.page-head {
529 display: flex; align-items: flex-end; justify-content: space-between;
530 gap: var(--space-md);
531 margin-bottom: var(--space-xl);
532 flex-wrap: wrap;
533}
534.page-eyebrow {
535 display: inline-flex; align-items: center; gap: 8px;
536 font-size: 11px;
537 font-weight: 700;
538 letter-spacing: 2.4px;
539 text-transform: uppercase;
540 color: var(--col-accent-bright);
541 margin-bottom: var(--space-sm);
542}
543.page-eyebrow .dot {
544 width: 6px; height: 6px; border-radius: 50%;
545 background: var(--col-accent-bright);
546 box-shadow: 0 0 8px var(--col-accent-bright);
547 animation: pulse 1.8s ease-in-out infinite;
548}
549@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
550.page-title {
551 font-family: var(--font-display);
552 font-size: 32px;
553 font-weight: 700;
554 color: #fff;
555 letter-spacing: -0.5px;
556 line-height: 1.1;
557}
558.page-subtitle {
559 color: var(--col-text-2);
560 font-size: 14px;
561 margin-top: var(--space-xs);
562 max-width: 640px;
563}
564.page-actions { display: flex; gap: 10px; }
565
566
567/* ---------------------------------------------------------------------
568 9. Stat tiles
569--------------------------------------------------------------------- */
570.stat-row {
571 display: grid;
572 grid-template-columns: repeat(4, 1fr);
573 gap: var(--space-md);
574 margin-bottom: var(--space-xl);
575}
576.stat {
577 background: linear-gradient(160deg, var(--col-surface-1) 0%, var(--col-surface-2) 100%);
578 border: 1px solid var(--col-border);
579 border-radius: var(--radius-lg);
580 padding: var(--space-lg);
581 position: relative;
582 overflow: hidden;
583}
584.stat::before {
585 content: '';
586 position: absolute;
587 top: 0; right: 0;
588 width: 160px; height: 160px;
589 background: radial-gradient(circle, var(--col-accent-glow) 0%, transparent 70%);
590 filter: blur(40px);
591 opacity: 0.35;
592 pointer-events: none;
593}
594.stat-label {
595 font-size: 11px;
596 letter-spacing: 1.5px;
597 text-transform: uppercase;
598 color: var(--col-text-3);
599 font-weight: 600;
600 display: flex; align-items: center; gap: 8px;
601}
602.stat-label svg { width: 14px; height: 14px; color: var(--col-accent-bright); }
603.stat-value {
604 font-family: var(--font-display);
605 font-size: 32px;
606 font-weight: 700;
607 color: #fff;
608 margin-top: var(--space-xs);
609 letter-spacing: -0.5px;
610}
611.stat-meta { display: flex; align-items: center; gap: 6px; margin-top: var(--space-xs); font-size: 12px; }
612.stat-delta {
613 font-weight: 600;
614 display: inline-flex; align-items: center; gap: 3px;
615 padding: 2px 8px;
616 border-radius: 999px;
617 font-size: 11px;
618}
619.stat-delta.up { color: var(--col-success); background: rgba(34,197,94,0.12); }
620.stat-delta.down { color: var(--col-danger); background: rgba(239,68,68,0.12); }
621.stat-meta-label { color: var(--col-text-3); }
622
623
624/* ---------------------------------------------------------------------
625 10. Module / dashboard grid
626--------------------------------------------------------------------- */
627.dash-grid {
628 display: grid;
629 grid-template-columns: 2fr 1fr;
630 gap: var(--space-md);
631}
632.dash-grid-3 {
633 display: grid;
634 grid-template-columns: repeat(3, 1fr);
635 gap: var(--space-md);
636}
637.dash-grid-2 {
638 display: grid;
639 grid-template-columns: 1fr 1fr;
640 gap: var(--space-md);
641}
642
643
644/* ---------------------------------------------------------------------
645 11. Tables
646--------------------------------------------------------------------- */
647.table-wrap {
648 overflow-x: auto;
649 border-radius: var(--radius-md);
650 border: 1px solid var(--col-border);
651}
652.table {
653 width: 100%;
654 border-collapse: collapse;
655 font-size: 13px;
656}
657.table th {
658 text-align: left;
659 font-weight: 600;
660 font-size: 11px;
661 letter-spacing: 1.4px;
662 text-transform: uppercase;
663 color: var(--col-text-3);
664 padding: 12px 16px;
665 background: var(--col-surface-2);
666 border-bottom: 1px solid var(--col-border);
667 white-space: nowrap;
668}
669.table td {
670 padding: 14px 16px;
671 border-bottom: 1px solid var(--col-border);
672 color: var(--col-text);
673}
674.table tr:last-child td { border-bottom: none; }
675.table tr:hover td { background: rgba(255,255,255,0.02); }
676.table .num { font-variant-numeric: tabular-nums; text-align: right; }
677
678
679/* ---------------------------------------------------------------------
680 12. Pills, chips, status indicators
681--------------------------------------------------------------------- */
682.pill {
683 display: inline-flex; align-items: center; gap: 6px;
684 padding: 4px 10px;
685 font-size: 11px;
686 font-weight: 700;
687 letter-spacing: 0.6px;
688 /* Less-rounded corners + brighter text so pills read clearly on
689 deeply-tinted theme backgrounds (purple, neon, etc.) where the
690 prior pill-shape + soft text washed out against the page. */
691 border-radius: 6px;
692 background: rgba(0,0,0,0.30);
693 color: #fff;
694 border: 1px solid var(--col-border);
695}
696.pill svg { width: 11px; height: 11px; }
697.pill.success { color: var(--col-success); background: rgba(34,197,94,0.12); border-color: rgba(34,197,94,0.25); }
698.pill.warning { color: var(--col-warning); background: rgba(245,158,11,0.12); border-color: rgba(245,158,11,0.25); }
699.pill.danger { color: var(--col-danger); background: rgba(239,68,68,0.12); border-color: rgba(239,68,68,0.25); }
700.pill.info { color: var(--col-info); background: rgba(56,189,248,0.12); border-color: rgba(56,189,248,0.25); }
701.pill.brand { color: var(--col-accent-bright); background: rgba(6,182,212,0.15); border-color: rgba(6,182,212,0.3); }
702.pill.violet { color: var(--col-violet-bright); background: rgba(6,182,212,0.15); border-color: rgba(6,182,212,0.3); }
703
704.dot-status {
705 width: 8px; height: 8px;
706 border-radius: 50%;
707 display: inline-block;
708}
709.dot-status.green { background: var(--col-success); box-shadow: 0 0 8px var(--col-success); }
710.dot-status.yellow { background: var(--col-warning); box-shadow: 0 0 8px var(--col-warning); }
711.dot-status.red { background: var(--col-danger); box-shadow: 0 0 8px var(--col-danger); }
712.dot-status.gray { background: var(--col-text-dim); }
713
714
715/* ---------------------------------------------------------------------
716 13. Forms
717--------------------------------------------------------------------- */
718.form-group { margin-bottom: var(--space-md); }
719.form-label {
720 display: block;
721 font-size: 12px;
722 font-weight: 600;
723 letter-spacing: 0.5px;
724 color: var(--col-text-2);
725 margin-bottom: 6px;
726}
727.form-label .req { color: var(--col-danger); margin-left: 4px; }
728.form-help { font-size: 11px; color: var(--col-text-3); margin-top: 4px; }
729
730.input, .textarea, .select {
731 width: 100%;
732 padding: 10px 14px;
733 background: var(--col-surface-2);
734 border: 1px solid var(--col-border);
735 border-radius: var(--radius-md);
736 color: var(--col-text);
737 font-size: 13px;
738 outline: none;
739 transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
740}
741.input:focus, .textarea:focus, .select:focus {
742 border-color: var(--col-accent);
743 box-shadow: 0 0 0 3px rgba(6,182,212,0.15);
744 background: var(--col-surface-1);
745}
746.input::placeholder, .textarea::placeholder { color: var(--col-text-dim); }
747.textarea { min-height: 90px; resize: vertical; font-family: inherit; }
748.select {
749 appearance: none;
750 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2364748b'/%3E%3C/svg%3E");
751 background-repeat: no-repeat;
752 background-position: right 14px center;
753 padding-right: 32px;
754}
755
756.checkbox, .radio {
757 display: flex; align-items: center; gap: 10px;
758 cursor: pointer;
759 font-size: 13px;
760 color: var(--col-text);
761}
762.checkbox input, .radio input { width: 16px; height: 16px; accent-color: var(--col-accent); }
763
764.toggle {
765 display: inline-block;
766 position: relative;
767 width: 40px; height: 22px;
768 background: var(--col-surface-3);
769 border-radius: 999px;
770 cursor: pointer;
771 transition: background var(--t-fast);
772 flex-shrink: 0;
773 border: 1px solid var(--col-border);
774 vertical-align: middle;
775}
776.toggle::after {
777 content: '';
778 position: absolute;
779 top: 2px; left: 2px;
780 width: 16px; height: 16px;
781 border-radius: 50%;
782 background: #fff;
783 transition: transform var(--t-fast);
784}
785.toggle.on { background: var(--col-accent); border-color: var(--col-accent-deep); }
786.toggle.on::after { transform: translateX(18px); }
787
788
789/* ---------------------------------------------------------------------
790 14. Module cards (dashboard sections)
791--------------------------------------------------------------------- */
792.module {
793 background: var(--col-surface-1);
794 border: 1px solid var(--col-border);
795 border-radius: var(--radius-lg);
796 overflow: hidden;
797 position: relative;
798}
799
800/* ---------------------------------------------------------------- */
801/* Tutorial mode chrome. */
802/* Banner = always-on header strip across the top of a tutorial page. */
803/* Intro = longer preamble paragraphs beneath the banner. */
804/* Explainer = per-module "How this works" caption inside the body. */
805/* */
806/* All three share an indigo-blue palette plus a left accent stripe */
807/* so the talking blocks read as distinct from the rest of the page */
808/* chrome the moment they enter view. */
809/* ---------------------------------------------------------------- */
810.tutorial-banner {
811 position: relative;
812 display: flex;
813 align-items: flex-start;
814 gap: 16px;
815 padding: 18px 22px 18px 26px;
816 margin-bottom: var(--space-lg);
817 background:
818 linear-gradient(135deg,
819 rgba(30,58,138,0.45) 0%,
820 rgba(30,64,175,0.38) 45%,
821 rgba(14,116,144,0.28) 100%);
822 border: 1px solid rgba(6,182,212,0.55);
823 border-radius: var(--radius-lg);
824 box-shadow:
825 0 0 0 1px rgba(6,182,212,0.18) inset,
826 0 10px 30px rgba(30,58,138,0.32);
827 overflow: hidden;
828}
829.tutorial-banner::before {
830 content: '';
831 position: absolute;
832 top: 0; bottom: 0; left: 0;
833 width: 5px;
834 background: linear-gradient(180deg, #155e75 0%, #0e7490 100%);
835}
836.tutorial-banner-icon {
837 width: 38px; height: 38px;
838 border-radius: 50%;
839 display: grid; place-items: center;
840 background: linear-gradient(135deg, #155e75 0%, #0e7490 100%);
841 color: #fff;
842 flex-shrink: 0;
843 box-shadow: 0 0 16px rgba(14,116,144,0.55);
844}
845.tutorial-banner-icon svg { width: 20px; height: 20px; }
846.tutorial-banner-body { flex: 1; min-width: 0; }
847.tutorial-banner-title {
848 font-size: 15px;
849 font-weight: 800;
850 color: #06b6d4;
851 letter-spacing: 0.3px;
852 margin-bottom: 5px;
853 text-shadow: 0 0 10px rgba(14,116,144,0.45);
854}
855.tutorial-banner-text {
856 font-size: 13px;
857 line-height: 1.6;
858 color: #cbd5e1;
859}
860.tutorial-banner-text strong { color: #e2e8f0; font-weight: 700; }
861.tutorial-banner .btn { flex-shrink: 0; align-self: center; }
862
863/* Per-module explainer caption ("How this works..."). Smaller than
864 the banner but uses the same accent-stripe + blue glow so it
865 reads as part of the same family of talking blocks. */
866.tutorial-explainer {
867 position: relative;
868 background:
869 linear-gradient(135deg,
870 rgba(30,58,138,0.28) 0%,
871 rgba(30,64,175,0.22) 60%,
872 rgba(14,116,144,0.16) 100%);
873 border: 1px solid rgba(6,182,212,0.45);
874 border-radius: 10px;
875 padding: 12px 14px 12px 18px;
876 font-size: 12.5px;
877 line-height: 1.6;
878 color: #cbd5e1;
879 box-shadow: 0 4px 14px rgba(30,58,138,0.22);
880 overflow: hidden;
881}
882.tutorial-explainer::before {
883 content: '';
884 position: absolute;
885 top: 0; bottom: 0; left: 0;
886 width: 4px;
887 background: linear-gradient(180deg, #155e75 0%, #0e7490 100%);
888}
889.tutorial-explainer strong {
890 color: #e2e8f0;
891 font-weight: 700;
892 letter-spacing: 0.3px;
893}
894.tutorial-explainer code {
895 font-size: 11px;
896 background: rgba(0,0,0,0.38);
897 padding: 1px 6px;
898 border-radius: 4px;
899 color: #a5f3fc;
900 font-weight: 600;
901}
902.tutorial-explainer a { color: #a5f3fc; font-weight: 700; }
903
904/* Longer-form preamble shown beneath the banner. Brighter background
905 than before with the same left accent stripe so it visually links
906 to the banner above. */
907.tutorial-intro {
908 position: relative;
909 background:
910 linear-gradient(180deg,
911 rgba(30,58,138,0.20) 0%,
912 rgba(30,64,175,0.12) 55%,
913 rgba(14,116,144,0.06) 100%);
914 border: 1px solid rgba(6,182,212,0.28);
915 border-radius: var(--radius-lg);
916 padding: 26px 30px 26px 34px;
917 margin-bottom: var(--space-lg);
918 box-shadow: 0 4px 16px rgba(30,58,138,0.14);
919 overflow: hidden;
920}
921.tutorial-intro::before {
922 content: '';
923 position: absolute;
924 top: 0; bottom: 0; left: 0;
925 width: 4px;
926 background: linear-gradient(180deg, #155e75 0%, #0e7490 100%);
927 opacity: 0.55;
928}
929.tutorial-intro-eyebrow {
930 display: inline-block;
931 font-size: 12px;
932 font-weight: 800;
933 letter-spacing: 2.5px;
934 text-transform: uppercase;
935 color: #a5f3fc;
936 background: rgba(6,182,212,0.15);
937 border: 1px solid rgba(6,182,212,0.40);
938 border-radius: 7px;
939 padding: 7px 14px;
940 margin-bottom: 16px;
941}
942.tutorial-intro-title {
943 font-size: 24px;
944 font-weight: 800;
945 margin: 0 0 16px 0;
946 line-height: 1.25;
947 letter-spacing: -0.2px;
948 background: linear-gradient(135deg, #67e8f9 0%, #06b6d4 50%, #0e7490 100%);
949 -webkit-background-clip: text;
950 background-clip: text;
951 -webkit-text-fill-color: transparent;
952 color: transparent;
953 text-shadow: 0 0 28px rgba(14,116,144,0.30);
954}
955.tutorial-intro-text {
956 font-size: 14px;
957 line-height: 1.7;
958 color: #cbd5e1;
959 margin: 0 0 14px 0;
960}
961.tutorial-intro-text:last-child { margin-bottom: 0; }
962.tutorial-intro-text strong { color: #e2e8f0; font-weight: 700; }
963.tutorial-intro-text em { color: #a5f3fc; font-style: italic; }
964.tutorial-intro-text a { color: #a5f3fc; font-weight: 700; }
965.tutorial-intro-text code {
966 font-size: 12.5px;
967 background: rgba(0,0,0,0.40);
968 padding: 2px 7px;
969 border-radius: 4px;
970 color: #a5f3fc;
971 font-weight: 600;
972}
973.tutorial-intro-foot {
974 margin-top: 18px;
975 padding-top: 16px;
976 border-top: 1px dashed rgba(14,116,144,0.45);
977 font-size: 13.5px;
978}
979
980/* Search-results thumbnail. Square tile next to each model row so the
981 user can identify a product visually instead of by title alone.
982 Empty state shows a colored gradient with the first letter of the
983 title so rows without an uploaded image still have a visual anchor. */
984.search-thumb {
985 width: 120px; height: 120px;
986 border-radius: 12px;
987 object-fit: cover;
988 display: block;
989 background: var(--col-surface-2);
990 border: 1px solid var(--col-border);
991}
992.search-thumb.search-thumb-empty {
993 display: grid; place-items: center;
994 background: linear-gradient(135deg, rgba(6,182,212,0.30) 0%, rgba(6,182,212,0.25) 100%);
995 color: rgba(255,255,255,0.65);
996 font-size: 42px; font-weight: 800;
997 letter-spacing: 0.5px;
998 text-transform: uppercase;
999}
1000
1001/* Search-page Edit pill. Matches the topbar Help chip so the action
1002 reads as a real button instead of a tucked-away link. */
1003.search-edit-btn {
1004 display: inline-flex;
1005 align-items: center;
1006 gap: 7px;
1007 height: 36px;
1008 padding: 0 14px;
1009 border-radius: 10px;
1010 background: linear-gradient(135deg, rgba(6,182,212,0.22) 0%, rgba(14,116,144,0.18) 100%);
1011 border: 1px solid rgba(6,182,212,0.55);
1012 color: #a5f3fc;
1013 font-size: 13px;
1014 font-weight: 700;
1015 letter-spacing: 0.3px;
1016 text-decoration: none;
1017 box-shadow: 0 0 14px rgba(14,116,144,0.32);
1018 transition: background 0.15s, color 0.15s, transform 0.12s, box-shadow 0.15s;
1019}
1020.search-edit-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
1021.search-edit-btn:hover {
1022 background: linear-gradient(135deg, rgba(6,182,212,0.32) 0%, rgba(14,116,144,0.28) 100%);
1023 color: #fff;
1024 transform: translateY(-1px);
1025 box-shadow: 0 0 18px rgba(14,116,144,0.55);
1026}
1027
1028/* Live red unread dot used next to nav entries (Messages right now,
1029 but reusable). Only rendered server-side when there are real unread
1030 items so the indicator never lies. */
1031.menu-dot {
1032 display: inline-block;
1033 width: 8px; height: 8px;
1034 border-radius: 50%;
1035 background: #ef4444;
1036 margin-left: 6px;
1037 vertical-align: middle;
1038 box-shadow: 0 0 8px rgba(239,68,68,0.6);
1039}
1040
1041/* ---------------------------------------------------------------- */
1042/* Promotions (.pr-*) -- shared between rep (/promotions.cgi) and */
1043/* admin (/admin_promotions.cgi) templates. */
1044/* ---------------------------------------------------------------- */
1045.pr-kpis { display:grid; grid-template-columns: repeat(auto-fit,minmax(160px,1fr)); gap:12px; margin-bottom:22px; }
1046.pr-kpi { background: var(--col-surface-1); border:1px solid var(--col-border); border-radius:12px; padding:14px 16px; }
1047.pr-kpi .lbl { font-size:10px; letter-spacing:1.5px; text-transform:uppercase; color:var(--col-text-3); font-weight:700; }
1048.pr-kpi .val { font-size:24px; font-weight:700; color:#fff; font-family: var(--font-mono, monospace); margin-top:4px; }
1049.pr-kpi.is-active { border-color: rgba(34,197,94,0.40); }
1050.pr-kpi.is-active .val { color: #4ade80; }
1051.pr-kpi.is-scheduled .val { color: #67e8f9; }
1052.pr-kpi.is-paused .val { color: #fbbf24; }
1053.pr-kpi.is-expired .val { color: #94a3b8; }
1054
1055.pr-table {
1056 width:100%; border-collapse:separate; border-spacing:0;
1057 background: var(--col-surface-1); border:1px solid var(--col-border);
1058 border-radius:12px; overflow:hidden;
1059}
1060.pr-table thead th {
1061 background: var(--col-surface-2); padding:11px 14px; text-align:left;
1062 font-size:10px; letter-spacing:1.5px; text-transform:uppercase;
1063 color: var(--col-text-3); font-weight:700; border-bottom:1px solid var(--col-border);
1064}
1065.pr-table tbody td { padding:12px 14px; border-bottom:1px solid var(--col-border); font-size:13px; color:var(--col-text-2); vertical-align:middle; }
1066.pr-table tbody tr:last-child td { border-bottom: none; }
1067.pr-table tbody tr:hover td { background: rgba(6,182,212,0.06); }
1068.pr-table .num { text-align:right; font-family: var(--font-mono, monospace); }
1069.pr-table .name { color: var(--col-text); font-weight:600; }
1070.pr-table .meta { font-size:11px; color: var(--col-text-3); margin-top:2px; }
1071.pr-table code { background: rgba(0,0,0,0.30); padding:1px 6px; border-radius:4px; font-size:11px; color: #a5f3fc; }
1072.pr-table .pill { font-size:9px; font-weight:700; padding:3px 8px; border-radius:6px; letter-spacing:1px; text-transform:uppercase; }
1073.pr-table .pill.active { background: rgba(34,197,94,0.18); color: #4ade80; }
1074.pr-table .pill.paused { background: rgba(245,158,11,0.18); color: #fbbf24; }
1075.pr-table .pill.scheduled { background: rgba(6,182,212,0.18); color: #67e8f9; }
1076.pr-table .pill.expired { background: rgba(100,116,139,0.20); color: #94a3b8; }
1077.pr-table .pill.draft { background: rgba(100,116,139,0.18); color: #cbd5e1; }
1078.pr-table .pill.kind { background: rgba(6,182,212,0.18); color: #a5f3fc; }
1079.pr-table .pill.kind.bundle { background: rgba(34,197,94,0.18); color: #86efac; }
1080.pr-table .pill.kind.sale { background: rgba(245,158,11,0.18); color: #fcd34d; }
1081.pr-table .pill.kind.flash { background: rgba(236,72,153,0.18); color: #f9a8d4; }
1082.pr-table .actions a, .pr-table .actions button {
1083 color: #a5f3fc; font-size: 12px; font-weight:700; text-decoration:none;
1084 background:none; border:none; cursor:pointer; padding:0; font-family:inherit;
1085}
1086.pr-table .actions a:hover, .pr-table .actions button:hover { text-decoration: underline; }
1087.pr-table .actions form { display:inline; margin:0; }
1088.pr-table .actions .sep { color: var(--col-text-3); margin:0 6px; }
1089
1090.pr-form { background: var(--col-surface-1); border:1px solid var(--col-border); border-radius:14px; padding: 22px 26px; }
1091.pr-form-grid { display:grid; grid-template-columns: 1fr 1fr; gap:16px 24px; }
1092@media (max-width: 800px) { .pr-form-grid { grid-template-columns: 1fr; } }
1093.pr-field { display:flex; flex-direction:column; gap:6px; }
1094.pr-field.full { grid-column: 1 / -1; }
1095.pr-field label { font-size:11px; letter-spacing:1.5px; text-transform:uppercase; color:var(--col-text-3); font-weight:700; }
1096.pr-field input[type="text"],
1097.pr-field input[type="number"],
1098.pr-field input[type="datetime-local"],
1099.pr-field textarea,
1100.pr-field select {
1101 background: var(--col-surface-2); border:1px solid var(--col-border);
1102 color: var(--col-text); padding:9px 12px; border-radius:8px;
1103 font-size:14px; font-family:inherit;
1104}
1105.pr-field textarea { min-height: 70px; resize: vertical; }
1106.pr-field .hint { font-size: 11px; color: var(--col-text-3); }
1107.pr-radio-row { display:flex; gap:10px; flex-wrap:wrap; }
1108.pr-radio { display:flex; align-items:center; gap:6px; padding:8px 12px; border-radius:8px; border:1px solid var(--col-border); background: var(--col-surface-2); cursor:pointer; font-size:13px; }
1109.pr-radio input { accent-color: #06b6d4; }
1110.pr-radio.is-on { border-color: #06b6d4; background: rgba(6,182,212,0.10); }
1111.pr-actions { margin-top: 24px; display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; }
1112
1113.pr-models-box { background: var(--col-surface-2); border:1px solid var(--col-border); border-radius:10px; padding:12px; max-height: 240px; overflow-y: auto; }
1114.pr-model-row { display:flex; align-items:center; gap:10px; padding:6px 4px; border-radius:6px; }
1115.pr-model-row:hover { background: rgba(6,182,212,0.06); }
1116.pr-model-row input { accent-color: #06b6d4; }
1117
1118.pr-flash { padding:12px 16px; border-radius:10px; margin-bottom:18px; font-size:13px; }
1119.pr-flash.ok { background: rgba(34,197,94,0.12); border:1px solid rgba(34,197,94,0.35); color: #86efac; }
1120.pr-flash.err { background: rgba(239,68,68,0.12); border:1px solid rgba(239,68,68,0.35); color: #fca5a5; }
1121
1122/* ---------------------------------------------------------------- */
1123/* SEO editor pages (dashboard_seo.cgi + admin_seo.cgi). */
1124/* Two-column layout: form on the left, live SERP preview on right. */
1125/* ---------------------------------------------------------------- */
1126.seo-grid {
1127 display: grid;
1128 grid-template-columns: 1.5fr 1fr;
1129 gap: 18px;
1130 align-items: start;
1131}
1132@media (max-width: 1000px) { .seo-grid { grid-template-columns: 1fr; } }
1133
1134.seo-preview {
1135 background: var(--col-surface-1);
1136 border: 1px solid var(--col-border);
1137 border-radius: 14px;
1138 padding: 18px 22px;
1139 position: sticky;
1140 top: 80px;
1141}
1142.seo-preview-head {
1143 font-size: 11px;
1144 letter-spacing: 1.5px;
1145 text-transform: uppercase;
1146 color: var(--col-text-3);
1147 font-weight: 700;
1148 margin-bottom: 12px;
1149}
1150.seo-preview-card {
1151 /* Dark surface matching the rest of the dashboard. Still reads as a
1152 search result preview but no longer glares against the page. */
1153 background: var(--col-surface-2);
1154 color: var(--col-text);
1155 padding: 14px 16px;
1156 border-radius: 8px;
1157 font-family: arial, sans-serif;
1158 border: 1px solid var(--col-border);
1159}
1160.seo-preview-card .seo-preview-url {
1161 font-size: 12px;
1162 color: #94a3b8;
1163 margin-bottom: 4px;
1164 word-break: break-all;
1165}
1166.seo-preview-card .seo-preview-title {
1167 font-size: 18px;
1168 color: #67e8f9;
1169 line-height: 1.3;
1170 margin-bottom: 4px;
1171 font-weight: 600;
1172}
1173.seo-preview-card .seo-preview-desc {
1174 font-size: 13px;
1175 color: #cbd5e1;
1176 line-height: 1.45;
1177}
1178.seo-preview-note {
1179 margin-top: 14px;
1180 font-size: 11.5px;
1181 line-height: 1.6;
1182 color: var(--col-text-3);
1183}
1184.module-head {
1185 display: flex; align-items: center; justify-content: space-between;
1186 padding: var(--space-md) var(--space-lg);
1187 border-bottom: 1px solid var(--col-border);
1188 background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
1189 gap: 12px;
1190}
1191.module-head .left { display: flex; align-items: center; gap: 10px; min-width: 0; }
1192.module-icon {
1193 width: 32px; height: 32px;
1194 border-radius: var(--radius-sm);
1195 display: grid; place-items: center;
1196 background: var(--grad-brand-soft);
1197 color: var(--col-accent-bright);
1198 flex-shrink: 0;
1199}
1200.module-icon svg { width: 16px; height: 16px; }
1201.module-title {
1202 font-family: var(--font-display);
1203 font-size: 15px;
1204 font-weight: 600;
1205 color: #fff;
1206}
1207.module-sub {
1208 font-size: 11px;
1209 color: var(--col-text-3);
1210 letter-spacing: 0.5px;
1211 margin-top: 1px;
1212}
1213.module-body { padding: var(--space-lg); }
1214
1215
1216/* ---------------------------------------------------------------------
1217 15. Marketing / landing page
1218--------------------------------------------------------------------- */
1219.landing-nav {
1220 position: sticky;
1221 top: 0; z-index: 100;
1222 background: rgba(5, 8, 19, 0.7);
1223 backdrop-filter: blur(16px);
1224 border-bottom: 1px solid var(--col-border);
1225}
1226.landing-nav-inner {
1227 max-width: var(--content-max);
1228 margin: 0;
1229 padding: 16px var(--space-xl);
1230 display: flex;
1231 align-items: center;
1232 justify-content: space-between;
1233}
1234.landing-nav .links { display: flex; gap: 28px; }
1235.landing-nav .links a {
1236 font-size: 13px;
1237 color: var(--col-text-2);
1238 font-weight: 500;
1239 transition: color var(--t-fast);
1240}
1241.landing-nav .links a:hover { color: var(--col-text); }
1242.landing-nav .auth-actions { display: flex; gap: 10px; align-items: center; }
1243
1244.hero {
1245 padding: 100px var(--space-xl) 80px;
1246 position: relative;
1247 overflow: hidden;
1248}
1249.hero-glow-1, .hero-glow-2, .hero-glow-3 {
1250 position: absolute; pointer-events: none; border-radius: 50%;
1251 filter: blur(80px);
1252}
1253.hero-glow-1 { width: 720px; height: 720px; top: -260px; right: -120px; background: radial-gradient(circle, rgba(6,182,212,0.20), transparent 65%); }
1254.hero-glow-2 { width: 560px; height: 560px; bottom: -160px; left: 6%; background: radial-gradient(circle, rgba(6,182,212,0.18), transparent 65%); }
1255.hero-glow-3 { width: 480px; height: 480px; top: 20%; left: 40%; background: radial-gradient(circle, rgba(6,182,212,0.10), transparent 65%); }
1256
1257.hero-grid-bg {
1258 position: absolute; inset: 0; pointer-events: none;
1259 background-image: radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px);
1260 background-size: 38px 38px;
1261 mask-image: radial-gradient(ellipse 800px 600px at 50% 50%, black 30%, transparent 80%);
1262 -webkit-mask-image: radial-gradient(ellipse 800px 600px at 50% 50%, black 30%, transparent 80%);
1263}
1264
1265.hero-inner {
1266 max-width: var(--content-max);
1267 margin: 0;
1268 position: relative;
1269 z-index: 2;
1270 display: grid;
1271 grid-template-columns: 1.1fr 1fr;
1272 gap: var(--space-2xl);
1273 align-items: center;
1274}
1275.hero-pill {
1276 display: inline-flex; align-items: center; gap: 8px;
1277 padding: 6px 14px;
1278 border-radius: 999px;
1279 background: rgba(6,182,212,0.10);
1280 border: 1px solid rgba(6,182,212,0.30);
1281 color: var(--col-accent-bright);
1282 font-size: 11px;
1283 font-weight: 700;
1284 letter-spacing: 1.8px;
1285 text-transform: uppercase;
1286 margin-bottom: var(--space-lg);
1287}
1288.hero-pill .dot {
1289 width: 6px; height: 6px;
1290 border-radius: 50%;
1291 background: var(--col-accent-bright);
1292 box-shadow: 0 0 8px var(--col-accent-bright);
1293 animation: pulse 1.8s infinite;
1294}
1295.hero-title {
1296 font-family: var(--font-display);
1297 font-size: clamp(40px, 5.6vw, 76px);
1298 line-height: 0.98;
1299 font-weight: 700;
1300 letter-spacing: -1.5px;
1301 color: #fff;
1302 margin-bottom: var(--space-md);
1303}
1304.hero-title .grad {
1305 background: var(--grad-brand);
1306 -webkit-background-clip: text;
1307 background-clip: text;
1308 -webkit-text-fill-color: transparent;
1309}
1310.hero-sub {
1311 font-size: 17px;
1312 color: var(--col-text-2);
1313 max-width: 520px;
1314 margin-bottom: var(--space-xl);
1315 line-height: 1.65;
1316}
1317.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }
1318.hero-trust {
1319 display: flex; gap: 24px;
1320 margin-top: var(--space-xl);
1321 padding-top: var(--space-md);
1322 border-top: 1px solid var(--col-border);
1323 flex-wrap: wrap;
1324}
1325.hero-trust-item { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--col-text-3); }
1326.hero-trust-item svg { width: 16px; height: 16px; color: var(--col-success); }
1327
1328/* Hero visual: stacked floating cards mock */
1329.hero-visual {
1330 position: relative;
1331 height: 540px;
1332}
1333.float-card {
1334 position: absolute;
1335 background: linear-gradient(160deg, var(--col-surface-2) 0%, var(--col-surface-1) 100%);
1336 border: 1px solid var(--col-border-2);
1337 border-radius: var(--radius-lg);
1338 box-shadow: var(--shadow-lg);
1339 padding: var(--space-md);
1340 backdrop-filter: blur(8px);
1341}
1342.fc-1 {
1343 top: 20px; left: 0; width: 280px;
1344 animation: floaty 6s ease-in-out infinite;
1345}
1346.fc-2 {
1347 top: 100px; right: 0; width: 300px;
1348 animation: floaty 6s ease-in-out -2s infinite;
1349}
1350.fc-3 {
1351 bottom: 40px; left: 60px; width: 320px;
1352 animation: floaty 6s ease-in-out -4s infinite;
1353}
1354@keyframes floaty {
1355 0%,100% { transform: translateY(0); }
1356 50% { transform: translateY(-10px); }
1357}
1358
1359/* Section pattern */
1360.section {
1361 padding: var(--space-3xl) var(--space-xl);
1362 max-width: var(--content-max);
1363 margin: 0 auto;
1364 position: relative;
1365}
1366.section-eyebrow {
1367 display: inline-block;
1368 color: var(--col-accent-bright);
1369 font-size: 12px;
1370 font-weight: 700;
1371 letter-spacing: 2.5px;
1372 text-transform: uppercase;
1373 margin-bottom: var(--space-sm);
1374}
1375.section-title {
1376 font-family: var(--font-display);
1377 font-size: clamp(28px, 3vw, 44px);
1378 font-weight: 700;
1379 letter-spacing: -0.6px;
1380 line-height: 1.15;
1381 color: #fff;
1382 margin-bottom: var(--space-md);
1383 max-width: 760px;
1384}
1385.section-title .grad {
1386 background: var(--grad-brand);
1387 -webkit-background-clip: text;
1388 background-clip: text;
1389 -webkit-text-fill-color: transparent;
1390}
1391.section-sub {
1392 font-size: 16px;
1393 color: var(--col-text-2);
1394 max-width: 720px;
1395 line-height: 1.65;
1396 margin-bottom: var(--space-2xl);
1397}
1398
1399.feature-grid {
1400 display: grid;
1401 grid-template-columns: repeat(3, 1fr);
1402 gap: var(--space-md);
1403}
1404.feature {
1405 background: var(--col-surface-1);
1406 border: 1px solid var(--col-border);
1407 border-radius: var(--radius-lg);
1408 padding: var(--space-lg);
1409 transition: transform var(--t-med), border-color var(--t-med), box-shadow var(--t-med);
1410 position: relative;
1411 overflow: hidden;
1412}
1413.feature:hover {
1414 transform: translateY(-4px);
1415 border-color: var(--col-border-2);
1416 box-shadow: var(--shadow-md);
1417}
1418.feature-icon {
1419 width: 44px; height: 44px;
1420 border-radius: var(--radius-md);
1421 display: grid; place-items: center;
1422 background: var(--grad-brand-soft);
1423 color: var(--col-accent-bright);
1424 margin-bottom: var(--space-md);
1425 border: 1px solid rgba(6,182,212,0.25);
1426}
1427.feature-icon svg { width: 22px; height: 22px; }
1428.feature-title {
1429 font-family: var(--font-display);
1430 font-size: 18px;
1431 font-weight: 600;
1432 color: #fff;
1433 margin-bottom: var(--space-xs);
1434}
1435.feature-desc { font-size: 13px; color: var(--col-text-2); line-height: 1.65; }
1436.feature-tag {
1437 position: absolute;
1438 top: var(--space-md);
1439 right: var(--space-md);
1440 font-size: 9px;
1441 font-weight: 700;
1442 letter-spacing: 1.5px;
1443 text-transform: uppercase;
1444 padding: 3px 8px;
1445 border-radius: 999px;
1446 background: rgba(6,182,212,0.18);
1447 color: var(--col-violet-bright);
1448 border: 1px solid rgba(6,182,212,0.3);
1449}
1450
1451/* Pricing */
1452.pricing-grid {
1453 display: grid;
1454 grid-template-columns: repeat(4, 1fr);
1455 gap: var(--space-md);
1456}
1457.price-card {
1458 background: var(--col-surface-1);
1459 border: 1px solid var(--col-border);
1460 border-radius: var(--radius-lg);
1461 padding: var(--space-lg);
1462 display: flex;
1463 flex-direction: column;
1464 position: relative;
1465}
1466.price-card.featured {
1467 border-color: rgba(6,182,212,0.5);
1468 background: linear-gradient(160deg, var(--col-surface-2) 0%, var(--col-surface-1) 100%);
1469 box-shadow: 0 0 40px rgba(6,182,212,0.18);
1470}
1471.price-card.featured::before {
1472 content: 'MOST POPULAR';
1473 position: absolute;
1474 top: -10px; left: 50%; transform: translateX(-50%);
1475 background: var(--grad-brand);
1476 color: #fff;
1477 font-size: 10px;
1478 font-weight: 700;
1479 letter-spacing: 1.6px;
1480 padding: 4px 12px;
1481 border-radius: 999px;
1482}
1483.price-tier {
1484 font-family: var(--font-display);
1485 font-size: 18px;
1486 font-weight: 600;
1487 color: #fff;
1488 margin-bottom: var(--space-xs);
1489}
1490.price-amt {
1491 font-family: var(--font-display);
1492 font-size: 38px;
1493 font-weight: 700;
1494 color: #fff;
1495 letter-spacing: -1px;
1496}
1497.price-amt .per { font-size: 13px; color: var(--col-text-3); font-weight: 500; }
1498.price-desc { color: var(--col-text-2); font-size: 13px; margin: var(--space-sm) 0 var(--space-md); }
1499.price-list {
1500 margin: var(--space-md) 0 var(--space-lg);
1501 display: flex; flex-direction: column; gap: 8px;
1502}
1503.price-list li {
1504 font-size: 13px;
1505 color: var(--col-text-2);
1506 display: flex; align-items: flex-start; gap: 8px;
1507}
1508.price-list svg { width: 14px; height: 14px; color: var(--col-success); flex-shrink: 0; margin-top: 3px; }
1509
1510
1511/* ---------------------------------------------------------------------
1512 16. Auth pages (login, signup)
1513--------------------------------------------------------------------- */
1514.auth-shell {
1515 min-height: 100vh;
1516 display: grid;
1517 grid-template-columns: 1fr 1fr;
1518}
1519.auth-side {
1520 position: relative;
1521 background: linear-gradient(140deg, #0a0f24 0%, #1a1142 50%, #0a0f24 100%);
1522 display: flex;
1523 flex-direction: column;
1524 justify-content: space-between;
1525 padding: var(--space-2xl);
1526 overflow: hidden;
1527}
1528.auth-side::before {
1529 content: '';
1530 position: absolute;
1531 inset: 0;
1532 background-image: radial-gradient(rgba(255,255,255,0.05) 1px, transparent 1px);
1533 background-size: 40px 40px;
1534 pointer-events: none;
1535}
1536.auth-side-glow {
1537 position: absolute;
1538 width: 700px; height: 700px;
1539 top: -160px; right: -200px;
1540 background: radial-gradient(circle, rgba(6,182,212,0.30), transparent 60%);
1541 filter: blur(60px);
1542}
1543.auth-side-content { position: relative; z-index: 2; max-width: 460px; }
1544.auth-quote {
1545 font-family: var(--font-display);
1546 font-size: 26px;
1547 line-height: 1.35;
1548 color: #fff;
1549 font-weight: 500;
1550 letter-spacing: -0.3px;
1551 margin-bottom: var(--space-md);
1552}
1553.auth-quote-attr { font-size: 13px; color: var(--col-text-2); }
1554
1555.auth-main {
1556 display: flex; flex-direction: column;
1557 padding: var(--space-2xl);
1558 background: var(--col-bg);
1559 position: relative;
1560}
1561.auth-form-wrap {
1562 width: 100%; max-width: 420px;
1563 margin: auto;
1564}
1565.auth-title {
1566 font-family: var(--font-display);
1567 font-size: 30px;
1568 font-weight: 700;
1569 color: #fff;
1570 letter-spacing: -0.5px;
1571 margin-bottom: var(--space-xs);
1572}
1573.auth-sub { color: var(--col-text-2); font-size: 14px; margin-bottom: var(--space-xl); }
1574.auth-divider {
1575 display: flex; align-items: center; gap: 10px;
1576 color: var(--col-text-3);
1577 font-size: 11px;
1578 letter-spacing: 1.5px;
1579 text-transform: uppercase;
1580 margin: var(--space-md) 0;
1581}
1582.auth-divider::before, .auth-divider::after {
1583 content: '';
1584 flex: 1;
1585 height: 1px;
1586 background: var(--col-border);
1587}
1588.auth-foot {
1589 text-align: center;
1590 font-size: 13px;
1591 color: var(--col-text-2);
1592 margin-top: var(--space-lg);
1593}
1594.auth-foot a { color: var(--col-accent-bright); font-weight: 600; }
1595
1596
1597/* ---------------------------------------------------------------------
1598 17. Charts (lightweight CSS-only sparklines / bars)
1599--------------------------------------------------------------------- */
1600.chart {
1601 width: 100%;
1602 height: 220px;
1603 position: relative;
1604}
1605.bars {
1606 display: flex; align-items: flex-end; gap: 8px;
1607 height: 100%;
1608 padding: var(--space-md) 0;
1609}
1610.bar {
1611 flex: 1;
1612 background: var(--grad-brand);
1613 border-radius: 6px 6px 0 0;
1614 min-height: 8px;
1615 position: relative;
1616 transition: filter var(--t-fast);
1617}
1618.bar:hover { filter: brightness(1.2); }
1619.bar::after {
1620 content: attr(data-label);
1621 position: absolute;
1622 bottom: -22px; left: 50%; transform: translateX(-50%);
1623 font-size: 10px;
1624 color: var(--col-text-3);
1625 letter-spacing: 0.5px;
1626}
1627
1628.spark {
1629 width: 100%;
1630 height: 80px;
1631 display: block;
1632}
1633.spark path { fill: none; stroke: var(--col-accent-bright); stroke-width: 2; }
1634.spark .area { fill: rgba(6,182,212,0.18); stroke: none; }
1635
1636
1637/* ---------------------------------------------------------------------
1638 18. Upload zone
1639--------------------------------------------------------------------- */
1640.dropzone {
1641 border: 2px dashed var(--col-border-2);
1642 background: var(--col-surface-1);
1643 border-radius: var(--radius-lg);
1644 padding: var(--space-2xl);
1645 text-align: center;
1646 transition: border-color var(--t-fast), background var(--t-fast);
1647 cursor: pointer;
1648}
1649.dropzone:hover, .dropzone.drag {
1650 border-color: var(--col-accent);
1651 background: rgba(6,182,212,0.05);
1652}
1653.dropzone-icon {
1654 width: 64px; height: 64px;
1655 border-radius: 50%;
1656 background: var(--grad-brand-soft);
1657 display: grid; place-items: center;
1658 margin: 0 auto var(--space-md);
1659 color: var(--col-accent-bright);
1660}
1661.dropzone-icon svg { width: 28px; height: 28px; }
1662.dropzone-title { font-family: var(--font-display); font-size: 18px; font-weight: 600; color: #fff; margin-bottom: 6px; }
1663.dropzone-sub { color: var(--col-text-3); font-size: 13px; }
1664
1665
1666/* ---------------------------------------------------------------------
1667 19. Model cards
1668--------------------------------------------------------------------- */
1669.model-grid {
1670 display: grid;
1671 grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
1672 gap: var(--space-md);
1673}
1674.model-card {
1675 background: var(--col-surface-1);
1676 border: 1px solid var(--col-border);
1677 border-radius: var(--radius-lg);
1678 overflow: hidden;
1679 transition: transform var(--t-med), border-color var(--t-med), box-shadow var(--t-med);
1680 position: relative;
1681}
1682.model-card:hover {
1683 transform: translateY(-3px);
1684 border-color: var(--col-border-2);
1685 box-shadow: var(--shadow-md);
1686}
1687.model-thumb {
1688 aspect-ratio: 4 / 3;
1689 background: var(--col-surface-2);
1690 position: relative;
1691 overflow: hidden;
1692}
1693.model-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow); }
1694.model-card:hover .model-thumb img { transform: scale(1.05); }
1695.model-thumb-overlay {
1696 position: absolute;
1697 inset: 0;
1698 background: linear-gradient(180deg, transparent 50%, rgba(5,8,19,0.85) 100%);
1699 display: flex;
1700 flex-direction: column;
1701 justify-content: flex-end;
1702 padding: var(--space-md);
1703}
1704.model-badges { position: absolute; top: 10px; left: 10px; display: flex; gap: 6px; }
1705.model-info { padding: var(--space-md); }
1706.model-name {
1707 font-family: var(--font-display);
1708 font-size: 15px;
1709 font-weight: 600;
1710 color: #fff;
1711 margin-bottom: 4px;
1712 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
1713}
1714.model-row {
1715 display: flex; align-items: center; justify-content: space-between;
1716 font-size: 12px;
1717 color: var(--col-text-3);
1718}
1719.model-price {
1720 font-family: var(--font-display);
1721 font-size: 16px;
1722 font-weight: 700;
1723 color: var(--col-accent-bright);
1724}
1725
1726
1727/* ---------------------------------------------------------------------
1728 20. Tabs
1729--------------------------------------------------------------------- */
1730.tabs {
1731 display: flex;
1732 gap: 4px;
1733 padding: 4px;
1734 background: var(--col-surface-2);
1735 border: 1px solid var(--col-border);
1736 border-radius: var(--radius-md);
1737 margin-bottom: var(--space-lg);
1738 width: fit-content;
1739}
1740.tab {
1741 padding: 8px 16px;
1742 font-size: 13px;
1743 font-weight: 600;
1744 color: var(--col-text-2);
1745 border-radius: var(--radius-sm);
1746 cursor: pointer;
1747 transition: background var(--t-fast), color var(--t-fast);
1748 white-space: nowrap;
1749}
1750.tab:hover { color: var(--col-text); }
1751.tab.active {
1752 background: var(--col-surface-3);
1753 color: #fff;
1754 box-shadow: inset 0 0 0 1px var(--col-border-2);
1755}
1756
1757
1758/* ---------------------------------------------------------------------
1759 21. Progress bar
1760--------------------------------------------------------------------- */
1761.progress {
1762 width: 100%;
1763 height: 6px;
1764 background: var(--col-surface-3);
1765 border-radius: 999px;
1766 overflow: hidden;
1767}
1768.progress-fill {
1769 height: 100%;
1770 background: var(--grad-brand);
1771 border-radius: inherit;
1772 transition: width var(--t-slow);
1773}
1774
1775
1776/* ---------------------------------------------------------------------
1777 22. Banners / alerts
1778--------------------------------------------------------------------- */
1779.banner {
1780 display: flex; align-items: center; gap: 12px;
1781 padding: 12px 16px;
1782 border-radius: var(--radius-md);
1783 font-size: 13px;
1784 border: 1px solid;
1785}
1786.banner svg { width: 18px; height: 18px; flex-shrink: 0; }
1787.banner.info { background: rgba(56,189,248,0.10); color: #bae6fd; border-color: rgba(56,189,248,0.25); }
1788.banner.success { background: rgba(34,197,94,0.10); color: #bbf7d0; border-color: rgba(34,197,94,0.25); }
1789.banner.warning { background: rgba(245,158,11,0.10); color: #fde68a; border-color: rgba(245,158,11,0.25); }
1790.banner.danger { background: rgba(239,68,68,0.10); color: #fecaca; border-color: rgba(239,68,68,0.25); }
1791.banner-action { margin-left: auto; }
1792
1793
1794/* ---------------------------------------------------------------------
1795 23. Footer (landing)
1796--------------------------------------------------------------------- */
1797.site-foot {
1798 border-top: 1px solid var(--col-border);
1799 background: var(--col-bg-2);
1800 padding: var(--space-2xl) var(--space-xl);
1801 margin-top: var(--space-3xl);
1802}
1803.foot-grid {
1804 max-width: var(--content-max);
1805 margin: 0 auto;
1806 display: grid;
1807 grid-template-columns: 2fr repeat(4, 1fr);
1808 gap: var(--space-2xl);
1809}
1810.foot-col h5 {
1811 font-size: 11px;
1812 font-weight: 700;
1813 letter-spacing: 2px;
1814 text-transform: uppercase;
1815 color: var(--col-text-3);
1816 margin-bottom: var(--space-md);
1817}
1818.foot-col ul { display: flex; flex-direction: column; gap: 8px; }
1819.foot-col a { color: var(--col-text-2); font-size: 13px; transition: color var(--t-fast); }
1820.foot-col a:hover { color: var(--col-text); }
1821.foot-bottom {
1822 max-width: var(--content-max);
1823 margin: var(--space-xl) auto 0;
1824 padding-top: var(--space-md);
1825 border-top: 1px solid var(--col-border);
1826 display: flex;
1827 justify-content: space-between;
1828 font-size: 12px;
1829 color: var(--col-text-3);
1830}
1831
1832
1833/* ---------------------------------------------------------------------
1834 24. Utilities
1835--------------------------------------------------------------------- */
1836.flex { display: flex; }
1837.flex-col { display: flex; flex-direction: column; }
1838.items-center { align-items: center; }
1839.items-end { align-items: flex-end; }
1840.justify-between { justify-content: space-between; }
1841.justify-center { justify-content: center; }
1842.gap-2 { gap: 8px; } .gap-3 { gap: 12px; } .gap-4 { gap: 16px; } .gap-6 { gap: 24px; }
1843.mt-1 { margin-top: 8px; } .mt-2 { margin-top: 16px; } .mt-3 { margin-top: 24px; } .mt-4 { margin-top: 32px; }
1844.mb-1 { margin-bottom: 8px; } .mb-2 { margin-bottom: 16px; } .mb-3 { margin-bottom: 24px; } .mb-4 { margin-bottom: 32px; }
1845.text-center { text-align: center; }
1846.text-dim { color: var(--col-text-3); }
1847.text-secondary { color: var(--col-text-2); }
1848.text-success { color: var(--col-success); }
1849.text-danger { color: var(--col-danger); }
1850.text-warning { color: var(--col-warning); }
1851.text-brand { color: var(--col-accent-bright); }
1852.font-mono { font-family: var(--font-mono); }
1853.text-xs { font-size: 11px; } .text-sm { font-size: 13px; } .text-md { font-size: 15px; }
1854.text-lg { font-size: 18px; } .text-xl { font-size: 24px; }
1855.fw-600 { font-weight: 600; } .fw-700 { font-weight: 700; }
1856.tabular { font-variant-numeric: tabular-nums; }
1857.divider { height: 1px; background: var(--col-border); margin: var(--space-md) 0; }
1858.hide { display: none !important; }
1859
1860
1861/* ---------------------------------------------------------------------
1862 25. Scrollbar
1863--------------------------------------------------------------------- */
1864::-webkit-scrollbar { width: 10px; height: 10px; }
1865::-webkit-scrollbar-track { background: var(--col-bg-2); }
1866::-webkit-scrollbar-thumb { background: var(--col-surface-3); border-radius: 999px; border: 2px solid var(--col-bg-2); }
1867::-webkit-scrollbar-thumb:hover { background: var(--col-surface-4); }
1868
1869
1870/* ---------------------------------------------------------------------
1871 26. Responsive
1872--------------------------------------------------------------------- */
1873@media (max-width: 1100px) {
1874 .stat-row { grid-template-columns: repeat(2, 1fr); }
1875 .feature-grid { grid-template-columns: repeat(2, 1fr); }
1876 .pricing-grid { grid-template-columns: repeat(2, 1fr); }
1877 .foot-grid { grid-template-columns: 1fr 1fr; }
1878 .dash-grid, .dash-grid-3, .dash-grid-2 { grid-template-columns: 1fr; }
1879 .auth-shell { grid-template-columns: 1fr; }
1880 .auth-side { display: none; }
1881 .hero-inner { grid-template-columns: 1fr; }
1882 .hero-visual { display: none; }
1883}
1884@media (max-width: 760px) {
1885 /* Landing / marketing pages (not the dashboard wrapper). The dashboard
1886 sidebar overlay logic lives in the <=1200px block below; do NOT
1887 re-introduce `.sidebar { display: none; }` here -- it broke the
1888 slide-in toggle because display:none beats the overlay's
1889 position:fixed regardless of source order. */
1890 .search-box { display: none; }
1891 .section { padding: var(--space-2xl) var(--space-md); }
1892 .hero { padding: 60px var(--space-md); }
1893}
1894
1895/* ---------------------------------------------------------------------
1896 Tablet / foldable / landscape-phone (<= 1200px).
1897 --------------------------------------------------------------------- */
1898@media (max-width: 1200px) {
1899
1900 /* Layout: no sidebar column on mobile -- it becomes a slide-in
1901 overlay (rules below). Main content gets the full width by
1902 default; tapping the hamburger in the topbar slides the sidebar
1903 in on top of it. CRITICAL: must be a SINGLE column. Sidebar
1904 below is `position: fixed`, which removes it from grid flow --
1905 if the template still declares two columns, .app-main lands in
1906 column 1 (width 0) and the entire content collapses. */
1907 .app { grid-template-columns: 1fr; }
1908 .topbar-brand { display: inline-flex; }
1909
1910 /* Sidebar -> overlay panel. Pulled out of the grid via position:fixed,
1911 translated off-screen by default, slid in when html.mobile-nav-open
1912 is on the root element. Box-shadow gives it depth over the content. */
1913 /* Stacking order at narrow widths (topbar is z:150 so we sit above it
1914 so the dim also covers the topbar -- otherwise the topbar pokes
1915 through the backdrop and reads as "weird, not darkened"):
1916 backdrop = 160, sidebar = 170, toggle (open) = 180. */
1917 .sidebar {
1918 position: fixed !important;
1919 top: 0; left: 0; bottom: 0;
1920 width: 260px;
1921 height: 100vh;
1922 transform: translateX(-100%);
1923 opacity: 1 !important;
1924 visibility: visible !important;
1925 transition: transform 0.25s ease;
1926 z-index: 170;
1927 box-shadow: 4px 0 20px rgba(0,0,0,0.5);
1928 }
1929 html.mobile-nav-open .sidebar {
1930 transform: translateX(0);
1931 }
1932
1933 /* Backdrop catches taps outside the sidebar so the nav closes when
1934 you tap the page. Transparent on purpose -- the user disliked the
1935 dim effect; the sliding panel + box-shadow already reads as a
1936 foreground element without needing a darkened layer behind it. */
1937 html.mobile-nav-open body::before {
1938 content: "";
1939 position: fixed;
1940 top: 0; left: 0; right: 0; bottom: 0;
1941 background: transparent;
1942 z-index: 160;
1943 }
1944
1945 /* Toggle stays in the topbar even at the mobile breakpoint -- a tap
1946 opens the slide-in overlay, another tap closes it. No fixed-
1947 position juggling needed now that the button lives inside the
1948 topbar's flex row. */
1949
1950 /* All multi-column form layouts collapse to a single column so labels
1951 stack above inputs and inputs reach the full content width. */
1952 .pr-form-grid,
1953 .dash-grid,
1954 .dash-grid-3,
1955 .dash-grid-2,
1956 .seo-grid,
1957 .auth-shell,
1958 .hero-inner,
1959 .foot-grid,
1960 .feature-grid,
1961 .pricing-grid,
1962 .stat-row {
1963 grid-template-columns: 1fr !important;
1964 }
1965 .auth-side,
1966 .hero-visual { display: none; }
1967
1968 /* Form modules tighten in -- the 22/26 desktop padding feels cavernous
1969 on a phone-width container. */
1970 .pr-form { padding: 18px 16px; }
1971 .module { padding: 16px; }
1972
1973 /* Inputs go thumb-friendly. 16px is the magic number that suppresses
1974 iOS Safari's auto-zoom on focus; 44px min-height matches the Apple
1975 HIG / Material touch target guideline. */
1976 .input, .textarea, .select,
1977 .pr-field input[type="text"],
1978 .pr-field input[type="number"],
1979 .pr-field input[type="datetime-local"],
1980 .pr-field input[type="email"],
1981 .pr-field input[type="password"],
1982 .pr-field textarea,
1983 .pr-field select {
1984 font-size: 16px;
1985 padding: 12px 14px;
1986 min-height: 44px;
1987 width: 100%;
1988 box-sizing: border-box;
1989 }
1990 .pr-field textarea,
1991 .textarea { min-height: 96px; }
1992
1993 /* Labels stay uppercase + tracked even on the smallest device --
1994 reinforces the existing rule in case a UA stylesheet leaks in. */
1995 .pr-field label,
1996 .form-label {
1997 text-transform: uppercase;
1998 letter-spacing: 1.5px;
1999 font-size: 11px;
2000 font-weight: 700;
2001 }
2002
2003 /* Touch-friendly buttons. The base .btn loses its lat-padding on
2004 small screens; bumping min-height keeps it hittable. */
2005 .btn { min-height: 44px; padding: 10px 16px; font-size: 14px; }
2006 .btn-sm { min-height: 38px; padding: 8px 12px; font-size: 13px; }
2007
2008 /* Headings scale down a step. .page-title is 36-40px on desktop. */
2009 .page-head .page-title { font-size: 28px; line-height: 1.2; }
2010 .page-subtitle { font-size: 14px; }
2011
2012 /* Section + content padding tightens. */
2013 .app-content { padding: 20px 32px; }
2014
2015 /* Tables that don't fit the viewport get horizontal scroll instead of
2016 overflowing the layout. Wrap any .table in a .table-wrap div for
2017 this to work; most pages already do. */
2018 .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
2019 .table { min-width: 560px; }
2020
2021 /* Tab strips (Settings, Admin, etc.) -- base style uses
2022 `width: fit-content` + `white-space: nowrap`, which overflows the
2023 viewport when there are 4+ tabs on a phone. Let the strip take the
2024 full width and scroll its contents horizontally so every tab stays
2025 reachable without the page itself scrolling sideways. */
2026 .tabs {
2027 width: 100%;
2028 max-width: 100%;
2029 overflow-x: auto;
2030 -webkit-overflow-scrolling: touch;
2031 scrollbar-width: thin;
2032 }
2033
2034 /* Topbar tools row -- chat-pill, msg-pill, help-btn. Tighter padding
2035 at narrow widths so all three fit alongside the brand + title, but
2036 the text labels ("Chat", "Messages", "Help") stay visible at every
2037 viewport size per product preference -- the buttons never collapse
2038 to bare dots/icons. */
2039 .topbar-tools { gap: 6px; }
2040 .chat-pill,
2041 .msg-pill { padding: 0 10px; height: 32px; gap: 6px; }
2042 .help-btn { padding: 0 10px; height: 32px; gap: 6px; }
2043}
2044
2045/* Small phone -- Samsung phone external panel, iPhone SE in portrait, etc. */
2046@media (max-width: 700px) {
2047 .page-head .page-title { font-size: 22px; }
2048 .page-subtitle { font-size: 13px; }
2049 .topbar { padding-right: 8px; }
2050 .pill { padding: 6px 10px; font-size: 12px; }
2051 .module { padding: 12px; border-radius: 10px; }
2052 .pr-form { padding: 14px 12px; }
2053 .pr-actions .btn { flex: 1; } /* full-width submit on phones */
2054}
2055
2056
2057/* =====================================================================
2058 27. Brand-warmth recipe (per AB feedback_brand_warmth_recipe.md)
2059 --------------------------------------------------------------------
2060 Ports the AB sunset recipe to ContactForge' blue (#06b6d4) -> violet
2061 (#7c3aed) palette. The base CSS above stays intact -- this section
2062 only layers warm radial overlays, brand-tinted borders, and brand
2063 glow on top of every dashboard chrome surface so the brand "bleeds
2064 through" the dark interior the way it does on the landing page.
2065
2066 Brand triples used throughout this section:
2067 BRAND = 59, 130, 246 (#06b6d4 -- primary blue)
2068 BRAND-2 = 124, 58, 237 (#7c3aed -- violet)
2069 VIOLET-BR = 167, 139, 250 (#a78bfa -- light violet, used like peach)
2070
2071 Scoped to the dashboard wrapper (.app > .sidebar / .topbar / .app-
2072 content); marketing/landing styles are deliberately untouched.
2073===================================================================== */
2074
2075/* ---- Body atmosphere: stronger overlapping radials ----------------- */
2076body::before {
2077 background:
2078 radial-gradient(ellipse 1200px 700px at 8% -5%, rgba(6,182,212,0.18), transparent 60%),
2079 radial-gradient(ellipse 900px 600px at 100% 30%, rgba(6,182,212,0.14), transparent 60%),
2080 radial-gradient(ellipse 700px 400px at 50% 110%, rgba(6,182,212,0.10), transparent 60%);
2081}
2082
2083/* ---- Sidebar: layered glow + brand border-right + outward shadow --- */
2084.sidebar {
2085 background:
2086 radial-gradient(ellipse 150% 50% at 0% 0%, rgba(6,182,212,0.22), transparent 65%),
2087 radial-gradient(ellipse 130% 45% at 100% 30%, rgba(6,182,212,0.12), transparent 60%),
2088 radial-gradient(ellipse 120% 45% at 20% 100%, rgba(6,182,212,0.14), transparent 65%),
2089 linear-gradient(180deg, #101a2e 0%, #0c1224 55%, #080c1a 100%);
2090 border-right: 1px solid rgba(6,182,212,0.25);
2091 box-shadow: 1px 0 26px rgba(6,182,212,0.10);
2092}
2093
2094/* Sidebar section labels: light-violet, slightly muted -- gives the
2095 group bands a second-brand color instead of cold gray. */
2096.sidebar-section-label {
2097 color: #a78bfa;
2098 opacity: 0.85;
2099}
2100
2101/* Active nav item already gradients; reinforce the inner brand ring
2102 and ensure the left accent bar reads as a brand light source. */
2103.sidebar-link.active {
2104 background: linear-gradient(90deg,
2105 rgba(6,182,212,0.28),
2106 rgba(6,182,212,0.10) 70%,
2107 transparent);
2108 box-shadow: inset 0 0 0 1px rgba(6,182,212,0.30);
2109}
2110
2111/* Sidebar foot divider picks up brand alpha so the user-chip strip
2112 feels like a continuation of the brand surface above it. */
2113.sidebar-foot { border-top-color: rgba(6,182,212,0.22); }
2114.sidebar-brand { border-bottom-color: rgba(6,182,212,0.22); }
2115
2116/* ---- Topbar: brand-tinted horizontal fade --------------------------- */
2117.topbar {
2118 background:
2119 linear-gradient(90deg,
2120 rgba(6,182,212,0.12) 0%,
2121 rgba(6,182,212,0.06) 40%,
2122 rgba(8,12,26,0.72) 100%),
2123 rgba(8,12,26,0.72);
2124 border-bottom: 1px solid rgba(6,182,212,0.22);
2125 box-shadow: 0 8px 24px rgba(6,182,212,0.05);
2126}
2127
2128/* Topbar page title gets a subtle gradient so the heading reads as
2129 part of the brand chrome instead of plain white. */
2130.topbar-title {
2131 background: linear-gradient(135deg, #fff 0%, #fff 50%, #a78bfa 110%);
2132 -webkit-background-clip: text;
2133 background-clip: text;
2134 -webkit-text-fill-color: transparent;
2135 color: transparent;
2136}
2137
2138/* ---- Cards: brand-tinted border + soft top wash + inset highlight -- */
2139.card,
2140.module,
2141.pr-form,
2142.pr-kpi,
2143.pr-table,
2144.seo-preview,
2145.feature {
2146 background:
2147 linear-gradient(180deg, rgba(6,182,212,0.05) 0%, transparent 40%),
2148 var(--col-surface-1);
2149 border-color: rgba(6,182,212,0.16);
2150 box-shadow: 0 1px 0 rgba(6,182,212,0.06) inset;
2151}
2152.card:hover,
2153.module:hover,
2154.feature:hover,
2155.pr-kpi:hover { border-color: rgba(6,182,212,0.32); }
2156
2157/* Card title gets a glowing brand accent bar in front of the text. */
2158.card-title { display: inline-flex; align-items: center; gap: 10px; }
2159.card-title::before {
2160 content: '';
2161 width: 3px; height: 14px;
2162 border-radius: 3px;
2163 background: linear-gradient(180deg, #06b6d4 0%, #7c3aed 100%);
2164 box-shadow: 0 0 8px rgba(6,182,212,0.55);
2165 flex-shrink: 0;
2166}
2167
2168/* Module-head (dashboard sections w/ icon + title) gets the same
2169 brand bleed at the top so the chrome reads as one family. */
2170.module-head {
2171 background:
2172 linear-gradient(180deg, rgba(6,182,212,0.06), transparent),
2173 linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
2174 border-bottom-color: rgba(6,182,212,0.18);
2175}
2176
2177/* ---- Stat tiles / KPI cards: brand-edge + left accent bar ---------- */
2178.stat {
2179 border-color: rgba(6,182,212,0.22);
2180 box-shadow: 0 8px 24px rgba(6,182,212,0.05);
2181 transition: transform var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
2182}
2183.stat:hover {
2184 transform: translateY(-1px);
2185 border-color: rgba(6,182,212,0.45);
2186 box-shadow: 0 10px 30px rgba(6,182,212,0.14);
2187}
2188.stat::after {
2189 content: '';
2190 position: absolute;
2191 left: 0; top: 0; bottom: 0;
2192 width: 3px;
2193 background: linear-gradient(180deg, #06b6d4 0%, #7c3aed 100%);
2194}
2195.stat-value {
2196 background: linear-gradient(135deg, #fff 0%, #a78bfa 130%);
2197 -webkit-background-clip: text;
2198 background-clip: text;
2199 -webkit-text-fill-color: transparent;
2200}
2201.stat-label { color: #a78bfa; opacity: 0.85; }
2202
2203/* pr-kpi (promotions KPI tiles) share the same treatment. */
2204.pr-kpi {
2205 position: relative;
2206 overflow: hidden;
2207}
2208.pr-kpi::after {
2209 content: '';
2210 position: absolute;
2211 left: 0; top: 0; bottom: 0;
2212 width: 3px;
2213 background: linear-gradient(180deg, #06b6d4 0%, #7c3aed 100%);
2214}
2215.pr-kpi .lbl { color: #a78bfa; opacity: 0.85; }
2216
2217/* ---- Tables: violet-light headers + brand-tinted hover ------------- */
2218.table th,
2219.pr-table thead th {
2220 color: #a78bfa;
2221 border-bottom-color: rgba(6,182,212,0.22);
2222 background: rgba(6,182,212,0.05);
2223}
2224.table tr:hover td { background: rgba(6,182,212,0.06); }
2225
2226/* ---- Forms: violet-light labels + stronger brand focus ring -------- */
2227.form-label,
2228.pr-field label {
2229 color: #a78bfa;
2230 opacity: 0.95;
2231}
2232.input:focus,
2233.textarea:focus,
2234.select:focus,
2235.pr-field input[type="text"]:focus,
2236.pr-field input[type="number"]:focus,
2237.pr-field input[type="datetime-local"]:focus,
2238.pr-field textarea:focus,
2239.pr-field select:focus {
2240 border-color: #06b6d4;
2241 box-shadow: 0 0 0 3px rgba(6,182,212,0.20);
2242 background: var(--col-surface-1);
2243}
2244
2245/* ---- Page header: gradient title text ----------------------------- */
2246.page-head .page-title {
2247 background: linear-gradient(135deg, #fff 0%, #fff 40%, #a78bfa 100%);
2248 -webkit-background-clip: text;
2249 background-clip: text;
2250 -webkit-text-fill-color: transparent;
2251 color: transparent;
2252 text-shadow: 0 0 28px rgba(6,182,212,0.25);
2253}
2254.page-eyebrow { color: #a78bfa; }
2255
2256/* ---- Dropzone: subtle brand glow + warmer hover ------------------- */
2257.dropzone {
2258 background:
2259 linear-gradient(180deg, rgba(6,182,212,0.05) 0%, transparent 50%),
2260 var(--col-surface-1);
2261 border-color: rgba(6,182,212,0.30);
2262}
2263.dropzone:hover,
2264.dropzone.drag {
2265 border-color: #06b6d4;
2266 background:
2267 linear-gradient(180deg, rgba(6,182,212,0.12) 0%, transparent 60%),
2268 var(--col-surface-1);
2269 box-shadow: 0 0 0 3px rgba(6,182,212,0.15);
2270}
2271
2272/* ---- Tabs: brand-tinted active state ------------------------------ */
2273.tabs {
2274 background:
2275 linear-gradient(180deg, rgba(6,182,212,0.05), transparent),
2276 var(--col-surface-2);
2277 border-color: rgba(6,182,212,0.18);
2278}
2279.tab.active {
2280 background: linear-gradient(135deg, rgba(6,182,212,0.18), rgba(6,182,212,0.10));
2281 box-shadow: inset 0 0 0 1px rgba(6,182,212,0.35);
2282}
2283
2284/* ---- Auth box: warm wash + brand glow ----------------------------- */
2285.auth-main {
2286 background:
2287 radial-gradient(ellipse 700px 500px at 100% 0%, rgba(6,182,212,0.12), transparent 60%),
2288 radial-gradient(ellipse 600px 400px at 0% 100%, rgba(6,182,212,0.08), transparent 60%),
2289 var(--col-bg);
2290}
2291.auth-form-wrap {
2292 background:
2293 linear-gradient(160deg, rgba(6,182,212,0.08) 0%, transparent 45%),
2294 var(--col-surface-1);
2295 border: 1px solid rgba(6,182,212,0.22);
2296 border-radius: var(--radius-lg);
2297 padding: var(--space-xl);
2298 box-shadow: 0 24px 60px rgba(6,182,212,0.10);
2299}
2300
2301/* ---- Banners: keep semantic colors but lift info-banner accent ---- */
2302.banner.info {
2303 background: rgba(6,182,212,0.10);
2304 border-color: rgba(6,182,212,0.30);
2305 color: #bfdbfe;
2306}
2307
2308/* ---- Pill .brand variant: slightly heavier glow ------------------- */
2309.pill.brand {
2310 box-shadow: 0 0 12px rgba(6,182,212,0.20);
2311}
2312
2313/* ---- Progress fill: keep brand gradient but add subtle glow ------- */
2314.progress-fill {
2315 box-shadow: 0 0 12px rgba(6,182,212,0.45);
2316}
2317
2318/* ---- Brand-mark blur halo: cyan base to match the brand mark -- */
2319.brand-mark::after {
2320 background: #06b6d4;
2321 opacity: 0.55;
2322}
2323
2324/* ---- Scrollbar thumb: brand-tinted hover -------------------------- */
2325::-webkit-scrollbar-thumb:hover { background: rgba(6,182,212,0.45); }
2326
2327/* ---- Sidebar scrollbar: violet thumb so it reads as brand chrome --- */
2328.sidebar-nav { scrollbar-width: thin; scrollbar-color: rgba(6,182,212,0.55) transparent; }
2329.sidebar-nav::-webkit-scrollbar { width: 8px; }
2330.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
2331.sidebar-nav::-webkit-scrollbar-thumb {
2332 background: linear-gradient(180deg, rgba(6,182,212,0.65), rgba(167,139,250,0.55));
2333 border: 2px solid transparent;
2334 background-clip: padding-box;
2335 border-radius: 999px;
2336}
2337.sidebar-nav::-webkit-scrollbar-thumb:hover {
2338 background: linear-gradient(180deg, rgba(6,182,212,0.85), rgba(167,139,250,0.75));
2339 background-clip: padding-box;
2340}
2341
2342/* =====================================================================
2343 END brand-warmth recipe
2344===================================================================== */
2345
2346/* WIDTH-STANDARDIZATION: neutralize legacy inline max-width caps and extra horizontal padding on the page wrapper so all sites match PTMatrix. */
2347.app-content > div { max-width: none !important; }
2348.app-content > div:not(.card):not(.card-elevated):not(.module):not(.myc-shell):not(.mte-shell):not(.gov-shell):not([class*="-wrap"]):not([class*="-card"]):not(.afnl-hero):not(.fnl-hero):not([class*=hero]) { padding-left: 0 !important; padding-right: 0 !important; }
2349
2350
2351/* Chip range picker: Custom datetime-local inputs -- brand-themed to
2352 match the site (2026-07-09). Scoped to #customWrap so it only styles
2353 the chip-picker's Custom inputs, never other forms on the page. */
2354#customWrap input[type="datetime-local"] {
2355 background: var(--col-surface, #0f1a26);
2356 color: var(--col-text, #e5e7eb);
2357 border: 1px solid var(--col-border, rgba(255,255,255,.12));
2358 border-radius: 8px;
2359 padding: 5px 10px;
2360 font-size: 12px;
2361 font-family: inherit;
2362 color-scheme: dark;
2363 outline: none;
2364 transition: border-color .15s ease;
2365}
2366#customWrap input[type="datetime-local"]:hover,
2367#customWrap input[type="datetime-local"]:focus {
2368 border-color: var(--col-brand, var(--col-primary, var(--col-accent, #5aa9ff)));
2369}
2370#customWrap input[type="datetime-local"]::-webkit-calendar-picker-indicator {
2371 filter: invert(1) brightness(1.4);
2372 cursor: pointer;
2373 opacity: 0.75;
2374}
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help