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

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

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

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