Skip to main content

max / makenotwork

256.2 KB · 10962 lines History Blame Raw
1 /* ============================================================================
2 MNW global stylesheet. Charter: docs/design-system.md.
3
4 Build new features by COMPOSING these primitives, in this order of preference:
5
6 1. Use a UTILITY class for one-off adjustments (.mb-4, .text-sm, .nowrap)
7 2. Use a LAYOUT PRIMITIVE to position content (.container, .stack-row, .field-row, .list-row)
8 3. Use a COMPONENT PRIMITIVE for a UI element (.card, .callout, .badge, .progress-bar, .empty-state, .input--sm, .small)
9 4. Extend a primitive with a modifier (.card--bordered, .callout--warning, .stack-row--bordered)
10 5. ONLY THEN consider a new class — and add it to the right section below
11
12 A new class is a smell, not a goal. Before writing one:
13 • grep this file for the visual shape you want; almost everything is here
14 • if you can't find it, consider whether the shape belongs in the design system
15 (then add it to the appropriate section here AND to docs/design-system.md)
16 • page-scoped rules (`.foo-page .bar`) are a last resort, not a first move
17
18 --------------------------------------------------------------------------
19 FILE STRUCTURE (search by section name for anchor)
20
21 FOUNDATIONS
22 @font-face declarations (top of file)
23 :root tokens — color, type, space, radius, shadow
24 Element base — h1/h2/h3, p, a, button, input, table
25
26 UTILITIES
27 Spacing (.m-0, .mt-*, .mb-*, .ml-*, .my-*)
28 Sizing (.col-*, .w-*, .maxw-*, .minw-*)
29 Text (.text-sm, .text-xs, .text-center, .text-right, .fw-bold,
30 .nowrap, .muted, .dimmed, .dimmer, .is-faded, .danger-text)
31 State (.hidden, .is-selected, .is-active, .unstyled-link)
32 Shapes (.square-cover, .scroll-x)
33
34 LAYOUT PRIMITIVES (page-scaffolding shapes)
35 .container + .container--narrow / --medium / --wide
36 .stack-row + --bordered / --tight / --top — toolbar / header bar
37 .field-row + .form-group.is-grow — inline form row
38 .list-row + .list-row-title — vertical item list
39 .form-row — 2-col grid form
40 .cover-row + .cover-thumb + .cover-empty — image picker
41
42 COMPONENT PRIMITIVES (reusable UI blocks)
43 .content-section — light-bg page section box
44 .card / .card-muted / .card--bordered / .card--selectable
45 .form-group / .form-section / details.form-section
46 .section-header / .section-lead / .section-group-label
47 .badge + variants (-success/-warning/-danger)
48 .callout + --danger / --warning / --solid-warning
49 .banner + --info / --warning — full-bleed page-top notice
50 .alert + -note / -tip / -warning / -caution — left-border inline notice
51 .modal + .modal-overlay
52 .empty-state + --compact / --chart / --lg
53 .progress-bar-container + .progress-bar (--slim, --rounded, --highlight)
54 .upload-status + __row + __msg.is-success / .is-error
55 .field-status / .save-status + .success / .error / .saving
56 .toast + .toast--success / --error / --warning
57 .breadcrumb / .pagination
58 .tabs + .tab.is-selected
59
60 CONTROL MODIFIERS (compose onto buttons/inputs)
61 .small / .btn-compact / .btn-link / .btn-tiny — button sizes
62 .primary / .secondary / .danger / .saved — button intents
63 .input--xs / --sm / --mono / --upper / --numeric — input sizes/shapes
64
65 FEATURE SUBAPPS (their own CSS scope)
66 .git-* (git source browser at /source/*)
67 Pricing calculator on /pricing
68 Markdown preview / docs-ui in /docs/*
69
70 PAGE-SCOPED LAYOUTS (when truly page-specific)
71 .item-page / .project-page / .article-page / .purchase-page / .cart-* /
72 .library-page / .feed-page / .discover-page / .landing / .creators-page /
73 .health-page / .import-page / .delete-account-page / .export-page /
74 .receipt-page / .fan-plus-page / .stripe-disclaimer-page / .buy-page /
75 .user-page / .collection-page / .changelog-page / .policy-page /
76 .tag-tree-page / .project-blog-page / .project-paywall-page /
77 .confirm-delete-page / .admin-page / .dashboard-page
78
79 DASHBOARD TABS (one section per tab partial)
80 Per-tab classes scoped under their canonical body class. Use modifier
81 composition where possible; only add tab-specific rules when the shape
82 genuinely diverges from a primitive.
83
84 RESPONSIVE (@media at end of file)
85 768px tablet
86 480px phone
87
88 --------------------------------------------------------------------------
89 When in doubt: read docs/design-system.md first. Update both files together
90 when you add a primitive.
91 ============================================================================ */
92
93 @font-face {
94 font-family: "Young Serif";
95 src: url("/static/fonts/ysrf.woff2") format("woff2"),
96 url("/static/fonts/ysrf.ttf") format("truetype");
97 font-display: swap;
98 }
99
100 @font-face {
101 font-family: "IBM Plex Mono";
102 src: url("/static/fonts/IBMPlexMono-Regular.woff2") format("woff2"),
103 url("/static/fonts/IBMPlexMono-Regular.ttf") format("truetype");
104 font-weight: normal;
105 font-display: swap;
106 }
107
108 @font-face {
109 font-family: "IBM Plex Mono";
110 src: url("/static/fonts/IBMPlexMono-Bold.woff2") format("woff2"),
111 url("/static/fonts/IBMPlexMono-Bold.ttf") format("truetype");
112 font-weight: bold;
113 font-display: swap;
114 }
115
116 @font-face {
117 font-family: "Lato";
118 src: url("/static/fonts/Lato-Regular.woff2") format("woff2"),
119 url("/static/fonts/Lato-Regular.ttf") format("truetype");
120 font-weight: normal;
121 font-display: swap;
122 }
123
124 @font-face {
125 font-family: "Lato";
126 src: url("/static/fonts/Lato-Bold.woff2") format("woff2"),
127 url("/static/fonts/Lato-Bold.ttf") format("truetype");
128 font-weight: bold;
129 font-display: swap;
130 }
131
132 :root {
133 /* Typography (three-tier system) */
134 --font-heading: "Young Serif", serif;
135 --font-mono: "IBM Plex Mono", monospace;
136 --font-body: "Lato", sans-serif;
137
138 /* Brand colors per style guide */
139 --background: #ede8e1;
140 --detail: #3d3530;
141 --highlight: #6c5ce7;
142 --light-background: #f4f0eb;
143
144 /* Extended palette */
145 --surface-muted: #ddd7c5;
146 --surface-alt: #ebe7db;
147 --surface-border: #d0cbb8;
148 --surface-raised: #f5f0eb;
149 --border: #d0cbb8;
150 --text-muted: #8a8480;
151 --input-background: #e2dad2;
152 --overlay: rgba(0, 0, 0, 0.5);
153
154 /* Semantic colors */
155 --primary-dark: #000000;
156 --primary-light: #ffffff;
157 --success: #27ae60;
158 --success-bg: #e8fde8;
159 --warning: #8b7355;
160 --warning-bg: #fff3cd;
161 --warning-border: #ffc107;
162 --danger: #c0392b;
163 --danger-bg: #fde8e8;
164 --error: #d62828;
165 --error-bg: #fef2f2;
166 --stripe: #635BFF;
167
168 /* Health status indicators */
169 --health-ok: #22c55e;
170 --health-warn: #f59e0b;
171 --health-error: #ef4444;
172 --health-unknown: #9ca3af;
173
174 /* Focus ring color for accessibility */
175 --focus-ring: #6c5ce7;
176 --highlight-faint: rgba(108, 92, 231, 0.08);
177
178 /* Diff / code review */
179 --diff-add: #2d7d2d;
180 --diff-add-bg: rgba(45, 125, 45, 0.08);
181 --diff-del: #a83232;
182 --diff-del-bg: rgba(168, 50, 50, 0.08);
183
184 /* Aliases used by git browser */
185 --secondary-bg: #f4f0eb;
186 --text: #3d3530;
187
188 /* Legacy aliases — defined to end silent var() fallback failures
189 in inline-styled templates. Consolidate during phase 2.12. */
190 --accent: var(--highlight);
191 --accent-color: var(--highlight);
192 --border-color: var(--border);
193 --background-color: var(--background);
194
195 /* Spacing scale (charter: docs/design-system.md) */
196 --space-1: 0.25rem;
197 --space-2: 0.5rem;
198 --space-3: 0.75rem;
199 --space-4: 1rem;
200 --space-5: 1.5rem;
201 --space-6: 2rem;
202
203 /* Radius scale */
204 --radius-sm: 2px;
205 --radius-md: 4px;
206 --radius-round: 50%;
207
208 /* Shadow scale.
209 --shadow-1/-2/-3 are blurred elevation (true floating: popovers,
210 dropdowns, modals). --shadow-raised/-card/-inset are hard-offset
211 "sticker on paper" depth for everyday affordance — buttons feel
212 pressable, cards feel layered, inputs feel recessed. Pick by role:
213 blurred = floats over page, hard-offset = is part of page. */
214 --shadow-edge: #bbb; /* heavier — pressable (button, tab) */
215 --shadow-edge-soft: #ddd; /* lighter — surface (card, input) */
216 --shadow-raised: 2px 2px var(--shadow-edge);
217 --shadow-card: 2px 2px var(--shadow-edge-soft);
218 --shadow-inset: inset 2px 2px var(--shadow-edge-soft);
219 --shadow-1: 0 1px 3px rgba(0, 0, 0, 0.06);
220 --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.10);
221 --shadow-3: 0 4px 12px rgba(0, 0, 0, 0.15);
222 }
223
224 /* Reset */
225 * {
226 margin: 0;
227 padding: 0;
228 box-sizing: border-box;
229 }
230
231 /* Base styles */
232 body {
233 margin: 0;
234 background-color: var(--background);
235 color: var(--detail);
236 font-family: var(--font-body);
237 line-height: 1.6;
238 }
239
240 /* Padded page layout for most content pages */
241 .padded-page {
242 padding: 1.5rem;
243 }
244
245 /* Centered page layout for landing, login, signup */
246 .centered-page {
247 display: flex;
248 flex-direction: column;
249 justify-content: center;
250 align-items: center;
251 min-height: 100vh;
252 gap: 2rem;
253 }
254
255 .centered-page h1 {
256 font-size: 4.5rem;
257 }
258
259 .message-container {
260 max-width: 500px;
261 text-align: center;
262 }
263
264 .centered-wrapper {
265 justify-content: center;
266 text-align: center;
267 }
268
269 h1 {
270 font-family: var(--font-heading);
271 font-weight: normal;
272 color: var(--detail);
273 text-align: center;
274 font-size: 2.5rem;
275 }
276
277 h2,
278 h3 {
279 font-family: var(--font-mono);
280 font-weight: normal;
281 color: var(--detail);
282 }
283
284 /* Heading classes (charter: docs/design-system.md — every h1/h2 in a
285 template must carry one of these so the role is explicit).
286
287 .brand-h1 — the "Makenot.work" wordmark on auth/wizard pages.
288 .page-title — page-level h1 (Young Serif, centered).
289 .subtitle-h2 — page subtitle h2 used under .brand-h1 in auth/wizards.
290 .subsection-title — h2 inside dashboards, tabs, and prose partials
291 (mono, no border — the default-h2 role made explicit).
292 .section-header — h2 prose sub-section heading with bottom border
293 (existing rule, see SECTIONS block). */
294 .brand-h1,
295 .page-title {
296 font-family: var(--font-heading);
297 font-weight: normal;
298 color: var(--detail);
299 text-align: center;
300 font-size: 2.5rem;
301 }
302
303 .subtitle-h2 {
304 font-family: var(--font-mono);
305 font-weight: normal;
306 color: var(--detail);
307 text-align: center;
308 font-size: 1.5rem;
309 }
310
311 .subsection-title {
312 font-family: var(--font-mono);
313 font-weight: normal;
314 color: var(--detail);
315 }
316
317 p {
318 font-family: var(--font-body);
319 color: var(--detail);
320 }
321
322 a {
323 color: var(--detail);
324 text-decoration: none;
325 }
326
327 a:hover {
328 text-decoration: underline;
329 }
330
331 /* The signature dot */
332 .dot {
333 color: var(--highlight);
334 }
335
336 /* Container — default 1200px max-width. Modifier classes for narrower pages,
337 or comma-grouped page-scoped overrides below for body-class-based control. */
338 .container {
339 max-width: 1200px;
340 margin: 0 auto;
341 padding: 2rem;
342 }
343 .container--narrow { max-width: 600px; }
344 .container--medium { max-width: 800px; }
345 .container--wide { max-width: 900px; }
346
347 /* Per-page container width overrides (selected via body class). One rule
348 per width tier; new pages should add their body class here rather than
349 defining a new .foo-page .container rule. */
350 .delete-account-page .container,
351 .receipt-page .container,
352 .user-page .container { max-width: 600px; margin: 0 auto; }
353
354 .import-page .container,
355 .export-page .container { max-width: 800px; margin: 0 auto; }
356
357 .fan-plus-page .container,
358 .feed-page .container,
359 .creators-page .container { max-width: 900px; margin: 0 auto; }
360
361 /* ===========================================
362 BUTTONS
363 =========================================== */
364
365 button {
366 color: var(--detail);
367 background: var(--light-background);
368 padding: 6px 12px;
369 border: 1px solid var(--detail);
370 font-family: inherit;
371 cursor: pointer;
372 box-shadow: var(--shadow-raised);
373 transition: box-shadow 0.1s ease, transform 0.05s ease;
374 }
375
376 button:hover {
377 box-shadow: 3px 3px var(--shadow-edge);
378 }
379
380 button:active {
381 box-shadow: none;
382 transform: translate(2px, 2px);
383 }
384
385 .btn-primary {
386 background: var(--primary-dark);
387 color: var(--primary-light);
388 border: none;
389 padding: 0.75rem 1.5rem;
390 font-family: inherit;
391 font-size: 1rem;
392 cursor: pointer;
393 box-shadow: var(--shadow-raised);
394 transition: box-shadow 0.1s ease, transform 0.05s ease;
395 display: inline-block;
396 text-decoration: none;
397 }
398
399 .btn-primary:hover {
400 box-shadow: 3px 3px var(--shadow-edge);
401 text-decoration: none;
402 }
403
404 .btn-primary:active {
405 box-shadow: none;
406 transform: translate(2px, 2px);
407 }
408
409 .btn-secondary {
410 background: var(--surface-muted);
411 color: var(--detail);
412 border: none;
413 padding: 0.75rem 1.5rem;
414 font-family: var(--font-mono);
415 font-size: 1rem;
416 cursor: pointer;
417 box-shadow: var(--shadow-raised);
418 transition: box-shadow 0.1s ease, transform 0.05s ease;
419 display: inline-block;
420 text-decoration: none;
421 }
422
423 .btn-secondary:hover {
424 box-shadow: 3px 3px var(--shadow-edge);
425 text-decoration: none;
426 }
427
428 .btn-secondary:active {
429 box-shadow: none;
430 transform: translate(2px, 2px);
431 }
432
433 .btn-danger {
434 background: var(--danger);
435 color: var(--primary-light);
436 border: none;
437 padding: 0.75rem 1.5rem;
438 font-family: var(--font-mono);
439 font-size: 1rem;
440 cursor: pointer;
441 box-shadow: var(--shadow-raised);
442 transition: box-shadow 0.1s ease, transform 0.05s ease;
443 display: inline-block;
444 text-decoration: none;
445 }
446
447 .btn-danger:hover {
448 box-shadow: 3px 3px var(--shadow-edge);
449 text-decoration: none;
450 }
451
452 .btn-danger:active {
453 box-shadow: none;
454 transform: translate(2px, 2px);
455 }
456
457 /* Disabled state for all button variants (charter rule).
458 Applies whether disabled via attribute or aria-disabled. */
459 button:disabled,
460 button[aria-disabled="true"],
461 .btn-primary:disabled,
462 .btn-secondary:disabled,
463 .btn-danger:disabled {
464 opacity: 0.5;
465 cursor: not-allowed;
466 box-shadow: none;
467 transform: none;
468 }
469
470 /* Button size + style modifiers (charter: docs/design-system.md).
471 Use these on top of .btn-primary / -secondary / -danger.
472
473 .btn--large — large CTA padding bump.
474 .btn--icon — square icon-only / micro button (small padding,
475 tight line-height).
476 .btn--link — visually a link, semantically a button (no bg/
477 border, opacity-fade hover, mono).
478
479 Some surfaces have tuned button variants that are NOT compositions
480 of these modifiers and keep their own classes:
481 .big-button — Young Serif 200×60 anchor on splash pages.
482 .order-btn — list reorder up/down (with active flash).
483 .play-button — circular media-player play control.
484 .speed-button — segment in media-player speed group.
485 .shortcuts-help-btn — 1.5rem square help glyph in toolbars.
486 .toast-retry-btn — inline bordered button inside a toast,
487 uses currentColor to inherit toast tone.
488 These are documented variants, not deprecation targets. */
489 .btn--large {
490 padding: 1rem 2.25rem;
491 font-size: 1.125rem;
492 }
493
494 .btn--icon {
495 padding: var(--space-1) var(--space-2);
496 font-size: 0.85rem;
497 line-height: 1;
498 min-width: 1.75rem;
499 }
500
501 .btn--link {
502 background: none;
503 color: var(--detail);
504 border: none;
505 padding: 0;
506 font-family: var(--font-mono);
507 font-size: 1rem;
508 cursor: pointer;
509 /* Link semantics — flat, no depth. Overrides the shadow that would
510 otherwise cascade from `button` / `form button` when a .btn--link
511 happens to be a <button> inside a <form> (e.g. logout). */
512 box-shadow: none;
513 transition: opacity 0.2s ease;
514 }
515
516 .btn--link:hover {
517 opacity: 0.6;
518 box-shadow: none;
519 }
520
521 .btn--link:active {
522 box-shadow: none;
523 transform: none;
524 }
525
526 /* Menu / disclosure openers — buttons whose job is to reveal a menu,
527 filter panel, expander, or popover. They navigate UI, they don't
528 commit anything, so they override the base `button` depth-lift back
529 to flat. Add new opener selectors here as they appear. */
530 .context-menu-btn,
531 .discover-filter-toggle,
532 .tip-toggle,
533 .bundle-toggle {
534 box-shadow: none;
535 }
536
537 .context-menu-btn:hover,
538 .discover-filter-toggle:hover,
539 .tip-toggle:hover,
540 .bundle-toggle:hover {
541 box-shadow: none;
542 }
543
544 .context-menu-btn:active,
545 .discover-filter-toggle:active,
546 .tip-toggle:active,
547 .bundle-toggle:active {
548 box-shadow: none;
549 transform: none;
550 }
551
552 /* ===========================================
553 FORMS
554 =========================================== */
555
556 form {
557 display: flex;
558 flex-direction: column;
559 gap: 1rem;
560 width: 100%;
561 }
562
563 .form-container {
564 max-width: 400px;
565 background: var(--light-background);
566 padding: 2rem;
567 }
568
569 label {
570 font-family: var(--font-mono);
571 color: var(--detail);
572 font-size: 14px;
573 }
574
575 input[type="text"],
576 input[type="email"],
577 input[type="password"],
578 input[type="number"],
579 input[type="date"],
580 textarea,
581 select {
582 width: 100%;
583 background: var(--input-background);
584 border: 1px solid var(--border);
585 padding: 0.75rem;
586 font-family: var(--font-mono);
587 font-size: 0.9rem;
588 color: var(--detail);
589 box-shadow: var(--shadow-inset);
590 }
591
592 input::placeholder,
593 textarea::placeholder {
594 opacity: 0.5;
595 }
596
597 input[type="text"]:focus,
598 input[type="email"]:focus,
599 input[type="password"]:focus,
600 input[type="number"]:focus,
601 textarea:focus,
602 select:focus {
603 outline: none;
604 border: 1px solid var(--highlight);
605 }
606
607 textarea {
608 min-height: 100px;
609 resize: vertical;
610 }
611
612 select {
613 cursor: pointer;
614 }
615
616 input[type="submit"],
617 form button {
618 font-family: var(--font-heading);
619 font-size: 16px;
620 color: var(--detail);
621 background: var(--light-background);
622 padding: 12px 24px;
623 border: 1px solid var(--detail);
624 cursor: pointer;
625 box-shadow: var(--shadow-raised);
626 transition: box-shadow 0.1s ease, transform 0.05s ease, background 0.2s ease;
627 }
628
629 input[type="submit"]:hover,
630 form button:hover {
631 background: var(--background);
632 box-shadow: 3px 3px var(--shadow-edge);
633 }
634
635 input[type="submit"]:active,
636 form button:active {
637 box-shadow: none;
638 transform: translate(2px, 2px);
639 }
640
641 .form-group {
642 margin-bottom: 1.5rem;
643 }
644
645 .form-group label {
646 display: block;
647 margin-bottom: 0.5rem;
648 font-size: 0.9rem;
649 }
650
651 .form-group input,
652 .form-group textarea,
653 .form-group select {
654 width: 100%;
655 }
656
657 .form-row {
658 display: grid;
659 grid-template-columns: 1fr 1fr;
660 gap: 1rem;
661 }
662
663 .hint {
664 font-size: 0.85rem;
665 opacity: 0.6;
666 margin-top: 0.5rem;
667 }
668
669 /* Field-level validation error, paired with .form-group--error.
670 Canonical: `partials/_ui.html` ui::form_field macro. */
671 .form-group--error label {
672 color: var(--error);
673 }
674
675 .form-group--error input,
676 .form-group--error textarea,
677 .form-group--error select {
678 border-color: var(--error);
679 }
680
681 .field-error {
682 font-size: 0.85rem;
683 color: var(--error);
684 margin-top: var(--space-2);
685 }
686
687 /* Loading skeleton placeholder.
688 Canonical: `partials/_ui.html` ui::loading_skeleton macro. */
689 .loading-skeleton {
690 background: var(--surface-muted);
691 border-radius: var(--radius-md);
692 animation: skeleton-pulse 1.2s ease-in-out infinite;
693 }
694
695 .loading-skeleton--row {
696 height: 1.25rem;
697 margin: var(--space-2) 0;
698 }
699
700 .loading-skeleton--card {
701 height: 8rem;
702 margin: var(--space-3) 0;
703 }
704
705 .loading-skeleton--list .loading-skeleton--row + .loading-skeleton--row {
706 margin-top: var(--space-2);
707 }
708
709 @keyframes skeleton-pulse {
710 0%, 100% { opacity: 0.5; }
711 50% { opacity: 0.9; }
712 }
713
714 /* Checkbox group */
715 .checkbox-group {
716 display: flex;
717 align-items: start;
718 gap: 0.75rem;
719 cursor: pointer;
720 transition: background 0.2s ease;
721 margin-bottom: 0.5rem;
722 }
723
724 .checkbox-group input[type="checkbox"] {
725 width: auto;
726 margin-top: 0.25rem;
727 margin-bottom: 0.25rem;
728 cursor: pointer;
729 }
730 /* Radio group */
731 .radio-group {
732 display: flex;
733 flex-direction: column;
734 gap: 0.75rem;
735 margin-top: 0.5rem;
736 }
737 /* ===========================================
738 TABS
739 =========================================== */
740
741 .tabs {
742 display: flex;
743 flex-wrap: nowrap;
744 gap: 0;
745 margin-bottom: 0;
746 }
747
748 .tab {
749 background: var(--surface-muted);
750 color: var(--detail);
751 border: none;
752 padding: 0.75rem 2rem;
753 font-family: var(--font-mono);
754 font-size: 1rem;
755 cursor: pointer;
756 /* Tabs navigate, they don't commit — stay flat. Overrides the base
757 `button` shadow if a tab is a <button>. */
758 box-shadow: none;
759 transition:
760 background 0.2s ease,
761 opacity 0.2s ease;
762 opacity: 0.6;
763 white-space: nowrap;
764 flex-shrink: 0;
765 }
766
767 .tab.is-selected {
768 background: var(--light-background);
769 opacity: 1;
770 }
771
772 .tab:hover {
773 opacity: 1;
774 }
775
776 .tab-more-wrap {
777 position: relative;
778 flex-shrink: 0;
779 }
780
781 .tab-overflow-menu {
782 position: absolute;
783 top: 100%;
784 right: 0;
785 z-index: 10;
786 background: var(--background);
787 border: 1px solid var(--border);
788 min-width: 180px;
789 box-shadow: var(--shadow-2);
790 }
791
792 .tab-overflow-menu .tab {
793 display: block;
794 width: 100%;
795 text-align: left;
796 padding: 0.6rem 1rem;
797 opacity: 0.7;
798 }
799
800 .tab-overflow-menu .tab:hover {
801 opacity: 1;
802 }
803
804 .tab-overflow-menu .tab.is-selected {
805 opacity: 1;
806 }
807
808 .tab-content {
809 display: none;
810 background: var(--light-background);
811 padding: 2rem;
812 }
813
814 .tab-content.active {
815 display: block;
816 }
817
818 /* ===========================================
819 TABLES
820 =========================================== */
821
822 .data-table {
823 width: 100%;
824 border-collapse: collapse;
825 font-size: 0.9rem;
826 font-family: var(--font-body);
827 margin-bottom: 1rem;
828 }
829
830 .data-table thead {
831 background: var(--surface-muted);
832 }
833
834 .data-table th {
835 text-align: left;
836 padding: 0.75rem 1rem;
837 font-weight: normal;
838 }
839
840 .data-table th.sortable {
841 cursor: pointer;
842 transition: background 0.2s ease;
843 user-select: none;
844 }
845
846 .data-table th.sortable:hover {
847 background: var(--border);
848 }
849
850 .data-table th.sortable::after {
851 content: " ^";
852 opacity: 0.3;
853 font-size: 0.8rem;
854 }
855
856 .data-table tbody tr {
857 transition: background 0.1s ease;
858 }
859
860 .data-table tbody tr:nth-child(odd) {
861 background: var(--surface-alt);
862 }
863
864 .data-table tbody tr:nth-child(even) {
865 background: var(--light-background);
866 }
867
868 .data-table tbody tr:hover {
869 background: var(--surface-muted);
870 }
871
872 .data-table td {
873 padding: 0.75rem 1rem;
874 border-top: 1px solid var(--border);
875 }
876
877 /* ===========================================
878 COMPACT TABLES (dashboard/admin — lighter than .data-table)
879 =========================================== */
880
881 .compact-table {
882 width: 100%;
883 border-collapse: collapse;
884 }
885
886 .compact-table thead tr {
887 font-size: 0.85rem;
888 opacity: 0.7;
889 }
890
891 .compact-table th {
892 padding: 0.5rem 0.75rem;
893 text-align: left;
894 }
895
896 .compact-table td {
897 padding: 0.75rem;
898 }
899
900 .compact-table tbody tr {
901 border-bottom: 1px solid var(--border);
902 }
903
904 /* ===========================================
905 UTILITIES
906 =========================================== */
907
908 .text-sm { font-size: 0.85rem; }
909 .text-xs { font-size: 0.8rem; }
910 .muted { opacity: 0.7; }
911 .dimmed { opacity: 0.6; }
912 .dimmer { opacity: 0.5; }
913 .meta { font-size: 0.85rem; opacity: 0.7; }
914 .nowrap { white-space: nowrap; }
915 .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
916 .text-center { text-align: center; }
917 .text-right { text-align: right; }
918 .fw-bold { font-weight: bold; }
919 .unstyled-link { text-decoration: none; color: inherit; }
920 .square-cover { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
921
922 /* Spacing utilities (mapped to --space-* scale).
923 mt = margin-top, mb = margin-bottom, my = vertical, mx = horizontal,
924 m0 = margin reset. Use sparingly; prefer parent layout primitives. */
925 .m-0 { margin: 0; }
926 .mt-0 { margin-top: 0; }
927 .mt-2 { margin-top: var(--space-2); }
928 .mt-3 { margin-top: var(--space-3); }
929 .mt-4 { margin-top: var(--space-4); }
930 .mt-5 { margin-top: var(--space-5); }
931 .mt-6 { margin-top: var(--space-6); }
932 .mb-0 { margin-bottom: 0; }
933 .mb-2 { margin-bottom: var(--space-2); }
934 .mb-3 { margin-bottom: var(--space-3); }
935 .mb-4 { margin-bottom: var(--space-4); }
936 .mb-5 { margin-bottom: var(--space-5); }
937 .mb-6 { margin-bottom: var(--space-6); }
938 .my-2 { margin-top: var(--space-2); margin-bottom: var(--space-2); }
939 .my-3 { margin-top: var(--space-3); margin-bottom: var(--space-3); }
940 .my-4 { margin-top: var(--space-4); margin-bottom: var(--space-4); }
941
942 /* Min-width utilities for tables inside .scroll-x wrappers. */
943 .minw-300 { min-width: 300px; }
944 .minw-400 { min-width: 400px; }
945 .minw-500 { min-width: 500px; }
946 .minw-600 { min-width: 600px; }
947 .minw-700 { min-width: 700px; }
948 .minw-800 { min-width: 800px; }
949
950 /* Compact button sizes. Canonical: .small (broad use, 0.25rem 0.6rem 0.8rem).
951 The tiny / row-btn / cart-row-btn aliases are visually equivalent — within
952 sub-pixel of each other in the original templates — and folded into .small. */
953 .small { padding: 0.25rem 0.6rem; font-size: 0.8rem; }
954
955 /* Canonical empty-state primitive. Use modifiers for tight/sized contexts.
956 Markup: <div class="empty-state">…</div> (optionally with .empty-state--compact
957 inside dropdowns or .empty-state--chart inside a fixed-height chart slot). */
958 .empty-state { text-align: center; padding: 2rem; opacity: 0.6; }
959 .empty-state--compact { padding: 0.75rem; font-size: 0.9rem; }
960 .empty-state--chart { height: 200px; padding: 0; display: flex; align-items: center; justify-content: center; opacity: 0.5; }
961 .empty-state-hint { font-family: var(--font-mono); font-size: 0.8rem; margin-top: 0.5rem; opacity: 0.6; }
962
963 .tab-docs {
964 display: flex;
965 justify-content: flex-end;
966 margin-bottom: 1rem;
967 }
968
969 .tab-docs a {
970 font-family: var(--font-mono);
971 font-size: 0.8rem;
972 opacity: 0.5;
973 transition: opacity 0.2s ease;
974 }
975
976 .tab-docs a:hover {
977 opacity: 1;
978 }
979
980 /* ===========================================
981 BADGES
982 =========================================== */
983
984 .badge {
985 display: inline-block;
986 padding: 0.2rem 0.5rem;
987 font-size: 0.75rem;
988 font-family: var(--font-mono);
989 background: var(--primary-dark);
990 color: var(--primary-light);
991 }
992
993 .badge-success,
994 .badge.active,
995 .badge.complete {
996 background: var(--success);
997 }
998
999 .badge-warning,
1000 .badge.pending,
1001 .badge.draft {
1002 background: var(--warning);
1003 }
1004
1005 .badge-danger,
1006 .badge.failed {
1007 background: var(--danger);
1008 }
1009
1010 .badge.current {
1011 background: var(--success);
1012 }
1013
1014 .badge.suppressed {
1015 background: var(--warning);
1016 }
1017
1018 .badge.suspended {
1019 background: var(--danger-bg);
1020 color: var(--danger);
1021 }
1022
1023 .badge.free {
1024 background: var(--highlight);
1025 color: var(--primary-light);
1026 }
1027
1028 /* ===========================================
1029 TAGS
1030 =========================================== */
1031
1032 .tag {
1033 display: inline-block;
1034 background: var(--primary-dark);
1035 color: var(--primary-light);
1036 padding: 0.2rem 0.4rem;
1037 font-size: 0.75rem;
1038 margin-right: 0.25rem;
1039 }
1040
1041 .tag-input {
1042 background: var(--surface-muted);
1043 padding: 0.5rem;
1044 margin-bottom: 0.5rem;
1045 display: flex;
1046 flex-wrap: wrap;
1047 gap: 0.5rem;
1048 min-height: 40px;
1049 }
1050
1051 .tag-input .tag {
1052 display: flex;
1053 align-items: center;
1054 gap: 0.5rem;
1055 padding: 0.25rem 0.5rem;
1056 font-size: 0.85rem;
1057 }
1058
1059 .tag-input .tag button {
1060 background: none;
1061 border: none;
1062 color: var(--primary-light);
1063 cursor: pointer;
1064 padding: 0;
1065 font-size: 1rem;
1066 }
1067
1068 /* ===========================================
1069 CARDS
1070 =========================================== */
1071
1072 /* Canonical card primitive (charter: docs/design-system.md).
1073 Variants:
1074 .card — filled, hover-step (default content card).
1075 .card.card-muted — surface-muted fill, no hover (dashboard stat / analytics blocks).
1076 .card.card--bordered — bordered, padded, no fill (marketing cards: feature/tier/use-case).
1077 .card.card--selectable — radio-card pattern; pair with .is-selected.
1078 .card.card--grid — grid-cell card (discover grid).
1079 Legacy class names (.stat-card, .analytics-card, .feature-card, .tier-card,
1080 .use-case-card) are aliased to these recipes below — templates migrate at
1081 their own pace. */
1082 .card {
1083 background: var(--light-background);
1084 padding: 1.5rem;
1085 margin-bottom: 1rem;
1086 text-decoration: none;
1087 color: var(--detail);
1088 display: block;
1089 border: 1px solid var(--border);
1090 box-shadow: var(--shadow-card);
1091 transition: background 0.2s ease;
1092 }
1093
1094 .card:hover {
1095 background: var(--surface-muted);
1096 }
1097
1098 /* Muted card primitive. */
1099 .card-muted {
1100 background: var(--surface-muted);
1101 padding: 1.5rem;
1102 }
1103 /* Bordered card (.card--bordered alias for .feature-card, .tier-card, .use-case-card, .fork-card). */
1104 .card--bordered,
1105 .feature-card,
1106 .tier-card,
1107 .use-case-card,
1108 .fork-card {
1109 background: transparent;
1110 padding: 1rem;
1111 border: 1px solid var(--border);
1112 margin-bottom: 0;
1113 }
1114 .use-case-card { padding: 1.25rem; }
1115 .fork-card { padding: 1.5rem; display: flex; flex-direction: column; }
1116
1117 .card-title {
1118 font-size: 1.2rem;
1119 margin-bottom: 0.5rem;
1120 font-family: var(--font-heading);
1121 }
1122
1123 .card-meta {
1124 font-size: 0.85rem;
1125 color: var(--text-muted);
1126 margin-bottom: 0.5rem;
1127 font-family: var(--font-mono);
1128 }
1129
1130 .card-description {
1131 font-size: 0.9rem;
1132 opacity: 0.8;
1133 font-family: var(--font-body);
1134 }
1135
1136 /* ===========================================
1137 STATS
1138 =========================================== */
1139
1140 .stats-grid {
1141 display: grid;
1142 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
1143 gap: 1rem;
1144 margin-bottom: 1.5rem;
1145 }
1146
1147 .stats-row {
1148 display: flex;
1149 gap: 1.5rem;
1150 margin: 1.5rem 0;
1151 }
1152
1153 .stat-box {
1154 background: var(--light-background);
1155 padding: 1rem 1.5rem;
1156 flex: 1;
1157 text-align: center;
1158 }
1159
1160 .stat-box .number {
1161 font-family: var(--font-heading);
1162 font-weight: bold;
1163 font-size: 1.5rem;
1164 }
1165
1166 .stat-box .label {
1167 font-size: 0.8rem;
1168 opacity: 0.7;
1169 }
1170
1171 /* .stat-card base recipe defined above with .card-muted */
1172
1173 .stat-label {
1174 font-size: 0.85rem;
1175 opacity: 0.7;
1176 margin-bottom: 0.25rem;
1177 }
1178
1179 .stat-value {
1180 font-size: 1.5rem;
1181 }
1182
1183 .stat-change {
1184 font-size: 0.85rem;
1185 opacity: 0.6;
1186 }
1187
1188 .stat-change.positive {
1189 color: var(--success);
1190 }
1191
1192 .stat-change.negative {
1193 color: var(--danger);
1194 }
1195
1196 /* ===========================================
1197 FILTER BAR
1198 =========================================== */
1199
1200 .filter-bar {
1201 display: flex;
1202 gap: 0.5rem;
1203 margin: 1.5rem 0;
1204 flex-wrap: wrap;
1205 align-items: center;
1206 }
1207
1208 .filter-bar > .label {
1209 font-size: 0.85rem;
1210 opacity: 0.7;
1211 margin-right: 0.5rem;
1212 }
1213
1214 .filter-bar button {
1215 padding: 0.3rem 0.8rem;
1216 font-size: 0.85rem;
1217 }
1218
1219 /* ===========================================
1220 DISCUSSION SECTION
1221 =========================================== */
1222
1223 /* Sits inside the parent container; previously had max-width: 720px and
1224 margin: 2rem auto, which looked indented on wide pages (.library-page,
1225 .item-page) where every neighbouring card filled the container. Let the
1226 parent dictate width — article-page already constrains via
1227 .article-container; player pages have their own narrow layout. */
1228 .discussion-section {
1229 margin: 2rem 0;
1230 padding: 1.5rem;
1231 border: 1px solid var(--border);
1232 font-family: var(--font-mono);
1233 }
1234
1235 .discussion-section h3 {
1236 font-family: var(--font-heading);
1237 font-size: 1.25rem;
1238 margin: 0 0 0.5rem;
1239 }
1240
1241 .discussion-section p {
1242 margin: 0 0 0.75rem;
1243 color: var(--text-muted);
1244 font-size: 0.875rem;
1245 }
1246
1247 .discussion-section a {
1248 color: var(--highlight);
1249 text-decoration: none;
1250 font-size: 0.875rem;
1251 }
1252
1253 /* ===========================================
1254 INFO & WARNING BOXES
1255 =========================================== */
1256
1257 /* Notification surface roles (charter: docs/design-system.md).
1258 Five distinct components — keep them distinct, don't merge:
1259 .toast — transient, JS-dismissible, bottom-right corner.
1260 .banner — full-bleed page-top notice (sandbox, restart,
1261 founder pricing). One short sentence + optional link.
1262 .alert — inline directive callout with uppercase mono title
1263 (NOTE / TIP / IMPORTANT / WARNING / CAUTION). Used in
1264 docs and longer-form bodies.
1265 .info-box — informational headed block with h3 + bullet list
1266 inside forms / wizards (distinct register from .alert).
1267 .warning-box — loud yellow-on-yellow attention-grabber for
1268 page-level warnings (delete confirms, account
1269 warnings). Louder than .alert-warning intentionally.
1270 .error-message — inline form-field error; hidden by default, shown
1271 with .is-active. Distinct from page-level .alert. */
1272 .info-box {
1273 background: var(--surface-muted);
1274 padding: 1rem;
1275 margin-bottom: 1rem;
1276 font-size: 0.9rem;
1277 font-family: var(--font-body);
1278 }
1279
1280 .info-box h3 {
1281 font-size: 1rem;
1282 font-weight: normal;
1283 margin-bottom: 0.5rem;
1284 }
1285
1286 .info-box ul {
1287 list-style: none;
1288 margin-top: 0.5rem;
1289 }
1290
1291 .info-box li {
1292 padding: 0.25rem 0;
1293 }
1294
1295 .info-box li::before {
1296 content: "- ";
1297 opacity: 0.5;
1298 }
1299
1300 .warning-box {
1301 background: var(--warning);
1302 color: var(--primary-light);
1303 padding: 1rem;
1304 margin-bottom: 1rem;
1305 font-size: 0.9rem;
1306 font-family: var(--font-body);
1307 }
1308
1309 .error-message {
1310 font-family: var(--font-mono);
1311 color: var(--error);
1312 background: var(--error-bg);
1313 padding: 12px;
1314 border: 1px solid var(--error);
1315 border-radius: 2px;
1316 text-align: center;
1317 font-size: 14px;
1318 display: none;
1319 }
1320
1321 /* Full-page error layout (templates/pages/error.html). Distinct from
1322 the inline `.error-message` form-error class above; named to avoid
1323 collision. */
1324 .error-page {
1325 min-height: 100vh;
1326 display: flex;
1327 align-items: center;
1328 justify-content: center;
1329 padding: var(--space-6);
1330 background: var(--background);
1331 }
1332
1333 .error-container {
1334 text-align: center;
1335 max-width: 560px;
1336 }
1337
1338 .error-status {
1339 font-size: 0.85rem;
1340 font-weight: 600;
1341 letter-spacing: 0.08em;
1342 text-transform: uppercase;
1343 color: var(--text-muted);
1344 margin-bottom: var(--space-4);
1345 }
1346
1347 .error-page-message {
1348 font-size: 1.5rem;
1349 line-height: 1.4;
1350 color: var(--detail);
1351 margin-bottom: var(--space-6);
1352 }
1353
1354 .error-actions {
1355 display: flex;
1356 gap: var(--space-4);
1357 justify-content: center;
1358 }
1359
1360 .error-actions a.primary,
1361 .error-actions a.secondary {
1362 text-decoration: none;
1363 }
1364
1365 /* Minimal direct-purchase page (templates/pages/buy.html). Standalone
1366 page used for link-in-bio sharing — no site chrome, just a card.
1367 Scoped under .buy-page so the rules don't bleed into the rest of
1368 the app. Tokenized; previously lived as a page-isolated <style>. */
1369 .buy-page {
1370 min-height: 100vh;
1371 display: flex;
1372 align-items: center;
1373 justify-content: center;
1374 padding: var(--space-6);
1375 }
1376
1377 .buy-page .buy-card {
1378 background: var(--light-background);
1379 border-radius: 12px;
1380 padding: var(--space-6);
1381 max-width: 420px;
1382 width: 100%;
1383 box-shadow: var(--shadow-3);
1384 }
1385
1386 .buy-page .cover,
1387 .buy-page .no-cover {
1388 width: 100%;
1389 aspect-ratio: 1;
1390 max-height: 280px;
1391 border-radius: 8px;
1392 margin-bottom: var(--space-5);
1393 background: var(--surface-raised);
1394 }
1395
1396 .buy-page .cover {
1397 object-fit: cover;
1398 }
1399
1400 .buy-page .no-cover {
1401 display: flex;
1402 align-items: center;
1403 justify-content: center;
1404 font-size: 3rem;
1405 opacity: 0.2;
1406 }
1407
1408 .buy-page h1 {
1409 text-align: left;
1410 font-size: 1.4rem;
1411 margin-bottom: var(--space-1);
1412 }
1413
1414 .buy-page .creator {
1415 font-family: var(--font-mono);
1416 font-size: 0.85rem;
1417 opacity: 0.6;
1418 margin-bottom: var(--space-5);
1419 }
1420
1421 .buy-page .creator a {
1422 color: inherit;
1423 }
1424
1425 .buy-page .price {
1426 font-family: var(--font-mono);
1427 font-size: 1.3rem;
1428 margin-bottom: var(--space-5);
1429 }
1430
1431 .buy-page .description {
1432 font-size: 0.9rem;
1433 line-height: 1.5;
1434 opacity: 0.8;
1435 margin-bottom: var(--space-5);
1436 max-height: 4.5em;
1437 overflow: hidden;
1438 }
1439
1440 .buy-page .buy-btn {
1441 display: block;
1442 width: 100%;
1443 padding: 14px;
1444 background: var(--highlight);
1445 color: var(--primary-light);
1446 border: none;
1447 border-radius: 6px;
1448 font-size: 1rem;
1449 font-weight: 600;
1450 cursor: pointer;
1451 text-align: center;
1452 text-decoration: none;
1453 transition: opacity 0.2s ease;
1454 }
1455
1456 .buy-page .buy-btn:hover {
1457 opacity: 0.85;
1458 }
1459
1460 .buy-page .buy-btn:disabled {
1461 opacity: 0.6;
1462 cursor: wait;
1463 }
1464
1465 .buy-page .pwyw-input {
1466 display: flex;
1467 align-items: center;
1468 gap: var(--space-1);
1469 margin-bottom: var(--space-4);
1470 }
1471
1472 .buy-page .pwyw-input input {
1473 width: 100px;
1474 padding: 8px;
1475 border: 1px solid var(--border);
1476 border-radius: var(--radius-md);
1477 font-size: 1rem;
1478 }
1479
1480 .buy-page .note {
1481 font-size: 0.8rem;
1482 opacity: 0.5;
1483 text-align: center;
1484 margin-top: var(--space-4);
1485 }
1486
1487 .buy-page .note a {
1488 color: var(--highlight);
1489 }
1490
1491 .buy-page .footer {
1492 text-align: center;
1493 margin-top: var(--space-5);
1494 padding-top: var(--space-4);
1495 border-top: 1px solid var(--border);
1496 font-size: 0.8rem;
1497 opacity: 0.5;
1498 }
1499
1500 .buy-page .footer a {
1501 color: inherit;
1502 }
1503
1504 /* Sectioned content (templates/pages/item.html, project.html,
1505 library_downloads.html). Tab+panel pattern shared by all three
1506 pages — kept global, NOT scoped under .item-page. */
1507 .section-tabs {
1508 display: flex;
1509 gap: 0;
1510 border-bottom: 1px solid var(--border);
1511 margin-bottom: var(--space-5);
1512 }
1513
1514 .section-tab {
1515 background: none;
1516 border: none;
1517 padding: 0.6rem 1.2rem;
1518 cursor: pointer;
1519 font-size: 0.95rem;
1520 opacity: 0.6;
1521 border-bottom: 2px solid transparent;
1522 font-family: var(--font-body);
1523 color: var(--text);
1524 }
1525
1526 .section-tab.is-selected {
1527 opacity: 1;
1528 border-bottom-color: var(--detail);
1529 }
1530
1531 .section-tab:hover { opacity: 0.9; }
1532
1533 /* .section-panel.active is a visibility toggle (display: none / block),
1534 not a selection — kept as .active. */
1535 .section-panel { display: none; }
1536 .section-panel.active { display: block; }
1537 .section-panel p { margin-bottom: var(--space-4); }
1538 .section-panel ul,
1539 .section-panel ol {
1540 margin-left: var(--space-5);
1541 margin-bottom: var(--space-4);
1542 }
1543 .section-panel li { margin-bottom: var(--space-2); }
1544 .section-panel h1,
1545 .section-panel h2,
1546 .section-panel h3 {
1547 margin-top: var(--space-4);
1548 margin-bottom: var(--space-2);
1549 }
1550 .section-panel pre {
1551 background: var(--surface-muted);
1552 padding: var(--space-4);
1553 overflow-x: auto;
1554 margin-bottom: var(--space-4);
1555 }
1556 .section-panel code { font-size: 0.9rem; }
1557
1558 /* Item detail page (templates/pages/item.html). Scoped under .item-page
1559 body class so the .item-title / .item-meta / .item-price / .item-footer
1560 names don't collide with the store-front item-card on project.html. */
1561 .item-page .item-layout {
1562 display: grid;
1563 grid-template-columns: 400px 1fr;
1564 gap: var(--space-6);
1565 margin-bottom: var(--space-6);
1566 }
1567
1568 .item-page .item-layout.no-media { grid-template-columns: 1fr; }
1569
1570 .item-page .item-title {
1571 font-size: 2rem;
1572 margin-bottom: var(--space-2);
1573 }
1574
1575 .item-page .item-creator {
1576 font-size: 1rem;
1577 opacity: 0.7;
1578 margin-bottom: var(--space-5);
1579 }
1580
1581 .item-page .item-creator a { color: var(--detail); }
1582
1583 .item-page .item-price {
1584 font-size: 2.5rem;
1585 margin-bottom: var(--space-5);
1586 }
1587
1588 .item-page .item-meta {
1589 display: grid;
1590 grid-template-columns: 1fr 1fr;
1591 gap: var(--space-4);
1592 margin-bottom: var(--space-5);
1593 padding-bottom: var(--space-5);
1594 border-bottom: 1px solid var(--border);
1595 }
1596
1597 .item-page .meta-item { font-size: 0.9rem; }
1598 .item-page .meta-label { opacity: 0.7; margin-bottom: var(--space-1); }
1599 .item-page .meta-value { font-weight: bold; }
1600
1601 .item-page .item-tags { margin-bottom: var(--space-5); }
1602
1603 /* purchase-box uses .card-muted for the box; only its h3/ul/li specifics remain. */
1604 .purchase-box h3 {
1605 font-size: 1rem;
1606 font-weight: normal;
1607 margin-bottom: var(--space-4);
1608 }
1609 .purchase-box ul { list-style: none; margin-bottom: var(--space-4); }
1610 .purchase-box li { padding: var(--space-1) 0; }
1611 .purchase-box li::before {
1612 content: "";
1613 opacity: 0.5;
1614 }
1615
1616 .item-page .btn-primary {
1617 width: 100%;
1618 padding: var(--space-4) var(--space-6);
1619 font-size: 1.1rem;
1620 }
1621
1622 .item-page .btn-secondary {
1623 width: 100%;
1624 margin-top: var(--space-2);
1625 }
1626
1627 .item-page .payment-note {
1628 font-size: 0.85rem;
1629 opacity: 0.6;
1630 text-align: center;
1631 margin-top: var(--space-4);
1632 }
1633
1634 /* bundle-child uses .list-row co-class; only the gap-4 override remains. */
1635 .bundle-child { gap: var(--space-4); padding: var(--space-3) 0; }
1636
1637 .item-page .bundle-child-type {
1638 font-size: 0.8rem;
1639 padding: 0.2rem 0.6rem;
1640 background: var(--surface-muted);
1641 white-space: nowrap;
1642 }
1643
1644 .item-page .bundle-child-title { flex: 1; }
1645 .item-page .bundle-child-title a { color: var(--detail); }
1646 .item-page .bundle-child-price { font-size: 0.9rem; opacity: 0.7; }
1647
1648 .item-page .bundle-notice {
1649 background: var(--surface-muted);
1650 padding: var(--space-5);
1651 margin-bottom: var(--space-5);
1652 text-align: center;
1653 }
1654
1655 .item-page .bundle-notice a { color: var(--detail); }
1656
1657 .item-page .item-description p { margin-bottom: var(--space-4); text-align: left; }
1658 .item-page .item-description ul { margin-left: var(--space-5); margin-bottom: var(--space-4); }
1659 .item-page .item-description li { margin-bottom: var(--space-2); }
1660
1661 .item-page .features-grid {
1662 display: grid;
1663 grid-template-columns: repeat(2, 1fr);
1664 gap: var(--space-5);
1665 }
1666 .item-page .version-number { font-size: 1.1rem; }
1667 .item-page .item-footer {
1668 margin-top: 3rem;
1669 padding-top: var(--space-6);
1670 border-top: 1px solid var(--border);
1671 text-align: center;
1672 opacity: 0.6;
1673 font-size: 0.85rem;
1674 }
1675
1676 .item-page .item-footer a { color: var(--detail); }
1677
1678 @media (max-width: 768px) {
1679 .item-page .item-layout { grid-template-columns: 1fr; }
1680 .item-page .features-grid { grid-template-columns: 1fr; }
1681 }
1682
1683 @media (max-width: 480px) {
1684 .item-page .item-title { font-size: 1.5rem; }
1685 .item-page .item-price { font-size: 1.8rem; }
1686 .item-page .item-meta { grid-template-columns: 1fr; gap: var(--space-2); }
1687 .item-page .item-media,
1688 .item-page .item-details { padding: var(--space-4); }
1689 .item-page .item-description { padding: var(--space-4); }
1690 .item-page .item-description h2 { font-size: 1.2rem; }
1691 .item-page .purchase-box { padding: var(--space-4); }
1692 }
1693
1694 /* Project store-front page (templates/pages/project.html). Scoped under
1695 .project-page body class — `.item-card`, `.item-title`, `.item-meta`,
1696 `.item-price`, etc. here mean store-front item cards, distinct from
1697 the item-detail-page versions scoped under .item-page above. */
1698 .project-page .store-header { margin-bottom: 3rem; }
1699 .project-page .store-title { font-size: 3rem; margin-bottom: var(--space-2); }
1700 .project-page .store-meta {
1701 font-size: 0.9rem;
1702 opacity: 0.7;
1703 margin-bottom: var(--space-5);
1704 }
1705 .project-page .store-meta a { color: var(--detail); }
1706 .project-page .store-description {
1707 font-size: 1.1rem;
1708 max-width: 800px;
1709 margin-bottom: var(--space-6);
1710 text-align: left;
1711 }
1712 .project-page .store-actions {
1713 display: flex;
1714 gap: var(--space-4);
1715 flex-wrap: wrap;
1716 }
1717
1718 .project-page .items-section { margin-bottom: 3rem; }
1719
1720 .project-page .items-grid {
1721 display: grid;
1722 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
1723 gap: var(--space-6);
1724 }
1725
1726 .project-page .item-card {
1727 background: var(--light-background);
1728 transition: background 0.2s ease;
1729 cursor: pointer;
1730 display: flex;
1731 flex-direction: column;
1732 height: 100%;
1733 }
1734
1735 .project-page .item-card:hover { background: var(--surface-muted); }
1736
1737 .project-page a.item-thumbnail {
1738 width: 100%;
1739 height: 300px;
1740 background: var(--border);
1741 display: flex;
1742 align-items: center;
1743 justify-content: center;
1744 font-size: 3rem;
1745 opacity: 0.3;
1746 text-decoration: none;
1747 }
1748
1749 .project-page a.item-thumbnail:hover { opacity: 0.5; }
1750
1751 .project-page .item-content {
1752 padding: var(--space-5);
1753 display: flex;
1754 flex-direction: column;
1755 flex-grow: 1;
1756 }
1757
1758 .project-page .item-title {
1759 font-size: 1.2rem;
1760 margin-bottom: var(--space-2);
1761 font-family: var(--font-heading);
1762 font-weight: bold;
1763 }
1764
1765 .project-page .item-title a { color: inherit; text-decoration: none; }
1766 .project-page .item-title a:hover { text-decoration: underline; }
1767
1768 .project-page .item-meta {
1769 font-size: 0.85rem;
1770 opacity: 0.7;
1771 margin-bottom: var(--space-4);
1772 }
1773
1774 .project-page .item-tags { margin-bottom: var(--space-4); }
1775
1776 .project-page .item-description {
1777 font-size: 0.9rem;
1778 margin-bottom: var(--space-4);
1779 opacity: 0.8;
1780 text-align: left;
1781 flex-grow: 1;
1782 }
1783
1784 .project-page .item-footer {
1785 display: flex;
1786 justify-content: space-between;
1787 align-items: center;
1788 margin-top: auto;
1789 }
1790
1791 .project-page .item-price { font-size: 1.3rem; }
1792 .project-page .item-stats { font-size: 0.85rem; opacity: 0.6; }
1793
1794 .project-page .store-footer {
1795 margin-top: 4rem;
1796 padding-top: var(--space-6);
1797 border-top: 1px solid var(--border);
1798 opacity: 0.6;
1799 }
1800
1801 .project-page .store-footer a { color: var(--detail); }
1802
1803 .project-page .item-content .btn-primary,
1804 .project-page .item-content .btn-secondary {
1805 width: 100%;
1806 margin-top: var(--space-4);
1807 }
1808
1809 /* project.html allows .section-tabs to wrap (other pages don't). */
1810 .project-page .section-tabs { flex-wrap: wrap; }
1811
1812 .project-page .tiers-section { margin-bottom: 3rem; }
1813
1814 .project-page .tiers-grid {
1815 display: grid;
1816 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1817 gap: var(--space-5);
1818 }
1819
1820 .project-page .tier-card {
1821 background: var(--light-background);
1822 padding: var(--space-6);
1823 display: flex;
1824 flex-direction: column;
1825 }
1826
1827 .project-page .tier-name {
1828 font-family: var(--font-heading);
1829 font-weight: bold;
1830 font-size: 1.3rem;
1831 margin-bottom: var(--space-2);
1832 }
1833
1834 .project-page .tier-price {
1835 font-size: 1.5rem;
1836 margin-bottom: var(--space-4);
1837 }
1838
1839 .project-page .tier-description {
1840 font-size: 0.9rem;
1841 opacity: 0.8;
1842 margin-bottom: var(--space-5);
1843 flex-grow: 1;
1844 text-align: left;
1845 }
1846
1847 .project-page .tier-card form { margin-top: auto; }
1848 .project-page .tier-card button,
1849 .project-page .tier-card .btn-primary { width: 100%; }
1850
1851 .project-page .tier-active-badge {
1852 font-size: 0.85rem;
1853 padding: var(--space-2) var(--space-4);
1854 background: var(--surface-muted);
1855 text-align: center;
1856 opacity: 0.7;
1857 }
1858
1859 @media (max-width: 480px) {
1860 .project-page .store-title { font-size: 2rem; }
1861 .project-page .items-grid { grid-template-columns: 1fr; }
1862 .project-page a.item-thumbnail { height: 200px; }
1863 .project-page .store-description { font-size: 1rem; }
1864 .project-page .tiers-grid { grid-template-columns: 1fr; }
1865 }
1866
1867 /* Library downloads page (templates/pages/library_downloads.html).
1868 Scoped under .library-page body class. Class names like .item-footer,
1869 .bundle-child, etc. overlap with .item-page; the scope keeps them
1870 distinct. */
1871 .library-page .library-header {
1872 display: grid;
1873 grid-template-columns: 200px 1fr;
1874 gap: var(--space-5);
1875 margin-bottom: var(--space-6);
1876 align-items: center;
1877 }
1878
1879 .library-page .library-header.no-cover { grid-template-columns: 1fr; }
1880
1881 .library-page .library-cover img {
1882 width: 100%;
1883 aspect-ratio: 1 / 1;
1884 object-fit: cover;
1885 display: block;
1886 }
1887
1888 .library-page .library-title {
1889 font-size: 2rem;
1890 margin-bottom: var(--space-1);
1891 }
1892
1893 /* Byline sits under the centered H1 (global `h1 { text-align: center }`),
1894 so center it too — otherwise it floats flush-left while the title is
1895 centered above. Same for the back-link breadcrumb. When a cover is
1896 present the grid scope below restores left-alignment in the text column. */
1897 .library-page .library-creator {
1898 font-size: 0.95rem;
1899 opacity: 0.7;
1900 margin-bottom: var(--space-4);
1901 text-align: center;
1902 }
1903
1904 .library-page .library-creator a { color: var(--detail); }
1905
1906 .library-page .library-back {
1907 font-size: 0.85rem;
1908 opacity: 0.7;
1909 text-align: center;
1910 }
1911 .library-page .library-back a { color: var(--detail); }
1912
1913 /* When a cover is present, the title block sits in the right grid column;
1914 left-align in that context so the column reads as a coherent block next
1915 to the cover instead of a centered island. */
1916 .library-page .library-header:not(.no-cover) .library-title,
1917 .library-page .library-header:not(.no-cover) .library-creator {
1918 text-align: left;
1919 }
1920
1921 .library-page .downloads-hero h2 {
1922 font-size: 1.5rem;
1923 margin-bottom: var(--space-4);
1924 padding-bottom: var(--space-2);
1925 border-bottom: 1px solid var(--border);
1926 }
1927
1928 .library-page .download-row {
1929 display: flex;
1930 align-items: center;
1931 gap: var(--space-4);
1932 padding: 0.6rem 0;
1933 border-bottom: 1px solid var(--border);
1934 }
1935
1936 .library-page .download-row:last-child { border-bottom: none; }
1937
1938 .library-page .download-version {
1939 min-width: 4em;
1940 font-family: var(--font-mono);
1941 font-size: 0.9rem;
1942 }
1943
1944 .library-page .download-label { flex: 1; }
1945
1946 .library-page .download-size {
1947 font-size: 0.85rem;
1948 opacity: 0.6;
1949 min-width: 5em;
1950 text-align: right;
1951 }
1952
1953 .library-page .download-notice {
1954 background: var(--surface-muted);
1955 padding: var(--space-5);
1956 margin-bottom: var(--space-6);
1957 font-size: 0.85rem;
1958 opacity: 0.8;
1959 }
1960
1961 .library-page .download-notice strong { font-family: var(--font-mono); }
1962
1963 /* Inline download list on library_audio.html / library_video.html
1964 (below the media player). */
1965
1966 .library-page .library-downloads h3 {
1967 font-size: 1.1rem;
1968 margin-bottom: var(--space-4);
1969 }
1970
1971 .library-page .library-section h2 {
1972 font-size: 1.3rem;
1973 margin-bottom: var(--space-4);
1974 padding-bottom: var(--space-2);
1975 border-bottom: 1px solid var(--border);
1976 }
1977
1978 .library-page .bundle-child {
1979 display: flex;
1980 align-items: center;
1981 gap: var(--space-4);
1982 padding: var(--space-3) 0;
1983 border-bottom: 1px solid var(--border);
1984 }
1985
1986 .library-page .bundle-child:last-child { border-bottom: none; }
1987
1988 .library-page .bundle-child-type {
1989 font-size: 0.8rem;
1990 padding: 0.2rem 0.6rem;
1991 background: var(--surface-muted);
1992 white-space: nowrap;
1993 }
1994
1995 .library-page .bundle-child-title { flex: 1; }
1996 .library-page .bundle-child-title a { color: var(--detail); }
1997
1998 .library-page .item-footer {
1999 margin-top: 3rem;
2000 padding-top: var(--space-6);
2001 border-top: 1px solid var(--border);
2002 text-align: center;
2003 opacity: 0.6;
2004 font-size: 0.85rem;
2005 }
2006
2007 .library-page .item-footer a { color: var(--detail); }
2008
2009 @media (max-width: 600px) {
2010 .library-page .library-header { grid-template-columns: 1fr; }
2011 .library-page .library-cover img { max-width: 200px; }
2012 }
2013
2014 /* Article reader pages (templates/pages/text_reader.html, blog_post.html,
2015 library_text.html). Long-form article layout — centered narrow column,
2016 author header, large heading, magazine-style body type. Scoped under
2017 .article-page body class. */
2018 .article-page .article-container {
2019 max-width: 680px;
2020 margin: 0 auto;
2021 padding: 3rem 1.5rem 5rem;
2022 }
2023
2024 .article-page .author-header {
2025 display: flex;
2026 align-items: center;
2027 gap: var(--space-4);
2028 margin-bottom: var(--space-6);
2029 }
2030
2031 .article-page .author-avatar {
2032 width: 48px;
2033 height: 48px;
2034 background: var(--surface-muted);
2035 border-radius: var(--radius-round);
2036 display: flex;
2037 align-items: center;
2038 justify-content: center;
2039 font-family: var(--font-heading);
2040 font-size: 1.25rem;
2041 color: var(--detail);
2042 }
2043
2044 .article-page .author-info { flex: 1; }
2045
2046 .article-page .author-name {
2047 font-family: var(--font-mono);
2048 font-size: 1rem;
2049 color: var(--detail);
2050 }
2051
2052 .article-page .author-name a {
2053 color: inherit;
2054 text-decoration: none;
2055 }
2056
2057 .article-page .author-name a:hover { text-decoration: underline; }
2058
2059 .article-page .article-meta {
2060 font-family: var(--font-mono);
2061 font-size: 0.875rem;
2062 color: var(--text-muted);
2063 }
2064
2065 .article-page .article-title {
2066 font-family: var(--font-heading);
2067 font-size: 2.5rem;
2068 font-weight: normal;
2069 line-height: 1.2;
2070 margin-bottom: var(--space-5);
2071 color: var(--detail);
2072 text-align: left;
2073 }
2074
2075 .article-page .article-deck {
2076 font-family: var(--font-mono);
2077 font-size: 1.25rem;
2078 color: var(--text-muted);
2079 margin-bottom: 2.5rem;
2080 line-height: 1.6;
2081 }
2082
2083 .article-page .article-body {
2084 font-family: var(--font-body);
2085 font-size: 1.125rem;
2086 line-height: 1.9;
2087 }
2088
2089 .article-page .article-body p { margin-bottom: var(--space-5); }
2090
2091 .article-page .article-body h1 {
2092 font-family: var(--font-heading);
2093 font-size: 2rem;
2094 font-weight: normal;
2095 margin-top: 3rem;
2096 margin-bottom: var(--space-4);
2097 color: var(--detail);
2098 text-align: left;
2099 }
2100
2101 .article-page .article-body h2 {
2102 font-family: var(--font-mono);
2103 font-size: 1.75rem;
2104 font-weight: normal;
2105 margin-top: 3rem;
2106 margin-bottom: var(--space-4);
2107 color: var(--detail);
2108 }
2109
2110 .article-page .article-body h3 {
2111 font-family: var(--font-mono);
2112 font-size: 1.375rem;
2113 font-weight: normal;
2114 margin-top: 2.5rem;
2115 margin-bottom: var(--space-3);
2116 color: var(--detail);
2117 }
2118
2119 .article-page .article-body blockquote {
2120 border-left: 3px solid var(--highlight);
2121 padding-left: var(--space-5);
2122 margin: var(--space-6) 0;
2123 font-style: italic;
2124 color: var(--text-muted);
2125 }
2126
2127 .article-page .article-body ul,
2128 .article-page .article-body ol {
2129 margin-bottom: var(--space-5);
2130 padding-left: var(--space-5);
2131 }
2132
2133 .article-page .article-body li { margin-bottom: var(--space-2); }
2134
2135 .article-page .article-body a {
2136 color: var(--highlight);
2137 text-decoration: underline;
2138 text-decoration-color: rgba(108, 92, 231, 0.4);
2139 text-underline-offset: 2px;
2140 }
2141
2142 .article-page .article-body a:hover {
2143 text-decoration-color: var(--highlight);
2144 }
2145
2146 .article-page .article-body strong { font-weight: bold; }
2147 .article-page .article-body em { font-style: italic; }
2148
2149 .article-page .article-body code {
2150 font-family: var(--font-mono);
2151 background: var(--surface-muted);
2152 padding: 0.125rem 0.375rem;
2153 font-size: 0.9em;
2154 }
2155
2156 .article-page .article-body pre {
2157 background: var(--surface-muted);
2158 padding: var(--space-4);
2159 overflow-x: auto;
2160 margin-bottom: var(--space-5);
2161 }
2162
2163 .article-page .article-body pre code {
2164 background: none;
2165 padding: 0;
2166 }
2167
2168 .article-page .article-body hr {
2169 border: none;
2170 text-align: center;
2171 margin: 3rem 0;
2172 }
2173
2174 .article-page .article-body hr::before {
2175 content: "* * *";
2176 color: var(--text-muted);
2177 letter-spacing: 1rem;
2178 }
2179
2180 .article-page .article-footer {
2181 margin-top: 4rem;
2182 padding-top: var(--space-6);
2183 border-top: 1px solid var(--border);
2184 }
2185
2186 .article-page .author-bio {
2187 display: flex;
2188 gap: var(--space-4);
2189 padding: var(--space-5);
2190 background: var(--light-background);
2191 }
2192
2193 .article-page .author-bio .author-avatar {
2194 width: 64px;
2195 height: 64px;
2196 font-size: 1.5rem;
2197 flex-shrink: 0;
2198 }
2199
2200 .article-page .author-bio-content { flex: 1; }
2201
2202 .article-page .author-bio-name {
2203 font-family: var(--font-mono);
2204 font-size: 1.125rem;
2205 margin-bottom: var(--space-2);
2206 }
2207
2208 .article-page .author-bio-name a {
2209 color: inherit;
2210 text-decoration: none;
2211 }
2212
2213 .article-page .author-bio-name a:hover { text-decoration: underline; }
2214
2215 .article-page .article-tags {
2216 margin-top: var(--space-6);
2217 display: flex;
2218 gap: var(--space-2);
2219 flex-wrap: wrap;
2220 }
2221
2222 .article-page .article-tag {
2223 font-family: var(--font-mono);
2224 background: var(--surface-muted);
2225 color: var(--detail);
2226 padding: 0.375rem 0.75rem;
2227 font-size: 0.8125rem;
2228 text-decoration: none;
2229 }
2230
2231 .article-page .text-reader-footer {
2232 font-family: var(--font-mono);
2233 text-align: center;
2234 padding: var(--space-6);
2235 font-size: 0.875rem;
2236 color: var(--text-muted);
2237 border-top: 1px solid var(--border);
2238 }
2239
2240 .article-page .text-reader-footer a {
2241 color: var(--detail);
2242 text-decoration: none;
2243 }
2244
2245 .article-page .text-reader-footer a:hover { text-decoration: underline; }
2246
2247 /* Blog-specific: nav crumb above the article. */
2248 .article-page .blog-nav {
2249 font-family: var(--font-mono);
2250 font-size: 0.875rem;
2251 margin-bottom: var(--space-6);
2252 }
2253
2254 .article-page .blog-nav a { color: var(--detail); text-decoration: none; }
2255 .article-page .blog-nav a:hover { text-decoration: underline; }
2256
2257 @media (max-width: 600px) {
2258 .article-page .article-title { font-size: 2rem; }
2259 .article-page .article-deck { font-size: 1.125rem; }
2260 .article-page .article-body { font-size: 1rem; }
2261 }
2262
2263 /* Admin dashboards (templates/dashboards/admin-*.html). Every admin
2264 page had a duplicate `h1 { font-size: 2rem; margin-bottom: 0.5rem; }`
2265 inline — consolidated here. */
2266
2267 /* System health dashboard (templates/pages/health.html). */
2268 .health-page {
2269 padding: var(--space-6);
2270 }
2271
2272 .health-page .health-container {
2273 max-width: 900px;
2274 margin: 0 auto;
2275 }
2276
2277 .health-page .health-grid {
2278 display: grid;
2279 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
2280 gap: var(--space-5);
2281 margin-bottom: var(--space-6);
2282 }
2283
2284 .health-page .health-card {
2285 background: var(--surface-muted);
2286 padding: var(--space-5);
2287 }
2288
2289 .health-page .health-card h3 {
2290 font-family: var(--font-mono);
2291 font-size: 0.9rem;
2292 margin-bottom: var(--space-4);
2293 display: flex;
2294 align-items: center;
2295 gap: var(--space-2);
2296 }
2297
2298 .health-page .status-indicator {
2299 width: 10px;
2300 height: 10px;
2301 border-radius: var(--radius-round);
2302 display: inline-block;
2303 }
2304
2305 .health-page .status-ok { background: var(--health-ok); }
2306 .health-page .status-warn { background: var(--health-warn); }
2307 .health-page .status-error { background: var(--health-error); }
2308 .health-page .status-unknown { background: var(--health-unknown); }
2309
2310 .health-page .health-card dl {
2311 display: grid;
2312 grid-template-columns: auto 1fr;
2313 gap: var(--space-2) var(--space-4);
2314 font-size: 0.85rem;
2315 }
2316
2317 .health-page .health-card dt { opacity: 0.7; }
2318 .health-page .health-card dd {
2319 font-family: var(--font-mono);
2320 text-align: right;
2321 }
2322
2323 .health-page .section-title {
2324 font-family: var(--font-mono);
2325 font-size: 1rem;
2326 margin: var(--space-6) 0 var(--space-4);
2327 padding-bottom: var(--space-2);
2328 border-bottom: 1px solid var(--border);
2329 }
2330 .health-page .test-list {
2331 list-style: none;
2332 padding: 0;
2333 margin: 0;
2334 }
2335
2336 .health-page .test-list li {
2337 display: flex;
2338 justify-content: space-between;
2339 padding: var(--space-2) 0;
2340 border-bottom: 1px solid var(--border);
2341 font-size: 0.85rem;
2342 }
2343
2344 .health-page .test-list li:last-child { border-bottom: none; }
2345
2346 .health-page .test-name { font-family: var(--font-mono); }
2347
2348 .health-page .test-pass { color: var(--health-ok); }
2349 .health-page .test-fail { color: var(--health-error); }
2350 .health-page .summary-bar {
2351 display: flex;
2352 gap: var(--space-6);
2353 padding: var(--space-4);
2354 background: var(--surface-muted);
2355 margin-bottom: var(--space-6);
2356 font-family: var(--font-mono);
2357 font-size: 0.9rem;
2358 }
2359
2360 .health-page .summary-item {
2361 display: flex;
2362 align-items: center;
2363 gap: var(--space-2);
2364 }
2365
2366 .health-page .timestamp {
2367 font-size: 0.8rem;
2368 opacity: 0.6;
2369 text-align: right;
2370 margin-top: var(--space-6);
2371 }
2372
2373 .health-page details.check-list {
2374 background: var(--light-background);
2375 padding: var(--space-5);
2376 margin-bottom: var(--space-6);
2377 }
2378
2379 .health-page details.check-list summary {
2380 font-family: var(--font-mono);
2381 font-size: 0.9rem;
2382 cursor: pointer;
2383 list-style: none;
2384 display: flex;
2385 align-items: center;
2386 gap: var(--space-2);
2387 }
2388
2389 .health-page details.check-list summary::-webkit-details-marker { display: none; }
2390
2391 .health-page details.check-list summary::before {
2392 content: "";
2393 font-size: 0.6rem;
2394 transition: transform 0.15s;
2395 }
2396
2397 .health-page details.check-list[open] summary::before {
2398 transform: rotate(90deg);
2399 }
2400
2401 .health-page details.check-list .test-list {
2402 margin-top: var(--space-4);
2403 }
2404 /* Import data wizard (templates/dashboards/dashboard-import.html).
2405 Page-specific upload + column-mapping + progress flow. Migration also
2406 fixed token bypasses: --border-color → --border, --accent → --highlight,
2407 --success-background → --success-bg, --error-background → --error-bg. */
2408
2409 .import-page .back-link {
2410 display: inline-block;
2411 margin-bottom: var(--space-5);
2412 font-size: 0.9rem;
2413 opacity: 0.7;
2414 }
2415
2416 .import-page .back-link:hover { opacity: 1; }
2417
2418 .import-page .form-group { margin-bottom: var(--space-5); }
2419
2420 .import-page .form-group label {
2421 display: block;
2422 font-family: var(--font-mono);
2423 font-size: 0.9rem;
2424 font-weight: bold;
2425 margin-bottom: var(--space-2);
2426 }
2427
2428 .import-page .form-group select,
2429 .import-page .form-group input[type="file"] {
2430 width: 100%;
2431 padding: var(--space-2);
2432 font-size: 0.9rem;
2433 border: 1px solid var(--border);
2434 background: var(--background);
2435 }
2436
2437 .import-page .csv-preview {
2438 margin-top: var(--space-4);
2439 overflow-x: auto;
2440 }
2441
2442 .import-page .csv-preview table {
2443 width: 100%;
2444 border-collapse: collapse;
2445 font-size: 0.85rem;
2446 }
2447
2448 .import-page .csv-preview th,
2449 .import-page .csv-preview td {
2450 padding: 0.4rem 0.6rem;
2451 border: 1px solid var(--border);
2452 text-align: left;
2453 }
2454
2455 .import-page .csv-preview th {
2456 background: var(--surface-muted);
2457 font-family: var(--font-mono);
2458 }
2459
2460 .import-page .column-mapping { margin-top: var(--space-4); }
2461
2462 .import-page .mapping-row {
2463 display: flex;
2464 align-items: center;
2465 gap: var(--space-4);
2466 margin-bottom: var(--space-2);
2467 }
2468
2469 .import-page .mapping-row label {
2470 min-width: 100px;
2471 font-size: 0.85rem;
2472 font-family: var(--font-mono);
2473 margin-bottom: 0;
2474 }
2475
2476 .import-page .mapping-row select {
2477 flex: 1;
2478 padding: 0.3rem;
2479 font-size: 0.85rem;
2480 }
2481
2482 .import-page .progress-stats {
2483 display: flex;
2484 gap: var(--space-6);
2485 font-size: 0.85rem;
2486 font-family: var(--font-mono);
2487 }
2488
2489 .import-page .progress-stats .stat-value { font-weight: bold; }
2490
2491 .import-page .import-result {
2492 padding: var(--space-4);
2493 margin-bottom: var(--space-4);
2494 font-size: 0.9rem;
2495 }
2496
2497 .import-page .import-result.success { background: var(--success-bg); }
2498 .import-page .import-result.error { background: var(--error-bg); }
2499
2500 .import-page .error-log {
2501 margin-top: var(--space-4);
2502 padding: var(--space-2);
2503 background: var(--surface-muted);
2504 font-family: var(--font-mono);
2505 font-size: 0.8rem;
2506 max-height: 200px;
2507 overflow-y: auto;
2508 white-space: pre-wrap;
2509 }
2510
2511 .import-page .import-history { margin-top: var(--space-6); }
2512
2513 .import-page .history-table {
2514 width: 100%;
2515 border-collapse: collapse;
2516 font-size: 0.85rem;
2517 }
2518
2519 .import-page .history-table th,
2520 .import-page .history-table td {
2521 padding: var(--space-2);
2522 border-bottom: 1px solid var(--border);
2523 text-align: left;
2524 }
2525
2526 .import-page .history-table th {
2527 font-family: var(--font-mono);
2528 font-weight: bold;
2529 }
2530
2531 .import-page .status-badge {
2532 display: inline-block;
2533 padding: 0.15rem 0.5rem;
2534 font-size: 0.8rem;
2535 font-family: var(--font-mono);
2536 }
2537
2538 .import-page .status-badge.completed { color: var(--success); }
2539 .import-page .status-badge.processing { color: var(--highlight); }
2540 .import-page .status-badge.failed { color: var(--danger); }
2541 .import-page .status-badge.pending { opacity: 0.6; }
2542
2543 .import-page .import-note {
2544 background: var(--surface-muted);
2545 padding: var(--space-4);
2546 margin-top: var(--space-6);
2547 font-size: 0.9rem;
2548 }
2549
2550 .import-page .import-note h3 {
2551 font-family: var(--font-mono);
2552 font-size: 0.9rem;
2553 margin-bottom: var(--space-2);
2554 }
2555
2556 /* Delete account page (templates/dashboards/dashboard-delete-account.html).
2557 Overrides .warning-box to use --danger (delete is danger, not warning)
2558 and the .form-status partial styling. Scoped to keep the global versions
2559 intact for other pages. */
2560
2561 .delete-account-page .warning-box {
2562 background: var(--danger);
2563 color: var(--primary-light);
2564 padding: var(--space-5);
2565 margin-bottom: var(--space-6);
2566 }
2567
2568 .delete-account-page .warning-box h3 {
2569 font-family: var(--font-mono);
2570 font-size: 1rem;
2571 margin-bottom: var(--space-2);
2572 }
2573
2574 .delete-account-page .warning-box ul {
2575 margin: var(--space-2) 0 0 var(--space-5);
2576 font-size: 0.9rem;
2577 }
2578
2579 .delete-account-page .warning-box li { margin-bottom: var(--space-1); }
2580
2581 .delete-account-page .export-prompt {
2582 background: var(--surface-muted);
2583 padding: var(--space-5);
2584 margin-bottom: var(--space-6);
2585 }
2586
2587 .delete-account-page .export-prompt h3 {
2588 font-family: var(--font-mono);
2589 font-size: 1rem;
2590 margin-bottom: var(--space-2);
2591 }
2592
2593 .delete-account-page .export-prompt p {
2594 font-size: 0.9rem;
2595 margin-bottom: var(--space-4);
2596 }
2597
2598 .delete-account-page .delete-form {
2599 background: var(--light-background);
2600 padding: var(--space-5);
2601 }
2602
2603 .delete-account-page .delete-form .form-group { margin-bottom: var(--space-5); }
2604
2605 .delete-account-page .delete-form label {
2606 display: block;
2607 margin-bottom: var(--space-2);
2608 font-family: var(--font-mono);
2609 font-size: 0.9rem;
2610 }
2611
2612 .delete-account-page .delete-form .hint {
2613 font-size: 0.85rem;
2614 opacity: 0.7;
2615 margin-top: var(--space-1);
2616 }
2617
2618 .delete-account-page .delete-form input[type="text"] {
2619 width: 100%;
2620 padding: var(--space-3);
2621 font-size: 1rem;
2622 border: 2px solid var(--border);
2623 background: var(--input-background);
2624 }
2625
2626 .delete-account-page .delete-form input[type="text"]:focus {
2627 border-color: var(--danger);
2628 outline: none;
2629 }
2630
2631 .delete-account-page .back-link {
2632 display: inline-block;
2633 margin-bottom: var(--space-5);
2634 font-size: 0.9rem;
2635 opacity: 0.7;
2636 }
2637
2638 .delete-account-page .back-link:hover { opacity: 1; }
2639
2640 .delete-account-page .form-actions {
2641 display: flex;
2642 gap: var(--space-4);
2643 align-items: center;
2644 }
2645
2646 .delete-account-page .form-status { font-size: 0.9rem; }
2647 .delete-account-page .form-status.error { color: var(--danger); }
2648 .delete-account-page .form-status.success { color: var(--success); }
2649
2650 /* Export data page (templates/dashboards/dashboard-export.html).
2651 `.export-card` and its inner classes (`-info`, `-title`, `-desc`, `-meta`)
2652 are intentionally page-scoped: this is a row-layout card (info on left,
2653 action button on right, flex justify-between) that doesn't fit `.card-muted`
2654 cleanly. Background uses `--light-background` rather than `--surface-muted`
2655 for visual distinction from the surrounding dashboard surface. */
2656
2657 .export-page .export-cards {
2658 display: grid;
2659 gap: var(--space-4);
2660 }
2661
2662 .export-page .export-card {
2663 background: var(--light-background);
2664 padding: var(--space-5);
2665 display: flex;
2666 justify-content: space-between;
2667 align-items: flex-start;
2668 gap: var(--space-4);
2669 }
2670
2671 .export-page .export-card-info { flex: 1; }
2672
2673 .export-page .export-card-title {
2674 font-family: var(--font-mono);
2675 font-weight: bold;
2676 font-size: 1.1rem;
2677 margin-bottom: var(--space-2);
2678 }
2679
2680 .export-page .export-card-desc {
2681 font-size: 0.9rem;
2682 opacity: 0.8;
2683 margin-bottom: var(--space-2);
2684 }
2685
2686 .export-page .export-card-meta {
2687 font-size: 0.8rem;
2688 opacity: 0.6;
2689 }
2690
2691 .export-page .export-card button { white-space: nowrap; }
2692
2693 .export-page .export-note {
2694 background: var(--surface-muted);
2695 padding: var(--space-4);
2696 margin-top: var(--space-6);
2697 font-size: 0.9rem;
2698 }
2699
2700 .export-page .export-note h3 {
2701 font-family: var(--font-mono);
2702 font-size: 0.9rem;
2703 margin-bottom: var(--space-2);
2704 }
2705
2706 .export-page .back-link {
2707 display: inline-block;
2708 margin-bottom: var(--space-5);
2709 font-size: 0.9rem;
2710 opacity: 0.7;
2711 }
2712
2713 .export-page .back-link:hover { opacity: 1; }
2714
2715 .export-page .export-status {
2716 margin-top: var(--space-2);
2717 font-size: 0.85rem;
2718 }
2719
2720 .export-page .export-status.success { color: var(--success); }
2721 .export-page .export-status.error { color: var(--danger); }
2722
2723 /* Receipt page (templates/pages/receipt.html). */
2724
2725 .receipt-page .receipt-header {
2726 display: flex;
2727 justify-content: space-between;
2728 align-items: flex-start;
2729 margin-bottom: var(--space-6);
2730 padding-bottom: var(--space-5);
2731 border-bottom: 1px solid var(--border);
2732 }
2733
2734 .receipt-page .receipt-row {
2735 display: flex;
2736 justify-content: space-between;
2737 padding: var(--space-2) 0;
2738 font-size: 0.95rem;
2739 }
2740
2741 .receipt-page .receipt-row.total {
2742 font-weight: bold;
2743 font-size: 1.1rem;
2744 border-top: 1px solid var(--border);
2745 padding-top: var(--space-4);
2746 margin-top: var(--space-2);
2747 }
2748
2749 .receipt-page .receipt-label { opacity: 0.7; }
2750
2751 .receipt-page .receipt-footer {
2752 margin-top: var(--space-6);
2753 padding-top: var(--space-5);
2754 border-top: 1px solid var(--border);
2755 font-size: 0.85rem;
2756 opacity: 0.6;
2757 }
2758
2759 .receipt-page .back-link {
2760 display: inline-block;
2761 margin-bottom: var(--space-5);
2762 font-size: 0.9rem;
2763 opacity: 0.7;
2764 }
2765
2766 .receipt-page .back-link:hover { opacity: 1; }
2767
2768 @media print {
2769 .receipt-page .back-link,
2770 .receipt-page .site-header,
2771 .receipt-page .print-btn { display: none !important; }
2772 .receipt-page .receipt-box { border: 1px solid var(--border); }
2773 }
2774
2775 /* Fan+ subscription page (templates/pages/fan_plus.html). */
2776 .fan-plus-page h1 { font-size: 2.5rem; margin-bottom: var(--space-2); }
2777 .fan-plus-page h2 { font-size: 1.5rem; margin-top: var(--space-6); margin-bottom: var(--space-4); }
2778
2779 .fan-plus-page .fan-plus-section { margin-bottom: var(--space-6); line-height: 1.7; }
2780 .fan-plus-page .fan-plus-section ul { padding-left: var(--space-5); margin: var(--space-3) 0; }
2781 .fan-plus-page .fan-plus-section li { margin-bottom: var(--space-2); }
2782
2783 .fan-plus-page .price-callout {
2784 font-size: 1.3rem;
2785 font-family: var(--font-mono);
2786 margin: var(--space-5) 0;
2787 }
2788
2789 .fan-plus-page .subscribe-form { margin: var(--space-6) 0; }
2790
2791 .fan-plus-page .subscribe-btn {
2792 display: inline-block;
2793 padding: var(--space-3) var(--space-6);
2794 background: var(--highlight);
2795 color: var(--primary-light);
2796 border: none;
2797 font-size: 1.1rem;
2798 cursor: pointer;
2799 font-family: var(--font-mono);
2800 }
2801
2802 .fan-plus-page .subscribe-btn:hover { opacity: 0.9; }
2803
2804 .fan-plus-page .status-box {
2805 padding: var(--space-5);
2806 background: var(--light-background);
2807 margin: var(--space-5) 0;
2808 }
2809
2810 .fan-plus-page .status-box p { margin: var(--space-2) 0; }
2811
2812 .fan-plus-page .success-banner {
2813 padding: var(--space-4) var(--space-5);
2814 background: var(--success-bg);
2815 margin-bottom: var(--space-5);
2816 font-family: var(--font-mono);
2817 }
2818
2819 .fan-plus-page .login-link { font-family: var(--font-mono); }
2820
2821 /* Purchase confirmation page (templates/pages/purchase.html). */
2822 .purchase-page .container {
2823 max-width: 800px;
2824 margin: var(--space-6) auto;
2825 padding: 0 var(--space-6);
2826 }
2827
2828 .purchase-page .tagline {
2829 font-size: 0.85rem;
2830 opacity: 0.7;
2831 margin-bottom: var(--space-6);
2832 text-align: center;
2833 }
2834
2835 .purchase-page .checkout-box { margin-bottom: var(--space-5); }
2836
2837 .purchase-page h2 { font-size: 1.8rem; margin-bottom: var(--space-2); }
2838
2839 .purchase-page .step-indicator {
2840 font-size: 0.85rem;
2841 opacity: 0.6;
2842 margin-bottom: var(--space-5);
2843 }
2844
2845 .purchase-page .item-summary {
2846 background: var(--background);
2847 padding: var(--space-5);
2848 margin-bottom: var(--space-5);
2849 display: flex;
2850 gap: var(--space-5);
2851 }
2852
2853 .purchase-page .item-thumbnail {
2854 width: 120px;
2855 height: 120px;
2856 background: var(--surface-muted);
2857 flex-shrink: 0;
2858 display: flex;
2859 align-items: center;
2860 justify-content: center;
2861 font-size: 3rem;
2862 opacity: 0.3;
2863 }
2864
2865 .purchase-page .item-details { flex: 1; }
2866
2867 .purchase-page .item-title {
2868 font-size: 1.2rem;
2869 margin-bottom: var(--space-2);
2870 font-family: var(--font-heading);
2871 font-weight: bold;
2872 }
2873
2874 .purchase-page .item-creator {
2875 font-size: 0.9rem;
2876 opacity: 0.7;
2877 margin-bottom: var(--space-4);
2878 }
2879
2880 .purchase-page .item-creator a { color: var(--detail); }
2881 .purchase-page .item-description { font-size: 0.9rem; opacity: 0.8; }
2882
2883 .purchase-page .price-breakdown {
2884 background: var(--background);
2885 padding: var(--space-5);
2886 margin-bottom: var(--space-5);
2887 }
2888
2889 .purchase-page .price-breakdown h2 { font-size: 1.1rem; margin-bottom: var(--space-4); }
2890
2891 .purchase-page .price-row {
2892 display: flex;
2893 justify-content: space-between;
2894 padding: var(--space-2) 0;
2895 border-bottom: 1px solid var(--border);
2896 }
2897
2898 .purchase-page .price-row:last-child {
2899 border-bottom: none;
2900 margin-top: var(--space-2);
2901 font-size: 1.2rem;
2902 padding-top: var(--space-4);
2903 border-top: 2px solid var(--border);
2904 }
2905
2906 .purchase-page .price-row.total { font-weight: bold; }
2907
2908 .purchase-page .payment-section { margin-bottom: var(--space-5); }
2909 .purchase-page .payment-section h2 { font-size: 1.1rem; margin-bottom: var(--space-4); }
2910
2911 .purchase-page .btn-primary { width: 100%; }
2912 .purchase-page .btn-secondary { width: 100%; margin-top: var(--space-4); }
2913
2914 .purchase-page .security-note {
2915 font-size: 0.85rem;
2916 opacity: 0.6;
2917 text-align: center;
2918 margin-top: var(--space-4);
2919 }
2920
2921 /* Replaces inline styles in pages/purchase.html. */
2922 .purchase-page h1 { text-align: center; }
2923
2924 .purchase-page .price-breakdown-note {
2925 margin-top: var(--space-2);
2926 font-size: 0.8rem;
2927 opacity: 0.6;
2928 }
2929
2930 .purchase-page .creator-breakdown {
2931 background: var(--background);
2932 padding: var(--space-4) var(--space-5);
2933 margin-bottom: var(--space-5);
2934 font-size: 0.9rem;
2935 }
2936 .purchase-page .creator-breakdown h2 {
2937 font-size: 0.95rem;
2938 margin-bottom: var(--space-3);
2939 opacity: 0.7;
2940 }
2941 .purchase-page .creator-breakdown .price-row { opacity: 0.8; }
2942 .purchase-page .creator-breakdown .price-row.is-total {
2943 opacity: 1;
2944 font-weight: bold;
2945 border-top: 1px solid var(--border);
2946 margin-top: var(--space-2);
2947 padding-top: var(--space-2);
2948 /* override .price-row:last-child upsize */
2949 font-size: inherit;
2950 border-bottom: none;
2951 }
2952 .purchase-page .creator-breakdown .platform-fee-amount { color: var(--detail); }
2953 .purchase-page .creator-breakdown-note {
2954 margin-top: var(--space-3);
2955 font-size: 0.85rem;
2956 opacity: 0.6;
2957 }
2958
2959 .purchase-page .payment-section-lead {
2960 margin-bottom: var(--space-5);
2961 opacity: 0.8;
2962 }
2963
2964 .purchase-page .pending-checkout {
2965 margin-bottom: var(--space-5);
2966 background: var(--surface-muted);
2967 padding: 1rem 1.25rem;
2968 }
2969 .purchase-page .pending-checkout p { margin: 0 0 var(--space-3); }
2970 .purchase-page .pending-checkout p.is-sub {
2971 font-size: 0.9rem;
2972 opacity: 0.8;
2973 }
2974 .purchase-page .pending-checkout form { margin: 0; }
2975
2976 /* Checkout form field wrappers. */
2977 .purchase-page .checkout-field { margin-bottom: var(--space-4); }
2978 .purchase-page .checkout-field-label {
2979 font-size: 0.85rem;
2980 display: block;
2981 margin-bottom: 0.25rem;
2982 }
2983 .purchase-page .pwyw-row {
2984 display: flex;
2985 align-items: center;
2986 gap: 0.25rem;
2987 }
2988 .purchase-page .pwyw-symbol { font-size: 1.1rem; }
2989 .purchase-page .pwyw-input { width: 120px; }
2990 .purchase-page .pwyw-min-note {
2991 font-size: 0.8rem;
2992 opacity: 0.6;
2993 margin-top: 0.25rem;
2994 }
2995 .purchase-page .promo-input {
2996 width: 200px;
2997 text-transform: uppercase;
2998 }
2999 .purchase-page .share-contact-label {
3000 font-size: 0.85rem;
3001 display: flex;
3002 align-items: center;
3003 gap: 0.4rem;
3004 cursor: pointer;
3005 }
3006 .purchase-page .share-contact-checkbox { width: auto; }
3007
3008 .purchase-page .cart-alt-link {
3009 text-align: center;
3010 margin-top: var(--space-3);
3011 font-size: 0.85rem;
3012 opacity: 0.7;
3013 }
3014 .purchase-page .guest-hint {
3015 font-size: 0.8rem;
3016 opacity: 0.6;
3017 margin-top: var(--space-3);
3018 text-align: center;
3019 }
3020 .purchase-page .guest-login-prompt {
3021 font-size: 0.8rem;
3022 margin-top: var(--space-2);
3023 text-align: center;
3024 }
3025
3026 /* ===========================================
3027 PROJECT SETTINGS TAB
3028 (replaces inline styles in partials/tabs/project_settings.html and
3029 related innerHTML in static/project-sections.js)
3030 =========================================== */
3031
3032 .proj-image-hint {
3033 font-size: 0.85rem;
3034 opacity: 0.7;
3035 margin: 0 0 var(--space-2);
3036 }
3037
3038 /* Canonical inline form-status text following a Save / Change button.
3039 Two class names because templates evolved with both — they're aliases.
3040 States via .success / .error / .saving modifier. */
3041 .field-status,
3042 .save-status {
3043 margin-left: var(--space-2);
3044 font-size: 0.85rem;
3045 }
3046 .field-status.success, .save-status.success { color: var(--success); }
3047 .field-status.error, .save-status.error { color: var(--error); }
3048 .field-status.saving, .save-status.saving { opacity: 0.6; }
3049
3050 /* Muted lead paragraph above a form button (monetization / features / delete). */
3051 .section-lead {
3052 margin-bottom: var(--space-4);
3053 opacity: 0.7;
3054 text-align: left;
3055 }
3056
3057 /* Large intro paragraph under a page h1 (creators, policy, changelog, fan_plus). */
3058 .page-intro {
3059 font-size: 1.1rem;
3060 margin-bottom: var(--space-6);
3061 line-height: 1.6;
3062 }
3063
3064 .subscription-note p {
3065 opacity: 0.7;
3066 font-size: 0.9rem;
3067 }
3068
3069 .features-grid-status {
3070 margin-top: var(--space-2);
3071 display: inline-block;
3072 }
3073
3074 /* "Pages" disclosure (project-level markdown sections). */
3075 .pages-toggle { margin-top: var(--space-6); }
3076 .pages-toggle > summary { cursor: pointer; }
3077 .pages-toggle > summary h2 { display: inline; }
3078 .pages-intro {
3079 font-size: 0.85rem;
3080 opacity: 0.7;
3081 margin: 0.75rem 0 var(--space-4);
3082 }
3083
3084 /* psection-* mirrors section-mgmt-* (used by item_details) but psection
3085 class hooks are also queried by static/project-sections.js. */
3086 .psection-row-title { flex: 1; font-weight: bold; }
3087 .psection-row-anchor { font-size: 0.75rem; opacity: 0.6; }
3088 .psection-row-length { font-size: 0.8rem; opacity: 0.6; }
3089
3090 .psection-edit-btn,
3091 .psection-del-btn {
3092 padding: 0.25rem 0.6rem;
3093 font-size: 0.8rem;
3094 }
3095
3096 .psection-add-details { margin-top: var(--space-4); }
3097 .psection-add-details > summary {
3098 cursor: pointer;
3099 font-size: 0.95rem;
3100 }
3101 .psection-add-fields { margin-top: var(--space-3); }
3102
3103 .psection-edit-modal {
3104 margin-top: var(--space-4);
3105 padding: var(--space-4);
3106 background: var(--surface-muted);
3107 }
3108 .psection-edit-actions {
3109 display: flex;
3110 gap: var(--space-2);
3111 }
3112
3113 /* ===========================================
3114 CART PAGE (replaces inline styles in pages/cart.html)
3115 =========================================== */
3116
3117 .cart-empty {
3118 text-align: center;
3119 padding: 3rem 1rem;
3120 }
3121 .cart-empty-hint {
3122 font-size: 0.9rem;
3123 opacity: 0.7;
3124 margin-bottom: var(--space-5);
3125 }
3126
3127 /* Multi-creator summary bar (only renders when seller_groups.len() > 1). */
3128 .cart-multi-bar-note {
3129 opacity: 0.7;
3130 margin-left: var(--space-2);
3131 }
3132 .cart-multi-bar-form {
3133 display: flex;
3134 align-items: center;
3135 gap: var(--space-3);
3136 }
3137 .cart-share-label {
3138 font-size: 0.85rem;
3139 display: flex;
3140 align-items: center;
3141 gap: var(--space-2);
3142 }
3143
3144 /* Per-seller group card. */
3145 .cart-group { margin-bottom: var(--space-6); }
3146 .cart-group-title { margin-bottom: 0.25rem; }
3147 .cart-group-count {
3148 font-size: 0.85rem;
3149 opacity: 0.6;
3150 margin-bottom: var(--space-4);
3151 }
3152
3153 /* PWYW editable price cell. */
3154 .cart-pwyw-cell {
3155 display: flex;
3156 align-items: center;
3157 justify-content: flex-end;
3158 gap: 0.25rem;
3159 }
3160 .cart-pwyw-symbol { font-size: 0.9rem; }
3161
3162 /* Compact action button used in cart/wishlist tables. */
3163
3164 /* Bottom summary row of each seller group. */
3165 .cart-group-summary {
3166 margin-top: var(--space-4);
3167 display: flex;
3168 justify-content: space-between;
3169 align-items: center;
3170 flex-wrap: wrap;
3171 gap: var(--space-3);
3172 }
3173 .cart-subtotal {
3174 font-family: var(--font-heading);
3175 font-size: 1.1rem;
3176 }
3177 .cart-fee-line {
3178 font-size: 0.85rem;
3179 opacity: 0.6;
3180 }
3181 .cart-savings {
3182 font-size: 0.85rem;
3183 color: var(--accent);
3184 margin-top: 0.25rem;
3185 }
3186 .cart-stripe-not-ready {
3187 font-size: 0.9rem;
3188 opacity: 0.6;
3189 }
3190
3191 /* Checkout form within a seller group. */
3192 .cart-promo-row { margin-bottom: var(--space-2); }
3193 .cart-checkout-share {
3194 display: flex;
3195 align-items: center;
3196 gap: var(--space-2);
3197 font-size: 0.85rem;
3198 margin-bottom: var(--space-2);
3199 }
3200
3201 /* Wishlist suggestions section below the cart. */
3202 .cart-wishlist { margin-top: var(--space-6); }
3203
3204 /* Generic "faded out" row state — used by Add-to-Cart click handler in cart.html
3205 to indicate the wishlist row has been moved into the cart. */
3206 .is-faded { opacity: 0.4; }
3207
3208 /* ===========================================
3209 PROFILE TAB (replaces inline styles in partials/tabs/user_profile.html)
3210 =========================================== */
3211
3212 /* Inline form row: input(s) + button laid out horizontally, bottom-aligned.
3213 Distinct from .form-row (which is a 1fr 1fr grid). */
3214 .field-row {
3215 display: flex;
3216 gap: var(--space-3);
3217 align-items: flex-end;
3218 }
3219 .field-row > .form-group { margin-bottom: 0; }
3220 .field-row > .form-group.is-grow { flex: 1; }
3221 .field-row > .form-group.is-grow-2 { flex: 2; }
3222 .field-row > button { margin-bottom: 0; }
3223
3224 /* Custom domain section. */
3225 .profile-domain-header { margin-bottom: var(--space-4); }
3226 .profile-domain-status {
3227 margin-left: var(--space-2);
3228 }
3229 .profile-domain-status.is-verified { color: var(--success); }
3230 .profile-domain-status.is-pending { color: var(--warning); }
3231
3232 .dns-row {
3233 display: flex;
3234 align-items: center;
3235 gap: var(--space-2);
3236 margin-bottom: var(--space-2);
3237 }
3238 .dns-row:last-of-type { margin-bottom: 0; }
3239 .dns-row-label {
3240 font-size: 0.8rem;
3241 opacity: 0.7;
3242 min-width: 70px;
3243 }
3244 .dns-row-value {
3245 font-size: 0.85rem;
3246 flex: 1;
3247 }
3248 .dns-row-copy {
3249 padding: 0.15rem 0.5rem;
3250 font-size: 0.75rem;
3251 }
3252 .profile-domain-actions {
3253 display: flex;
3254 gap: var(--space-3);
3255 }
3256 .profile-domain-result { margin-top: var(--space-3); }
3257 .profile-domain-lead {
3258 font-size: 0.9rem;
3259 opacity: 0.8;
3260 }
3261 .profile-domain-add-result { margin-top: var(--space-3); }
3262
3263 /* Personal feed row: URL input + Copy button. */
3264 .profile-feed-row {
3265 display: flex;
3266 gap: var(--space-2);
3267 align-items: center;
3268 }
3269 .profile-feed-input {
3270 flex: 1;
3271 font-size: 0.85rem;
3272 font-family: var(--font-mono);
3273 opacity: 0.8;
3274 }
3275 .profile-feed-lead { margin-bottom: var(--space-3); }
3276
3277 .purchase-page .checkout-footer {
3278 margin-top: var(--space-6);
3279 padding-top: var(--space-5);
3280 border-top: 1px solid var(--border);
3281 opacity: 0.6;
3282 text-align: center;
3283 font-size: 0.85rem;
3284 }
3285
3286 .purchase-page .checkout-footer a { color: var(--detail); }
3287
3288 @media (max-width: 480px) {
3289 .purchase-page .container { padding: 0 var(--space-3); }
3290 .purchase-page .item-summary { flex-direction: column; }
3291 .purchase-page .item-thumbnail { width: 100%; height: 160px; }
3292 .purchase-page .checkout-box { padding: var(--space-5); }
3293 .purchase-page h2 { font-size: 1.4rem; }
3294 }
3295
3296 /* Feed page (templates/pages/feed.html). Compact tabular layout of
3297 items from followed users / projects / tags. */
3298 .feed-page .page-title { font-size: 1.5rem; margin-bottom: var(--space-4); }
3299 .feed-page .feed-meta { font-size: 0.8rem; opacity: 0.6; margin-bottom: var(--space-3); }
3300
3301 .feed-page .table-header {
3302 display: grid;
3303 grid-template-columns: 50px 1fr 100px 70px 70px;
3304 gap: var(--space-2);
3305 padding: var(--space-2) var(--space-3);
3306 background: var(--surface-alt);
3307 font-size: 0.75rem;
3308 opacity: 0.7;
3309 text-transform: uppercase;
3310 letter-spacing: 0.03em;
3311 }
3312
3313 .feed-page .col-right { text-align: right; }
3314
3315 .feed-page .results-table {
3316 border: 1px solid var(--border);
3317 border-top: none;
3318 }
3319
3320 .feed-page .table-row {
3321 display: grid;
3322 grid-template-columns: 50px 1fr 100px 70px 70px;
3323 gap: var(--space-2);
3324 padding: 0.4rem var(--space-3);
3325 align-items: center;
3326 text-decoration: none;
3327 color: var(--detail);
3328 font-size: 0.85rem;
3329 border-bottom: 1px solid var(--border);
3330 transition: background 0.1s ease;
3331 }
3332
3333 .feed-page .table-row:last-child { border-bottom: none; }
3334 .feed-page .table-row:nth-child(odd) { background: var(--light-background); }
3335 .feed-page .table-row:nth-child(even) { background: var(--surface-alt); }
3336 .feed-page .table-row:hover { background: var(--surface-muted); }
3337
3338 .feed-page .item-name-cell {
3339 display: flex;
3340 flex-direction: column;
3341 gap: 0.1rem;
3342 min-width: 0;
3343 }
3344
3345 .feed-page .item-name {
3346 white-space: nowrap;
3347 overflow: hidden;
3348 text-overflow: ellipsis;
3349 }
3350
3351 .feed-page .item-creator { font-size: 0.75rem; opacity: 0.5; }
3352
3353 .feed-page .badge {
3354 text-transform: uppercase;
3355 letter-spacing: 0.03em;
3356 background: var(--surface-muted);
3357 }
3358
3359 .feed-page .empty-state {
3360 text-align: center;
3361 padding: 3rem var(--space-5);
3362 background: var(--light-background);
3363 border: 1px solid var(--border);
3364 }
3365
3366 .feed-page .empty-state h2 { font-size: 1.3rem; margin-bottom: var(--space-2); }
3367 .feed-page .empty-state p { opacity: 0.7; margin-bottom: var(--space-5); }
3368
3369 .feed-page .pagination {
3370 display: flex;
3371 gap: var(--space-1);
3372 justify-content: center;
3373 margin-top: var(--space-4);
3374 }
3375
3376 .feed-page .pagination a,
3377 .feed-page .pagination span {
3378 padding: 0.4rem 0.7rem;
3379 font-size: 0.85rem;
3380 text-decoration: none;
3381 color: var(--detail);
3382 border: 1px solid var(--border);
3383 }
3384
3385 .feed-page .pagination span.current {
3386 background: var(--primary-dark);
3387 color: var(--primary-light);
3388 border-color: var(--primary-dark);
3389 }
3390
3391 .feed-page .pagination a:hover { background: var(--surface-muted); }
3392
3393 @media (max-width: 600px) {
3394 .feed-page .table-header,
3395 .feed-page .table-row { grid-template-columns: 1fr 70px; }
3396 .feed-page .table-header span:nth-child(1),
3397 .feed-page .table-row .badge:first-child,
3398 .feed-page .table-header span:nth-child(3),
3399 .feed-page .table-header span:nth-child(4),
3400 .feed-page .table-row span:nth-child(3),
3401 .feed-page .table-row span:nth-child(4) { display: none; }
3402 }
3403
3404 /* (Stripe Connect disclaimer page rules defined in the canonical
3405 STRIPE DISCLAIMER PAGE section near end of file.) */
3406
3407 /* User profile page (templates/pages/user.html). */
3408 .user-page .profile-header { text-align: center; margin-bottom: 3rem; }
3409
3410 .user-page .profile-avatar {
3411 width: 120px;
3412 height: 120px;
3413 background: var(--light-background);
3414 margin: 0 auto var(--space-4);
3415 display: flex;
3416 align-items: center;
3417 justify-content: center;
3418 font-size: 3rem;
3419 opacity: 0.5;
3420 }
3421
3422 .user-page .profile-name { font-size: 2rem; margin-bottom: var(--space-2); }
3423
3424 .user-page .profile-username {
3425 font-size: 0.9rem;
3426 opacity: 0.7;
3427 margin-bottom: var(--space-4);
3428 }
3429
3430 .user-page .profile-bio {
3431 font-size: 1rem;
3432 max-width: 500px;
3433 margin: 0 auto;
3434 text-align: center;
3435 }
3436
3437 .user-page .links-section { margin-bottom: var(--space-6); }
3438 .user-page .link-item { text-align: center; }
3439
3440 .user-page .link-title {
3441 font-size: 1.1rem;
3442 margin-bottom: var(--space-1);
3443 font-family: var(--font-heading);
3444 font-weight: bold;
3445 }
3446
3447 .user-page .link-description { font-size: 0.85rem; opacity: 0.7; }
3448
3449 .user-page .project-title {
3450 font-size: 1.1rem;
3451 margin-bottom: var(--space-2);
3452 font-family: var(--font-heading);
3453 font-weight: bold;
3454 }
3455
3456 .user-page .project-meta {
3457 font-size: 0.85rem;
3458 opacity: 0.7;
3459 margin-bottom: var(--space-2);
3460 }
3461
3462 .user-page .project-description { font-size: 0.9rem; opacity: 0.8; }
3463
3464 /* Creators / become-a-creator page (templates/pages/creators.html). */
3465 .creators-page h1 { font-size: 2.5rem; margin-bottom: var(--space-2); }
3466 .creators-page h2 { font-size: 1.5rem; margin-top: var(--space-6); margin-bottom: var(--space-4); }
3467
3468 .creators-page .how-it-works { margin-bottom: var(--space-6); }
3469 .creators-page .how-it-works ol { padding-left: var(--space-5); line-height: 1.8; }
3470
3471 .creators-page .stats-row { gap: var(--space-6); margin: var(--space-6) 0; }
3472 .creators-page .stat-box { padding: var(--space-5); }
3473 .creators-page .stat-box .number { font-size: 2rem; }
3474 .creators-page .stat-box .label { font-size: 0.85rem; margin-top: var(--space-1); }
3475
3476 .creators-page .wave-table {
3477 width: 100%;
3478 border-collapse: collapse;
3479 margin: var(--space-4) 0;
3480 }
3481
3482 .creators-page .wave-table th,
3483 .creators-page .wave-table td {
3484 padding: var(--space-3) var(--space-4);
3485 text-align: left;
3486 border-bottom: 1px solid var(--border);
3487 }
3488
3489 .creators-page .wave-table th {
3490 font-family: var(--font-mono);
3491 font-size: 0.85rem;
3492 opacity: 0.7;
3493 }
3494
3495 .creators-page .cta {
3496 margin-top: var(--space-6);
3497 padding: var(--space-5);
3498 background: var(--light-background);
3499 text-align: center;
3500 }
3501
3502 .creators-page .cta a { margin: 0 var(--space-2); }
3503
3504 /* Tag tree browse page (templates/pages/tag_tree.html). */
3505 .tag-tree-page .breadcrumbs {
3506 font-size: 0.85rem;
3507 margin-bottom: var(--space-5);
3508 opacity: 0.7;
3509 }
3510 .tag-tree-page .breadcrumbs a { text-decoration: none; color: inherit; }
3511 .tag-tree-page .breadcrumbs a:hover { opacity: 0.6; }
3512 .tag-tree-page .breadcrumbs .sep { margin: 0 0.3rem; opacity: 0.4; }
3513
3514 .tag-tree-page .tag-grid {
3515 display: grid;
3516 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
3517 gap: var(--space-3);
3518 }
3519
3520 .tag-tree-page .tag-card {
3521 background: var(--surface-muted);
3522 padding: var(--space-3) var(--space-4);
3523 text-decoration: none;
3524 color: var(--detail);
3525 border: 1px solid var(--border);
3526 transition: background 0.1s ease;
3527 }
3528
3529 .tag-tree-page .tag-card:hover {
3530 background: var(--surface-muted);
3531 text-decoration: none;
3532 }
3533
3534 .tag-tree-page .tag-card-name {
3535 font-family: var(--font-heading);
3536 font-weight: bold;
3537 font-size: 0.95rem;
3538 }
3539
3540 .tag-tree-page .tag-card-meta {
3541 font-size: 0.75rem;
3542 opacity: 0.5;
3543 margin-top: var(--space-1);
3544 }
3545
3546 .tag-tree-page .empty-state {
3547 opacity: 0.5;
3548 font-size: 0.9rem;
3549 padding: var(--space-6) 0;
3550 }
3551
3552 /* Confirm delete prompt (templates/pages/confirm_delete.html). Overrides
3553 the global .warning-box to use --danger-bg (matches the delete-account
3554 semantic). Also tokenized previously-broken fallbacks. */
3555 .confirm-delete-page .warning-box {
3556 background: var(--danger-bg);
3557 border: 1px solid var(--danger);
3558 border-radius: 8px;
3559 padding: var(--space-5);
3560 margin-bottom: var(--space-5);
3561 }
3562
3563 .confirm-delete-page .warning-box p {
3564 margin: 0;
3565 color: var(--danger);
3566 }
3567
3568 /* Project paywall page (templates/pages/project_paywall.html). */
3569 .project-paywall-page .paywall-cover { margin-bottom: var(--space-5); }
3570 .project-paywall-page .paywall-cover img {
3571 width: 120px;
3572 height: 120px;
3573 border-radius: 8px;
3574 object-fit: cover;
3575 }
3576
3577 .project-paywall-page .paywall-title {
3578 font-family: var(--font-heading);
3579 font-size: 3rem;
3580 margin-bottom: var(--space-2);
3581 }
3582
3583 .project-paywall-page .paywall-creator {
3584 font-size: 0.95rem;
3585 opacity: 0.7;
3586 margin-bottom: var(--space-5);
3587 }
3588
3589 .project-paywall-page .paywall-creator a { color: var(--detail); }
3590
3591 .project-paywall-page .paywall-description {
3592 font-size: 1.1rem;
3593 max-width: 800px;
3594 margin: 0 auto var(--space-6);
3595 text-align: left;
3596 }
3597
3598 .project-paywall-page .paywall-tiers {
3599 display: grid;
3600 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
3601 gap: var(--space-5);
3602 margin-top: var(--space-5);
3603 text-align: left;
3604 }
3605
3606 .project-paywall-page .paywall-tiers .tier-card {
3607 background: var(--light-background);
3608 padding: var(--space-6);
3609 display: flex;
3610 flex-direction: column;
3611 }
3612
3613 .project-paywall-page .paywall-tiers .tier-card h3 {
3614 font-family: var(--font-heading);
3615 font-weight: bold;
3616 font-size: 1.3rem;
3617 margin-bottom: var(--space-2);
3618 }
3619
3620 .project-paywall-page .paywall-tiers .tier-price {
3621 font-size: 1.5rem;
3622 margin-bottom: var(--space-4);
3623 }
3624
3625 .project-paywall-page .paywall-tiers .tier-card form,
3626 .project-paywall-page .paywall-tiers .tier-card .button { margin-top: auto; }
3627
3628 .project-paywall-page .paywall-tiers .tier-card button,
3629 .project-paywall-page .paywall-tiers .tier-card .button { width: 100%; }
3630
3631 /* Collection detail page (templates/pages/collection.html). */
3632 .collection-page .container { max-width: 700px; }
3633 .collection-page .collection-header { margin-bottom: var(--space-6); }
3634 .collection-page .collection-title { font-size: 2rem; margin-bottom: var(--space-1); }
3635
3636 .collection-page .collection-owner {
3637 font-size: 0.9rem;
3638 opacity: 0.7;
3639 margin-bottom: var(--space-3);
3640 }
3641
3642 .collection-page .collection-description {
3643 font-size: 0.95rem;
3644 opacity: 0.85;
3645 margin-bottom: var(--space-3);
3646 }
3647
3648 .collection-page .collection-meta { font-size: 0.85rem; opacity: 0.6; }
3649
3650 .collection-page .collection-item {
3651 display: flex;
3652 justify-content: space-between;
3653 align-items: flex-start;
3654 padding: var(--space-4);
3655 background: var(--light-background);
3656 margin-bottom: var(--space-2);
3657 }
3658
3659 .collection-page .collection-item-info { flex: 1; }
3660
3661 .collection-page .collection-item-title {
3662 font-family: var(--font-heading);
3663 font-weight: bold;
3664 font-size: 1.05rem;
3665 margin-bottom: var(--space-1);
3666 }
3667
3668 .collection-page .collection-item-title a { text-decoration: none; }
3669
3670 .collection-page .collection-item-meta { font-size: 0.85rem; opacity: 0.7; }
3671
3672 .collection-page .collection-item-price {
3673 font-size: 0.9rem;
3674 white-space: nowrap;
3675 margin-left: var(--space-4);
3676 }
3677
3678 .collection-page .empty-state {
3679 text-align: center;
3680 padding: 3rem var(--space-4);
3681 opacity: 0.6;
3682 }
3683
3684 /* Project blog index page (templates/pages/project_blog.html). */
3685 .project-blog-page .blog-header { margin-bottom: 3rem; }
3686 .project-blog-page .blog-title { font-size: 2.5rem; margin-bottom: var(--space-2); }
3687
3688 .project-blog-page .blog-meta {
3689 font-size: 0.9rem;
3690 opacity: 0.7;
3691 margin-bottom: var(--space-5);
3692 }
3693
3694 .project-blog-page .blog-meta a { color: var(--detail); }
3695
3696 .project-blog-page .blog-actions {
3697 display: flex;
3698 gap: var(--space-4);
3699 }
3700
3701 .project-blog-page .posts-list { max-width: 800px; }
3702
3703 .project-blog-page .post-entry {
3704 padding: var(--space-5) 0;
3705 border-bottom: 1px solid var(--border);
3706 }
3707
3708 .project-blog-page .post-entry:first-child { padding-top: 0; }
3709 .project-blog-page .post-title { font-size: 1.5rem; margin-bottom: var(--space-2); }
3710 .project-blog-page .post-title a { color: inherit; text-decoration: none; }
3711 .project-blog-page .post-title a:hover { text-decoration: underline; }
3712
3713 .project-blog-page .post-date {
3714 font-size: 0.85rem;
3715 opacity: 0.6;
3716 font-family: var(--font-mono);
3717 }
3718
3719 .project-blog-page .empty-state { padding: 3rem 0; opacity: 0.6; }
3720
3721 /* Canonical "page-level h1" — left-aligned, smaller than the global centered
3722 default. Used by dashboards, admin, health, import, delete-account, export,
3723 receipt. Aliased via comma-grouped selectors so each page picks it up via
3724 its body class without redefining. */
3725 .dashboard-page h1,
3726 .admin-page h1,
3727 .health-page h1,
3728 .import-page h1,
3729 .delete-account-page h1,
3730 .export-page h1,
3731 .receipt-page h1 {
3732 font-size: 2rem;
3733 margin-bottom: var(--space-2);
3734 text-align: left;
3735 }
3736 .delete-account-page h1 { color: var(--danger); }
3737
3738 /* Canonical subtitle under a page h1 — muted, with bottom space. */
3739 .health-page .subtitle,
3740 .import-page .subtitle,
3741 .delete-account-page .subtitle,
3742 .export-page .subtitle {
3743 opacity: 0.7;
3744 margin-bottom: var(--space-6);
3745 text-align: left;
3746 }
3747 .health-page .subtitle { text-align: center; }
3748
3749 /* User Settings tab (templates/partials/tabs/user_settings.html).
3750 Left-rail nav layout for the Settings dashboard tab. Selection uses the
3751 canonical .is-selected modifier. */
3752 .settings-layout { display: flex; gap: var(--space-6); }
3753 .settings-nav { flex-shrink: 0; min-width: 140px; }
3754 .settings-nav a {
3755 display: block;
3756 padding: var(--space-2) var(--space-3);
3757 text-decoration: none;
3758 color: var(--detail);
3759 opacity: 0.6;
3760 font-family: var(--font-mono);
3761 font-size: 0.9rem;
3762 transition: opacity 0.15s ease;
3763 }
3764 .settings-nav a:hover { opacity: 1; }
3765 .settings-nav a.is-selected { opacity: 1; background: var(--surface-muted); }
3766 .settings-body { flex: 1; min-width: 0; }
3767 @media (max-width: 768px) {
3768 .settings-layout { flex-direction: column; gap: var(--space-4); }
3769 .settings-nav { display: flex; flex-wrap: wrap; gap: 0; min-width: 0; }
3770 .settings-nav a { padding: 0.4rem 0.6rem; font-size: 0.85rem; }
3771 }.library-page .feed-table-header {
3772 display: grid;
3773 grid-template-columns: 50px 1fr 100px 70px 70px;
3774 gap: var(--space-2);
3775 padding: var(--space-2) var(--space-3);
3776 background: var(--surface-alt);
3777 font-size: 0.75rem;
3778 opacity: 0.7;
3779 text-transform: uppercase;
3780 letter-spacing: 0.03em;
3781 }
3782 .library-page .feed-col-right { text-align: right; }
3783 .library-page .feed-results-table { border: 1px solid var(--border); border-top: none; }
3784 .library-page .feed-table-row {
3785 display: grid;
3786 grid-template-columns: 50px 1fr 100px 70px 70px;
3787 gap: var(--space-2);
3788 padding: 0.4rem var(--space-3);
3789 align-items: center;
3790 text-decoration: none;
3791 color: var(--detail);
3792 font-size: 0.85rem;
3793 border-bottom: 1px solid var(--border);
3794 transition: background 0.1s ease;
3795 }
3796 .library-page .feed-table-row:last-child { border-bottom: none; }
3797 .library-page .feed-table-row:nth-child(odd) { background: var(--light-background); }
3798 .library-page .feed-table-row:nth-child(even) { background: var(--surface-alt); }
3799 .library-page .feed-table-row:hover { background: var(--surface-muted); }
3800 .library-page .feed-item-name-cell {
3801 display: flex;
3802 flex-direction: column;
3803 gap: 0.1rem;
3804 min-width: 0;
3805 }
3806 .library-page .feed-item-name {
3807 white-space: nowrap;
3808 overflow: hidden;
3809 text-overflow: ellipsis;
3810 }
3811 .library-page .feed-item-creator { font-size: 0.75rem; opacity: 0.5; }
3812 .library-page .feed-pagination {
3813 display: flex;
3814 gap: var(--space-1);
3815 justify-content: center;
3816 margin-top: var(--space-4);
3817 }
3818 .library-page .feed-pagination a,
3819 .library-page .feed-pagination span {
3820 padding: 0.4rem 0.7rem;
3821 font-size: 0.85rem;
3822 text-decoration: none;
3823 color: var(--detail);
3824 border: 1px solid var(--border);
3825 }
3826 .library-page .feed-pagination span.current {
3827 background: var(--primary-dark);
3828 color: var(--primary-light);
3829 border-color: var(--primary-dark);
3830 }
3831 .library-page .feed-pagination a:hover { background: var(--surface-muted); }
3832 @media (max-width: 600px) {
3833 .library-page .feed-table-header,
3834 .library-page .feed-table-row {
3835 grid-template-columns: 1fr 70px;
3836 }
3837 .library-page .feed-table-header span:nth-child(1),
3838 .library-page .feed-table-row .badge:first-child,
3839 .library-page .feed-table-header span:nth-child(3),
3840 .library-page .feed-table-header span:nth-child(4),
3841 .library-page .feed-table-row span:nth-child(3),
3842 .library-page .feed-table-row span:nth-child(4) {
3843 display: none;
3844 }
3845 }
3846
3847 /* User-level dashboard (templates/dashboards/dashboard-user.html).
3848 Scoped under .dashboard-user-page to avoid colliding with .project-card
3849 / .project-title / .project-meta on the public profile (user.html) and
3850 the user_projects tab partial. */
3851 .dashboard-user-page .stat-value { font-size: 2rem; margin-bottom: var(--space-1); }
3852
3853 .dashboard-user-page .project-card {
3854 background: var(--light-background);
3855 padding: var(--space-5);
3856 margin-bottom: var(--space-4);
3857 display: flex;
3858 justify-content: space-between;
3859 align-items: flex-start;
3860 }
3861
3862 .dashboard-user-page .project-info { flex: 1; }
3863
3864 .dashboard-user-page .project-title {
3865 font-family: var(--font-heading);
3866 font-weight: bold;
3867 font-size: 1.2rem;
3868 margin-bottom: var(--space-1);
3869 }
3870
3871 .dashboard-user-page .project-meta {
3872 font-size: 0.85rem;
3873 opacity: 0.7;
3874 margin-bottom: var(--space-2);
3875 }
3876
3877 .dashboard-user-page .project-stats { font-size: 0.9rem; }
3878 .dashboard-user-page .project-actions {
3879 display: flex;
3880 gap: var(--space-2);
3881 }
3882
3883 .dashboard-user-page .project-actions button {
3884 padding: 0.4rem 0.8rem;
3885 font-size: 0.85rem;
3886 }
3887 @media (max-width: 768px) {
3888 .dashboard-user-page .project-card { flex-direction: column; }
3889 .dashboard-user-page .project-actions { margin-top: var(--space-3); }
3890 }
3891
3892 /* Project dashboard (templates/dashboards/dashboard-project.html). */
3893 .dashboard-project-page .project-meta { font-size: 0.9rem; opacity: 0.7; }
3894 .dashboard-project-page .stat-value { font-size: 2rem; margin-bottom: var(--space-1); }
3895
3896 .dashboard-project-page .content-header {
3897 display: flex;
3898 justify-content: space-between;
3899 align-items: center;
3900 margin-bottom: var(--space-5);
3901 }
3902
3903 .dashboard-project-page .content-header h2 { font-size: 1.3rem; }
3904
3905 .dashboard-project-page .item-thumbnail {
3906 width: 40px;
3907 height: 40px;
3908 background: var(--border);
3909 display: inline-block;
3910 vertical-align: middle;
3911 margin-right: var(--space-2);
3912 }
3913
3914 .dashboard-project-page .item-actions {
3915 display: flex;
3916 gap: var(--space-2);
3917 }
3918
3919 .dashboard-project-page .item-actions button {
3920 padding: 0.4rem 0.8rem;
3921 font-size: 0.85rem;
3922 }
3923
3924 .dashboard-project-page .data-section { margin-bottom: var(--space-6); }
3925
3926 .dashboard-project-page .data-section h2 {
3927 font-size: 1.3rem;
3928 margin-bottom: var(--space-4);
3929 padding-bottom: var(--space-2);
3930 border-bottom: 1px solid var(--border);
3931 }
3932
3933 /* Item dashboard (templates/dashboards/dashboard-item.html). */
3934 .dashboard-item-page .item-meta {
3935 font-size: 0.9rem;
3936 opacity: 0.7;
3937 display: flex;
3938 gap: var(--space-4);
3939 align-items: center;
3940 }
3941
3942 .dashboard-item-page .stat-value { font-size: 1.5rem; }
3943
3944 .dashboard-item-page .section-header {
3945 display: flex;
3946 justify-content: space-between;
3947 align-items: center;
3948 margin-bottom: var(--space-5);
3949 padding-bottom: var(--space-3);
3950 border-bottom: 1px solid var(--border);
3951 }
3952
3953 .dashboard-item-page .section-header h2 { font-size: 1.3rem; }
3954
3955 @media (max-width: 768px) {
3956 .dashboard-item-page .section-header {
3957 flex-direction: column;
3958 align-items: flex-start;
3959 gap: var(--space-3);
3960 }
3961 .dashboard-item-page .section-header .action-buttons { width: 100%; }
3962 }
3963
3964 /* Blog editor dashboard (templates/dashboards/dashboard-blog-editor.html). */
3965 .blog-editor .editor-form { max-width: 800px; }
3966 .blog-editor .editor-form .form-group { margin-bottom: var(--space-5); }
3967 .blog-editor .editor-form textarea {
3968 font-family: var(--font-mono);
3969 font-size: 0.9rem;
3970 min-height: 400px;
3971 resize: vertical;
3972 }
3973
3974 /* Changelog page (templates/pages/changelog.html). */
3975 .changelog-page .container { max-width: 900px; margin: 0 auto; }
3976 .changelog-page h1 { font-size: 2.5rem; margin-bottom: var(--space-2); }
3977 .changelog-page .changelog-entry {
3978 margin-bottom: 2.5rem;
3979 padding-bottom: var(--space-6);
3980 border-bottom: 1px solid var(--border);
3981 }
3982 .changelog-page .changelog-entry:last-child { border-bottom: none; }
3983 .changelog-page .changelog-date {
3984 font-family: var(--font-mono);
3985 font-size: 0.9rem;
3986 opacity: 0.6;
3987 margin-bottom: var(--space-2);
3988 }
3989 .changelog-page .changelog-entry h2 { font-size: 1.3rem; margin-bottom: var(--space-3); }
3990 .changelog-page .changelog-entry ul {
3991 padding-left: var(--space-5);
3992 margin: var(--space-2) 0;
3993 line-height: 1.7;
3994 }
3995 .changelog-page .changelog-entry li { margin-bottom: var(--space-1); }
3996
3997 /* Policy page (templates/pages/policy.html). */
3998 .policy-page .container { max-width: 900px; margin: 0 auto; }
3999 .policy-page h1 { font-size: 2.5rem; margin-bottom: var(--space-2); }
4000 .policy-page h2 {
4001 font-size: 1.5rem;
4002 margin-top: var(--space-6);
4003 margin-bottom: var(--space-4);
4004 }
4005 .policy-page .policy-section { margin-bottom: var(--space-6); line-height: 1.7; }
4006 .policy-page .policy-section ul {
4007 padding-left: var(--space-5);
4008 margin: var(--space-3) 0;
4009 }
4010 .policy-page .policy-section li { margin-bottom: var(--space-1); }
4011 .policy-page .contact {
4012 margin-top: var(--space-6);
4013 padding: var(--space-5);
4014 background: var(--light-background);
4015 }
4016
4017 /* Admin page extras (in addition to global .admin-page h1). */
4018 .admin-page .metrics-grid {
4019 display: grid;
4020 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
4021 gap: var(--space-4);
4022 margin-bottom: var(--space-6);
4023 }
4024
4025 .admin-page .metric-card {
4026 padding: var(--space-4);
4027 border: 1px solid var(--border);
4028 border-radius: var(--radius-md);
4029 }
4030
4031 .admin-page .metric-card .value {
4032 font-size: 1.8rem;
4033 font-family: var(--font-mono);
4034 font-weight: 600;
4035 }
4036
4037 .admin-page .metric-card .label {
4038 font-size: 0.85rem;
4039 color: var(--text-muted);
4040 margin-top: var(--space-1);
4041 }
4042
4043 .admin-page .metric-card.warn .value { color: var(--warning); }
4044 .admin-page .metric-card.error .value { color: var(--danger); }
4045
4046 .admin-page .section-heading {
4047 font-size: 1.2rem;
4048 margin: var(--space-5) 0 var(--space-3);
4049 font-family: var(--font-mono);
4050 }
4051
4052 /* Scan pipeline dashboard. See docs/scan-pipeline-audit.md § 5. */
4053
4054 .admin-scan-section {
4055 margin-top: var(--space-6);
4056 }
4057
4058 .admin-section-header {
4059 display: flex;
4060 justify-content: space-between;
4061 align-items: baseline;
4062 margin-bottom: var(--space-3);
4063 gap: var(--space-3);
4064 }
4065
4066 .admin-section-header h2 {
4067 font-size: 1.1rem;
4068 font-family: var(--font-mono);
4069 margin: 0;
4070 }
4071
4072 .layer-health-grid {
4073 display: grid;
4074 grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
4075 gap: var(--space-3);
4076 }
4077
4078 .layer-health-card {
4079 padding: var(--space-3);
4080 border: 1px solid var(--border);
4081 border-radius: var(--radius-md);
4082 border-left-width: 4px;
4083 font-size: 0.85rem;
4084 }
4085
4086 .layer-health-card .layer-name {
4087 font-family: var(--font-mono);
4088 font-weight: 600;
4089 font-size: 0.95rem;
4090 margin-bottom: var(--space-2);
4091 }
4092
4093 .layer-health-card .layer-stat {
4094 display: flex;
4095 justify-content: space-between;
4096 margin-bottom: 2px;
4097 }
4098
4099 .layer-health-card .layer-stat .dimmed {
4100 color: var(--text-muted);
4101 }
4102
4103 .layer-health-card.layer-ok { border-left-color: var(--success, #527a3e); }
4104 .layer-health-card.layer-degraded { border-left-color: var(--warning); }
4105 .layer-health-card.layer-down { border-left-color: var(--danger); }
4106
4107 .layer-chips {
4108 display: flex;
4109 flex-wrap: wrap;
4110 gap: 4px;
4111 max-width: 360px;
4112 }
4113
4114 .layer-chip {
4115 display: inline-block;
4116 font-family: var(--font-mono);
4117 font-size: 0.7rem;
4118 padding: 1px 6px;
4119 border-radius: var(--radius-sm);
4120 border: 1px solid transparent;
4121 cursor: help;
4122 line-height: 1.4;
4123 }
4124
4125 .layer-chip-pass { background: #e6f0dc; border-color: #c4d8a8; color: #3a5a2a; }
4126 .layer-chip-skip { background: var(--bg-page); border-color: var(--border); color: var(--text-muted); }
4127 .layer-chip-fail { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 600; }
4128 .layer-chip-error { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning); font-weight: 600; }
4129
4130 .scan-history-grid table { font-size: 0.85rem; }
4131
4132 .scan-history-grid summary {
4133 cursor: pointer;
4134 font-family: var(--font-mono);
4135 padding: var(--space-2) 0;
4136 user-select: none;
4137 }
4138
4139 .scan-row-meta {
4140 font-size: 0.75rem;
4141 color: var(--text-muted);
4142 margin-top: 2px;
4143 }
4144
4145 .audit-filter-form {
4146 display: flex;
4147 flex-wrap: wrap;
4148 align-items: flex-end;
4149 gap: var(--space-3);
4150 padding: var(--space-3) 0;
4151 margin-bottom: var(--space-3);
4152 border-bottom: 1px solid var(--border);
4153 }
4154
4155 .audit-filter-form label {
4156 display: flex;
4157 flex-direction: column;
4158 gap: 2px;
4159 }
4160
4161 .audit-filter-form input,
4162 .audit-filter-form select {
4163 font-size: 0.9rem;
4164 }
4165
4166 .layer-chips-cell { vertical-align: top; }
4167
4168 .layer-detail-disclosure {
4169 margin-top: var(--space-2);
4170 }
4171
4172 .layer-detail-disclosure summary {
4173 cursor: pointer;
4174 user-select: none;
4175 padding: 2px 0;
4176 }
4177
4178 .layer-detail-list {
4179 margin: var(--space-2) 0 0;
4180 display: grid;
4181 grid-template-columns: max-content 1fr;
4182 gap: 2px var(--space-3);
4183 font-size: 0.8rem;
4184 }
4185
4186 .layer-detail-list dt {
4187 font-family: var(--font-mono);
4188 }
4189
4190 .layer-detail-list dd {
4191 margin: 0;
4192 color: var(--text-muted);
4193 word-break: break-word;
4194 }
4195
4196 .admin-page table {
4197 width: 100%;
4198 border-collapse: collapse;
4199 font-size: 0.9rem;
4200 }
4201
4202 .admin-page th,
4203 .admin-page td {
4204 text-align: left;
4205 padding: 0.4rem 0.6rem;
4206 border-bottom: 1px solid var(--border);
4207 }
4208
4209 .admin-page th {
4210 font-family: var(--font-mono);
4211 font-size: 0.8rem;
4212 text-transform: uppercase;
4213 color: var(--text-muted);
4214 }
4215
4216 .admin-page td.mono { font-family: var(--font-mono); }
4217
4218 .admin-page .refresh-note {
4219 font-size: 0.8rem;
4220 color: var(--text-muted);
4221 margin-bottom: var(--space-4);
4222 font-family: var(--font-mono);
4223 }
4224
4225 .admin-page .grafana-link {
4226 font-family: var(--font-mono);
4227 font-size: 0.85rem;
4228 margin-top: var(--space-5);
4229 }
4230
4231 .admin-page .appeal-count {
4232 font-size: 0.9rem;
4233 opacity: 0.7;
4234 margin-bottom: var(--space-5);
4235 }
4236
4237 .admin-page .decide-form {
4238 display: flex;
4239 gap: var(--space-2);
4240 align-items: flex-end;
4241 flex-wrap: wrap;
4242 }
4243
4244 .admin-page .decide-form textarea {
4245 min-width: 200px;
4246 font-size: 0.85rem;
4247 }
4248
4249 .admin-page .suspend-form {
4250 display: flex;
4251 gap: var(--space-2);
4252 align-items: flex-end;
4253 }
4254
4255 .admin-page .suspend-form input[type="text"] {
4256 min-width: 200px;
4257 font-size: 0.85rem;
4258 }
4259
4260 .admin-page .lottery-form {
4261 background: var(--light-background);
4262 padding: var(--space-5);
4263 margin: var(--space-5) 0;
4264 display: flex;
4265 gap: var(--space-4);
4266 align-items: flex-end;
4267 }
4268
4269 .admin-page .lottery-form .form-group { margin-bottom: 0; }
4270
4271 .admin-page .lottery-form label {
4272 font-size: 0.85rem;
4273 display: block;
4274 margin-bottom: var(--space-1);
4275 }
4276
4277 .admin-page .lottery-form input[type="number"] { width: 80px; }
4278
4279 /* Page-top notice (charter primitive — replaces #restart-banner and
4280 the inline sandbox banner in dashboard-project). Full-bleed across
4281 the viewport, monospace, one short sentence + optional action.
4282 Hero callouts on the landing page use `.alert` instead (multi-paragraph). */
4283 .banner {
4284 padding: var(--space-3) var(--space-5);
4285 font-family: var(--font-mono);
4286 font-size: 0.9rem;
4287 text-align: center;
4288 color: var(--detail);
4289 }
4290
4291 .banner--info {
4292 background: var(--highlight-faint);
4293 border-bottom: 2px solid var(--focus-ring);
4294 }
4295
4296 .banner--warning {
4297 background: var(--warning-bg);
4298 border-bottom: 2px solid var(--warning-border);
4299 }
4300
4301 .banner a {
4302 color: inherit;
4303 text-decoration: underline;
4304 }
4305
4306 /* ===========================================
4307 SECTIONS
4308 =========================================== */
4309
4310 .section-header {
4311 font-size: 1.5rem;
4312 font-weight: normal;
4313 margin-bottom: 1rem;
4314 padding-bottom: 0.5rem;
4315 border-bottom: 1px solid var(--border);
4316 font-family: var(--font-mono);
4317 }
4318
4319 /* Canonical "page section box" — light-background card with padding + bottom
4320 space. One of these in the codebase. Aliased to the per-page class names
4321 that were just relabels of this same shape. Templates can use the alias
4322 name OR add `.content-section` as a co-class. */
4323 .content-section,
4324 .import-page .import-form,
4325 .import-page .import-progress,
4326 .library-page .library-section,
4327 .library-page .library-downloads,
4328 .library-page .downloads-hero,
4329 .receipt-page .receipt-box,
4330 .stripe-disclaimer-page .disclaimer-box,
4331 .project-page .project-sections {
4332 background: var(--light-background);
4333 padding: var(--space-6);
4334 margin-bottom: var(--space-6);
4335 }
4336
4337 /* Variants of the canonical shape that want top-spacing instead of bottom,
4338 or a tighter --space-5 padding. */
4339 .library-page .library-downloads,
4340 .receipt-page .receipt-box { margin-bottom: 0; margin-top: var(--space-5); }
4341 .import-page .import-progress { padding: var(--space-5); margin-bottom: var(--space-4); }
4342 .stripe-disclaimer-page .disclaimer-box { margin-bottom: var(--space-5); }
4343
4344 .form-section {
4345 margin-bottom: 2rem;
4346 }
4347
4348 .section-group-label {
4349 font-family: var(--font-mono);
4350 font-size: 0.8rem;
4351 font-weight: bold;
4352 text-transform: uppercase;
4353 letter-spacing: 0.05em;
4354 color: var(--text-muted);
4355 margin: 2.5rem 0 1rem 0;
4356 padding-top: 1.5rem;
4357 border-top: 2px solid var(--border);
4358 }
4359
4360 .form-section h2 {
4361 font-size: 1.3rem;
4362 font-weight: normal;
4363 margin-bottom: 1rem;
4364 padding-bottom: 0.5rem;
4365 border-bottom: 1px solid var(--border);
4366 }
4367
4368 details.form-section > summary {
4369 cursor: pointer;
4370 list-style: disclosure-closed;
4371 }
4372
4373 details.form-section[open] > summary {
4374 list-style: disclosure-open;
4375 margin-bottom: 1rem;
4376 }
4377
4378 details.form-section > summary > h2 {
4379 display: inline;
4380 }
4381
4382 details.form-section > summary:hover > h2 {
4383 color: var(--detail);
4384 }
4385
4386 /* ===========================================
4387 NAVIGATION
4388 =========================================== */
4389
4390 nav {
4391 margin-bottom: 2rem;
4392 }
4393
4394 .nav-links {
4395 display: flex;
4396 gap: 2rem;
4397 flex-wrap: wrap;
4398 }
4399
4400 .nav-links a {
4401 color: var(--detail);
4402 text-decoration: none;
4403 font-family: var(--font-mono);
4404 transition: opacity 0.2s ease;
4405 }
4406
4407 .nav-links a:hover {
4408 opacity: 0.6;
4409 }
4410
4411 .shortcuts-help-btn {
4412 font-family: var(--font-mono);
4413 color: var(--text-muted);
4414 font-size: 0.85rem;
4415 width: 1.5rem;
4416 height: 1.5rem;
4417 border: 1px solid var(--border);
4418 border-radius: 3px;
4419 display: inline-flex;
4420 align-items: center;
4421 justify-content: center;
4422 cursor: pointer;
4423 transition: opacity 0.2s ease;
4424 padding: 0;
4425 background: none;
4426 }
4427
4428 .shortcuts-help-btn:hover {
4429 opacity: 0.6;
4430 }
4431
4432 .breadcrumb {
4433 font-size: 0.9rem;
4434 color: var(--text-muted);
4435 margin-bottom: 0.5rem;
4436 font-family: var(--font-mono);
4437 }
4438
4439 .breadcrumb a {
4440 color: var(--detail);
4441 text-decoration: none;
4442 }
4443
4444 .breadcrumb a:hover {
4445 text-decoration: underline;
4446 }
4447
4448 /* ===========================================
4449 HEADER & FOOTER
4450 =========================================== */
4451
4452 header {
4453 background: transparent;
4454 border-bottom: none;
4455 padding: 0;
4456 margin-bottom: 2rem;
4457 }
4458
4459 footer {
4460 text-align: center;
4461 font-family: var(--font-mono);
4462 color: var(--text-muted);
4463 }
4464
4465 .profile-footer {
4466 margin-top: 3rem;
4467 padding-top: 1.5rem;
4468 border-top: 1px solid var(--border);
4469 text-align: center;
4470 opacity: 0.6;
4471 font-size: 0.85rem;
4472 }
4473
4474 .profile-footer a {
4475 color: var(--detail);
4476 text-decoration: none;
4477 }
4478
4479 .profile-footer a:hover {
4480 text-decoration: underline;
4481 }
4482
4483 /* Site-wide header */
4484 .site-header {
4485 display: flex;
4486 justify-content: space-between;
4487 align-items: center;
4488 padding: 1rem 1.5rem;
4489 margin-bottom: 1.5rem;
4490 }
4491
4492 .site-header nav {
4493 margin: 0;
4494 }
4495
4496 .site-header .nav-links {
4497 gap: 1.5rem;
4498 }
4499
4500 .site-logo {
4501 font-family: var(--font-heading);
4502 font-size: 1.25rem;
4503 text-decoration: none;
4504 color: var(--detail);
4505 }
4506
4507 .site-logo:hover {
4508 opacity: 0.8;
4509 }
4510
4511 .nav-form {
4512 display: contents;
4513 }
4514
4515 /* Header search */
4516 .header-search {
4517 flex: 0 1 220px;
4518 margin: 0 1rem;
4519 }
4520
4521 .header-search input {
4522 width: 100%;
4523 padding: 0.35rem 0.6rem;
4524 font-size: 0.85rem;
4525 font-family: var(--font-mono);
4526 border: 1px solid var(--border);
4527 background: var(--background);
4528 color: var(--detail);
4529 border-radius: 3px;
4530 }
4531
4532 .header-search input:focus {
4533 outline: 2px solid var(--focus-ring);
4534 outline-offset: -1px;
4535 }
4536
4537 /* Hamburger toggle — hidden by default, shown at 768px */
4538 .nav-toggle-checkbox {
4539 display: none;
4540 }
4541
4542 .nav-toggle-label {
4543 display: none;
4544 cursor: pointer;
4545 padding: 0.5rem;
4546 z-index: 11;
4547 }
4548
4549 .nav-toggle-label span {
4550 display: block;
4551 width: 22px;
4552 height: 2px;
4553 background: var(--detail);
4554 margin: 5px 0;
4555 transition: transform 0.2s ease, opacity 0.2s ease;
4556 }
4557
4558 /* ===========================================
4559 LAYOUT UTILITIES
4560 =========================================== */
4561
4562 .action-buttons {
4563 display: flex;
4564 gap: 1rem;
4565 flex-wrap: wrap;
4566 }
4567 /* ===========================================
4568 SPECIFIC COMPONENTS
4569 =========================================== */
4570
4571 /* Login container */
4572 .login-container {
4573 display: flex;
4574 flex-direction: column;
4575 max-width: 400px;
4576 width: 100%;
4577 margin: 0 auto;
4578 background: var(--light-background);
4579 padding: 2rem;
4580 }
4581 /* Logo */
4582 .logo {
4583 font-family: var(--font-heading);
4584 color: var(--detail);
4585 font-size: 24px;
4586 }
4587
4588 .tagline {
4589 font-family: var(--font-mono);
4590 color: var(--text-muted);
4591 text-align: center;
4592 }
4593
4594 .centered-page .tagline {
4595 margin-bottom: 0.25rem;
4596 }
4597 /* Skip link */
4598 .skip-link {
4599 text-align: center;
4600 margin-top: 1rem;
4601 }
4602
4603 .skip-link a {
4604 color: var(--primary-dark);
4605 text-decoration: none;
4606 font-size: 0.9rem;
4607 opacity: 0.7;
4608 }
4609
4610 .skip-link a:hover {
4611 text-decoration: underline;
4612 }
4613
4614 /* Footer link */
4615 .foot-link {
4616 margin-top: 0.5em;
4617 }
4618
4619 /* Status indicators */
4620 .status-indicator {
4621 display: inline-block;
4622 width: 8px;
4623 height: 8px;
4624 background: var(--primary-dark);
4625 margin-right: 0.5rem;
4626 }
4627
4628 .status-indicator.active {
4629 background: var(--success);
4630 }
4631
4632 /* Amount styling */
4633 .amount-in {
4634 color: var(--success);
4635 }
4636
4637 .amount-out {
4638 opacity: 0.7;
4639 }
4640
4641 /* File upload */
4642 .file-upload-area {
4643 background: var(--surface-muted);
4644 padding: 2rem;
4645 text-align: center;
4646 cursor: pointer;
4647 transition: background 0.2s ease;
4648 margin-bottom: 1rem;
4649 }
4650
4651 .file-upload-area:hover,
4652 .file-upload-area.dragover {
4653 background: var(--border);
4654 }
4655 /* Chart placeholder */
4656 .chart-container {
4657 background: var(--surface-muted);
4658 padding: 1.5rem;
4659 margin-bottom: 1.5rem;
4660 }
4661
4662 .chart-header {
4663 display: flex;
4664 justify-content: space-between;
4665 align-items: center;
4666 margin-bottom: 1rem;
4667 }
4668
4669 .chart-header h2 {
4670 font-size: 1.2rem;
4671 font-weight: normal;
4672 }
4673
4674 .chart-bars {
4675 display: flex;
4676 align-items: flex-end;
4677 gap: 2px;
4678 height: 200px;
4679 padding: 0 0.5rem;
4680 }
4681
4682 .chart-bar-col {
4683 flex: 1;
4684 display: flex;
4685 flex-direction: column;
4686 align-items: center;
4687 min-width: 0;
4688 cursor: default;
4689 position: relative;
4690 }
4691
4692 .chart-bar-col[data-tooltip]:hover::before {
4693 content: attr(data-tooltip);
4694 position: absolute;
4695 bottom: 100%;
4696 left: 50%;
4697 transform: translateX(-50%);
4698 background: var(--primary-dark);
4699 color: var(--primary-light);
4700 font-size: 0.75rem;
4701 font-family: var(--font-mono);
4702 padding: 0.25rem 0.5rem;
4703 white-space: nowrap;
4704 z-index: 10;
4705 pointer-events: none;
4706 margin-bottom: 0.25rem;
4707 }
4708
4709 .chart-bar {
4710 width: 100%;
4711 background: var(--primary-dark);
4712 min-height: 2px;
4713 transition: opacity 0.15s;
4714 }
4715
4716 .chart-bar-col:hover .chart-bar {
4717 opacity: 0.8;
4718 }
4719
4720 .chart-bar-label {
4721 font-size: 0.7rem;
4722 opacity: 0.5;
4723 margin-top: 0.25rem;
4724 white-space: nowrap;
4725 overflow: hidden;
4726 text-overflow: ellipsis;
4727 max-width: 100%;
4728 }
4729
4730 /* Time selector */
4731 .time-selector {
4732 display: flex;
4733 gap: 0.5rem;
4734 }
4735
4736 .time-selector button {
4737 background: var(--light-background);
4738 border: none;
4739 padding: 0.5rem 1rem;
4740 font-family: inherit;
4741 font-size: 0.85rem;
4742 cursor: pointer;
4743 opacity: 0.6;
4744 }
4745
4746 .time-selector button.is-selected {
4747 opacity: 1;
4748 background: var(--primary-dark);
4749 color: var(--primary-light);
4750 }
4751
4752 /* Analytics */
4753 .analytics-grid {
4754 display: grid;
4755 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4756 gap: 1.5rem;
4757 margin-bottom: 1.5rem;
4758 }
4759 .analytics-list {
4760 list-style: none;
4761 }
4762
4763 .analytics-list li {
4764 padding: 0.5rem 0;
4765 border-bottom: 1px solid var(--border);
4766 display: flex;
4767 justify-content: space-between;
4768 }
4769
4770 .analytics-list li:last-child {
4771 border-bottom: none;
4772 }
4773
4774 /* Quick actions */
4775 .quick-actions {
4776 background: var(--surface-muted);
4777 padding: 1.5rem;
4778 }
4779
4780 .quick-actions h2 {
4781 font-size: 1.2rem;
4782 font-weight: normal;
4783 margin-bottom: 1rem;
4784 }
4785
4786 /* Filter controls */
4787 .filter-controls {
4788 display: flex;
4789 gap: 1rem;
4790 margin-bottom: 1rem;
4791 flex-wrap: wrap;
4792 align-items: center;
4793 }
4794
4795 .filter-group {
4796 display: flex;
4797 gap: 0.5rem;
4798 align-items: center;
4799 }
4800 /* UUID styling */
4801 .uuid {
4802 font-family: inherit;
4803 opacity: 0.5;
4804 font-size: 0.85rem;
4805 }
4806 /* ===========================================
4807 HTMX LOADING INDICATORS
4808 =========================================== */
4809
4810 .htmx-indicator {
4811 display: none;
4812 }
4813
4814 .htmx-request .htmx-indicator {
4815 display: inline;
4816 }
4817
4818 .htmx-request.htmx-indicator {
4819 display: inline;
4820 }
4821
4822 /* Loading spinner animation */
4823 @keyframes htmx-spin {
4824 0% { opacity: 0.3; }
4825 50% { opacity: 1; }
4826 100% { opacity: 0.3; }
4827 }
4828
4829 .htmx-indicator {
4830 animation: htmx-spin 1s ease-in-out infinite;
4831 }
4832
4833 /* Disable buttons during request */
4834 .htmx-request button[type="submit"] {
4835 opacity: 0.6;
4836 cursor: wait;
4837 }
4838
4839 /* ===========================================
4840 TOAST NOTIFICATIONS
4841 =========================================== */
4842
4843 .toast-container {
4844 position: fixed;
4845 bottom: 1.5rem;
4846 right: 1.5rem;
4847 z-index: 1000;
4848 display: flex;
4849 flex-direction: column;
4850 gap: 0.5rem;
4851 }
4852
4853 .toast {
4854 background: var(--primary-dark);
4855 color: var(--primary-light);
4856 padding: 0.75rem 1.25rem;
4857 font-family: var(--font-mono);
4858 font-size: 0.9rem;
4859 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
4860 animation: toast-in 0.3s ease-out;
4861 max-width: 300px;
4862 display: flex;
4863 align-items: center;
4864 gap: 0.75rem;
4865 }
4866
4867 .toast-dismiss {
4868 background: none;
4869 border: none;
4870 color: inherit;
4871 font-size: 1.1rem;
4872 cursor: pointer;
4873 opacity: 0.7;
4874 padding: 0;
4875 line-height: 1;
4876 flex-shrink: 0;
4877 }
4878
4879 .toast-dismiss:hover {
4880 opacity: 1;
4881 }
4882
4883 .toast-success {
4884 background: var(--success);
4885 }
4886
4887 .toast-error {
4888 background: var(--error);
4889 }
4890
4891 .toast-warning {
4892 background: var(--warning);
4893 }
4894
4895 .toast-info {
4896 background: var(--primary-dark);
4897 }
4898
4899 .toast-retry-btn {
4900 background: none;
4901 border: 1px solid currentColor;
4902 color: inherit;
4903 font-family: var(--font-mono);
4904 font-size: 0.8rem;
4905 font-weight: 600;
4906 padding: 0.15rem 0.5rem;
4907 margin-left: 0.75rem;
4908 cursor: pointer;
4909 }
4910
4911 .toast-retry-btn:hover {
4912 background: rgba(255, 255, 255, 0.15);
4913 }
4914
4915 .toast.fade-out {
4916 animation: toast-out 0.3s ease-in forwards;
4917 }
4918
4919 @keyframes toast-in {
4920 from {
4921 transform: translateX(100%);
4922 opacity: 0;
4923 }
4924 to {
4925 transform: translateX(0);
4926 opacity: 1;
4927 }
4928 }
4929
4930 @keyframes toast-out {
4931 from {
4932 transform: translateX(0);
4933 opacity: 1;
4934 }
4935 to {
4936 transform: translateX(100%);
4937 opacity: 0;
4938 }
4939 }
4940
4941 /* ===========================================
4942 "NEW" BADGE (data-new-until)
4943 ===========================================
4944 Applied by whats_new.js while today's date is <= the element's
4945 data-new-until. Renders a small violet dot to the right of the
4946 element's content. Pair with relative-positioned parents. */
4947
4948 .is-new {
4949 position: relative;
4950 }
4951
4952 .is-new::after {
4953 content: "";
4954 position: absolute;
4955 top: -2px;
4956 right: -8px;
4957 width: 6px;
4958 height: 6px;
4959 border-radius: 50%;
4960 background: var(--violet, #6c5ce7);
4961 box-shadow: 0 0 0 2px var(--background, #fff);
4962 }
4963
4964 /* ===========================================
4965 RESTART WARNING BANNER
4966 =========================================== */
4967
4968 /* Page-top behavior extensions on top of .banner.banner--warning.
4969 Color / typography come from the .banner primitive. */
4970 #restart-banner {
4971 position: fixed;
4972 top: 0;
4973 left: 0;
4974 right: 0;
4975 z-index: 10000;
4976 padding: 0.6rem 1rem;
4977 animation: banner-slide-down 0.3s ease-out;
4978 }
4979
4980 @keyframes banner-slide-down {
4981 from {
4982 transform: translateY(-100%);
4983 }
4984 to {
4985 transform: translateY(0);
4986 }
4987 }
4988
4989 /* ===========================================
4990 SAVE STATUS INDICATORS
4991 =========================================== */
4992
4993 /* Username availability status */
4994 .username-status {
4995 display: block;
4996 margin-top: 0.25rem;
4997 font-size: 0.85rem;
4998 }
4999
5000 .username-status.available {
5001 color: var(--success);
5002 }
5003
5004 .username-status.taken {
5005 color: var(--error);
5006 }
5007
5008 /* ===========================================
5009 HTMX TRANSITIONS
5010 =========================================== */
5011
5012 /* Fade in for swapped content */
5013 .htmx-added {
5014 animation: htmx-fade-in 0.2s ease-out;
5015 }
5016
5017 @keyframes htmx-fade-in {
5018 from {
5019 opacity: 0;
5020 }
5021 to {
5022 opacity: 1;
5023 }
5024 }
5025
5026 /* Settling animation for swapped content */
5027 .htmx-settling {
5028 opacity: 0.8;
5029 }
5030
5031 /* Swap animation */
5032 .htmx-swapping {
5033 opacity: 0.5;
5034 transition: opacity 0.2s ease-out;
5035 }
5036
5037 /* ===========================================
5038 ACCESSIBILITY - FOCUS STYLES
5039 =========================================== */
5040
5041 /* Focus-visible for keyboard navigation */
5042 *:focus-visible {
5043 outline: 2px solid var(--focus-ring);
5044 outline-offset: 2px;
5045 }
5046
5047 /* Remove default focus outline since we use focus-visible */
5048 *:focus:not(:focus-visible) {
5049 outline: none;
5050 }
5051
5052 /* Ensure buttons and links are keyboard accessible */
5053 button:focus-visible,
5054 a:focus-visible,
5055 input:focus-visible,
5056 select:focus-visible,
5057 textarea:focus-visible {
5058 outline: 2px solid var(--focus-ring);
5059 outline-offset: 2px;
5060 }
5061
5062 /* Tab focus styles */
5063 .tab:focus-visible {
5064 outline: 2px solid var(--focus-ring);
5065 outline-offset: -2px;
5066 }
5067
5068 /* Canonical "selected" recipe (charter: docs/design-system.md).
5069 Apply `.is-selected` to any interactive container to mark it as the
5070 currently-selected option. `.badge.active` is intentionally distinct —
5071 it expresses completion status, not selection. Visibility toggles
5072 (`.tab-content.active`, `.section-panel.active`, `.editor-panel.active`)
5073 also keep `.active` since they're not selection state. */
5074 .is-selected {
5075 background: var(--highlight-faint);
5076 border-color: var(--focus-ring);
5077 }
5078
5079 /* Skip to main content link (for screen readers) */
5080 .skip-to-main {
5081 position: absolute;
5082 top: -100px;
5083 left: 0;
5084 background: var(--primary-dark);
5085 color: var(--primary-light);
5086 padding: 8px;
5087 z-index: 100;
5088 transition: top 0.2s ease;
5089 }
5090
5091 .skip-to-main:focus {
5092 top: 0;
5093 }
5094
5095 /* Visually hidden but accessible to screen readers */
5096 .sr-only {
5097 position: absolute;
5098 width: 1px;
5099 height: 1px;
5100 padding: 0;
5101 margin: -1px;
5102 overflow: hidden;
5103 clip: rect(0, 0, 0, 0);
5104 white-space: nowrap;
5105 border: 0;
5106 }
5107
5108 /* Status indicator with text for accessibility */
5109 .status-indicator::after {
5110 content: attr(data-status);
5111 position: absolute;
5112 width: 1px;
5113 height: 1px;
5114 padding: 0;
5115 margin: -1px;
5116 overflow: hidden;
5117 clip: rect(0, 0, 0, 0);
5118 white-space: nowrap;
5119 border: 0;
5120 }
5121
5122 /* ===========================================
5123 PAYWALL
5124 =========================================== */
5125
5126 .paywall-section {
5127 margin: 2rem 0;
5128 padding: 2rem;
5129 background: var(--surface-muted);
5130 text-align: center;
5131 }
5132
5133 .paywall-box h2 {
5134 font-family: var(--font-heading);
5135 font-weight: normal;
5136 margin-bottom: 0.5rem;
5137 }
5138
5139 .paywall-price {
5140 font-family: var(--font-mono);
5141 font-size: 1.5rem;
5142 margin-bottom: 0.5rem;
5143 }
5144
5145 .paywall-desc {
5146 font-family: var(--font-body);
5147 color: var(--text-muted);
5148 margin-bottom: 1.5rem;
5149 }
5150
5151 .paywall-note {
5152 font-family: var(--font-mono);
5153 font-size: 0.875rem;
5154 color: var(--text-muted);
5155 margin-top: 1rem;
5156 }
5157
5158 .paywall-note a {
5159 color: var(--highlight);
5160 }
5161
5162 /* ===========================================
5163 MODALS
5164 =========================================== */
5165
5166 .modal-overlay {
5167 position: fixed;
5168 inset: 0;
5169 background: var(--overlay);
5170 display: flex;
5171 align-items: center;
5172 justify-content: center;
5173 z-index: 1000;
5174 }
5175
5176 .modal {
5177 background: var(--background);
5178 padding: 2rem;
5179 max-width: 500px;
5180 width: 90%;
5181 max-height: 90vh;
5182 overflow-y: auto;
5183 }
5184
5185 .modal h2 {
5186 margin-bottom: 1.5rem;
5187 }
5188
5189 .modal .form-actions {
5190 display: flex;
5191 gap: 1rem;
5192 justify-content: flex-end;
5193 margin-top: 1.5rem;
5194 }
5195
5196 /* ===========================================
5197 LINK ROWS (Dashboard Links Section)
5198 =========================================== */
5199
5200 .link-row {
5201 display: flex;
5202 gap: 0.75rem;
5203 align-items: center;
5204 margin-bottom: 0.75rem;
5205 padding: 0.75rem;
5206 background: var(--surface-muted);
5207 transition: opacity 0.2s ease, background 0.2s ease;
5208 }
5209
5210 .link-row input[type="text"],
5211 .link-row input[type="url"] {
5212 flex: 1;
5213 min-width: 0;
5214 }
5215
5216 .link-row .btn-danger {
5217 padding: 0.5rem 0.75rem;
5218 font-size: 0.85rem;
5219 }
5220
5221 /* Link order buttons */
5222 .link-order-buttons {
5223 display: flex;
5224 flex-direction: column;
5225 gap: 2px;
5226 }
5227
5228 .order-btn {
5229 background: var(--surface-muted);
5230 border: 1px solid var(--border);
5231 padding: 0.15rem 0.4rem;
5232 font-size: 0.65rem;
5233 line-height: 1;
5234 cursor: pointer;
5235 opacity: 0.6;
5236 transition: opacity 0.15s ease, background 0.15s ease;
5237 }
5238
5239 .order-btn:hover {
5240 opacity: 1;
5241 background: var(--border);
5242 }
5243
5244 .order-btn:active {
5245 background: var(--primary-dark);
5246 color: var(--primary-light);
5247 }
5248
5249 /* ===========================================
5250 TEXT EDITOR
5251 =========================================== */
5252
5253 .text-editor {
5254 width: 100%;
5255 }
5256
5257 .editor-tabs {
5258 display: flex;
5259 gap: 0;
5260 margin-bottom: 0;
5261 }
5262
5263 .editor-tab {
5264 background: var(--surface-muted);
5265 border: none;
5266 padding: 0.5rem 1.5rem;
5267 font-family: var(--font-mono);
5268 font-size: 0.9rem;
5269 cursor: pointer;
5270 opacity: 0.6;
5271 transition: opacity 0.2s ease, background 0.2s ease;
5272 }
5273
5274 .editor-tab.is-selected {
5275 background: var(--input-background);
5276 opacity: 1;
5277 }
5278
5279 .editor-tab:hover {
5280 opacity: 1;
5281 }
5282
5283 .editor-panel {
5284 display: none;
5285 }
5286
5287 .editor-panel.active {
5288 display: block;
5289 }
5290
5291 .editor-panel textarea {
5292 width: 100%;
5293 min-height: 400px;
5294 padding: 1rem;
5295 font-family: var(--font-mono);
5296 font-size: 0.9rem;
5297 line-height: 1.6;
5298 resize: vertical;
5299 border: none;
5300 background: var(--input-background);
5301 }
5302
5303 .editor-footer {
5304 display: flex;
5305 justify-content: space-between;
5306 padding: 0.5rem 1rem;
5307 background: var(--surface-muted);
5308 font-size: 0.85rem;
5309 opacity: 0.7;
5310 }
5311
5312 .markdown-preview {
5313 min-height: 400px;
5314 padding: 1.5rem;
5315 background: var(--light-background);
5316 font-family: var(--font-body);
5317 line-height: 1.8;
5318 }
5319
5320 .markdown-preview h1,
5321 .markdown-preview h2,
5322 .markdown-preview h3 {
5323 margin-top: 1.5rem;
5324 margin-bottom: 0.5rem;
5325 }
5326
5327 .markdown-preview h1 {
5328 font-size: 1.8rem;
5329 }
5330
5331 .markdown-preview h2 {
5332 font-size: 1.4rem;
5333 }
5334
5335 .markdown-preview h3 {
5336 font-size: 1.1rem;
5337 }
5338
5339 .markdown-preview p {
5340 margin-bottom: 1rem;
5341 }
5342
5343 .markdown-preview code {
5344 background: var(--surface-muted);
5345 padding: 0.1rem 0.3rem;
5346 font-family: var(--font-mono);
5347 font-size: 0.9em;
5348 }
5349
5350 /* ===========================================
5351 AUDIO UPLOAD
5352 =========================================== */
5353
5354 .audio-upload {
5355 width: 100%;
5356 }
5357
5358 .current-audio {
5359 display: flex;
5360 justify-content: space-between;
5361 align-items: center;
5362 padding: 1rem;
5363 background: var(--surface-muted);
5364 margin-bottom: 1rem;
5365 }
5366
5367 .audio-info {
5368 display: flex;
5369 align-items: center;
5370 gap: 1rem;
5371 }
5372
5373 .audio-icon {
5374 font-size: 1.5rem;
5375 opacity: 0.6;
5376 }
5377
5378 .audio-details {
5379 display: flex;
5380 flex-direction: column;
5381 }
5382
5383 .audio-filename {
5384 font-family: var(--font-mono);
5385 font-size: 0.9rem;
5386 }
5387
5388 .audio-duration {
5389 font-size: 0.85rem;
5390 opacity: 0.6;
5391 }
5392
5393 .upload-area .file-upload-area {
5394 padding: 3rem 2rem;
5395 }
5396
5397 .upload-icon {
5398 font-size: 2rem;
5399 opacity: 0.4;
5400 margin-bottom: 0.5rem;
5401 }
5402
5403 .upload-text {
5404 font-size: 1.1rem;
5405 margin-bottom: 0.5rem;
5406 }
5407
5408 .upload-hint {
5409 font-size: 0.85rem;
5410 opacity: 0.6;
5411 }
5412
5413 .upload-progress {
5414 padding: 1.5rem;
5415 background: var(--surface-muted);
5416 }
5417
5418 .progress-info {
5419 display: flex;
5420 justify-content: space-between;
5421 margin-bottom: 0.75rem;
5422 font-size: 0.9rem;
5423 }
5424
5425 /* Canonical progress bar primitive. One of these in the codebase.
5426 - .progress-bar-container is the track (8px default; --slim = 6px)
5427 - .progress-bar is the fill (success-green default; --highlight = purple)
5428 - Add .progress-bar-container--rounded for the 3px-radius pill variant
5429 Spacing (mb-4 / mt-2 etc.) is added by the caller, not baked in. */
5430 .progress-bar-container {
5431 height: 8px;
5432 background: var(--border);
5433 overflow: hidden;
5434 }
5435 .progress-bar-container--slim { height: 6px; }
5436 .progress-bar-container--rounded { border-radius: 3px; }
5437
5438 .progress-bar {
5439 width: 0%;
5440 height: 100%;
5441 background: var(--success);
5442 transition: width 0.2s ease;
5443 }
5444 .progress-bar--highlight { background: var(--highlight); }
5445
5446 /* Upload status block (filename + percent label + progress bar). One of these
5447 in the codebase. Used by wizard upload flows and standalone audio/video upload partials. */
5448 .upload-status { margin-top: var(--space-2); }
5449 .upload-status-row {
5450 display: flex;
5451 align-items: center;
5452 gap: var(--space-2);
5453 }
5454 .upload-status-row span { font-size: 0.85rem; }
5455 .upload-status-msg { margin-top: var(--space-2); }
5456 .upload-status-msg.is-success { color: var(--success); }
5457 .upload-status-msg.is-error { color: var(--error); }
5458
5459 /* Inline progress cell rendered inside a table-row status cell (batch uploads). */
5460 .upload-progress-row {
5461 display: flex;
5462 align-items: center;
5463 gap: 0.4rem;
5464 }
5465 .upload-progress-row .progress-bar-container { flex: 1; min-width: 60px; }
5466 .upload-progress-pct {
5467 font-size: 0.75rem;
5468 min-width: 2.5em;
5469 text-align: right;
5470 }
5471
5472 .upload-success {
5473 padding: 1.5rem;
5474 background: var(--surface-muted);
5475 text-align: center;
5476 }
5477 .upload-error {
5478 padding: 1.5rem;
5479 background: var(--surface-muted);
5480 text-align: center;
5481 }
5482
5483 .hidden {
5484 display: none !important;
5485 }
5486
5487 /* ===========================================
5488 VIEW TOGGLE (Grid/List)
5489 =========================================== */
5490
5491 .view-controls {
5492 display: flex;
5493 gap: 0.25rem;
5494 margin-left: auto;
5495 }
5496
5497 .view-btn {
5498 background: var(--surface-muted);
5499 border: none;
5500 padding: 0.4rem 0.6rem;
5501 font-family: var(--font-mono);
5502 font-size: 0.9rem;
5503 cursor: pointer;
5504 opacity: 0.5;
5505 transition: opacity 0.2s ease;
5506 }
5507
5508 .view-btn:hover {
5509 opacity: 0.8;
5510 }
5511
5512 .view-btn.is-selected {
5513 opacity: 1;
5514 background: var(--primary-dark);
5515 color: var(--primary-light);
5516 }
5517 .results-container.results-list .results-table {
5518 display: block;
5519 }
5520
5521 .results-container.results-grid .results-table {
5522 display: none;
5523 }
5524
5525 .results-container.results-grid .results-grid {
5526 display: grid;
5527 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
5528 gap: 1.5rem;
5529 border: 1px solid var(--border);
5530 border-top: none;
5531 padding: 1.5rem;
5532 background: var(--light-background);
5533 }
5534
5535 /* Grid cards */
5536 .grid-card {
5537 background: var(--surface-alt);
5538 text-decoration: none;
5539 color: var(--detail);
5540 display: flex;
5541 flex-direction: column;
5542 transition: background 0.2s ease;
5543 }
5544
5545 .grid-card:hover {
5546 background: var(--surface-muted);
5547 text-decoration: none;
5548 }
5549
5550 .grid-card-thumbnail {
5551 height: 120px;
5552 background: var(--border);
5553 display: flex;
5554 align-items: center;
5555 justify-content: center;
5556 font-size: 0.8rem;
5557 opacity: 0.5;
5558 text-transform: uppercase;
5559 }
5560
5561 .grid-card-content {
5562 padding: 1rem;
5563 display: flex;
5564 flex-direction: column;
5565 gap: 0.25rem;
5566 }
5567
5568 .grid-card-title {
5569 font-family: var(--font-heading);
5570 font-size: 1.1rem;
5571 }
5572
5573 .grid-card-meta {
5574 font-size: 0.85rem;
5575 opacity: 0.6;
5576 }
5577
5578 .grid-card-footer {
5579 display: flex;
5580 justify-content: space-between;
5581 align-items: center;
5582 margin-top: 0.5rem;
5583 font-size: 0.85rem;
5584 }
5585
5586 .grid-card-category {
5587 opacity: 0.6;
5588 }
5589
5590 .grid-card-price {
5591 font-weight: bold;
5592 }
5593
5594 .grid-card-stat {
5595 opacity: 0.6;
5596 }
5597
5598 /* ===========================================
5599 PROJECT PAGE VIEW TOGGLE
5600 =========================================== */
5601
5602 .items-header {
5603 display: flex;
5604 justify-content: space-between;
5605 align-items: center;
5606 margin-bottom: 1.5rem;
5607 }
5608
5609 .items-header .section-header {
5610 margin-bottom: 0;
5611 border-bottom: none;
5612 padding-bottom: 0;
5613 }
5614
5615 /* Grid view is default on project page */
5616 .items-container.items-grid-view .items-grid {
5617 display: grid;
5618 }
5619
5620 .items-container.items-grid-view .items-list {
5621 display: none;
5622 }
5623
5624 .items-container.items-list-view .items-grid {
5625 display: none;
5626 }
5627
5628 .items-container.items-list-view .items-list {
5629 display: block;
5630 }
5631
5632 /* List items styling */
5633 .items-list {
5634 display: none;
5635 }
5636
5637 .list-item {
5638 display: flex;
5639 justify-content: space-between;
5640 align-items: center;
5641 padding: 1rem 1.25rem;
5642 background: var(--light-background);
5643 margin-bottom: 0.5rem;
5644 text-decoration: none;
5645 color: var(--detail);
5646 transition: background 0.2s ease;
5647 }
5648
5649 .list-item:hover {
5650 background: var(--surface-muted);
5651 text-decoration: none;
5652 }
5653
5654 .list-item-info {
5655 display: flex;
5656 flex-direction: column;
5657 gap: 0.25rem;
5658 }
5659
5660 .list-item-title {
5661 font-family: var(--font-heading);
5662 font-size: 1.1rem;
5663 }
5664
5665 .list-item-meta {
5666 font-size: 0.85rem;
5667 opacity: 0.6;
5668 }
5669
5670 .list-item-price {
5671 font-size: 1.1rem;
5672 font-weight: bold;
5673 }
5674
5675 /* ===========================================
5676 LANDING PAGE
5677 =========================================== */
5678
5679 .landing-hero {
5680 max-width: 720px;
5681 width: 100%;
5682 text-align: center;
5683 }
5684
5685 .landing-headline {
5686 font-family: var(--font-heading);
5687 font-size: 1.4rem;
5688 margin-bottom: 0.5rem;
5689 }
5690
5691 .landing-sub {
5692 font-size: 1rem;
5693 line-height: 1.6;
5694 opacity: 0.75;
5695 margin-bottom: 0;
5696 }
5697
5698 .landing-fork {
5699 display: grid;
5700 grid-template-columns: 1fr 1fr;
5701 gap: 1rem;
5702 margin-top: 2rem;
5703 text-align: left;
5704 }
5705
5706 .fork-heading {
5707 font-family: var(--font-mono);
5708 font-size: 0.9rem;
5709 font-weight: 600;
5710 text-transform: uppercase;
5711 letter-spacing: 0.05em;
5712 margin-bottom: 1rem;
5713 }
5714
5715 .fork-list {
5716 list-style: none;
5717 margin: 0;
5718 padding: 0;
5719 flex: 1;
5720 }
5721
5722 .fork-list li {
5723 margin-bottom: 0.6rem;
5724 font-size: 0.9rem;
5725 line-height: 1.5;
5726 }
5727
5728 .fork-list strong {
5729 font-family: var(--font-mono);
5730 font-size: 0.8rem;
5731 }
5732
5733 .fork-actions {
5734 margin-top: 1.25rem;
5735 display: flex;
5736 flex-direction: column;
5737 align-items: center;
5738 gap: 0.5rem;
5739 }
5740
5741 .fork-actions .big-button {
5742 width: 100%;
5743 }
5744
5745 .fork-secondary-link {
5746 font-family: var(--font-mono);
5747 font-size: 0.8rem;
5748 opacity: 0.6;
5749 transition: opacity 0.2s ease;
5750 }
5751
5752 .fork-secondary-link:hover {
5753 opacity: 1;
5754 }
5755
5756 .founder-tagline {
5757 font-family: var(--font-body);
5758 font-size: 0.95rem;
5759 line-height: 1.55;
5760 margin: 1.25rem auto 0;
5761 max-width: 560px;
5762 color: var(--text);
5763 }
5764
5765 .founder-tagline-mark {
5766 font-family: var(--font-mono);
5767 font-size: 0.75rem;
5768 font-weight: 600;
5769 text-transform: uppercase;
5770 letter-spacing: 0.08em;
5771 color: var(--highlight);
5772 padding: 0.15rem 0.5rem;
5773 border: 1px solid var(--highlight);
5774 border-radius: 3px;
5775 margin-right: 0.4rem;
5776 white-space: nowrap;
5777 }
5778
5779 .fork-card--founder {
5780 border-color: var(--highlight);
5781 box-shadow: 0 0 0 1px var(--highlight-faint);
5782 }
5783
5784 .founder-tier-grid {
5785 display: grid;
5786 grid-template-columns: 1fr 1fr;
5787 gap: 0.4rem 0.75rem;
5788 margin-bottom: 0.85rem;
5789 padding-bottom: 0.85rem;
5790 border-bottom: 1px dashed var(--border);
5791 }
5792
5793 .founder-tier {
5794 display: flex;
5795 flex-direction: column;
5796 gap: 0.1rem;
5797 }
5798
5799 .founder-tier-name {
5800 font-family: var(--font-mono);
5801 font-size: 0.7rem;
5802 font-weight: 600;
5803 text-transform: uppercase;
5804 letter-spacing: 0.05em;
5805 opacity: 0.7;
5806 }
5807
5808 .founder-tier-price {
5809 font-family: var(--font-heading);
5810 font-size: 1rem;
5811 line-height: 1.1;
5812 }
5813
5814 .founder-tier-price del {
5815 opacity: 0.4;
5816 margin-right: 0.25rem;
5817 font-weight: 400;
5818 }
5819
5820 .founder-tier-price strong {
5821 color: var(--highlight);
5822 font-weight: 700;
5823 }
5824
5825 .founder-tier-unit {
5826 font-family: var(--font-mono);
5827 font-size: 0.75rem;
5828 opacity: 0.6;
5829 margin-left: 0.1rem;
5830 }
5831
5832 .founder-slots {
5833 font-family: var(--font-mono);
5834 font-size: 0.8rem;
5835 margin: 0 0 1rem;
5836 line-height: 1.3;
5837 }
5838
5839 .founder-slots-number {
5840 font-family: var(--font-heading);
5841 font-size: 1.4rem;
5842 color: var(--highlight);
5843 font-weight: 700;
5844 margin-right: 0.25rem;
5845 }
5846
5847 .founder-slots-cap {
5848 opacity: 0.55;
5849 margin-left: 0.25rem;
5850 }
5851
5852 .founder-slots--cap {
5853 opacity: 0.7;
5854 font-size: 0.75rem;
5855 }
5856
5857 .landing-stats-line {
5858 font-family: var(--font-mono);
5859 font-size: 0.85rem;
5860 opacity: 0.6;
5861 margin-top: 2rem;
5862 }
5863
5864 .landing-stats-line a {
5865 opacity: 0.8;
5866 transition: opacity 0.2s ease;
5867 }
5868
5869 .landing-stats-line a:hover {
5870 opacity: 1;
5871 }
5872
5873 .landing-principles {
5874 margin-top: 2rem;
5875 width: 100%;
5876 }
5877
5878 .landing-use-cases {
5879 margin-top: 2rem;
5880 width: 100%;
5881 }
5882
5883 .use-case-line {
5884 font-family: var(--font-mono);
5885 font-size: 0.85rem;
5886 opacity: 0.7;
5887 letter-spacing: 0.02em;
5888 }
5889
5890 .landing-prose {
5891 font-size: 1.05rem;
5892 line-height: 1.7;
5893 margin-bottom: 0.5rem;
5894 }
5895
5896 .notify-form {
5897 display: flex;
5898 gap: 0.5rem;
5899 max-width: 400px;
5900 margin: 0 auto;
5901 }
5902
5903 .notify-input {
5904 flex: 1;
5905 padding: 0.5rem 0.75rem;
5906 border: 1px solid var(--border);
5907 border-radius: 4px;
5908 font-family: var(--font-body);
5909 font-size: 0.9rem;
5910 background: var(--background);
5911 color: var(--text);
5912 }
5913
5914 .notify-status {
5915 font-family: var(--font-mono);
5916 font-size: 0.8rem;
5917 text-align: center;
5918 margin-top: 0.5rem;
5919 min-height: 1.2em;
5920 }
5921
5922 .notify-status.success {
5923 color: var(--text);
5924 }
5925
5926 .notify-status.error {
5927 color: var(--danger);
5928 }
5929
5930 .section-label {
5931 font-family: var(--font-mono);
5932 font-size: 0.85rem;
5933 letter-spacing: 0.05em;
5934 text-transform: uppercase;
5935 opacity: 0.6;
5936 margin-bottom: 1.25rem;
5937 }
5938
5939 .tier-section {
5940 margin: 2rem 0;
5941 width: 100%;
5942 }
5943 /* Marketing pricing variant of .card--bordered. */
5944 .tier-name {
5945 font-family: var(--font-mono);
5946 font-size: 0.85rem;
5947 font-weight: 600;
5948 margin-bottom: 0.15rem;
5949 }
5950
5951 .tier-price {
5952 font-family: var(--font-heading);
5953 font-size: 1.1rem;
5954 margin-bottom: 0.25rem;
5955 }
5956
5957 .tier-desc {
5958 font-size: 0.85rem;
5959 opacity: 0.7;
5960 }
5961
5962 .tier-card.planned {
5963 opacity: 0.5;
5964 border-style: dashed;
5965 position: relative;
5966 }
5967 .landing-cta {
5968 display: flex;
5969 align-items: center;
5970 justify-content: center;
5971 gap: 2rem;
5972 width: fit-content;
5973 margin: 1.5rem auto 2rem;
5974 }
5975 .secondary-links {
5976 display: flex;
5977 gap: 1.5rem;
5978 justify-content: center;
5979 margin-top: 1rem;
5980 }
5981
5982 .secondary-links a {
5983 font-size: 0.9rem;
5984 opacity: 0.6;
5985 transition: opacity 0.2s ease;
5986 }
5987
5988 .secondary-links a:hover {
5989 opacity: 1;
5990 }
5991 .section-link {
5992 display: block;
5993 margin-top: 0.75rem;
5994 font-family: var(--font-mono);
5995 font-size: 0.8rem;
5996 opacity: 0.55;
5997 transition: opacity 0.2s ease;
5998 }
5999
6000 .section-link:hover {
6001 opacity: 1;
6002 }
6003
6004 .feature-grid {
6005 display: grid;
6006 grid-template-columns: 1fr 1fr;
6007 gap: 0.75rem;
6008 text-align: left;
6009 }
6010
6011 .feature-name {
6012 font-family: var(--font-mono);
6013 font-size: 0.85rem;
6014 font-weight: 600;
6015 margin-bottom: 0.25rem;
6016 }
6017
6018 .feature-desc {
6019 font-size: 0.85rem;
6020 opacity: 0.7;
6021 }
6022
6023 .how-list {
6024 list-style: none;
6025 margin: 0;
6026 padding: 0;
6027 text-align: left;
6028 }
6029
6030 .how-list li {
6031 margin-bottom: 0.6rem;
6032 font-size: 0.95rem;
6033 }
6034
6035 .how-list strong {
6036 font-family: var(--font-mono);
6037 font-size: 0.85rem;
6038 }
6039
6040 .explore-links {
6041 display: flex;
6042 flex-wrap: wrap;
6043 gap: 1rem 1.5rem;
6044 justify-content: center;
6045 }
6046
6047 .explore-links a {
6048 font-family: var(--font-mono);
6049 font-size: 0.85rem;
6050 opacity: 0.7;
6051 transition: opacity 0.2s ease;
6052 }
6053
6054 .explore-links a:hover {
6055 opacity: 1;
6056 }
6057
6058 /* ===========================================
6059 PRICING CALCULATOR
6060 =========================================== */
6061
6062 .pricing-page {
6063 max-width: 800px;
6064 }
6065
6066 .pricing-input-wrap {
6067 display: flex;
6068 align-items: baseline;
6069 justify-content: center;
6070 gap: 0.25rem;
6071 }
6072
6073 .pricing-currency {
6074 font-family: var(--font-heading);
6075 font-size: 2.5rem;
6076 opacity: 0.5;
6077 }
6078
6079 .pricing-input {
6080 font-family: var(--font-heading);
6081 font-size: 2.5rem;
6082 width: 5ch;
6083 text-align: center;
6084 background: transparent;
6085 border: none;
6086 border-bottom: 2px solid var(--border);
6087 color: var(--detail);
6088 padding: 0.25rem 0;
6089 -moz-appearance: textfield;
6090 }
6091
6092 .pricing-input::-webkit-inner-spin-button,
6093 .pricing-input::-webkit-outer-spin-button {
6094 -webkit-appearance: none;
6095 margin: 0;
6096 }
6097
6098 .pricing-input:focus {
6099 outline: none;
6100 border-bottom-color: var(--highlight);
6101 }
6102
6103 .pricing-period {
6104 font-family: var(--font-mono);
6105 font-size: 1rem;
6106 opacity: 0.5;
6107 }
6108
6109 .tier-selector {
6110 display: grid;
6111 grid-template-columns: 1fr 1fr;
6112 gap: 0.75rem;
6113 text-align: left;
6114 }
6115
6116 .tier-option {
6117 cursor: pointer;
6118 transition: border-color 0.15s ease;
6119 }
6120
6121 .tier-option input[type="radio"] {
6122 position: absolute;
6123 opacity: 0;
6124 pointer-events: none;
6125 }
6126
6127 .tier-option:focus-within {
6128 outline: 2px solid var(--focus-ring);
6129 outline-offset: 2px;
6130 }
6131
6132 .tier-option.is-selected {
6133 border-color: var(--highlight);
6134 border-width: 2px;
6135 padding: calc(1rem - 1px);
6136 }
6137
6138 .mnw-summary {
6139 text-align: center;
6140 padding: 1.5rem;
6141 background: var(--light-background);
6142 border: 1px solid var(--border);
6143 }
6144
6145 .mnw-keep {
6146 font-family: var(--font-heading);
6147 font-size: 2.5rem;
6148 margin-bottom: 0.5rem;
6149 }
6150
6151 .mnw-detail {
6152 font-size: 0.9rem;
6153 opacity: 0.7;
6154 }
6155
6156 .data-table .highlight {
6157 background: var(--light-background);
6158 border-left: 3px solid var(--highlight);
6159 }
6160
6161 .savings-positive {
6162 color: var(--success);
6163 font-weight: 600;
6164 }
6165
6166 .savings-negative {
6167 color: var(--danger);
6168 }
6169
6170 .pricing-disclaimer {
6171 font-size: 0.8rem;
6172 opacity: 0.55;
6173 margin-top: 0.75rem;
6174 line-height: 1.5;
6175 }
6176
6177 .breakeven-note {
6178 font-family: var(--font-mono);
6179 font-size: 0.85rem;
6180 padding: 1rem;
6181 background: var(--light-background);
6182 border-left: 3px solid var(--warning);
6183 line-height: 1.6;
6184 }
6185
6186 /* ===========================================
6187 DOCUMENTATION PAGES
6188 =========================================== */
6189
6190 .doc-container {
6191 max-width: 680px;
6192 margin: 0 auto;
6193 padding: 3rem 1.5rem 5rem;
6194 }
6195
6196 .doc-breadcrumb {
6197 font-family: var(--font-mono);
6198 font-size: 0.875rem;
6199 margin-bottom: 2rem;
6200 }
6201
6202 .doc-breadcrumb a { color: var(--detail); text-decoration: none; }
6203 .doc-breadcrumb a:hover { text-decoration: underline; }
6204
6205 .doc-title {
6206 font-family: var(--font-heading);
6207 font-size: 2.5rem;
6208 font-weight: normal;
6209 line-height: 1.2;
6210 margin-bottom: 1.5rem;
6211 color: var(--detail);
6212 text-align: left;
6213 }
6214
6215 .doc-body {
6216 font-family: var(--font-body);
6217 font-size: 1.125rem;
6218 line-height: 1.9;
6219 }
6220
6221 .doc-body p { margin-bottom: 1.5rem; }
6222
6223 .doc-body h1 {
6224 font-family: var(--font-heading);
6225 font-size: 2rem;
6226 font-weight: normal;
6227 margin-top: 3rem;
6228 margin-bottom: 1rem;
6229 color: var(--detail);
6230 text-align: left;
6231 }
6232
6233 .doc-body h2 {
6234 font-family: var(--font-mono);
6235 font-size: 1.75rem;
6236 font-weight: normal;
6237 margin-top: 3rem;
6238 margin-bottom: 1rem;
6239 color: var(--detail);
6240 }
6241
6242 .doc-body h3 {
6243 font-family: var(--font-mono);
6244 font-size: 1.375rem;
6245 font-weight: normal;
6246 margin-top: 2.5rem;
6247 margin-bottom: 0.75rem;
6248 color: var(--detail);
6249 }
6250
6251 .doc-body blockquote {
6252 border-left: 3px solid var(--highlight);
6253 padding-left: 1.5rem;
6254 margin: 2rem 0;
6255 font-style: italic;
6256 color: var(--text-muted);
6257 }
6258
6259 .doc-body ul, .doc-body ol { margin-bottom: 1.5rem; padding-left: 1.5rem; }
6260 .doc-body li { margin-bottom: 0.5rem; }
6261
6262 .doc-body a {
6263 color: var(--highlight);
6264 text-decoration: underline;
6265 text-decoration-color: rgba(108, 92, 231, 0.4);
6266 text-underline-offset: 2px;
6267 }
6268
6269 .doc-body a:hover { text-decoration-color: var(--highlight); }
6270 .doc-body strong { font-weight: bold; }
6271 .doc-body em { font-style: italic; }
6272
6273 .doc-body code {
6274 font-family: var(--font-mono);
6275 background: var(--surface-muted);
6276 padding: 0.125rem 0.375rem;
6277 font-size: 0.9em;
6278 }
6279
6280 .doc-body pre {
6281 background: var(--surface-muted);
6282 padding: 1rem;
6283 overflow-x: auto;
6284 margin-bottom: 1.5rem;
6285 }
6286
6287 .doc-body pre code { background: none; padding: 0; }
6288
6289 .doc-body hr { border: none; text-align: center; margin: 3rem 0; }
6290 .doc-body hr::before { content: "* * *"; color: var(--text-muted); letter-spacing: 1rem; }
6291
6292 .doc-body table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; }
6293 .doc-body th, .doc-body td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border); }
6294 .doc-body th { font-family: var(--font-mono); font-weight: 600; }
6295
6296 .text-reader-footer {
6297 font-family: var(--font-mono);
6298 text-align: center;
6299 padding: 2rem;
6300 font-size: 0.875rem;
6301 color: var(--text-muted);
6302 border-top: 1px solid var(--border);
6303 }
6304
6305 .text-reader-footer a { color: var(--detail); text-decoration: none; }
6306 .text-reader-footer a:hover { text-decoration: underline; }
6307
6308 /* Docs index page */
6309 .docs-index {
6310 max-width: 680px;
6311 margin: 0 auto;
6312 padding: 3rem 1.5rem 5rem;
6313 }
6314
6315 .docs-index-title {
6316 font-family: var(--font-heading);
6317 font-size: 2.5rem;
6318 font-weight: normal;
6319 line-height: 1.2;
6320 margin-bottom: 2.5rem;
6321 color: var(--detail);
6322 }
6323
6324 .docs-section {
6325 margin-bottom: 2.5rem;
6326 }
6327
6328 .docs-section h2 {
6329 font-family: var(--font-mono);
6330 font-size: 1.25rem;
6331 font-weight: normal;
6332 color: var(--text-muted);
6333 margin-bottom: 0.75rem;
6334 }
6335
6336 .docs-section ul {
6337 list-style: none;
6338 padding: 0;
6339 margin: 0;
6340 }
6341
6342 .docs-section li {
6343 margin-bottom: 0.5rem;
6344 }
6345
6346 .docs-section a {
6347 font-family: var(--font-body);
6348 font-size: 1.125rem;
6349 color: var(--detail);
6350 text-decoration: none;
6351 }
6352
6353 .docs-section a:hover {
6354 color: var(--highlight);
6355 text-decoration: underline;
6356 }
6357
6358 .docs-section details {
6359 margin-bottom: 1rem;
6360 }
6361
6362 .docs-section summary {
6363 font-family: var(--font-mono);
6364 font-size: 1rem;
6365 color: var(--text-muted);
6366 cursor: pointer;
6367 padding: 0.25rem 0;
6368 list-style: disclosure-closed;
6369 }
6370
6371 .docs-section details[open] > summary {
6372 list-style: disclosure-open;
6373 margin-bottom: 0.25rem;
6374 }
6375
6376 .docs-section summary:hover {
6377 color: var(--detail);
6378 }
6379
6380 .docs-section details ul {
6381 padding-left: 1.25rem;
6382 }
6383
6384 /* Docs search */
6385 .docs-search-container {
6386 position: relative;
6387 margin-bottom: 2rem;
6388 }
6389 .docs-search-inline {
6390 display: inline-block;
6391 margin-bottom: 0;
6392 margin-left: auto;
6393 float: right;
6394 }
6395 .docs-search-input {
6396 width: 100%;
6397 max-width: 320px;
6398 padding: 0.5rem 0.75rem;
6399 font-family: var(--font-body);
6400 font-size: 0.95rem;
6401 background: var(--surface-muted);
6402 border: 1px solid var(--border);
6403 color: var(--detail);
6404 }
6405 .docs-search-input:focus {
6406 outline: 2px solid var(--highlight);
6407 border-color: var(--highlight);
6408 }
6409 .docs-search-input::placeholder { opacity: 0.5; }
6410 .docs-search-results {
6411 position: absolute;
6412 top: 100%;
6413 left: 0;
6414 right: 0;
6415 max-width: 320px;
6416 background: var(--background);
6417 border: 1px solid var(--border);
6418 border-top: none;
6419 max-height: 300px;
6420 overflow-y: auto;
6421 z-index: 20;
6422 box-shadow: 0 4px 8px rgba(0,0,0,0.08);
6423 }
6424 .docs-search-result {
6425 display: flex;
6426 justify-content: space-between;
6427 align-items: baseline;
6428 padding: 0.5rem 0.75rem;
6429 text-decoration: none;
6430 color: var(--detail);
6431 font-size: 0.9rem;
6432 border-bottom: 1px solid var(--border);
6433 }
6434 .docs-search-result:last-child { border-bottom: none; }
6435 .docs-search-result:hover { background: var(--surface-muted); }
6436 .docs-search-result-title { font-family: var(--font-body); }
6437 .docs-search-result-section { font-family: var(--font-mono); font-size: 0.75rem; opacity: 0.5; }.alert .alert-title {
6438 font-family: var(--font-mono);
6439 font-size: 0.85rem;
6440 font-weight: bold;
6441 text-transform: uppercase;
6442 letter-spacing: 0.04em;
6443 margin-bottom: 0.25rem;
6444 }
6445 .alert p:last-child { margin-bottom: 0; }
6446 .alert-note { border-left-color: var(--focus-ring); }
6447 .alert-note .alert-title { color: var(--focus-ring); }
6448 .alert-tip { border-left-color: var(--success); }
6449 .alert-tip .alert-title { color: var(--success); }
6450 .alert-important { border-left-color: var(--highlight); }
6451 .alert-important .alert-title { color: var(--highlight); }
6452 .alert-warning { border-left-color: var(--warning); }
6453 .alert-warning .alert-title { color: var(--warning); }
6454 .alert-caution { border-left-color: var(--danger); }
6455 .alert-caution .alert-title { color: var(--danger); }
6456
6457 /* ===========================================
6458 USE CASES PAGE
6459 =========================================== */
6460
6461 .use-cases-page {
6462 max-width: 900px;
6463 margin: 0 auto;
6464 }
6465
6466 .use-cases-intro {
6467 font-size: 1.1rem;
6468 margin-bottom: 2rem;
6469 line-height: 1.6;
6470 }
6471
6472 .use-case-grid {
6473 display: grid;
6474 grid-template-columns: 1fr 1fr 1fr;
6475 gap: 0.75rem;
6476 text-align: left;
6477 }
6478
6479 .use-case-grid-2col {
6480 grid-template-columns: 1fr 1fr;
6481 }
6482
6483 .use-case-card.coming-soon {
6484 border-style: dashed;
6485 opacity: 0.6;
6486 }
6487
6488 .use-case-title {
6489 font-family: var(--font-heading);
6490 font-size: 1.1rem;
6491 margin-bottom: 0.15rem;
6492 }
6493
6494 .use-case-who {
6495 font-family: var(--font-mono);
6496 font-size: 0.8rem;
6497 opacity: 0.6;
6498 margin-bottom: 0.5rem;
6499 }
6500
6501 .use-case-desc {
6502 font-size: 0.9rem;
6503 line-height: 1.5;
6504 margin-bottom: 0.5rem;
6505 }
6506
6507 .use-case-features {
6508 list-style: none;
6509 margin: 0 0 0.75rem;
6510 padding: 0;
6511 }
6512
6513 .use-case-features li {
6514 font-size: 0.85rem;
6515 padding-left: 1rem;
6516 position: relative;
6517 margin-bottom: 0.25rem;
6518 }
6519
6520 .use-case-features li::before {
6521 content: "-";
6522 position: absolute;
6523 left: 0;
6524 opacity: 0.5;
6525 }
6526
6527 .use-case-tier {
6528 font-family: var(--font-mono);
6529 font-size: 0.75rem;
6530 opacity: 0.5;
6531 }
6532
6533 /* ===========================================
6534 RESPONSIVE — 768px (tablet)
6535 =========================================== */
6536
6537 /* ==========================================================================
6538 Git Source Browser
6539 ========================================================================== */
6540
6541 .git-repo-header { margin-bottom: 1.5rem; }
6542 .git-repo-name { font-size: 1.5rem; margin: 0 0 0.25rem; }
6543 .git-repo-name a { color: var(--detail); text-decoration: none; }
6544 .git-repo-name a:hover { opacity: 0.6; }
6545 .git-repo-name .sep { opacity: 0.3; margin: 0 0.15rem; }
6546 .git-repo-desc { opacity: 0.6; margin: 0 0 1rem; font-size: 0.9rem; }
6547 .git-clone-url {
6548 font-family: var(--font-mono);
6549 font-size: 0.8rem;
6550 padding: 0.4rem 0.6rem;
6551 background: var(--secondary-bg);
6552 border: 1px solid var(--border);
6553 border-radius: 3px;
6554 display: inline-block;
6555 user-select: all;
6556 margin-bottom: 1rem;
6557 }
6558 .git-linked-project { margin-top: 0.5rem; font-size: 0.9rem; }
6559 .git-linked-project a { color: var(--detail); }
6560
6561 /* Ref bar (branch/tag selector + nav links) */
6562 .git-ref-bar {
6563 display: flex;
6564 align-items: center;
6565 gap: 1rem;
6566 margin-bottom: 1rem;
6567 font-size: 0.85rem;
6568 }
6569 .git-ref-select {
6570 font-family: var(--font-mono);
6571 font-size: 0.8rem;
6572 padding: 0.3rem 0.5rem;
6573 background: var(--secondary-bg);
6574 border: 1px solid var(--border);
6575 border-radius: 3px;
6576 }
6577 .git-nav-links { display: flex; gap: 1rem; }
6578 .git-nav-links a { text-decoration: none; color: var(--detail); opacity: 0.6; }
6579 .git-nav-links a:hover,
6580 .git-nav-links a.is-selected { opacity: 1; }
6581
6582 /* Breadcrumb navigation */
6583 .git-breadcrumb {
6584 font-family: var(--font-mono);
6585 font-size: 0.85rem;
6586 margin-bottom: 1rem;
6587 }
6588 .git-breadcrumb a { color: var(--detail); text-decoration: none; }
6589 .git-breadcrumb a:hover { text-decoration: underline; }
6590 .git-breadcrumb .sep { opacity: 0.3; margin: 0 0.15rem; }
6591
6592 /* File tree table */
6593 .git-tree { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
6594 .git-tree th {
6595 text-align: left;
6596 padding: 0.4rem 0.6rem;
6597 border-bottom: 2px solid var(--border);
6598 font-family: var(--font-mono);
6599 font-size: 0.75rem;
6600 opacity: 0.5;
6601 text-transform: uppercase;
6602 }
6603 .git-tree td { padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border); }
6604 .git-tree tr:last-child td { border-bottom: none; }
6605 .git-tree .icon { width: 1.5rem; text-align: center; opacity: 0.4; font-family: var(--font-mono); }
6606 .tree-icon-dir { font-weight: 700; color: var(--detail); }
6607 .tree-icon-file { font-size: 1.2em; }
6608 .git-tree .name a { text-decoration: none; color: var(--text); }
6609 .git-tree .name a:hover { text-decoration: underline; }
6610 .git-tree .size {
6611 text-align: right;
6612 opacity: 0.5;
6613 font-family: var(--font-mono);
6614 font-size: 0.8rem;
6615 }
6616
6617 /* README rendering */
6618 .git-readme { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--border); }
6619 .git-readme h2 { font-size: 1rem; opacity: 0.5; margin-bottom: 1rem; }
6620 .git-readme-body { line-height: 1.6; }
6621 .git-readme-body h1,
6622 .git-readme-body h2,
6623 .git-readme-body h3 { margin-top: 1.5rem; margin-bottom: 0.5rem; }
6624 .git-readme-body pre {
6625 background: var(--secondary-bg);
6626 padding: 0.8rem;
6627 border-radius: 3px;
6628 overflow-x: auto;
6629 font-family: var(--font-mono);
6630 font-size: 0.8rem;
6631 }
6632 .git-readme-body code {
6633 font-family: var(--font-mono);
6634 font-size: 0.85em;
6635 background: var(--secondary-bg);
6636 padding: 0.15rem 0.3rem;
6637 border-radius: 2px;
6638 }
6639 .git-readme-body pre code { background: none; padding: 0; }
6640 .git-readme-body table { border-collapse: collapse; margin: 1rem 0; }
6641 .git-readme-body th,
6642 .git-readme-body td { border: 1px solid var(--border); padding: 0.4rem 0.6rem; }
6643
6644 /* File viewer */
6645 .git-file-header {
6646 display: flex;
6647 justify-content: space-between;
6648 align-items: center;
6649 padding: 0.5rem 0.6rem;
6650 background: var(--secondary-bg);
6651 border: 1px solid var(--border);
6652 border-bottom: none;
6653 border-radius: 3px 3px 0 0;
6654 font-size: 0.8rem;
6655 }
6656 .git-file-meta {
6657 font-family: var(--font-mono);
6658 opacity: 0.6;
6659 }
6660 .git-file-actions a {
6661 font-family: var(--font-mono);
6662 text-decoration: none;
6663 color: var(--detail);
6664 opacity: 0.6;
6665 font-size: 0.8rem;
6666 }
6667 .git-file-actions a:hover { opacity: 1; }
6668 .git-file-content {
6669 border: 1px solid var(--border);
6670 border-radius: 0 0 3px 3px;
6671 overflow-x: auto;
6672 }
6673 .git-file-content table { border-collapse: collapse; width: 100%; }
6674 .git-file-content .line-number {
6675 width: 1px;
6676 white-space: nowrap;
6677 padding: 0 0.8rem;
6678 text-align: right;
6679 user-select: none;
6680 opacity: 0.3;
6681 font-family: var(--font-mono);
6682 font-size: 0.8rem;
6683 border-right: 1px solid var(--border);
6684 vertical-align: top;
6685 }
6686 .git-file-content .line-code {
6687 padding: 0 0.8rem;
6688 white-space: pre;
6689 font-family: var(--font-mono);
6690 font-size: 0.8rem;
6691 line-height: 1.5;
6692 }
6693 .git-file-content .line-code span {
6694 font-family: var(--font-mono);
6695 }
6696 .git-binary-notice {
6697 padding: 2rem;
6698 text-align: center;
6699 opacity: 0.5;
6700 font-family: var(--font-mono);
6701 font-size: 0.85rem;
6702 border: 1px solid var(--border);
6703 border-radius: 0 0 3px 3px;
6704 }
6705
6706 /* Syntax highlighting (syntect class-based) */
6707 .git-file-content .source { color: var(--text); }
6708 .git-file-content .keyword,
6709 .git-file-content .storage { color: #8959a8; }
6710 .git-file-content .string { color: #718c00; }
6711 .git-file-content .comment { color: #8e908c; font-style: italic; }
6712 .git-file-content .constant,
6713 .git-file-content .constant.numeric { color: #f5871f; }
6714 .git-file-content .entity.name { color: #4271ae; }
6715 .git-file-content .variable { color: #c82829; }
6716 .git-file-content .support { color: #3e999f; }
6717 .git-file-content .meta.preprocessor { color: #8959a8; }
6718
6719 /* Commit list */
6720 .git-commit-list { list-style: none; }
6721 .git-commit { padding: 0.75rem 0; border-bottom: 1px solid var(--border); }
6722 .git-commit:last-child { border-bottom: none; }
6723 .git-commit-message { font-size: 0.9rem; margin: 0 0 0.3rem; }
6724 .git-commit-message .summary { font-weight: 600; }
6725 .git-commit-meta {
6726 font-family: var(--font-mono);
6727 font-size: 0.75rem;
6728 opacity: 0.5;
6729 display: flex;
6730 gap: 1rem;
6731 flex-wrap: wrap;
6732 }
6733 .git-commit-oid { font-family: var(--font-mono); font-size: 0.75rem; }
6734 .git-commit-oid a { color: var(--detail); text-decoration: none; }
6735 .git-commit-oid a:hover { text-decoration: underline; }
6736 .git-pagination {
6737 display: flex;
6738 justify-content: center;
6739 gap: 1rem;
6740 margin-top: 1.5rem;
6741 padding-top: 1rem;
6742 font-size: 0.85rem;
6743 }
6744 .git-pagination a { color: var(--detail); text-decoration: none; }
6745 .git-pagination a:hover { text-decoration: underline; }
6746
6747 /* Release items on repo page */
6748 .git-release { margin-bottom: 1.5rem; padding: 1rem; background: var(--light-background); }
6749 .git-release-title { margin: 0 0 0.25rem; font-size: 1.1rem; }
6750 .git-release-title a { color: var(--text); text-decoration: none; }
6751 .git-release-meta { font-size: 0.85rem; opacity: 0.6; margin-bottom: 0.5rem; }
6752 .git-release-desc { font-size: 0.9rem; opacity: 0.8; margin-bottom: 0.75rem; }
6753 .git-release-versions { font-size: 0.8rem; }
6754 .git-release-version {
6755 display: flex;
6756 gap: 0.75rem;
6757 align-items: center;
6758 padding: 0.3rem 0;
6759 border-top: 1px solid var(--border);
6760 }
6761 .git-release-version .version-number { font-family: var(--font-mono); }
6762 .git-release-version .version-badge {
6763 font-size: 0.7rem;
6764 padding: 0.1rem 0.4rem;
6765 background: var(--detail);
6766 color: var(--background);
6767 border-radius: 2px;
6768 }
6769 .git-release-version .version-meta { opacity: 0.5; }
6770
6771 /* Git commit detail + diff */
6772 .git-commit-detail { margin-bottom: 1.5rem; }
6773 .git-commit-full-message {
6774 font-family: var(--font-mono);
6775 font-size: 0.85rem;
6776 white-space: pre-wrap;
6777 line-height: 1.5;
6778 padding: 1rem;
6779 background: var(--light-background);
6780 border: 1px solid var(--border);
6781 margin-bottom: 1rem;
6782 }
6783 .git-commit-detail-meta { font-size: 0.85rem; opacity: 0.7; line-height: 1.8; }
6784 .git-commit-detail-meta .git-commit-oid { font-family: var(--font-mono); font-size: 0.8rem; word-break: break-all; }
6785 .git-commit-parents a { font-family: var(--font-mono); color: var(--detail); text-decoration: none; }
6786 .git-commit-parents a:hover { text-decoration: underline; }
6787 .git-diff-stats {
6788 font-size: 0.85rem;
6789 padding: 0.75rem 0;
6790 margin-bottom: 1rem;
6791 border-bottom: 1px solid var(--border);
6792 }
6793 .git-diff-stats .additions { color: var(--diff-add); }
6794 .git-diff-stats .deletions { color: var(--diff-del); }
6795 .git-diff-file { margin-bottom: 1.5rem; border: 1px solid var(--border); }
6796 .git-diff-file-header {
6797 display: flex;
6798 align-items: center;
6799 gap: 0.5rem;
6800 padding: 0.5rem 0.75rem;
6801 background: var(--light-background);
6802 border-bottom: 1px solid var(--border);
6803 font-size: 0.85rem;
6804 flex-wrap: wrap;
6805 }
6806 .git-diff-file-header a { color: var(--text); text-decoration: none; }
6807 .git-diff-file-header a:hover { text-decoration: underline; }
6808 .git-diff-file-stats { margin-left: auto; font-size: 0.8rem; }
6809 .git-diff-file-stats .additions { color: var(--diff-add); }
6810 .git-diff-file-stats .deletions { color: var(--diff-del); margin-left: 0.25rem; }
6811 .diff-status-A, .diff-status-D, .diff-status-M, .diff-status-R {
6812 display: inline-block;
6813 width: 1.2rem;
6814 text-align: center;
6815 font-size: 0.75rem;
6816 font-weight: 700;
6817 font-family: var(--font-mono);
6818 border-radius: 2px;
6819 line-height: 1.4;
6820 }
6821 .diff-status-A { background: #d4edda; color: #155724; }
6822 .diff-status-D { background: #f8d7da; color: #721c24; }
6823 .diff-status-M { background: var(--warning-bg); color: var(--warning); }
6824 .diff-status-R { background: #d1ecf1; color: #0c5460; }
6825 .git-diff-table {
6826 width: 100%;
6827 border-collapse: collapse;
6828 font-family: var(--font-mono);
6829 font-size: 0.8rem;
6830 table-layout: fixed;
6831 }
6832 .git-diff-hunk-header td {
6833 padding: 0.3rem 0.5rem;
6834 background: var(--highlight-faint);
6835 color: var(--text);
6836 opacity: 0.6;
6837 font-size: 0.75rem;
6838 }
6839 .git-diff-lineno {
6840 width: 3.5rem;
6841 padding: 0 0.4rem;
6842 text-align: right;
6843 color: var(--text);
6844 opacity: 0.35;
6845 user-select: none;
6846 vertical-align: top;
6847 }
6848 .git-diff-origin {
6849 width: 1rem;
6850 text-align: center;
6851 user-select: none;
6852 vertical-align: top;
6853 }
6854 .git-diff-content {
6855 padding: 0 0.5rem;
6856 white-space: pre-wrap;
6857 word-break: break-all;
6858 }
6859 .git-diff-line-add { background: var(--diff-add-bg); }
6860 .git-diff-line-add .git-diff-origin { color: var(--diff-add); }
6861 .git-diff-line-del { background: var(--diff-del-bg); }
6862 .git-diff-line-del .git-diff-origin { color: var(--diff-del); }
6863 .git-diff-line-ctx { background: transparent; }
6864 .git-diff-truncated { padding: 0.5rem 0.75rem; font-size: 0.8rem; opacity: 0.5; font-style: italic; }
6865
6866 /* Git file view line linking */
6867 .git-file-content .line-number a {
6868 color: inherit;
6869 text-decoration: none;
6870 display: block;
6871 }
6872 .git-file-content .line-number a:hover { opacity: 0.7; }
6873 .git-file-content tr:target td,
6874 .git-file-content tr.highlighted td { background: var(--highlight-faint); }
6875
6876 /* Git blame view */
6877 .git-blame-content { overflow-x: auto; border: 1px solid var(--border); }
6878 .git-blame-content table { border-collapse: collapse; width: 100%; font-size: 0.8rem; }
6879 .git-blame-info {
6880 padding: 0 0.4rem;
6881 font-family: var(--font-mono);
6882 white-space: nowrap;
6883 width: 4.5rem;
6884 }
6885 .git-blame-info a { color: var(--detail); text-decoration: none; }
6886 .git-blame-info a:hover { text-decoration: underline; }
6887 .git-blame-author {
6888 padding: 0 0.3rem;
6889 font-size: 0.75rem;
6890 opacity: 0.5;
6891 white-space: nowrap;
6892 max-width: 8rem;
6893 overflow: hidden;
6894 text-overflow: ellipsis;
6895 }
6896 .git-blame-date {
6897 padding: 0 0.3rem;
6898 font-size: 0.75rem;
6899 opacity: 0.35;
6900 white-space: nowrap;
6901 width: 5.5rem;
6902 }
6903 .git-blame-content .line-number {
6904 padding: 0 0.5rem;
6905 text-align: right;
6906 opacity: 0.35;
6907 user-select: none;
6908 width: 3rem;
6909 font-family: var(--font-mono);
6910 }
6911 .git-blame-content .line-code {
6912 padding: 0 0.5rem;
6913 white-space: pre;
6914 font-family: var(--font-mono);
6915 }
6916 .git-blame-boundary td { border-top: 1px solid var(--border); }
6917
6918 /* Git user repos listing */
6919 .git-repos-list { list-style: none; }
6920 .git-repos-item { padding: 0.75rem 0; border-bottom: 1px solid var(--border); }
6921 .git-repos-item:last-child { border-bottom: none; }
6922 .git-repos-item-header { display: flex; align-items: center; gap: 0.5rem; }
6923 .git-repos-item-name {
6924 font-size: 1.1rem;
6925 font-weight: 600;
6926 color: var(--detail);
6927 text-decoration: none;
6928 }
6929 .git-repos-item-name:hover { text-decoration: underline; }
6930 .git-repos-visibility {
6931 font-size: 0.7rem;
6932 padding: 0.1rem 0.4rem;
6933 border: 1px solid var(--border);
6934 border-radius: 2px;
6935 opacity: 0.5;
6936 }
6937 .git-repos-item-desc { font-size: 0.85rem; opacity: 0.6; margin: 0.25rem 0 0; }.git-repos-instructions p { margin-bottom: 0.5rem; }
6938 .git-repos-owner { opacity: 0.6; }
6939 .git-repos-item-name .sep { opacity: 0.4; }
6940 .git-file-log-label {
6941 font-family: var(--font-mono);
6942 font-size: 0.8rem;
6943 opacity: 0.5;
6944 margin-right: 0.25rem;
6945 }
6946
6947 /* Site-wide footer */
6948 .site-footer {
6949 margin-top: 4rem;
6950 padding: 2rem 0;
6951 text-align: center;
6952 font-family: var(--font-mono);
6953 font-size: 0.8rem;
6954 opacity: 0.5;
6955 }
6956 .site-footer-links { margin-bottom: 0.5rem; }
6957 .site-footer-links a { margin: 0 0.75rem; color: inherit; text-decoration: none; }
6958 .site-footer-links a:hover { text-decoration: underline; }
6959
6960 @media (max-width: 768px) {
6961 /* Git browser mobile */
6962 .git-ref-bar { flex-wrap: wrap; gap: 0.5rem; }
6963 .git-repo-name { font-size: 1.2rem; }
6964 .git-clone-url { font-size: 0.75rem; word-break: break-all; }
6965 .git-tree .icon { display: none; }
6966 .git-tree td, .git-tree th { padding: 0.3rem 0.4rem; }
6967 .git-file-header { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
6968 .git-file-content .line-number { padding: 0 0.4rem; }
6969 .git-file-content .line-code { padding: 0 0.4rem; font-size: 0.75rem; }
6970 .git-commit-meta { flex-direction: column; gap: 0.25rem; }
6971 .git-release-version { flex-wrap: wrap; gap: 0.5rem; }
6972 .git-diff-file-header { font-size: 0.8rem; }
6973 .git-diff-table { font-size: 0.7rem; }
6974 .git-diff-lineno { width: 2.5rem; font-size: 0.65rem; }
6975 .git-blame-author { display: none; }
6976 .git-blame-date { display: none; }
6977
6978 .container {
6979 padding: 1.25rem;
6980 }
6981
6982 .padded-page {
6983 padding: 1rem;
6984 }
6985
6986 .form-row {
6987 grid-template-columns: 1fr;
6988 }
6989
6990 .tab {
6991 padding: 0.6rem 1.25rem;
6992 font-size: 0.9rem;
6993 }
6994
6995 .tab-content {
6996 padding: 1.25rem;
6997 }
6998
6999 .data-table th,
7000 .data-table td {
7001 padding: 0.5rem 0.6rem;
7002 font-size: 0.85rem;
7003 }
7004
7005 .modal {
7006 max-width: 95%;
7007 }
7008
7009 .stats-grid {
7010 grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
7011 }
7012
7013 .content-section {
7014 padding: 1.25rem;
7015 }
7016
7017 .action-buttons {
7018 flex-direction: column;
7019 }
7020
7021 .action-buttons button {
7022 width: 100%;
7023 }
7024
7025 .analytics-grid {
7026 grid-template-columns: 1fr;
7027 }
7028
7029 /* Hamburger menu */
7030 .nav-toggle-label {
7031 display: block;
7032 }
7033
7034 .header-search {
7035 display: none;
7036 flex: none;
7037 margin: 0;
7038 width: 100%;
7039 }
7040
7041 .nav-toggle-checkbox:checked ~ .header-search {
7042 display: block;
7043 position: absolute;
7044 top: 100%;
7045 left: 0;
7046 right: 0;
7047 padding: 0.75rem 1.5rem;
7048 background: var(--background);
7049 border-bottom: 1px solid var(--border);
7050 z-index: 11;
7051 }
7052
7053 .site-header nav {
7054 display: none;
7055 position: absolute;
7056 top: 100%;
7057 left: 0;
7058 right: 0;
7059 background: var(--background);
7060 border-bottom: 1px solid var(--border);
7061 padding: 1rem 1.5rem;
7062 z-index: 10;
7063 }
7064
7065 .site-header {
7066 position: relative;
7067 }
7068
7069 .nav-toggle-checkbox:checked ~ nav {
7070 display: block;
7071 }
7072
7073 .site-header .nav-links {
7074 flex-direction: column;
7075 gap: 0.75rem;
7076 }
7077
7078 /* Animate hamburger to X when open */
7079 .nav-toggle-checkbox:checked ~ .nav-toggle-label span:nth-child(1) {
7080 transform: rotate(45deg) translate(5px, 5px);
7081 }
7082
7083 .nav-toggle-checkbox:checked ~ .nav-toggle-label span:nth-child(2) {
7084 opacity: 0;
7085 }
7086
7087 .nav-toggle-checkbox:checked ~ .nav-toggle-label span:nth-child(3) {
7088 transform: rotate(-45deg) translate(5px, -5px);
7089 }
7090 }
7091
7092 /* Doc pages — mobile */
7093 @media (max-width: 600px) {
7094 .doc-title { font-size: 2rem; }
7095 .doc-body { font-size: 1rem; }
7096 .docs-index-title { font-size: 2rem; }
7097 }
7098
7099 /* ===========================================
7100 RESPONSIVE — 480px (phone)
7101 =========================================== */
7102
7103 @media (max-width: 480px) {
7104 .container {
7105 padding: 0.75rem;
7106 }
7107
7108 .padded-page {
7109 padding: 0.75rem;
7110 }
7111
7112 h1 {
7113 font-size: 1.8rem;
7114 }
7115
7116 .centered-page h1 {
7117 font-size: 3rem;
7118 }
7119
7120 .login-container,
7121 .form-container {
7122 max-width: 100%;
7123 padding: 1.25rem;
7124 }
7125
7126 .big-button {
7127 width: 100%;
7128 }
7129
7130 .stats-grid {
7131 grid-template-columns: repeat(2, 1fr);
7132 }
7133
7134 .tab {
7135 padding: 0.5rem 0.75rem;
7136 font-size: 0.85rem;
7137 }
7138
7139 .tab-content {
7140 padding: 1rem;
7141 }
7142
7143 .content-section {
7144 padding: 1rem;
7145 }
7146
7147 .section-header {
7148 flex-direction: column;
7149 align-items: flex-start;
7150 gap: 0.75rem;
7151 }
7152
7153 /* Landing page (merged from 500px) */
7154 .landing-fork,
7155 .tier-selector,
7156 .feature-grid,
7157 .use-case-grid,
7158 .use-case-grid-2col {
7159 grid-template-columns: 1fr;
7160 }
7161
7162 .explore-links {
7163 flex-direction: column;
7164 align-items: center;
7165 gap: 0.75rem;
7166 }
7167
7168 .pricing-input {
7169 font-size: 2rem;
7170 }
7171
7172 .pricing-currency {
7173 font-size: 2rem;
7174 }
7175
7176 .mnw-keep {
7177 font-size: 2rem;
7178 }
7179
7180 .secondary-links {
7181 flex-direction: column;
7182 align-items: center;
7183 gap: 0.75rem;
7184 }
7185
7186 .landing-cta {
7187 flex-direction: column;
7188 gap: 1rem;
7189 }
7190
7191 .toast-container {
7192 left: 0.75rem;
7193 right: 0.75rem;
7194 bottom: 0.75rem;
7195 }
7196
7197 .toast {
7198 max-width: 100%;
7199 }
7200 }
7201
7202 /* ===========================================
7203 DISCOVER PAGE
7204 =========================================== */
7205
7206 .discover-layout { display: grid; grid-template-columns: 200px 1fr; gap: 1.5rem; }
7207 .discover-layout.no-sidebar { grid-template-columns: 1fr; }
7208 .discover-layout.no-sidebar .discover-sidebar { display: none; }
7209 .discover-sidebar { font-size: 0.85rem; }
7210 .filter-section { margin-bottom: 1.25rem; }
7211 .filter-title { font-family: var(--font-heading); font-weight: bold; font-size: 0.85rem; margin-bottom: 0.5rem; color: var(--detail); }
7212 .filter-browse-link { font-size: 0.75rem; opacity: 0.5; font-weight: normal; }
7213 .filter-list { list-style: none; }
7214 .filter-item { padding: 0.25rem 0; cursor: pointer; display: flex; justify-content: space-between; align-items: center; transition: opacity 0.1s ease; }
7215 .filter-item:hover { opacity: 0.6; }
7216 .filter-item.is-selected { font-weight: bold; }
7217 .filter-item .count { opacity: 0.4; font-size: 0.8rem; }
7218 .filter-item-right { display: flex; align-items: center; gap: 0.3rem; }
7219 .tag-follow-btn { background: none; border: 1px solid var(--border); cursor: pointer; font-family: var(--font-mono); font-size: 0.7rem; opacity: 0.55; padding: 0.1rem 0.45rem; color: var(--detail); }
7220 .tag-follow-btn:hover { opacity: 1; }
7221 .tag-follow-btn.is-selected { opacity: 0.85; border-color: var(--focus-ring); background: var(--highlight-faint); }
7222 .filter-checkbox { display: flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0; cursor: pointer; }
7223 .filter-checkbox input { width: auto; margin: 0; }
7224 .price-inputs { display: flex; gap: 0.25rem; align-items: center; margin-bottom: 0.5rem; }
7225 .price-inputs input { width: 60px; padding: 0.3rem; font-size: 0.8rem; background: var(--surface-muted); border: none; }
7226 .price-inputs span { opacity: 0.4; }
7227 .price-distribution { margin-top: 0.5rem; }
7228 .price-distribution-item { font-size: 0.8rem; opacity: 0.6; padding: 0.1rem 0; }
7229 .discover-main { min-width: 0; }
7230 .mode-toggle { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; }
7231 .toggle-btn { background: var(--surface-muted); border: none; padding: 0.4rem 0.8rem; font-size: 0.85rem; font-family: inherit; cursor: pointer; transition: background 0.1s ease, opacity 0.1s ease; }
7232 .toggle-btn:hover { opacity: 0.7; }
7233 .toggle-btn.is-selected { background: var(--primary-dark); color: var(--primary-light); }
7234 .table-controls { background: var(--surface-muted); display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0.75rem; }
7235 .search-field { flex: 1 1 0; background: var(--background); border: none; padding: 0.5rem 0.75rem; font-family: inherit; font-size: 0.9rem; color: var(--detail); min-width: 0; }
7236 .search-field:focus { outline: 2px solid var(--highlight); }
7237 .search-field::placeholder { opacity: 0.5; }
7238 .table-meta { font-size: 0.75rem; opacity: 0.6; white-space: nowrap; flex-shrink: 0; }
7239 .sort-select { background: var(--background); border: none; padding: 0.3rem 0.4rem; font-size: 0.75rem; font-family: inherit; cursor: pointer; width: auto; flex-shrink: 0; }
7240 .table-header { display: grid; grid-template-columns: 50px 1fr 100px 70px 70px; gap: 0.5rem; padding: 0.5rem 0.75rem; background: var(--surface-alt); font-size: 0.75rem; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.03em; }
7241 .table-header.projects-header { grid-template-columns: 1fr 100px 80px 70px; }
7242 .table-header span { cursor: pointer; }
7243 .table-header span:hover { opacity: 0.6; }
7244 .col-right { text-align: right; }
7245 .results-table { border: 1px solid var(--border); border-top: none; }
7246 .table-row { display: grid; grid-template-columns: 50px 1fr 100px 70px 70px; gap: 0.5rem; padding: 0.4rem 0.75rem; align-items: center; text-decoration: none; color: var(--detail); font-size: 0.85rem; border-bottom: 1px solid var(--border); transition: background 0.1s ease; }
7247 .table-row-item { grid-template-columns: 1fr 30px; padding: 0; gap: 0; }
7248 .table-row-item .table-row-link { display: grid; grid-template-columns: 50px 1fr 100px 70px 70px; gap: 0.5rem; padding: 0.4rem 0.75rem; align-items: center; text-decoration: none; color: inherit; flex: 1; }
7249 .table-row-item .row-save { display: flex; align-items: center; justify-content: center; }
7250 .table-row.project-row { grid-template-columns: 1fr 100px 80px 70px; }
7251 .table-row:last-child { border-bottom: none; }
7252 .table-row:nth-child(odd) { background: var(--light-background); }
7253 .table-row:nth-child(even) { background: var(--surface-alt); }
7254 .table-row:hover { background: var(--surface-muted); text-decoration: none; }
7255 .row-type { font-size: 0.7rem; background: var(--surface-muted); padding: 0.2rem 0.4rem; text-align: center; opacity: 0.7; }
7256 .row-info { min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
7257 .row-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
7258 .row-creator { font-size: 0.75rem; opacity: 0.5; }.row-category { font-size: 0.8rem; opacity: 0.6; }
7259 .row-price { text-align: right; }
7260 .row-items { text-align: right; opacity: 0.6; font-size: 0.8rem; }
7261 .row-date { text-align: right; opacity: 0.5; font-size: 0.75rem; }.pagination { display: flex; gap: 0.25rem; }
7262 .pagination button { background: var(--background); border: none; padding: 0.3rem 0.6rem; font-size: 0.8rem; cursor: pointer; }
7263 .pagination button:disabled { opacity: 0.3; cursor: not-allowed; }
7264 .pagination button.is-selected { background: var(--primary-dark); color: var(--primary-light); }
7265
7266 /* Issue tabs (open / closed) inside the git browser */
7267 .issue-tabs { display: flex; gap: var(--space-2); margin-bottom: var(--space-4); }
7268 .issue-tab {
7269 padding: 0.4rem 0.9rem;
7270 border: 1px solid var(--border);
7271 background: var(--surface-alt);
7272 font-family: var(--font-mono);
7273 font-size: 0.85rem;
7274 color: var(--detail);
7275 text-decoration: none;
7276 opacity: 0.7;
7277 }
7278 .issue-tab:hover { opacity: 1; }
7279 .issue-tab.is-selected {
7280 opacity: 1;
7281 background: var(--highlight-faint);
7282 border-color: var(--focus-ring);
7283 }
7284 .page-info { opacity: 0.6; }
7285 .padded-page .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px solid var(--border); }
7286 .padded-page .page-header h1 { font-size: 1.5rem; text-align: center; position: absolute; left: 50%; transform: translateX(-50%); }
7287 .padded-page .page-header nav { margin: 0; }
7288 .padded-page .page-header .nav-links { gap: 1.5rem; }
7289 .discover-filter-toggle {
7290 display: none;
7291 font-family: var(--font-mono);
7292 font-size: 0.85rem;
7293 padding: 0.4rem 0.8rem;
7294 background: var(--light-background);
7295 border: 1px solid var(--border);
7296 cursor: pointer;
7297 margin-bottom: 1rem;
7298 }
7299
7300 .discover-filter-toggle .filter-count {
7301 background: var(--highlight);
7302 color: var(--primary-light);
7303 font-size: 0.75rem;
7304 padding: 0.1rem 0.4rem;
7305 border-radius: var(--radius-sm);
7306 margin-left: 0.25rem;
7307 }
7308
7309 @media (max-width: 900px) {
7310 .discover-filter-toggle { display: inline-block; }
7311 .discover-layout { grid-template-columns: 1fr; }
7312 .discover-sidebar { display: none; }
7313 .discover-sidebar.show { display: block; margin-bottom: 1rem; }
7314 .table-header, .table-row { grid-template-columns: 40px 1fr 60px; }
7315 .table-row-item { grid-template-columns: 1fr 30px; }
7316 .table-row-item .table-row-link { grid-template-columns: 40px 1fr 60px; }
7317 .table-header.projects-header, .table-row.project-row { grid-template-columns: 1fr 70px; }
7318 .row-date, .row-items, .row-category { display: none; }
7319 .table-header span:nth-child(3), .table-header span:nth-child(4), .table-header span:nth-child(5) { display: none; }
7320 .table-header.projects-header span:nth-child(3), .table-header.projects-header span:nth-child(4) { display: none; }
7321 }
7322
7323 @media (max-width: 480px) {
7324 .table-header, .table-row { grid-template-columns: 1fr 60px; }
7325 .table-row-item { grid-template-columns: 1fr 30px; }
7326 .table-row-item .table-row-link { grid-template-columns: 1fr 60px; }
7327 .row-type { display: none; }
7328 .table-header span:first-child { display: none; }
7329 .table-header.projects-header, .table-row.project-row { grid-template-columns: 1fr; }
7330 .table-header.projects-header span:nth-child(2) { display: none; }
7331 .row-price { font-size: 0.8rem; }
7332 .search-field { min-width: 0; width: 100%; }
7333 .table-controls { flex-wrap: wrap; }
7334 .mode-toggle { flex-wrap: wrap; }
7335 .table-footer { flex-direction: column; gap: 0.5rem; align-items: flex-start; }
7336 }
7337
7338 /* ── Feature Cards & Suggestion Input (shared by wizard + settings) ── */
7339
7340 .type-grid {
7341 display: grid;
7342 grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
7343 gap: 0.75rem;
7344 margin-bottom: 1rem;
7345 }
7346
7347 /* Canonical selectable-card primitive. One recipe; per-context size modifiers.
7348 Used by wizard type pickers, pricing-model pickers, content-choice pickers,
7349 monetization-mode pickers — anywhere a radio-like choice is rendered as a card. */
7350 .card--selectable,
7351 .type-card,
7352 .pricing-card,
7353 .content-choice-card {
7354 cursor: pointer;
7355 display: block;
7356 }
7357 .card--selectable input[type="radio"],
7358 .card--selectable input[type="checkbox"],
7359 .type-card input[type="radio"],
7360 .type-card input[type="checkbox"],
7361 .pricing-card input[type="radio"],
7362 .content-choice-card input[type="radio"] {
7363 position: absolute;
7364 opacity: 0;
7365 pointer-events: none;
7366 }
7367
7368 .card--selectable-inner,
7369 .type-card-inner,
7370 .pricing-card-inner {
7371 display: flex;
7372 flex-direction: column;
7373 align-items: center;
7374 justify-content: center;
7375 padding: 1rem 0.75rem;
7376 border: 2px solid var(--border);
7377 border-radius: var(--radius-md);
7378 background: var(--background);
7379 text-align: center;
7380 transition: border-color 0.15s, background 0.15s;
7381 min-height: 60px;
7382 }
7383 /* Variant: column-aligned content (text-heavy pricing cards). */
7384 .pricing-card-inner,
7385 .card--selectable.is-text-heavy .card--selectable-inner {
7386 align-items: stretch;
7387 text-align: left;
7388 padding: 1.25rem;
7389 }
7390
7391 .card--selectable input:checked + .card--selectable-inner,
7392 .card--selectable.is-selected .card--selectable-inner,
7393 .type-card input:checked + .type-card-inner,
7394 .type-card.is-selected .type-card-inner,
7395 .pricing-card input:checked + .pricing-card-inner,
7396 .pricing-card.is-selected .pricing-card-inner,
7397 .content-choice-card.is-selected {
7398 border-color: var(--highlight);
7399 background: var(--highlight-faint);
7400 }
7401
7402 .card--selectable:hover .card--selectable-inner,
7403 .type-card:hover .type-card-inner,
7404 .pricing-card:hover .pricing-card-inner,
7405 .content-choice-card:hover {
7406 background: var(--surface-muted);
7407 }
7408
7409 .card--selectable-label,
7410 .type-card-label,
7411 .pricing-card-label {
7412 font-weight: bold;
7413 font-size: 0.9rem;
7414 }
7415
7416 .card--selectable-desc,
7417 .type-card-desc,
7418 .pricing-card-desc {
7419 font-size: 0.75rem;
7420 color: var(--text-muted);
7421 margin-top: 0.25rem;
7422 }
7423
7424 /* Anchor-styled selectable card (used when the card itself is an `<a>` link
7425 rather than a radio-wrapping label). */
7426 .content-choice-card {
7427 text-decoration: none;
7428 color: inherit;
7429 }
7430
7431 /* Disabled selectable card — visually dimmed, ignores pointer events. */
7432 .card--selectable.is-disabled,
7433 .content-choice-card.is-disabled {
7434 opacity: 0.7;
7435 pointer-events: none;
7436 }
7437
7438 .suggestion-input {
7439 position: relative;
7440 }
7441
7442 .suggestion-dropdown {
7443 display: none;
7444 position: absolute;
7445 top: 100%;
7446 left: 0;
7447 right: 0;
7448 background: var(--background);
7449 border: 1px solid var(--border);
7450 border-top: none;
7451 border-radius: 0 0 var(--radius-md) var(--radius-md);
7452 max-height: 200px;
7453 overflow-y: auto;
7454 z-index: 10;
7455 box-shadow: var(--shadow-2);
7456 }
7457
7458 .suggestion-dropdown.open {
7459 display: block;
7460 }
7461
7462 .suggestion-item {
7463 padding: 0.5rem 0.75rem;
7464 cursor: pointer;
7465 font-size: 0.9rem;
7466 }
7467
7468 .suggestion-item:hover {
7469 background: var(--light-background);
7470 }
7471
7472 .suggestion-create {
7473 font-style: italic;
7474 opacity: 0.8;
7475 border-top: 1px solid var(--border);
7476 }
7477
7478 /* ── Tips ── */
7479
7480 .tip-section {
7481 margin-top: 1rem;
7482 text-align: center;
7483 }
7484
7485 .tip-toggle {
7486 font-family: var(--font-mono);
7487 font-size: 0.85rem;
7488 padding: 0.5rem 1.5rem;
7489 background: none;
7490 border: 1px solid var(--text);
7491 color: var(--text);
7492 cursor: pointer;
7493 text-decoration: none;
7494 display: inline-block;
7495 }
7496
7497 .tip-toggle:hover {
7498 background: var(--text);
7499 color: var(--background);
7500 }
7501
7502 .tip-form {
7503 margin-top: 1rem;
7504 display: flex;
7505 flex-direction: column;
7506 gap: 0.75rem;
7507 max-width: 300px;
7508 margin-left: auto;
7509 margin-right: auto;
7510 text-align: left;
7511 }
7512
7513 .tip-form.hidden {
7514 display: none;
7515 }
7516
7517 .tip-amount-row {
7518 display: flex;
7519 align-items: center;
7520 gap: 0.25rem;
7521 }
7522
7523 .tip-amount-row .pricing-currency {
7524 font-size: 1.2rem;
7525 opacity: 0.7;
7526 }
7527
7528 .tip-amount-input {
7529 width: 80px;
7530 font-size: 1.2rem;
7531 padding: 0.4rem 0.5rem;
7532 border: 1px solid var(--border);
7533 background: var(--light-background);
7534 font-family: var(--font-mono);
7535 }
7536
7537 .tip-message-input {
7538 width: 100%;
7539 font-size: 0.85rem;
7540 padding: 0.5rem;
7541 border: 1px solid var(--border);
7542 background: var(--light-background);
7543 font-family: var(--font-body);
7544 resize: vertical;
7545 }
7546
7547 .tip-submit {
7548 font-family: var(--font-mono);
7549 font-size: 0.85rem;
7550 padding: 0.5rem 1rem;
7551 background: var(--text);
7552 color: var(--background);
7553 border: none;
7554 cursor: pointer;
7555 }
7556
7557 .tip-submit:hover {
7558 opacity: 0.85;
7559 }
7560
7561 /* ===========================================
7562 COLLECTION PICKER (shared dropdown)
7563 =========================================== */
7564
7565 .collection-picker-anchor { position: relative; }
7566 .collection-picker {
7567 position: absolute; left: 0; right: 0; top: 100%; z-index: 50;
7568 background: var(--background); border: 1px solid var(--border);
7569 box-shadow: 0 2px 8px rgba(0,0,0,0.12); min-width: 220px;
7570 }
7571 .collection-picker-list { max-height: 200px; overflow-y: auto; padding: 0.25rem 0; }
7572 .collection-picker-item {
7573 display: flex; align-items: center; gap: 0.5rem;
7574 padding: 0.4rem 0.75rem; cursor: pointer; font-size: 0.9rem;
7575 }
7576 .collection-picker-item:hover { background: var(--surface-muted); }
7577 .collection-picker-loading,
7578 .collection-picker-create { border-top: 1px solid var(--border); padding: 0.5rem 0.75rem; }
7579 .collection-picker-create form { display: flex; gap: 0.5rem; }
7580 .collection-picker-create input { flex: 1; padding: 0.3rem 0.5rem; font-size: 0.85rem; min-width: 0; }
7581 .collection-picker-create button { font-size: 0.85rem; white-space: nowrap; }
7582
7583 /* Save button on discover cards */
7584 .row-save, .grid-card-save {
7585 background: none; border: none; cursor: pointer;
7586 font-size: 0.85rem; padding: 0.2rem 0.4rem; opacity: 0.4;
7587 color: var(--detail); transition: opacity 0.15s;
7588 }
7589 .row-save:hover, .grid-card-save:hover { opacity: 1; }
7590 .grid-card-save {
7591 position: absolute; top: 0.4rem; right: 0.4rem; z-index: 2;
7592 background: var(--background); border-radius: 3px; padding: 0.25rem 0.4rem;
7593 box-shadow: 0 1px 3px rgba(0,0,0,0.15); opacity: 0;
7594 }
7595 .grid-card:hover .grid-card-save { opacity: 0.7; }
7596 .grid-card-save:hover { opacity: 1; }
7597
7598 /* Item page save button saved state */
7599 button.saved { border-color: var(--highlight); color: var(--highlight); }
7600
7601 /* ===========================================
7602 SEARCH SUGGESTIONS
7603 =========================================== */
7604
7605 .search-wrapper { position: relative; flex: 1; min-width: 0; }
7606 .search-suggestions {
7607 display: none; position: absolute; left: 0; right: 0; top: 100%; z-index: 50;
7608 background: var(--background); border: 1px solid var(--border); border-top: none;
7609 box-shadow: 0 4px 12px rgba(0,0,0,0.1); max-height: 280px; overflow-y: auto;
7610 }
7611 .suggestion-item {
7612 display: flex; justify-content: space-between; align-items: center;
7613 padding: 0.5rem 0.75rem; text-decoration: none; color: var(--detail);
7614 font-size: 0.85rem; cursor: pointer;
7615 }
7616 .suggestion-item:hover, .suggestion-item.highlighted { background: var(--surface-muted); }
7617 .suggestion-category { font-size: 0.75rem; opacity: 0.5; text-transform: uppercase; letter-spacing: 0.05em; }
7618
7619 /* ===========================================
7620 DOC UI EXAMPLES (embedded live UI in docs)
7621 =========================================== */
7622
7623 .doc-ui {
7624 margin: 1.5rem 0; border: 1px solid var(--border); border-radius: 4px; overflow: hidden;
7625 }
7626 .doc-ui-frame {
7627 padding: 1rem; background: var(--light-background); pointer-events: none; user-select: none;
7628 }
7629 .doc-ui figcaption {
7630 padding: 0.5rem 1rem; font-size: 0.8rem; opacity: 0.6;
7631 border-top: 1px solid var(--border); background: var(--surface-alt);
7632 font-family: var(--font-mono);
7633 }
7634 .doc-ui-missing {
7635 padding: 1rem; opacity: 0.4; font-style: italic;
7636 }
7637
7638 /* Library "New" badge for items with undownloaded versions */
7639 .badge-new {
7640 background: var(--highlight); color: var(--primary-light); font-size: 0.7rem;
7641 padding: 0.1rem 0.35rem; border-radius: var(--radius-sm); margin-left: 0.4rem;
7642 vertical-align: middle; font-weight: bold;
7643 }
7644
7645 /* ===========================================
7646 BENEFIT LIST (bulleted feature lists, e.g. Stripe Connect prompt)
7647 =========================================== */
7648 .benefit-list {
7649 list-style: none;
7650 padding: 0;
7651 margin: 0 auto var(--space-5);
7652 max-width: 280px;
7653 text-align: left;
7654 display: flex;
7655 flex-direction: column;
7656 gap: var(--space-2);
7657 }
7658 .benefit-list li {
7659 position: relative;
7660 padding-left: 1.1rem;
7661 font-size: 0.9rem;
7662 }
7663 .benefit-list li::before {
7664 content: "";
7665 position: absolute;
7666 left: 0.15rem;
7667 top: 0.55rem;
7668 width: 6px;
7669 height: 6px;
7670 border-radius: var(--radius-round);
7671 background: var(--success);
7672 }
7673
7674 /* ===========================================
7675 CHECKLIST (setup / onboarding step lists)
7676 =========================================== */
7677 .checklist {
7678 margin-bottom: var(--space-5);
7679 padding: var(--space-4) var(--space-5);
7680 background: var(--light-background);
7681 border: 1px solid var(--border);
7682 }
7683 .checklist-header {
7684 display: flex;
7685 justify-content: space-between;
7686 align-items: center;
7687 margin-bottom: var(--space-3);
7688 }
7689 .checklist-title {
7690 margin: 0;
7691 font-family: var(--font-heading);
7692 font-weight: bold;
7693 }
7694 .checklist-mark {
7695 width: 1.1rem;
7696 height: 1.1rem;
7697 border-radius: var(--radius-round);
7698 border: 2px solid var(--border);
7699 flex-shrink: 0;
7700 box-sizing: border-box;
7701 }
7702 .checklist-mark--done {
7703 border-color: var(--success);
7704 background: var(--success);
7705 }
7706 .checklist-label {
7707 flex: 1;
7708 font-size: 0.9rem;
7709 }
7710 .checklist-label--done {
7711 opacity: 0.5;
7712 text-decoration: line-through;
7713 }
7714
7715 /* ===========================================
7716 PAYMENTS TAB (replaces inline styles in user_payments.html)
7717 =========================================== */
7718 /* Canonical "stack row" — title-on-left + actions-on-right header bar.
7719 One primitive; per-context modifiers handle gap, wrap, alignment, margins.
7720 Aliases below cover existing per-tab class names (kept as JS hooks). */
7721 .stack-row,
7722 .content-header,
7723 .user-media-header,
7724 .transactions-header,
7725 .analytics-range-bar,
7726 .cart-multi-bar {
7727 display: flex;
7728 justify-content: space-between;
7729 align-items: center;
7730 flex-wrap: wrap;
7731 gap: var(--space-4);
7732 }
7733 .stack-row--tight { gap: var(--space-3); flex-wrap: nowrap; }
7734 .stack-row--top { align-items: flex-start; }
7735 .stack-row--bordered,
7736 .transactions-header {
7737 margin-bottom: var(--space-4);
7738 padding-bottom: var(--space-3);
7739 border-bottom: 1px solid var(--border);
7740 }
7741 .content-header,
7742 .user-media-header,
7743 .analytics-range-bar { margin-bottom: var(--space-4); }
7744 .cart-multi-bar {
7745 margin-bottom: var(--space-5);
7746 padding: 1rem 1.25rem;
7747 background: var(--surface-muted);
7748 border: 1px solid var(--border-color);
7749 }
7750
7751 /* Canonical list row (flex, gap, padding, bottom border). Aliases below cover
7752 the per-tab variants — they exist as JS hooks but share the same look. */
7753 .list-row,
7754 .psection-row,
7755 .section-mgmt-row,
7756 .bundle-picker-row,
7757 .checklist-row {
7758 display: flex;
7759 align-items: center;
7760 gap: var(--space-3);
7761 padding: 0.6rem 0;
7762 border-bottom: 1px solid var(--border);
7763 }
7764 .list-row:last-child,
7765 .psection-row:last-child,
7766 .section-mgmt-row:last-child,
7767 .bundle-picker-row:last-child,
7768 .checklist-row:last-child { border-bottom: none; }
7769 .warn-glyph {
7770 font-size: 1.25rem;
7771 color: var(--warning);
7772 }
7773
7774 .card-h {
7775 margin: 0 0 var(--space-3) 0;
7776 font-size: 1rem;
7777 }
7778
7779 .amount-big {
7780 font-size: 1.25rem;
7781 font-weight: bold;
7782 }
7783
7784 .account-details {
7785 margin-top: var(--space-3);
7786 padding-top: var(--space-3);
7787 border-top: 1px solid var(--border);
7788 }
7789 .account-details summary { cursor: pointer; }
7790 .account-details-id {
7791 font-size: 0.8rem;
7792 opacity: 0.5;
7793 font-family: var(--font-mono);
7794 margin-top: var(--space-1);
7795 }
7796
7797 .stripe-actions {
7798 display: flex;
7799 gap: var(--space-4);
7800 flex-wrap: wrap;
7801 }
7802 .stripe-actions-disconnect { margin-left: auto; }
7803
7804 .payout-stats-grid {
7805 display: grid;
7806 grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
7807 gap: var(--space-4);
7808 margin-top: var(--space-4);
7809 padding-top: var(--space-4);
7810 border-top: 1px solid var(--border);
7811 }
7812
7813 .payouts-disabled-notice {
7814 margin-top: var(--space-4);
7815 padding: var(--space-3);
7816 background: var(--warning);
7817 color: var(--primary-light);
7818 font-size: 0.85rem;
7819 }
7820
7821 .fee-breakdown {
7822 display: grid;
7823 grid-template-columns: 1fr 1fr;
7824 gap: var(--space-2);
7825 font-size: 0.9rem;
7826 }
7827 .fee-row {
7828 display: flex;
7829 justify-content: space-between;
7830 padding: var(--space-2) 0;
7831 border-bottom: 1px solid var(--border);
7832 }
7833
7834 .checkbox-row {
7835 display: flex;
7836 align-items: flex-start;
7837 gap: var(--space-2);
7838 cursor: pointer;
7839 font-size: 0.9rem;
7840 }
7841 .check-inline {
7842 width: auto;
7843 margin-top: 0.2rem;
7844 }
7845
7846 .stripe-connect-prompt { text-align: center; padding: var(--space-5); }
7847 .stripe-logo { opacity: 0.8; }
7848 .stripe-connect-btn {
7849 background: var(--stripe);
7850 padding: var(--space-3) var(--space-6);
7851 }
7852
7853 .export-row {
7854 display: flex;
7855 justify-content: flex-end;
7856 margin-bottom: var(--space-3);
7857 }
7858
7859 .splits-grid {
7860 display: grid;
7861 grid-template-columns: 1fr 1fr;
7862 gap: var(--space-4);
7863 margin-bottom: var(--space-4);
7864 }
7865
7866 .tip-message {
7867 max-width: 300px;
7868 overflow: hidden;
7869 text-overflow: ellipsis;
7870 }
7871
7872 .transactions-title { font-size: 1.2rem; }
7873
7874 /* ===========================================
7875 CREATOR TAB (replaces inline styles in user_creator.html)
7876 =========================================== */
7877 .creator-tab-section {
7878 padding: var(--space-6);
7879 }
7880 .creator-tab-section--centered { text-align: center; }
7881 .creator-tab-section--no-top { padding-top: 0; }
7882
7883 .creator-h2 { font-size: 1.3rem; margin-bottom: var(--space-4); }
7884 .creator-h2--sm { font-size: 1.2rem; }
7885
7886 .creator-section-label {
7887 margin-left: var(--space-6);
7888 margin-right: var(--space-6);
7889 }
7890 .creator-form-section { padding: 0 var(--space-6); }
7891
7892 .creator-plan-box {
7893 background: var(--light-background);
7894 padding: var(--space-4) var(--space-5);
7895 }
7896 .creator-plan-head {
7897 display: flex;
7898 align-items: center;
7899 gap: var(--space-3);
7900 margin-bottom: var(--space-2);
7901 flex-wrap: wrap;
7902 }
7903 .creator-plan-name {
7904 font-family: var(--font-heading);
7905 font-weight: bold;
7906 font-size: 1.1rem;
7907 }
7908
7909 .badge--founder-locked {
7910 background: var(--detail);
7911 color: var(--light-background);
7912 }
7913 .badge--founder-pending {
7914 background: var(--surface-muted);
7915 }
7916
7917 .founder-callout {
7918 background: var(--light-background);
7919 border-left: 3px solid var(--detail);
7920 padding: 0.85rem 1rem;
7921 }
7922
7923 .creator-tier-grid {
7924 display: grid;
7925 grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
7926 gap: var(--space-4);
7927 }
7928 .creator-tier-card {
7929 background: var(--light-background);
7930 padding: var(--space-4);
7931 text-align: center;
7932 }
7933 .creator-tier-name {
7934 font-family: var(--font-heading);
7935 font-weight: bold;
7936 font-size: 1rem;
7937 margin-bottom: var(--space-1);
7938 }
7939 .creator-tier-link {
7940 color: inherit;
7941 text-decoration: none;
7942 border-bottom: 1px solid var(--border);
7943 }
7944 .creator-tier-sub {
7945 font-size: 0.75rem;
7946 opacity: 0.7;
7947 }
7948 .creator-tier-storage { font-size: 0.75rem; }
7949 .creator-tier-buttons {
7950 display: flex;
7951 flex-direction: column;
7952 gap: 0.4rem;
7953 }
7954 .creator-tier-btn {
7955 font-size: 0.85rem;
7956 width: 100%;
7957 }
7958
7959 .strike-dim {
7960 opacity: 0.5;
7961 text-decoration: line-through;
7962 }
7963
7964 .storage-box {
7965 background: var(--light-background);
7966 padding: var(--space-4) var(--space-5);
7967 }
7968 .storage-row {
7969 display: flex;
7970 justify-content: space-between;
7971 margin-bottom: var(--space-2);
7972 font-size: 0.9rem;
7973 }
7974 .storage-track {
7975 background: var(--border);
7976 height: 8px;
7977 width: 100%;
7978 overflow: hidden;
7979 }
7980 .storage-fill {
7981 background: var(--highlight);
7982 height: 100%;
7983 transition: width 0.3s;
7984 }
7985 .storage-fill--full { background: var(--danger); }
7986 .storage-breakdown {
7987 display: grid;
7988 grid-template-columns: 1fr 1fr;
7989 gap: var(--space-1) var(--space-5);
7990 margin-top: var(--space-3);
7991 font-size: 0.85rem;
7992 }
7993
7994 .broadcast-head {
7995 display: flex;
7996 justify-content: space-between;
7997 align-items: flex-start;
7998 }
7999 .broadcast-desc { flex: 1; }
8000 .broadcast-export { margin-left: var(--space-4); }
8001
8002 .creator-divider {
8003 margin: 0 var(--space-6);
8004 border-color: var(--border);
8005 }
8006
8007 .creator-intro { line-height: 1.6; }
8008 .creator-pitch-box {
8009 background: var(--light-background);
8010 padding: var(--space-5);
8011 }
8012
8013 .mono-sm {
8014 font-family: var(--font-mono);
8015 font-size: 0.9rem;
8016 }
8017
8018 /* ===========================================
8019 PROJECT CONTENT TAB (replaces inline styles in project_content.html)
8020 =========================================== */
8021
8022 .empty-state--lg { padding: var(--space-6) var(--space-4); }
8023
8024 .content-filters {
8025 display: flex;
8026 gap: var(--space-3);
8027 margin-bottom: var(--space-4);
8028 align-items: center;
8029 flex-wrap: wrap;
8030 }
8031 .content-filter-search {
8032 flex: 1;
8033 min-width: 180px;
8034 padding: 0.4rem 0.6rem;
8035 font-size: 0.9rem;
8036 }
8037 .content-filter-select {
8038 padding: 0.4rem;
8039 font-size: 0.85rem;
8040 }
8041
8042 .bulk-action-bar {
8043 padding: var(--space-3) var(--space-4);
8044 margin-bottom: var(--space-4);
8045 background: var(--surface-raised);
8046 border: 1px solid var(--border);
8047 border-radius: var(--radius-md);
8048 display: flex;
8049 align-items: center;
8050 gap: var(--space-2);
8051 flex-wrap: wrap;
8052 opacity: 0.4;
8053 }
8054 .bulk-action-bar--active { opacity: 1; }
8055 .bulk-count { font-weight: bold; min-width: 5rem; }
8056 .bulk-deselect { margin-left: auto; }
8057 .danger-text { color: var(--danger); }
8058
8059 .bulk-form {
8060 margin-bottom: var(--space-4);
8061 padding: var(--space-3) var(--space-4);
8062 background: var(--surface-muted);
8063 border: 1px solid var(--border);
8064 border-radius: var(--radius-md);
8065 }
8066 .bulk-form-row {
8067 display: flex;
8068 gap: var(--space-3);
8069 align-items: end;
8070 }
8071 .bulk-form-label {
8072 font-size: 0.85rem;
8073 display: block;
8074 margin-bottom: var(--space-1);
8075 }
8076
8077 /* Sortable table column header */
8078 .sortable-th { cursor: pointer; }
8079 .sort-arrow { opacity: 0.4; }
8080 .sort-arrow--active { opacity: 1; }
8081
8082 /* Data-table column-width utilities (numeric width hints,
8083 kept as classes to avoid inline `style="width: NN%"`) */
8084 .col-3 { width: 3%; }
8085 .col-5 { width: 5%; }
8086 .col-8 { width: 8%; }
8087 .col-10 { width: 10%; }
8088 .col-12 { width: 12%; }
8089 .col-15 { width: 15%; }
8090 .col-20 { width: 20%; }
8091 .col-32 { width: 32%; }
8092 .col-45 { width: 45%; }
8093
8094 /* Pixel-width utilities for inputs and narrow fixed-width controls.
8095 Use on form inputs that can't be sized by their parent column. */
8096 .w-80 { width: 80px; }
8097 .w-100 { width: 100px; }
8098 .w-120 { width: 120px; }
8099 .w-180 { width: 180px; }
8100 .w-220 { width: 220px; }
8101 .w-260 { width: 260px; }
8102 .w-full { width: 100%; }
8103 .maxw-320 { max-width: 320px; }
8104
8105 /* Canonical input shape modifiers. One base form-input look (defined globally
8106 at line ~365 input[type], textarea, select) plus these size + feature variants.
8107 Apply alongside the per-tab class which acts as a JS hook. */
8108 .input--xs {
8109 padding: 0.25rem 0.4rem;
8110 font-size: 0.85rem;
8111 }
8112 .input--sm {
8113 padding: 0.3rem 0.5rem;
8114 font-size: 0.85rem;
8115 }
8116 .input--mono { font-family: var(--font-mono); }
8117 .input--upper { text-transform: uppercase; }
8118 .input--numeric { text-align: right; }
8119
8120 .order-arrow-btn {
8121 padding: 0.1rem 0.3rem;
8122 font-size: 0.7rem;
8123 line-height: 1;
8124 }
8125
8126 .bundle-toggle {
8127 background: none;
8128 border: none;
8129 cursor: pointer;
8130 padding: 0 0.3rem 0 0;
8131 font-size: 0.8rem;
8132 color: var(--text-muted);
8133 }
8134 .bundle-child-cell { padding-left: 2.5rem; }
8135 .bundle-child-title { opacity: 0.85; }
8136 .bundle-child-arrow {
8137 color: var(--text-muted);
8138 margin-right: 0.3rem;
8139 }
8140
8141 .item-actions {
8142 display: flex;
8143 gap: var(--space-2);
8144 }
8145
8146 .badge--inline-tiny {
8147 font-size: 0.7rem;
8148 margin-left: 0.3rem;
8149 opacity: 0.7;
8150 }
8151
8152 .deleted-items-details { margin-top: var(--space-6); }
8153 .deleted-items-summary {
8154 cursor: pointer;
8155 font-size: 0.95rem;
8156 opacity: 0.7;
8157 }
8158
8159 .section-divider {
8160 margin: var(--space-6) 0;
8161 border: none;
8162 border-top: 1px solid var(--border);
8163 }
8164
8165 .inline-rename-input {
8166 font-weight: bold;
8167 width: 100%;
8168 padding: 0.2rem 0.4rem;
8169 font-size: inherit;
8170 }
8171
8172 /* ===========================================
8173 ITEM DETAILS TAB (replaces inline styles in item_details.html)
8174 =========================================== */
8175
8176 /* Compact button utility (small icon-side actions) */
8177 .btn-compact { padding: 0.4rem 0.8rem; }
8178
8179 .ml-2 { margin-left: var(--space-2); }
8180 .cursor-pointer { cursor: pointer; }
8181 .inline { display: inline; }
8182
8183 .tag-search-wrap { position: relative; }
8184 .tag-suggestions {
8185 position: absolute;
8186 z-index: 10;
8187 background: var(--surface-muted);
8188 border: 1px solid var(--border);
8189 width: 100%;
8190 max-height: 200px;
8191 overflow-y: auto;
8192 }
8193
8194 .advanced-details { margin-top: var(--space-5); }
8195 .advanced-summary {
8196 cursor: pointer;
8197 font-size: 0.95rem;
8198 opacity: 0.8;
8199 }
8200
8201 /* Bundle table inside item-details */
8202 .bundle-table {
8203 width: 100%;
8204 border-collapse: collapse;
8205 }
8206 .bundle-table-head {
8207 text-align: left;
8208 font-size: 0.8rem;
8209 opacity: 0.7;
8210 text-transform: uppercase;
8211 letter-spacing: 0.03em;
8212 }
8213 .bundle-row { border-bottom: 1px solid var(--border); }
8214 .bundle-cell { padding: var(--space-2); }
8215 .bundle-cell--first { padding-left: 0; }
8216 .bundle-cell--actions { width: 60px; }
8217 .bundle-cell--desc { font-size: 0.85rem; opacity: 0.8; }
8218 .bundle-cell--file { font-size: 0.85rem; }
8219
8220 .bundle-remove-btn {
8221 padding: 0.2rem 0.5rem;
8222 font-size: 0.75rem;
8223 }
8224
8225 .bundle-add-row {
8226 margin-top: var(--space-4);
8227 display: flex;
8228 gap: var(--space-3);
8229 align-items: center;
8230 }
8231
8232 .bundle-existing-details { margin-top: var(--space-4); }
8233 .bundle-existing-summary {
8234 cursor: pointer;
8235 font-size: 0.85rem;
8236 opacity: 0.7;
8237 }
8238 .bundle-existing-row {
8239 margin-top: var(--space-2);
8240 display: flex;
8241 gap: var(--space-2);
8242 align-items: center;
8243 }
8244 .bundle-existing-select {
8245 flex: 1;
8246 padding: 0.4rem;
8247 }
8248
8249 .sections-intro {
8250 font-size: 0.85rem;
8251 opacity: 0.7;
8252 margin: var(--space-3) 0 var(--space-4);
8253 }
8254
8255 .section-mgmt-title {
8256 flex: 1;
8257 font-weight: bold;
8258 }
8259 .section-edit-btn,
8260 .section-del-btn {
8261 padding: 0.25rem 0.6rem;
8262 font-size: 0.8rem;
8263 }
8264
8265 .section-add-details { margin-top: var(--space-4); }
8266 .section-add-summary {
8267 cursor: pointer;
8268 font-size: 0.95rem;
8269 }
8270
8271 .insert-image-btn {
8272 margin-top: var(--space-2);
8273 font-size: 0.85rem;
8274 }
8275
8276 .section-edit-modal {
8277 margin-top: var(--space-4);
8278 padding: var(--space-4);
8279 background: var(--surface-muted);
8280 }
8281 .section-edit-actions {
8282 display: flex;
8283 gap: var(--space-2);
8284 }
8285
8286 .publish-note {
8287 margin: var(--space-4) 0;
8288 opacity: 0.7;
8289 text-align: left;
8290 }
8291
8292 /* ===========================================
8293 CONTENT WIZARD STEP (replaces inline styles in wizards/steps/item/content.html)
8294 =========================================== */
8295
8296 /* (Wizard upload-status + slim progress moved into canonical .upload-status*
8297 / .progress-bar-container--slim primitives near top of file.) */
8298
8299 /* Bundle items picker — server-rendered rows and JS-appended rows share these. */
8300 .bundle-picker-row-title { flex: 1; }
8301 .bundle-picker-row-type { font-size: 0.8rem; opacity: 0.6; }
8302 .bundle-picker-row-unlisted {
8303 font-size: 0.8rem;
8304 display: flex;
8305 align-items: center;
8306 gap: 0.25rem;
8307 }
8308
8309 /* Batch upload queue table. */
8310 .batch-queue-table {
8311 width: 100%;
8312 border-collapse: collapse;
8313 }
8314 .batch-queue-table thead tr {
8315 border-bottom: 2px solid var(--border);
8316 text-align: left;
8317 }
8318 .batch-queue-table th,
8319 .batch-queue-table td {
8320 padding: 0.4rem 0.5rem;
8321 font-size: 0.85rem;
8322 }
8323 .batch-queue-table th:first-child,
8324 .batch-queue-table td:first-child { padding-left: 0; }
8325 .batch-queue-table th:last-child,
8326 .batch-queue-table td:last-child { padding-right: 0; text-align: right; }
8327 .batch-queue-table tbody tr { border-bottom: 1px solid var(--border); }
8328
8329 .batch-queue-name {
8330 max-width: 150px;
8331 overflow: hidden;
8332 text-overflow: ellipsis;
8333 white-space: nowrap;
8334 }
8335
8336 /* ===========================================
8337 ACCOUNT TAB (replaces inline styles in partials/tabs/user_account.html)
8338 =========================================== */
8339
8340 /* Canonical solid-tint callout (one of these in the codebase).
8341 Distinct from .alert (left-border) and .banner (full-bleed page notice).
8342 Variants:
8343 - .callout--danger (light bg, danger border — moderation, errors)
8344 - .callout--warning (light bg, warning border — DNS, email-not-verified)
8345 - .callout--solid-warning (full saturation warning bg, dark text — partial checkout) */
8346 .callout {
8347 padding: 0.75rem 1rem;
8348 margin-bottom: 1rem;
8349 font-size: 0.9rem;
8350 border: 1px solid;
8351 }
8352 .callout--danger {
8353 background: var(--danger-bg);
8354 border-color: var(--danger);
8355 }
8356 .callout--warning {
8357 background: var(--warning-bg);
8358 border-color: var(--warning-border);
8359 }
8360 .callout--solid-warning {
8361 background: var(--warning);
8362 color: var(--primary-dark);
8363 border-color: transparent;
8364 padding: 1rem 1.25rem;
8365 }
8366 .callout-title { text-transform: capitalize; }
8367 .callout-meta {
8368 opacity: 0.6;
8369 margin-left: 0.5rem;
8370 }
8371 .callout-body { margin: 0.5rem 0 0 0; }
8372 .callout-hint {
8373 font-size: 0.85rem;
8374 margin-top: 0.5rem;
8375 }
8376
8377 .account-mod-history { margin-top: 0.75rem; }
8378 .account-mod-history summary {
8379 cursor: pointer;
8380 font-size: 0.85rem;
8381 opacity: 0.7;
8382 }
8383 .account-mod-history-list { margin-top: 0.5rem; }
8384 .account-mod-history-item {
8385 padding: 0.5rem 0;
8386 border-bottom: 1px solid var(--border-color);
8387 font-size: 0.85rem;
8388 }
8389 .account-mod-history-reason {
8390 margin: 0.25rem 0 0 0;
8391 opacity: 0.8;
8392 }
8393
8394 .account-tip-card-title {
8395 font-weight: bold;
8396 margin-bottom: 0.5rem;
8397 }
8398 .account-tip-list {
8399 display: flex;
8400 flex-direction: column;
8401 gap: 0.25rem;
8402 opacity: 0.8;
8403 }
8404
8405 /* Resend-verification button needs left spacing from preceding strong. */
8406 .account-resend-btn { margin-left: 0.5rem; }
8407
8408 /* Cluster of small inline forms (manage-billing / cancel / resume). */
8409 .inline-form { display: inline; }
8410
8411 /* Notification preferences — bare fieldset + monospace legend. */
8412 .pref-fieldset {
8413 border: none;
8414 padding: 0;
8415 margin: 0 0 1.25rem 0;
8416 }
8417 .pref-fieldset--last { margin-bottom: 0.5rem; }
8418 .pref-legend {
8419 font-family: var(--font-mono);
8420 font-size: 0.85rem;
8421 font-weight: bold;
8422 margin-bottom: 0.5rem;
8423 }
8424
8425 /* ===========================================
8426 PROJECT CODE TAB (replaces inline styles in partials/tabs/project_code.html)
8427 =========================================== */
8428
8429 .proj-code-docs-link { margin-left: 1rem; }
8430
8431 .proj-code-linked-list { margin-bottom: var(--space-5); }
8432 .proj-code-linked-list > label { margin-bottom: var(--space-2); display: block; }
8433
8434 .proj-code-repo {
8435 margin-bottom: var(--space-4);
8436 padding: var(--space-3);
8437 background: var(--light-background);
8438 }
8439 .proj-code-repo-row {
8440 display: flex;
8441 align-items: center;
8442 gap: var(--space-3);
8443 }
8444 .proj-code-repo-link { flex: 1; }
8445 .proj-code-repo .danger { padding: var(--space-1) var(--space-3); font-size: 0.85rem; }
8446
8447 .proj-code-collab-block {
8448 margin-top: var(--space-2);
8449 padding-top: var(--space-2);
8450 border-top: 1px solid var(--border-color);
8451 }
8452 .proj-code-collab-label { font-size: 0.85rem; margin-bottom: var(--space-1); display: block; }
8453 .proj-code-collab-row {
8454 display: flex;
8455 align-items: center;
8456 gap: var(--space-2);
8457 margin-bottom: var(--space-1);
8458 font-size: 0.9rem;
8459 }
8460 .proj-code-collab-name { flex: 1; }
8461 .proj-code-collab-readonly { opacity: 0.5; }
8462
8463 .proj-code-add-collab-row {
8464 display: flex;
8465 gap: var(--space-2);
8466 align-items: center;
8467 }
8468 .proj-code-add-collab-row .collab-username-input {
8469 flex: 1;
8470 font-size: 0.85rem;
8471 padding: 0.3rem var(--space-2);
8472 }
8473 .proj-code-add-collab-row .collab-add-btn { white-space: nowrap; }
8474
8475 .proj-code-link-row {
8476 display: flex;
8477 gap: var(--space-2);
8478 align-items: center;
8479 }
8480 .proj-code-link-row #link-repo-select { flex: 1; }
8481 .proj-code-link-row #link-repo-btn { white-space: nowrap; }
8482
8483 .proj-code-create-section {
8484 margin-top: var(--space-5);
8485 padding-top: var(--space-4);
8486 border-top: 1px solid var(--border-color);
8487 }
8488 .proj-code-create-section #create-repo-name { flex: 1; }
8489 .proj-code-create-section #create-repo-btn { white-space: nowrap; }
8490 .proj-code-create-status { margin-top: var(--space-1); }
8491 .proj-code-create-status.is-error { color: var(--error); }
8492
8493 .proj-code-disabled {
8494 padding: var(--space-6);
8495 text-align: center;
8496 opacity: 0.7;
8497 }
8498
8499 /* ===========================================
8500 ADMIN REPORT ENTRIES (replaces inline styles in partials/admin_report_entries.html)
8501 =========================================== */
8502
8503 .admin-report-table {
8504 width: 100%;
8505 border-collapse: collapse;
8506 font-size: 0.85rem;
8507 }
8508 .admin-report-table thead tr {
8509 border-bottom: 2px solid var(--border);
8510 text-align: left;
8511 }
8512 .admin-report-table tbody tr {
8513 border-bottom: 1px solid var(--border);
8514 }
8515 .admin-report-table th,
8516 .admin-report-table td {
8517 padding: 0.5rem;
8518 }
8519 .admin-report-table td.admin-report-reason {
8520 max-width: 200px;
8521 overflow: hidden;
8522 text-overflow: ellipsis;
8523 white-space: nowrap;
8524 }
8525 .admin-report-table td.admin-report-date {
8526 white-space: nowrap;
8527 }
8528
8529 .admin-report-target-type {
8530 opacity: 0.5;
8531 font-size: 0.8rem;
8532 }
8533
8534 .admin-report-status-open {
8535 color: var(--accent);
8536 font-weight: 600;
8537 }
8538 .admin-report-status-closed { opacity: 0.6; }
8539
8540 .admin-report-resolve-form {
8541 display: inline-flex;
8542 gap: 0.3rem;
8543 align-items: center;
8544 }
8545 .admin-report-resolve-form input[type="text"] {
8546 width: 120px;
8547 padding: 0.2rem 0.4rem;
8548 font-size: 0.8rem;
8549 }
8550 .admin-report-dismiss-form { display: inline; }
8551
8552 .admin-report-admin-notes {
8553 font-size: 0.8rem;
8554 opacity: 0.6;
8555 }
8556
8557 /* ===========================================
8558 PROJECT PROMOTIONS TAB (replaces inline styles in partials/tabs/project_promotions.html)
8559 =========================================== */
8560
8561 .proj-promo-form {
8562 margin-bottom: 2rem;
8563 }
8564
8565 .proj-promo-grid {
8566 display: grid;
8567 grid-template-columns: 1fr 1fr;
8568 gap: 0.75rem 1.5rem;
8569 max-width: 500px;
8570 }
8571
8572 .proj-promo-grid--spaced {
8573 margin-top: 0.75rem;
8574 }
8575
8576 .proj-promo-grid--bordered {
8577 margin-top: 0.75rem;
8578 padding-top: 0.75rem;
8579 border-top: 1px solid var(--border);
8580 }
8581
8582 .proj-promo-trial-fields {
8583 display: none;
8584 max-width: 500px;
8585 margin-top: 0.75rem;
8586 }
8587
8588 .proj-promo-trial-fields.is-visible {
8589 display: block;
8590 }
8591
8592 .proj-promo-grid.is-hidden,
8593 .proj-promo-trial-fields.is-hidden {
8594 display: none;
8595 }
8596
8597 .proj-promo-form .form-group {
8598 margin-bottom: 0;
8599 }
8600
8601 .proj-promo-form .form-group label {
8602 font-size: 0.85rem;
8603 }
8604
8605 .proj-promo-trial-group {
8606 max-width: 240px;
8607 }
8608
8609 .proj-promo-scope {
8610 grid-column: 1 / -1;
8611 }
8612
8613 .proj-promo-actions {
8614 margin-top: 1rem;
8615 }
8616
8617 .proj-promo-hint {
8618 margin-top: 0.5rem;
8619 }
8620
8621 /* ===========================================
8622 PROJECT OVERVIEW TAB (replaces inline styles in partials/tabs/project_overview.html)
8623 =========================================== */
8624
8625 .proj-overview-setup {
8626 margin-bottom: var(--space-4);
8627 padding: 1.25rem;
8628 background: var(--light-background);
8629 border: 1px solid var(--border);
8630 }
8631 .proj-overview-setup-title {
8632 margin: 0 0 var(--space-3) 0;
8633 font-family: var(--font-heading);
8634 font-weight: bold;
8635 }
8636 .proj-overview-setup-row {
8637 display: flex;
8638 align-items: center;
8639 gap: var(--space-3);
8640 padding: var(--space-2) 0;
8641 border-bottom: 1px solid var(--border-color);
8642 }
8643 .proj-overview-setup-row:last-child { border-bottom: none; }
8644 .proj-overview-setup-check {
8645 color: var(--success);
8646 font-family: var(--font-mono);
8647 font-size: 0.75rem;
8648 text-transform: uppercase;
8649 letter-spacing: 0.04em;
8650 flex-shrink: 0;
8651 }
8652 .proj-overview-setup-bullet {
8653 width: 1.1rem;
8654 height: 1.1rem;
8655 border: 2px solid var(--border-color);
8656 border-radius: 50%;
8657 flex-shrink: 0;
8658 }
8659 .proj-overview-setup-label {
8660 flex: 1;
8661 font-size: 0.9rem;
8662 }
8663 .proj-overview-setup-label--done {
8664 opacity: 0.5;
8665 text-decoration: line-through;
8666 }
8667 .proj-overview-setup-btn {
8668 font-size: 0.8rem;
8669 padding: 0.25rem 0.6rem;
8670 }
8671
8672 .proj-overview-tools { margin-top: var(--space-6); }
8673 .proj-overview-tools-summary {
8674 cursor: pointer;
8675 font-size: 1rem;
8676 font-family: var(--font-heading);
8677 font-weight: bold;
8678 }
8679 .proj-overview-tools-grid {
8680 display: grid;
8681 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
8682 gap: var(--space-3);
8683 margin-top: var(--space-3);
8684 }
8685 .proj-overview-tool {
8686 background: var(--surface-muted);
8687 padding: var(--space-3);
8688 }
8689 .proj-overview-tool-name {
8690 font-weight: bold;
8691 font-size: 0.95rem;
8692 margin-bottom: var(--space-1);
8693 }
8694 .proj-overview-tool-desc {
8695 font-size: 0.85rem;
8696 opacity: 0.7;
8697 margin: 0;
8698 }
8699
8700 /* ===========================================
8701 PROJECT SYNCKIT TAB (replaces inline styles in partials/tabs/project_synckit.html)
8702 =========================================== */
8703
8704 .proj-synckit-intro { margin-bottom: 0.75rem; }
8705 .proj-synckit-intro-secondary { margin-bottom: 1.5rem; }
8706 .proj-synckit-create { margin-bottom: 1.5rem; }
8707 .proj-synckit-create-body {
8708 padding: var(--space-3); background: var(--light-background); border: 1px solid var(--border-color);
8709 }
8710 .proj-synckit-create-form {
8711 display: flex; flex-direction: row; gap: 0.75rem; align-items: flex-end;
8712 }
8713 .proj-synckit-label {
8714 display: block; font-size: 0.85rem; margin-bottom: var(--space-1);
8715 }
8716 .proj-synckit-code { font-size: 0.8rem; }
8717 .proj-synckit-code--wrap { font-size: 0.8rem; word-break: break-all; }
8718 .proj-synckit-code--selectable { font-size: 0.85rem; word-break: break-all; user-select: all; }
8719 .proj-synckit-btn-tight {
8720 margin-left: var(--space-2); padding: 0.15rem 0.4rem; font-size: 0.75rem;
8721 }
8722 .proj-synckit-btn-row {
8723 padding: 0.15rem 0.4rem; font-size: 0.75rem;
8724 }
8725 .proj-synckit-btn-row + .proj-synckit-btn-row { margin-left: var(--space-1); }
8726 .proj-synckit-hint-inline {
8727 font-size: 0.7rem; margin-left: var(--space-1);
8728 }
8729 .proj-synckit-hint-warn {
8730 font-size: 0.7rem; color: var(--error);
8731 }
8732 .proj-synckit-status-active { color: var(--success); }
8733 .proj-synckit-status-inactive { color: var(--error); }
8734 .proj-synckit-new-key {
8735 padding: 0.75rem; background: var(--light-background);
8736 border: 1px solid var(--border-color); margin-top: var(--space-2);
8737 }
8738 .proj-synckit-new-key-heading {
8739 margin: 0 0 var(--space-2) 0; font-weight: 500; color: var(--error);
8740 }
8741 .proj-synckit-create-status--error { color: var(--error); margin-top: var(--space-2); }
8742 .proj-synckit-create-status--reset { margin-top: var(--space-2); }
8743
8744 /* ===========================================
8745 ITEM PAGE (replaces inline styles in pages/item.html)
8746 =========================================== */
8747
8748 .item-page .breadcrumb {
8749 display: flex;
8750 justify-content: space-between;
8751 align-items: center;
8752 }
8753
8754 .item-page .breadcrumb-edit-link {
8755 font-size: 0.85rem;
8756 color: var(--detail);
8757 }
8758
8759 .item-page .video-player {
8760 width: 100%;
8761 max-height: 600px;
8762 background: var(--primary-dark);
8763 }
8764
8765 .item-page .item-cover-img {
8766 width: 100%;
8767 aspect-ratio: 1 / 1;
8768 object-fit: cover;
8769 display: block;
8770 }
8771
8772 .item-page .tag-link {
8773 text-decoration: none;
8774 color: inherit;
8775 }
8776
8777 .item-page .bundle-notice-inline {
8778 background: var(--surface-muted);
8779 padding: 1.25rem;
8780 }
8781
8782 .item-page .bundle-notice-title {
8783 font-weight: bold;
8784 margin-bottom: 0.5rem;
8785 }
8786
8787 .item-page .bundle-notice-desc {
8788 opacity: 0.8;
8789 font-size: 0.9rem;
8790 }
8791
8792 .item-page .bundle-notice-entry {
8793 margin-top: 0.75rem;
8794 }
8795
8796 .item-page .bundle-notice-entry a {
8797 font-weight: bold;
8798 }
8799
8800 .item-page .bundle-notice-price {
8801 opacity: 0.7;
8802 }
8803
8804 .item-page .bundle-notice-empty {
8805 margin-top: 0.5rem;
8806 opacity: 0.7;
8807 font-size: 0.9rem;
8808 }
8809
8810 .item-page .promo-details {
8811 margin-bottom: 1rem;
8812 font-size: 0.9rem;
8813 }
8814
8815 .item-page .promo-summary {
8816 cursor: pointer;
8817 opacity: 0.7;
8818 }
8819
8820 .item-page .promo-form {
8821 display: flex;
8822 gap: 0.5rem;
8823 align-items: center;
8824 margin-top: 0.5rem;
8825 }
8826
8827 .item-page .promo-input {
8828 flex: 1;
8829 padding: 0.4rem 0.6rem;
8830 font-size: 0.85rem;
8831 }
8832
8833 .item-page .action-row {
8834 margin-top: 1rem;
8835 }
8836
8837 .item-page .action-row-tight {
8838 margin-top: 0.5rem;
8839 }
8840
8841 .item-page .full-width-btn {
8842 width: 100%;
8843 font-size: 0.9rem;
8844 }
8845
8846 .item-page .license-preset-name {
8847 margin-bottom: 0.75rem;
8848 }
8849
8850 .item-page .license-summary {
8851 cursor: pointer;
8852 opacity: 0.7;
8853 font-size: 0.9rem;
8854 }
8855
8856 .item-page .license-text {
8857 white-space: pre-wrap;
8858 font-family: var(--font-body);
8859 font-size: 0.85rem;
8860 margin-top: 0.75rem;
8861 padding: 1rem;
8862 background: var(--surface-muted);
8863 }
8864
8865 .item-page .license-download {
8866 margin-top: 0.75rem;
8867 }
8868
8869 .item-page .license-download a {
8870 font-size: 0.9rem;
8871 color: var(--detail);
8872 }
8873
8874 .item-page .bundle-list-entry {
8875 margin-top: 0.5rem;
8876 }
8877
8878 .item-page .footer-links {
8879 margin-top: 0.5rem;
8880 }
8881
8882 /* ===========================================
8883 JOIN COMPLETE STEP (replaces inline styles in wizards/steps/join/complete.html)
8884 =========================================== */
8885 .join-complete-intro { margin-bottom: var(--space-5); }
8886 .join-complete-choices {
8887 display: grid; grid-template-columns: 1fr 1fr;
8888 gap: var(--space-4); max-width: 500px;
8889 }
8890 .join-complete-choice { text-decoration: none; color: inherit; display: block; }
8891 .join-complete-card {
8892 background: var(--surface-muted); padding: var(--space-4); text-align: center;
8893 border: 2px solid transparent; transition: border-color 0.15s;
8894 }
8895 .join-complete-choice:hover .join-complete-card,
8896 .join-complete-card--active { border-color: var(--detail); }
8897 .join-complete-card-title {
8898 font-family: var(--font-heading); font-weight: bold;
8899 font-size: 1.1rem; margin-bottom: var(--space-2);
8900 }
8901 .join-complete-card-desc {
8902 font-size: 0.85rem; opacity: 0.7; margin: 0;
8903 }
8904 .join-complete-footnote {
8905 font-size: 0.85rem; opacity: 0.5;
8906 margin-top: var(--space-4); text-align: center;
8907 }
8908
8909 /* ===========================================
8910 PROMO CODES LIST (replaces inline styles in partials/promo_codes_list.html)
8911 =========================================== */
8912 .promo-codes-row--expired { opacity: 0.5; }
8913 .promo-codes-row--pending { opacity: 0.7; }
8914 .promo-codes-schedule { font-size: 0.85rem; }
8915 .promo-codes-schedule-pending { color: var(--warning); }
8916 .promo-codes-schedule-expired { color: var(--danger); }
8917 .promo-codes-schedule-none { opacity: 0.5; }
8918 .promo-codes-actions { white-space: nowrap; }
8919 .promo-codes-edit-btn { font-size: 0.8rem; }
8920 .promo-codes-edit-row { background: var(--surface-muted); }
8921 .promo-codes-edit-cell { padding: var(--space-3); }
8922 .promo-codes-edit-form {
8923 display: flex; gap: var(--space-3); align-items: end; flex-wrap: wrap;
8924 }
8925 .promo-codes-edit-label {
8926 font-size: 0.8rem; display: block; margin-bottom: var(--space-1);
8927 }
8928 .promo-codes-edit-save { font-size: 0.85rem; }
8929 .promo-codes-bulk-row { margin-top: var(--space-3); }
8930 .promo-codes-bulk-btn { font-size: 0.85rem; opacity: 0.7; }
8931
8932 /* ===========================================
8933 USER MEDIA TAB (replaces inline styles in partials/tabs/user_media.html)
8934 =========================================== */
8935
8936 .user-media-intro {
8937 margin-bottom: 1rem;
8938 }
8939
8940 .user-media-upload {
8941 border: 2px dashed var(--border-color);
8942 padding: 1.5rem;
8943 margin-bottom: 1.5rem;
8944 text-align: center;
8945 background: var(--light-background);
8946 }
8947
8948 .user-media-upload--dragover {
8949 border-color: var(--accent);
8950 }
8951
8952 .user-media-upload-row {
8953 margin-bottom: 0.75rem;
8954 }
8955
8956 .user-media-upload-label {
8957 display: inline-block;
8958 font-size: 0.85rem;
8959 margin-right: 0.75rem;
8960 }
8961
8962 .user-media-upload-folder-input {
8963 padding: 0.3rem;
8964 font-size: 0.85rem;
8965 width: 140px;
8966 margin-left: 0.25rem;
8967 }
8968
8969 .user-media-upload-progress {
8970 margin-top: 0.75rem;
8971 }
8972
8973 .user-media-upload-status {
8974 font-size: 0.85rem;
8975 margin-bottom: 0.25rem;
8976 }
8977
8978 .user-media-upload-status--ok {
8979 color: var(--success);
8980 }
8981
8982 .user-media-upload-status--err {
8983 color: var(--error);
8984 }
8985
8986 .user-media-folders {
8987 margin-bottom: 1rem;
8988 display: flex;
8989 gap: 0.5rem;
8990 flex-wrap: wrap;
8991 align-items: center;
8992 }
8993
8994 .user-media-folders-label {
8995 font-size: 0.85rem;
8996 opacity: 0.7;
8997 }
8998
8999 .user-media-folders-btn {
9000 font-size: 0.8rem;
9001 }
9002
9003 .user-media-grid {
9004 display: grid;
9005 grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
9006 gap: 1rem;
9007 }
9008
9009 .user-media-card {
9010 background: var(--light-background);
9011 border: 1px solid var(--border-color);
9012 padding: 0.75rem;
9013 position: relative;
9014 }
9015
9016 .user-media-card-thumb {
9017 width: 100%;
9018 height: 120px;
9019 overflow: hidden;
9020 margin-bottom: 0.5rem;
9021 display: flex;
9022 align-items: center;
9023 justify-content: center;
9024 background: var(--surface-muted);
9025 }
9026
9027 .user-media-card-thumb--video {
9028 font-size: 2rem;
9029 opacity: 0.4;
9030 }
9031
9032 .user-media-card-img {
9033 max-width: 100%;
9034 max-height: 120px;
9035 object-fit: contain;
9036 }
9037
9038 .user-media-card-name {
9039 font-size: 0.8rem;
9040 word-break: break-all;
9041 margin-bottom: 0.25rem;
9042 }
9043
9044 .user-media-card-meta {
9045 font-size: 0.75rem;
9046 opacity: 0.6;
9047 margin-bottom: 0.5rem;
9048 }
9049
9050 .user-media-card-actions {
9051 display: flex;
9052 gap: 0.25rem;
9053 }
9054
9055 .user-media-card-btn {
9056 font-size: 0.7rem;
9057 padding: 0.15rem 0.4rem;
9058 }
9059
9060 /* ===========================================
9061 ITEM VERSION UPLOAD (replaces inline styles in partials/item_version_upload.html)
9062 =========================================== */
9063
9064 .item-version-upload-cell-sm {
9065 font-size: 0.85rem;
9066 }
9067
9068 .item-version-upload-no-file {
9069 opacity: 0.5;
9070 }
9071
9072 .item-version-upload-btn {
9073 padding: 0.4rem 0.8rem;
9074 font-size: 0.85rem;
9075 }
9076
9077 .item-version-upload-add-btn {
9078 padding: 0.4rem 0.8rem;
9079 }
9080
9081 .item-version-upload-grid {
9082 display: grid;
9083 grid-template-columns: 1fr 1fr;
9084 gap: var(--space-3);
9085 }
9086
9087 .item-version-upload-hint {
9088 margin-bottom: var(--space-2);
9089 }
9090
9091 .item-version-upload-file-table {
9092 width: 100%;
9093 border-collapse: collapse;
9094 }
9095
9096 .item-version-upload-file-table thead tr {
9097 text-align: left;
9098 font-size: 0.8rem;
9099 opacity: 0.7;
9100 text-transform: uppercase;
9101 letter-spacing: 0.03em;
9102 }
9103
9104 .item-version-upload-file-table th:first-child {
9105 padding: 0.4rem 0.5rem 0.4rem 0;
9106 }
9107
9108 .item-version-upload-file-table th + th {
9109 padding: 0.4rem 0.5rem;
9110 }
9111
9112 .item-version-upload-file-table th:last-child {
9113 width: 40px;
9114 }
9115
9116 .item-version-upload-add-row {
9117 margin-top: var(--space-2);
9118 }
9119
9120 .item-version-upload-queue {
9121 margin-bottom: 0.75rem;
9122 }
9123
9124 .item-version-upload-speed {
9125 font-size: 0.8rem;
9126 opacity: 0.6;
9127 margin-top: 0.25rem;
9128 }
9129
9130 /* ===========================================
9131 PROJECT PAGE (replaces inline styles in pages/project.html)
9132 =========================================== */
9133
9134 .project-page .store-cover {
9135 width: 120px;
9136 height: 120px;
9137 border-radius: 8px;
9138 object-fit: cover;
9139 margin-bottom: var(--space-5);
9140 }
9141 .project-page .store-actions .secondary {
9142 display: inline-block;
9143 padding: 0.5rem 1rem;
9144 text-decoration: none;
9145 }
9146 .project-page .follow-btn.is-selected {
9147 opacity: 0.7;
9148 }
9149 .project-page .follower-count-muted {
9150 font-size: 0.85rem;
9151 opacity: 0.7;
9152 padding: 0.5rem 0;
9153 }
9154 .project-page .item-tags .tag {
9155 text-decoration: none;
9156 color: inherit;
9157 }
9158 .project-page .promo-details {
9159 font-size: 0.85rem;
9160 margin-bottom: var(--space-2);
9161 }
9162 .project-page .promo-details summary {
9163 cursor: pointer;
9164 opacity: 0.7;
9165 }
9166 .project-page .promo-input {
9167 width: 100%;
9168 margin-top: 0.4rem;
9169 padding: 0.3rem 0.5rem;
9170 font-size: 0.85rem;
9171 text-transform: uppercase;
9172 }
9173 .project-page .store-footer-links {
9174 margin-top: var(--space-2);
9175 }
9176
9177 /* ===========================================
9178 INSERTION LIST (replaces inline styles in partials/insertion_list.html)
9179 =========================================== */
9180
9181 .insertion-list-heading {
9182 font-family: var(--font-mono);
9183 font-size: 1rem;
9184 margin-bottom: var(--space-4);
9185 }
9186 .insertion-list-toolbar {
9187 margin-bottom: var(--space-4);
9188 }
9189 .insertion-list-upload {
9190 font-family: var(--font-mono);
9191 }
9192 .insertion-list-table {
9193 width: 100%;
9194 font-family: var(--font-body);
9195 }
9196 .insertion-list-table th {
9197 text-align: left;
9198 font-family: var(--font-mono);
9199 font-size: 0.875rem;
9200 }
9201 .insertion-list-table th.insertion-list-th-actions {
9202 text-align: right;
9203 }
9204 .insertion-list-table .insertion-list-actions {
9205 text-align: right;
9206 }
9207 .insertion-list-table .insertion-list-action-btn {
9208 font-family: var(--font-mono);
9209 }
9210
9211 /* ===========================================
9212 PROJECT MEMBERS TAB (replaces inline styles in partials/tabs/project_members.html)
9213 =========================================== */
9214
9215 .proj-members-summary {
9216 background: var(--surface-muted);
9217 padding: 1.25rem;
9218 margin-bottom: var(--space-4);
9219 }
9220
9221 .proj-members-summary-row {
9222 display: flex;
9223 justify-content: space-between;
9224 align-items: center;
9225 }
9226
9227 .proj-members-stat {
9228 font-size: 1.5rem;
9229 font-weight: bold;
9230 }
9231
9232 .proj-members-add {
9233 margin-bottom: var(--space-6);
9234 }
9235
9236 .proj-members-add-grid {
9237 display: grid;
9238 grid-template-columns: 1fr auto auto;
9239 gap: var(--space-3);
9240 align-items: end;
9241 }
9242
9243 .proj-members-field-label {
9244 font-size: 0.85rem;
9245 display: block;
9246 margin-bottom: var(--space-1);
9247 }
9248
9249 .proj-members-field-label--spaced {
9250 margin-top: 0.75rem;
9251 }
9252
9253 .proj-members-add-result {
9254 margin-top: var(--space-2);
9255 }
9256
9257 .proj-members-name-link {
9258 color: inherit;
9259 }
9260
9261 .proj-members-split-cell {
9262 font-weight: bold;
9263 }
9264
9265 /* ===========================================
9266 PLACEMENT LIST (replaces inline styles in partials/placement_list.html)
9267 =========================================== */
9268
9269 .placement-list-heading {
9270 font-family: var(--font-mono);
9271 font-size: 1rem;
9272 margin-bottom: var(--space-3);
9273 }
9274 .placement-list-table {
9275 width: 100%;
9276 font-family: var(--font-body);
9277 margin-bottom: var(--space-4);
9278 }
9279 .placement-list-table th {
9280 text-align: left;
9281 font-family: var(--font-mono);
9282 font-size: 0.875rem;
9283 }
9284 .placement-list-table th.placement-list-th-actions {
9285 text-align: right;
9286 }
9287 .placement-list-table .placement-list-actions {
9288 text-align: right;
9289 }
9290 .placement-list-table .placement-list-remove {
9291 font-family: var(--font-mono);
9292 }
9293 .placement-list-form {
9294 display: flex;
9295 gap: var(--space-2);
9296 align-items: flex-end;
9297 flex-wrap: wrap;
9298 }
9299 .placement-list-label {
9300 display: block;
9301 font-family: var(--font-mono);
9302 font-size: 0.8125rem;
9303 margin-bottom: var(--space-1);
9304 }
9305 .placement-list-add {
9306 font-family: var(--font-mono);
9307 }
9308
9309 /* ===========================================
9310 USER SYNCKIT TAB (replaces inline styles in partials/tabs/user_synckit.html)
9311 =========================================== */
9312
9313 .user-synckit-create { margin-bottom: var(--space-5); }
9314 .user-synckit-create-body {
9315 padding: var(--space-4);
9316 background: var(--light-background);
9317 border: 1px solid var(--border-color);
9318 }
9319 .user-synckit-create-form {
9320 display: flex;
9321 flex-direction: row;
9322 gap: var(--space-3);
9323 align-items: flex-end;
9324 }
9325 .user-synckit-create-form label {
9326 display: block;
9327 font-size: 0.85rem;
9328 margin-bottom: var(--space-1);
9329 }
9330 .user-synckit-create-form input[type="text"],
9331 .user-synckit-create-form select {
9332 padding: var(--space-2);
9333 font-size: 0.9rem;
9334 }
9335 .user-synckit-create-form input[type="text"] { width: 220px; }
9336 .user-synckit-create-form select { width: 180px; }
9337
9338 .user-synckit-code { font-size: 0.8rem; }
9339 .user-synckit-hint {
9340 font-size: 0.7rem;
9341 margin-left: var(--space-1);
9342 }
9343
9344 .user-synckit-inline-btn {
9345 margin-left: var(--space-2);
9346 padding: 0.15rem 0.4rem;
9347 font-size: 0.75rem;
9348 }
9349 .user-synckit-row-btn {
9350 padding: 0.15rem 0.4rem;
9351 font-size: 0.75rem;
9352 }
9353 .user-synckit-row-btn + .user-synckit-row-btn {
9354 margin-left: var(--space-1);
9355 }
9356
9357 .user-synckit-status-active { color: var(--success); }
9358 .user-synckit-status-inactive { color: var(--error); }
9359
9360 .user-synckit-edit-btn {
9361 padding: 0.15rem 0.4rem;
9362 font-size: 0.75rem;
9363 }
9364
9365 .user-synckit-create-error {
9366 color: var(--error);
9367 margin-top: var(--space-2);
9368 }
9369
9370 /* ===========================================
9371 TOTP (replaces inline styles in partials/totp_setup.html and totp_status.html)
9372 =========================================== */
9373
9374 /* Section wrapper between TOTP subsections (QR + backup codes + confirm,
9375 or regenerate + disable). */
9376 .totp-section { margin-bottom: var(--space-5); }
9377
9378 /* Confirm-setup section is separated from the backup codes by a top border. */
9379 .totp-confirm {
9380 border-top: 1px solid var(--border);
9381 padding-top: var(--space-4);
9382 }
9383
9384 /* QR code container, centered above the manual-entry details. */
9385 .totp-qr {
9386 text-align: center;
9387 margin-bottom: var(--space-4);
9388 }
9389 .totp-qr img {
9390 max-width: 200px;
9391 image-rendering: pixelated;
9392 }
9393
9394 /* Collapsible "Manual entry key" group. */
9395 .totp-manual { margin-bottom: var(--space-4); }
9396 .totp-manual summary {
9397 cursor: pointer;
9398 opacity: 0.7;
9399 font-size: 0.85rem;
9400 }
9401 .totp-manual-secret {
9402 display: block;
9403 margin-top: var(--space-2);
9404 word-break: break-all;
9405 font-size: 0.85rem;
9406 padding: var(--space-2);
9407 background: var(--surface-muted);
9408 }
9409
9410 /* Backup codes grid (rendered list of one-time codes). */
9411 .backup-codes-grid {
9412 display: grid;
9413 grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
9414 gap: var(--space-2);
9415 }
9416 .backup-codes-grid code {
9417 padding: var(--space-2);
9418 background: var(--surface-muted);
9419 text-align: center;
9420 font-size: 0.9rem;
9421 }
9422
9423 /* Status row for the "Enabled" badge above the management forms. */
9424 .totp-status-row {
9425 display: flex;
9426 align-items: center;
9427 gap: var(--space-2);
9428 margin-bottom: var(--space-4);
9429 }
9430
9431 /* Container where regenerated backup codes are swapped in via HTMX. */
9432 .totp-regen-output { margin-top: var(--space-3); }
9433
9434 /* ===========================================
9435 DASHBOARD-USER SHELL (replaces inline styles in dashboards/dashboard-user.html)
9436 =========================================== */
9437
9438 .sandbox-banner {
9439 background: var(--highlight);
9440 color: var(--primary-light);
9441 padding: 0.75rem 1.5rem;
9442 text-align: center;
9443 font-family: var(--font-mono);
9444 font-size: 0.9rem;
9445 }
9446
9447 .sandbox-banner-link {
9448 color: var(--primary-light);
9449 text-decoration: underline;
9450 margin-left: 0.5rem;
9451 }
9452 .account-status-actions {
9453 display: flex;
9454 gap: 0.75rem;
9455 flex-wrap: wrap;
9456 margin-top: 1rem;
9457 }
9458
9459 .suspension-wrap {
9460 margin-bottom: 1rem;
9461 }
9462
9463 .password-warning-banner {
9464 margin-bottom: 1rem;
9465 padding: 1rem;
9466 background: var(--warning-bg);
9467 border: 1px solid var(--warning-border);
9468 font-size: 0.95rem;
9469 }
9470
9471 .dash-user-header-links {
9472 margin-bottom: 0.5rem;
9473 display: flex;
9474 gap: 1.5rem;
9475 }
9476
9477 .dash-user-header-link {
9478 font-size: 0.9rem;
9479 opacity: 0.7;
9480 }
9481
9482 .checklist-recovery {
9483 padding: 0.75rem 0;
9484 text-align: right;
9485 }
9486
9487 .checklist-recovery-link {
9488 font-size: 0.85rem;
9489 opacity: 0.7;
9490 }
9491
9492 .tab-spinner {
9493 margin-left: 1rem;
9494 }
9495
9496 /* ===========================================
9497 USER PROFILE PAGE (replaces inline styles in pages/user.html)
9498 =========================================== */
9499
9500 .user-page .creator-paused-notice {
9501 margin-bottom: 1.5rem;
9502 padding: 1rem;
9503 background: var(--surface-muted);
9504 border: 1px solid var(--border-color);
9505 text-align: center;
9506 font-size: 0.95rem;
9507 }
9508
9509 .user-page .profile-action-row {
9510 margin-top: 1rem;
9511 }
9512
9513 .user-page .profile-edit-btn {
9514 display: inline-block;
9515 padding: 0.5rem 1rem;
9516 text-decoration: none;
9517 font-size: 0.9rem;
9518 }
9519
9520 .user-page .follow-btn.is-selected {
9521 opacity: 0.7;
9522 }
9523
9524 .user-page .follower-count {
9525 margin-top: 1rem;
9526 font-size: 0.85rem;
9527 opacity: 0.7;
9528 }
9529
9530 .user-page .profile-share-row {
9531 margin-top: 0.75rem;
9532 display: flex;
9533 gap: 1rem;
9534 justify-content: center;
9535 font-size: 0.9rem;
9536 }
9537
9538 .user-page .profile-share-link {
9539 opacity: 0.7;
9540 }
9541
9542 .user-page .collections-section {
9543 margin-bottom: 2rem;
9544 }
9545
9546 /* ===========================================
9547 SUSPENSION BANNER (replaces inline styles in partials/suspension_banner.html)
9548 =========================================== */
9549
9550 .suspension-banner {
9551 background: var(--danger-bg);
9552 border: 1px solid var(--danger);
9553 padding: var(--space-5);
9554 margin-bottom: var(--space-5);
9555 }
9556
9557 .suspension-banner-title {
9558 margin: 0 0 var(--space-2) 0;
9559 color: var(--danger);
9560 }
9561
9562 .suspension-banner-reason {
9563 font-size: 0.9rem;
9564 margin: 0 0 var(--space-3) 0;
9565 }
9566
9567 .suspension-banner-denial {
9568 background: var(--light-background);
9569 padding: var(--space-3);
9570 margin-bottom: var(--space-3);
9571 font-size: 0.9rem;
9572 }
9573
9574 .suspension-banner-denial-response {
9575 margin: var(--space-1) 0 0 0;
9576 }
9577
9578 .suspension-banner-denial-hint {
9579 margin: var(--space-2) 0 0 0;
9580 opacity: 0.7;
9581 }
9582
9583 .suspension-banner-pending {
9584 font-size: 0.9rem;
9585 opacity: 0.7;
9586 margin: 0;
9587 }
9588
9589 .suspension-banner-appeal {
9590 margin-top: var(--space-2);
9591 }
9592
9593 .suspension-banner-appeal-summary {
9594 cursor: pointer;
9595 font-size: 0.9rem;
9596 }
9597
9598 .suspension-banner-appeal-form {
9599 margin-top: var(--space-3);
9600 }
9601
9602 .suspension-banner-appeal-text {
9603 width: 100%;
9604 margin-bottom: var(--space-2);
9605 font-size: 0.9rem;
9606 }
9607
9608 .suspension-banner-appeal-submit {
9609 font-size: 0.85rem;
9610 }
9611
9612 .suspension-banner-export {
9613 margin-top: var(--space-3);
9614 }
9615
9616 .suspension-banner-export-link {
9617 font-size: 0.9rem;
9618 }
9619
9620 /* ===========================================
9621 REPORT MODAL (replaces inline styles in partials/report_modal.html)
9622 =========================================== */
9623
9624 .report-modal-content {
9625 background: var(--background);
9626 padding: var(--space-6);
9627 width: 90%;
9628 max-width: 480px;
9629 max-height: 90vh;
9630 overflow-y: auto;
9631 }
9632
9633 .report-modal-title {
9634 font-size: 1.2rem;
9635 margin: 0;
9636 }
9637
9638 .report-modal-fieldset {
9639 border: none;
9640 padding: 0;
9641 margin: 0 0 var(--space-4) 0;
9642 }
9643
9644 .report-modal-legend {
9645 font-size: 0.9rem;
9646 font-weight: 600;
9647 margin-bottom: var(--space-2);
9648 }
9649
9650 .report-modal-option {
9651 display: block;
9652 margin-bottom: 0.4rem;
9653 cursor: pointer;
9654 }
9655
9656 .report-modal-details {
9657 margin-bottom: var(--space-4);
9658 }
9659
9660 .report-modal-details-label {
9661 display: block;
9662 font-size: 0.85rem;
9663 margin-bottom: var(--space-1);
9664 }
9665
9666 .report-modal-textarea {
9667 width: 100%;
9668 font-size: 0.85rem;
9669 }
9670
9671 .report-modal-actions {
9672 display: flex;
9673 gap: var(--space-2);
9674 justify-content: flex-end;
9675 }
9676
9677 /* ===========================================
9678 LIBRARY COLLECTIONS TAB (partials/tabs/library_collections.html)
9679 =========================================== */
9680
9681 .badge.is-faded { opacity: 0.5; }
9682 .lib-coll-new { margin-top: var(--space-5); }
9683 .lib-coll-new-summary { cursor: pointer; font-weight: bold; }
9684 .lib-coll-new-form { margin-top: var(--space-4); }
9685 .lib-coll-wishlist-heading {
9686 font-size: 1.1rem;
9687 margin-top: 2.5rem;
9688 margin-bottom: var(--space-4);
9689 opacity: 0.8;
9690 }
9691 .lib-coll-wishlist-wrap {
9692 overflow-x: auto;
9693 -webkit-overflow-scrolling: touch;
9694 }
9695 .lib-coll-wishlist-table { min-width: 500px; }
9696 .lib-coll-row-actions { white-space: nowrap; }
9697 .lib-coll-row-actions .lib-coll-cart-btn { margin-right: 0.25rem; }
9698
9699 /* ===========================================
9700 USER ANALYTICS TAB (partials/tabs/user_analytics.html)
9701 =========================================== */
9702
9703 .analytics-export-link { margin-left: var(--space-4); }
9704 .analytics-range-heading {
9705 font-size: 1.1rem;
9706 margin: 0;
9707 }
9708 .analytics-section--comparison { margin-bottom: 2rem; }
9709 .analytics-section--comparison h2 { margin-bottom: var(--space-4); }
9710 .analytics-table-wrap {
9711 overflow-x: auto;
9712 -webkit-overflow-scrolling: touch;
9713 }
9714 .analytics-table { min-width: 500px; }
9715 .analytics-revenue-cell {
9716 display: flex;
9717 align-items: center;
9718 gap: var(--space-2);
9719 }
9720 .analytics-revenue-bar {
9721 height: 10px;
9722 min-width: 2px;
9723 max-width: 80px;
9724 background: var(--highlight);
9725 }
9726
9727 /* ===========================================
9728 ITEM EMBED TAB (templates/partials/tabs/item_embed.html)
9729 =========================================== */
9730 .embed-intro {
9731 opacity: 0.7;
9732 font-size: 0.9rem;
9733 margin-bottom: var(--space-5);
9734 }
9735 .embed-option {
9736 margin-bottom: var(--space-5);
9737 padding: var(--space-4);
9738 border: 1px solid var(--border);
9739 border-radius: 6px;
9740 }
9741 .embed-option h4 {
9742 margin-bottom: 0.25rem;
9743 font-size: 0.95rem;
9744 }
9745 .embed-option-desc {
9746 font-size: 0.85rem;
9747 opacity: 0.7;
9748 margin-bottom: var(--space-2);
9749 }
9750 .embed-preview {
9751 margin: var(--space-3) 0;
9752 overflow: hidden;
9753 }
9754 .embed-iframe {
9755 border: none;
9756 border-radius: 4px;
9757 }
9758 .embed-layout-toggle {
9759 font-size: 0.85rem;
9760 margin-bottom: var(--space-2);
9761 display: flex;
9762 gap: var(--space-4);
9763 }
9764 .embed-layout-toggle label {
9765 cursor: pointer;
9766 display: flex;
9767 align-items: center;
9768 gap: 0.3rem;
9769 }
9770 .embed-code-row {
9771 display: flex;
9772 align-items: center;
9773 gap: var(--space-2);
9774 }
9775 .embed-snippet {
9776 flex: 1;
9777 padding: var(--space-2) var(--space-3);
9778 background: var(--light-background);
9779 border-radius: 4px;
9780 font-size: 11px;
9781 overflow-x: auto;
9782 white-space: nowrap;
9783 font-family: var(--font-mono);
9784 border: 1px solid var(--border);
9785 }
9786 .copy-btn {
9787 padding: 6px 12px;
9788 font-size: 12px;
9789 background: var(--accent);
9790 color: var(--primary-light);
9791 border: none;
9792 border-radius: var(--radius-md);
9793 cursor: pointer;
9794 white-space: nowrap;
9795 }
9796 .copy-btn:hover {
9797 opacity: 0.9;
9798 }
9799
9800 /* ===========================================
9801 ADMIN NAV (templates/partials/admin_nav.html)
9802 =========================================== */
9803 .admin-nav {
9804 display: flex;
9805 gap: var(--space-2);
9806 margin-bottom: var(--space-5);
9807 flex-wrap: wrap;
9808 font-family: var(--font-mono);
9809 font-size: 0.85rem;
9810 }
9811 .admin-nav a {
9812 padding: 0.3rem 0.8rem;
9813 text-decoration: none;
9814 }
9815
9816 /* ===========================================
9817 VIDEO PLAYER PAGE (templates/pages/video_player.html)
9818 =========================================== */
9819 .video-cover-img {
9820 width: 100%;
9821 display: block;
9822 background: var(--primary-dark);
9823 }
9824 .video-cover-placeholder {
9825 width: 100%;
9826 aspect-ratio: 16 / 9;
9827 background: var(--primary-dark);
9828 display: flex;
9829 align-items: center;
9830 justify-content: center;
9831 color: var(--text-muted);
9832 }
9833 .video-store-cta {
9834 margin: var(--space-6) 0;
9835 padding: var(--space-5);
9836 background: var(--surface-muted);
9837 text-align: center;
9838 }
9839 .video-cta-lead {
9840 font-size: 1.1rem;
9841 margin-bottom: var(--space-4);
9842 }
9843 .video-cta-price {
9844 font-size: 1.5rem;
9845 margin-bottom: var(--space-4);
9846 }
9847 .video-cta-fineprint {
9848 font-size: 0.85rem;
9849 opacity: 0.7;
9850 margin-top: 0.75rem;
9851 }
9852 .video-library-status {
9853 font-family: var(--font-mono);
9854 color: var(--text-muted);
9855 }
9856 .video-tag-link {
9857 text-decoration: none;
9858 color: inherit;
9859 }
9860
9861 /* ===========================================
9862 LIBRARY LOCKED PAGE (templates/pages/library_locked.html)
9863 =========================================== */
9864 .library-locked-byline {
9865 opacity: 0.7;
9866 }
9867 .library-locked-cover {
9868 max-width: 320px;
9869 margin: var(--space-4) 0;
9870 }
9871 .library-locked-purchase {
9872 margin-top: var(--space-6);
9873 }
9874 .library-locked-lead {
9875 opacity: 0.85;
9876 }
9877 .library-locked-actions {
9878 margin-top: var(--space-5);
9879 display: flex;
9880 gap: 0.75rem;
9881 flex-wrap: wrap;
9882 }
9883 .library-locked-bundles {
9884 margin-top: var(--space-5);
9885 }
9886 .library-locked-bundles-title {
9887 font-weight: bold;
9888 }
9889 .library-locked-bundle {
9890 margin-top: var(--space-2);
9891 }
9892 .library-locked-bundle-price {
9893 opacity: 0.7;
9894 }
9895
9896 /* ===========================================
9897 BLOG (replaces inline styles in project_blog.html
9898 and dashboard-blog-editor.html)
9899 =========================================== */
9900
9901 .blog-empty-state { padding: var(--space-6) 0; }
9902 .blog-empty-hint {
9903 opacity: 0.7;
9904 font-size: 0.9rem;
9905 margin-top: var(--space-2);
9906 }
9907 .blog-post-title-link { font-weight: bold; }
9908 .blog-post-actions {
9909 display: flex;
9910 gap: var(--space-2);
9911 }
9912
9913 /* Blog editor */
9914 .blog-editor h1 {
9915 font-size: 2rem;
9916 margin-bottom: var(--space-4);
9917 text-align: left;
9918 }
9919 .blog-editor .editor-form { max-width: 800px; }
9920 .blog-editor .editor-form .form-group { margin-bottom: 1.25rem; }
9921 .blog-editor .editor-form textarea {
9922 font-family: var(--font-mono);
9923 font-size: 0.9rem;
9924 min-height: 400px;
9925 resize: vertical;
9926 }
9927 .blog-editor-slug-spinner { font-size: 0.85rem; }
9928 .blog-editor-media-btn {
9929 margin-top: var(--space-2);
9930 font-size: 0.85rem;
9931 }
9932 .blog-editor-actions {
9933 display: flex;
9934 gap: var(--space-4);
9935 align-items: center;
9936 }
9937 .blog-editor-status { margin-top: var(--space-2); }
9938
9939 /* ===========================================
9940 AUDIO PLAYER (replaces inline styles in pages/audio_player.html)
9941 =========================================== */
9942
9943 .audio-store-cta {
9944 margin: 2rem 0;
9945 padding: var(--space-5);
9946 background: var(--surface-muted);
9947 text-align: center;
9948 }
9949 .audio-store-cta .audio-access-msg {
9950 font-size: 1.1rem;
9951 margin-bottom: var(--space-4);
9952 }
9953 .audio-store-cta .audio-price {
9954 font-size: 1.5rem;
9955 margin-bottom: var(--space-4);
9956 }
9957 .audio-store-cta .audio-fee-note {
9958 font-size: 0.85rem;
9959 opacity: 0.7;
9960 margin-top: 0.75rem;
9961 }
9962 .audio-library-status {
9963 font-family: var(--font-mono);
9964 color: var(--text-muted);
9965 }
9966 .audio-tag-link {
9967 text-decoration: none;
9968 color: inherit;
9969 }
9970
9971 /* ===========================================
9972 SECTIONS WIZARD STEP (templates/wizards/steps/item/sections.html)
9973 Parallels .psection-row used by item_details + project-sections.js,
9974 but isolated so wizard markup can evolve independently.
9975 =========================================== */
9976
9977 .section-row {
9978 display: flex;
9979 align-items: center;
9980 gap: var(--space-3);
9981 padding: 0.6rem 0;
9982 border-bottom: 1px solid var(--border);
9983 }
9984 .section-row-title { flex: 1; font-weight: bold; }
9985 .section-row-length { font-size: 0.8rem; opacity: 0.6; }
9986 .section-row .section-delete-btn {
9987 padding: 0.25rem 0.6rem;
9988 font-size: 0.8rem;
9989 }
9990
9991 .section-add-body { margin-top: var(--space-3); }
9992
9993 .wizard-actions { margin-top: var(--space-5); }
9994
9995 /* ===========================================
9996 PROJECT SUBSCRIPTIONS TAB (templates/partials/tabs/project_subscriptions.html)
9997 =========================================== */
9998
9999 .subs-connect-info {
10000 margin-bottom: var(--space-5);
10001 padding: 1.25rem;
10002 }
10003 .subs-new-tier { margin-bottom: var(--space-6); }
10004
10005 .tier-row-desc {
10006 font-size: 0.85rem;
10007 opacity: 0.7;
10008 margin-top: 0.25rem;
10009 }
10010 .tier-action-btn {
10011 font-size: 0.85rem;
10012 padding: 0.3rem 0.6rem;
10013 }
10014
10015 .subs-members-bar {
10016 margin-top: var(--space-6);
10017 display: flex;
10018 justify-content: space-between;
10019 align-items: center;
10020 }
10021
10022 /* ===========================================
10023 LIBRARY CONSUMPTION PAGES
10024 ===========================================
10025 Shared styles for the library-side consumption surfaces:
10026 text_reader.html, library_text.html (.article-page),
10027 library_downloads.html (.library-page),
10028 library_audio.html / library_video.html (.media-container + helpers).
10029 The .article-page and .library-page sections higher up in this file
10030 are activated by body classes set in the templates. */
10031
10032 /* Faded excerpt text on the public store-page text reader. */
10033 .article-page .article-body--excerpt { opacity: 0.85; }
10034
10035 /* Store-page call-to-action block (text_reader.html). */
10036 .article-page .store-cta {
10037 margin: 2.5rem 0;
10038 padding: var(--space-5);
10039 background: var(--surface-muted);
10040 text-align: center;
10041 }
10042 .article-page .store-cta-lead {
10043 font-size: 1.1rem;
10044 margin-bottom: var(--space-4);
10045 }
10046 .article-page .store-cta-price {
10047 font-size: 1.5rem;
10048 margin-bottom: var(--space-4);
10049 }
10050 .article-page .store-cta-note {
10051 font-size: 0.85rem;
10052 opacity: 0.7;
10053 margin-top: 0.75rem;
10054 }
10055 .article-page .store-cta .library-status {
10056 font-family: var(--font-mono);
10057 color: var(--text-muted);
10058 }
10059
10060 /* Plain (text-decoration-free, inherit-colored) tag link on text_reader.
10061 Distinguishes from the default linked .article-tag in library_text. */
10062 .article-page .article-tag--plain {
10063 text-decoration: none;
10064 color: inherit;
10065 }
10066
10067 /* Library back-link breadcrumb shared by the media library pages. */
10068 .media-container .library-back {
10069 font-size: 0.85rem;
10070 opacity: 0.7;
10071 margin: var(--space-4) 0;
10072 }
10073 .media-container .library-back a { color: var(--detail); }
10074
10075 /* Source-files download list under audio/video library pages.
10076 The .library-page version exists higher up; this block scopes the
10077 same look under .media-container for audio/video. */
10078 .media-container .library-downloads {
10079 background: var(--light-background);
10080 padding: 1.5rem;
10081 margin-top: var(--space-6);
10082 }
10083 .media-container .library-downloads h3 {
10084 font-size: 1.1rem;
10085 margin-bottom: var(--space-4);
10086 }
10087 .media-container .download-row {
10088 display: flex;
10089 align-items: center;
10090 gap: var(--space-4);
10091 padding: var(--space-2) 0;
10092 border-bottom: 1px solid var(--border);
10093 }
10094 .media-container .download-row:last-child { border-bottom: none; }
10095 .media-container .download-version {
10096 min-width: 4em;
10097 font-family: var(--font-mono);
10098 font-size: 0.9rem;
10099 }
10100 .media-container .download-label { flex: 1; }
10101 .media-container .download-label--empty { flex: 1; opacity: 0.5; }
10102 .media-container .download-size {
10103 font-size: 0.85rem;
10104 opacity: 0.6;
10105 min-width: 5em;
10106 text-align: right;
10107 }
10108
10109 /* Compact download button used in both library_downloads.html and
10110 media library pages. */
10111 .btn-download-compact {
10112 padding: 0.4rem 0.8rem;
10113 font-size: 0.85rem;
10114 }
10115
10116 /* Faded "no label" placeholder on library_downloads.html download rows. */
10117 .library-page .download-label--empty { opacity: 0.5; }
10118
10119 /* Library-downloads description <details> summary + body. */
10120 .library-page .lib-summary {
10121 cursor: pointer;
10122 font-family: var(--font-heading);
10123 font-size: 1.3rem;
10124 }
10125 .library-page .lib-summary-body { margin-top: var(--space-4); }
10126
10127 /* License section on library_downloads.html. */
10128 .library-page .lib-license-name { margin-bottom: 0.75rem; }
10129 .library-page .lib-license-download {
10130 font-size: 0.9rem;
10131 color: var(--detail);
10132 }
10133
10134 /* Footer below the item-footer (was inline on library_downloads.html). */
10135 .library-page .item-footer-sub { margin-top: var(--space-2); }
10136
10137 /* library_text.html footer (terse text-page footer, distinct from the
10138 text_reader.html .text-reader-footer that has its own classed style). */
10139 .article-page .lib-text-footer {
10140 text-align: center;
10141 padding: var(--space-6);
10142 font-size: 0.85rem;
10143 opacity: 0.6;
10144 border-top: 1px solid var(--border);
10145 }
10146 .article-page .lib-text-footer a { color: var(--detail); }
10147
10148 /* Media player play/pause icon initial state. The JS in media-player.js
10149 toggles via element.style.display directly, so we must NOT use
10150 !important here — element.style would still beat a normal-priority
10151 declaration, but !important in the stylesheet would defeat that. */
10152 .media-icon-hidden { display: none; }
10153
10154 /* Video element fills its .video-display parent. .video-display already
10155 provides a black background. */
10156 .video-display video { width: 100%; }
10157
10158 /* Cover image inside .cover-art on library_audio.html — the parent
10159 .cover-art already sets aspect ratio and centering; the inline
10160 width/aspect-ratio/object-fit was redundant with .cover-art img. */
10161
10162 /* ===========================================
10163 USER DASHBOARD TABS (support / sessions / buyer contacts)
10164 =========================================== */
10165
10166 /* Support tab (templates/partials/tabs/user_support.html). */
10167 .support-tab .support-intro-meta {
10168 margin-bottom: var(--space-5);
10169 font-size: 0.9rem;
10170 opacity: 0.8;
10171 }
10172 .support-tab .support-form { max-width: 600px; }
10173 .support-tab .response-times {
10174 margin-top: var(--space-6);
10175 font-size: 0.85rem;
10176 opacity: 0.7;
10177 }
10178 .support-tab .response-times ul {
10179 margin: var(--space-1) 0 0 var(--space-5);
10180 }
10181
10182 /* Sessions tab (templates/partials/tabs/user_sessions.html). */
10183 .sessions-tab .sessions-table { width: 100%; }
10184 .sessions-tab .device-cell {
10185 max-width: 300px;
10186 overflow: hidden;
10187 text-overflow: ellipsis;
10188 white-space: nowrap;
10189 }
10190
10191 /* Buyer contacts tab (templates/partials/tabs/buyer_contacts.html). */
10192 .buyer-contacts .contacts-table { min-width: 500px; }
10193
10194 /* Creators page extras (templates/pages/creators.html). */
10195 .creators-page .pricing-fineprint {
10196 font-size: 0.9rem;
10197 opacity: 0.8;
10198 margin-top: var(--space-2);
10199 }
10200 .creators-page .trial-callout {
10201 font-size: 0.9rem;
10202 margin-top: var(--space-5);
10203 }
10204
10205 /* ===========================================
10206 LIBRARY TABS
10207 Shared classes for the library-dashboard tab partials:
10208 library_wishlists, library_contacts, library_purchases,
10209 library_subscriptions. Migrated from inline styles.
10210 =========================================== */
10211
10212 /* Tables in library tabs need a minimum width so columns stay readable
10213 while the outer container scrolls horizontally on narrow viewports. */
10214
10215 /* Empty-state hint paragraph (smaller, slightly faded). */
10216 .library-tab-empty-hint {
10217 font-size: 0.9rem;
10218 opacity: 0.7;
10219 margin-bottom: var(--space-4);
10220 }
10221
10222 /* Compact row-action button (wishlist Add to Cart / Remove, etc.). */
10223
10224 .library-filter-wrap { margin-bottom: var(--space-4); }
10225
10226 /* Purchases table "Open" action link + context menu trigger group. */
10227 .library-row-actions {
10228 display: flex;
10229 align-items: center;
10230 gap: var(--space-2);
10231 }
10232 .library-row-open {
10233 font-size: 0.8rem;
10234 padding: var(--space-1) var(--space-3);
10235 text-decoration: none;
10236 white-space: nowrap;
10237 }
10238
10239 /* Section sub-heading inside purchases tab (e.g. "Subscriptions"). */
10240 .library-tab-subheading {
10241 font-size: 1.1rem;
10242 margin-top: var(--space-6);
10243 margin-bottom: var(--space-4);
10244 opacity: 0.8;
10245 }
10246
10247 /* Inline-block button styled as a link target on empty-state CTAs. */
10248 .library-tab-cta {
10249 display: inline-block;
10250 text-decoration: none;
10251 }
10252
10253 /* Context menu (dropdown) on each purchase row. */
10254 .context-menu-wrapper { position: relative; }
10255 .context-menu-btn {
10256 background: none;
10257 border: none;
10258 cursor: pointer;
10259 padding: var(--space-2);
10260 font-size: 1.25rem;
10261 line-height: 1;
10262 color: var(--text-muted);
10263 border-radius: 4px;
10264 }
10265 .context-menu-btn:hover {
10266 background: var(--surface-muted);
10267 color: var(--detail);
10268 }
10269 .context-menu {
10270 display: none;
10271 position: absolute;
10272 right: 0;
10273 top: 100%;
10274 background: var(--light-background);
10275 border: 1px solid var(--border);
10276 box-shadow: var(--shadow-2);
10277 min-width: 160px;
10278 z-index: 100;
10279 }
10280 .context-menu.open { display: block; }
10281 .context-menu-item {
10282 display: block;
10283 width: 100%;
10284 padding: var(--space-3) var(--space-4);
10285 text-align: left;
10286 background: none;
10287 border: none;
10288 font-family: var(--font-body);
10289 font-size: 0.9rem;
10290 color: var(--detail);
10291 cursor: pointer;
10292 text-decoration: none;
10293 }
10294 .context-menu-item:hover { background: var(--surface-muted); }
10295 .context-menu-item.danger { color: var(--danger); }
10296
10297 /* Inline license-key code chip shown beneath a purchase date. */
10298 .license-key-inline { margin-top: var(--space-1); }
10299 .key-code-small {
10300 font-size: 0.8rem;
10301 padding: 0.15rem 0.4rem;
10302 background: var(--surface-muted);
10303 border-radius: 3px;
10304 cursor: pointer;
10305 user-select: all;
10306 }
10307 .key-code-small:hover { background: var(--border); }
10308
10309 /* Library row title link reads as plain text until hovered. */
10310 .library-title-link { color: inherit; text-decoration: none; }
10311 .library-title-link:hover { text-decoration: underline; }
10312 /* ===========================================
10313 ADMIN ENTRIES (replaces inline styles in partials/admin_user_entries.html,
10314 partials/admin_waitlist_entries.html,
10315 partials/admin_appeal_entries.html)
10316 =========================================== */
10317
10318 /* Status badges built ad hoc (Active / Trusted). */
10319 .badge-active,
10320 .badge-trusted {
10321 background: var(--success-bg);
10322 color: var(--success);
10323 }
10324
10325 /* "Trust" toggle button sits next to a Trusted badge. */
10326 .admin-entries-trust-btn {
10327 margin-left: var(--space-1);
10328 }
10329
10330 /* Waitlist pitch cell — narrow body text. */
10331 .admin-entries-pitch {
10332 font-size: 0.9rem;
10333 max-width: 300px;
10334 }
10335 .admin-entries-pitch-empty {
10336 opacity: 0.5;
10337 font-style: italic;
10338 }
10339 .admin-entries-pitch-inviter {
10340 margin-top: var(--space-1);
10341 }
10342
10343 /* Appeal text columns. */
10344 .admin-entries-reason {
10345 font-size: 0.9rem;
10346 max-width: 200px;
10347 }
10348 .admin-entries-appeal {
10349 font-size: 0.9rem;
10350 max-width: 300px;
10351 }
10352
10353 /* Decide form textarea + stacked action buttons. */
10354 .admin-entries-decide-textarea {
10355 width: 200px;
10356 }
10357 .admin-entries-decide-actions {
10358 display: flex;
10359 flex-direction: column;
10360 gap: var(--space-1);
10361 }
10362
10363 /* Pagination row at the bottom of admin entry tables. */
10364 .admin-entries-pagination {
10365 display: flex;
10366 justify-content: center;
10367 align-items: center;
10368 gap: var(--space-4);
10369 padding: var(--space-4) 0;
10370 }
10371
10372 /* ===========================================
10373 ITEM TABS (item_settings, item_sales, item_overview partials)
10374 =========================================== */
10375
10376 /* Schedule form is hidden until "Schedule" button is clicked. JS toggles
10377 the `.hidden` utility class. */
10378 .item-settings-schedule-form {
10379 margin-top: var(--space-4);
10380 }
10381
10382 .item-sales-tab-header {
10383 display: flex;
10384 justify-content: space-between;
10385 align-items: center;
10386 margin-bottom: var(--space-4);
10387 }
10388 .item-sales-tab-header h2 { margin: 0; }
10389 .item-overview-embed {
10390 margin-top: var(--space-5);
10391 }
10392 .item-overview-embed > summary {
10393 cursor: pointer;
10394 font-weight: bold;
10395 font-size: 1.1rem;
10396 }
10397
10398 /* ===========================================
10399 ITEM TEXT EDITOR (partials/item_text_editor.html)
10400 =========================================== */
10401
10402 .text-editor-insert-btn {
10403 margin-top: var(--space-2);
10404 font-size: 0.85rem;
10405 }
10406
10407 .text-editor-placeholder {
10408 opacity: 0.6;
10409 }
10410
10411 .text-editor-actions {
10412 margin-top: var(--space-4);
10413 }
10414
10415 /* ===========================================
10416 PROJECT ANALYTICS TAB (partials/tabs/project_analytics.html)
10417 =========================================== */
10418
10419 .tab-docs-extra {
10420 margin-left: var(--space-4);
10421 }
10422
10423 .analytics-tab-header {
10424 display: flex;
10425 justify-content: space-between;
10426 align-items: center;
10427 margin-bottom: var(--space-4);
10428 }
10429 .analytics-tab-header h2 {
10430 font-size: 1.1rem;
10431 margin: 0;
10432 }
10433
10434 .analytics-empty-block {
10435 text-align: center;
10436 padding: var(--space-6) var(--space-4);
10437 opacity: 0.6;
10438 }
10439
10440 /* ===========================================
10441 RECEIPT PAGE INLINE FRAGMENTS (pages/receipt.html)
10442 =========================================== */
10443
10444 .receipt-page .receipt-brand {
10445 opacity: 0.6;
10446 font-size: 0.9rem;
10447 }
10448 .receipt-page .receipt-meta {
10449 text-align: right;
10450 }
10451 .receipt-page .receipt-meta-line {
10452 font-family: var(--font-mono);
10453 font-size: 0.85rem;
10454 opacity: 0.6;
10455 }
10456 .receipt-page .receipt-meta-sub {
10457 font-family: var(--font-mono);
10458 font-size: 0.75rem;
10459 opacity: 0.4;
10460 margin-top: 0.25rem;
10461 }
10462 .receipt-page .print-btn {
10463 margin-top: var(--space-4);
10464 font-size: 0.85rem;
10465 }
10466
10467 /* ===========================================
10468 IMPORT PAGE INLINE FRAGMENTS (dashboards/dashboard-import.html)
10469 =========================================== */
10470
10471 .import-page .import-preview-label,
10472 .import-page .import-mapping-label,
10473 .import-page .import-progress-label {
10474 font-family: var(--font-mono);
10475 font-size: 0.85rem;
10476 margin-bottom: var(--space-2);
10477 }
10478 .import-page .import-mapping-label {
10479 margin-bottom: 0.75rem;
10480 }
10481 .import-page .import-progress-label {
10482 font-size: 0.9rem;
10483 }
10484 .import-page .import-start-btn {
10485 margin-top: var(--space-4);
10486 }
10487 .import-page .import-history-heading {
10488 font-size: 1.3rem;
10489 margin-bottom: var(--space-4);
10490 }
10491
10492 /* ===========================================
10493 SLUG STATUS PARTIAL (partials/slug_status.html)
10494 =========================================== */
10495
10496 .slug-status {
10497 font-size: 0.85rem;
10498 }
10499 .slug-status.available { color: var(--success); }
10500 .slug-status.taken { color: var(--error); }
10501
10502 .slug-suggestions {
10503 font-size: 0.85rem;
10504 display: block;
10505 margin-top: 0.25rem;
10506 }
10507 .slug-suggestion-link {
10508 margin-right: var(--space-2);
10509 }
10510
10511 /* ===========================================
10512 STRIPE DISCLAIMER PAGE (pages/stripe_disclaimer.html)
10513 =========================================== */
10514
10515 .stripe-disclaimer-page .container {
10516 max-width: 700px;
10517 margin: var(--space-5) auto;
10518 padding: 0 var(--space-6);
10519 }
10520 .stripe-disclaimer-page .stripe-disclaimer-title {
10521 text-align: center;
10522 }
10523 .stripe-disclaimer-page .tagline {
10524 font-size: 0.85rem;
10525 opacity: 0.7;
10526 margin-bottom: var(--space-6);
10527 text-align: center;
10528 }
10529 .stripe-disclaimer-page h2 {
10530 font-size: 1.5rem;
10531 margin-bottom: var(--space-5);
10532 }
10533 .stripe-disclaimer-page .stripe-disclaimer-lead {
10534 margin-bottom: var(--space-5);
10535 opacity: 0.8;
10536 }
10537 .stripe-disclaimer-page .section { margin-bottom: var(--space-6); }
10538 .stripe-disclaimer-page .section h3 {
10539 font-size: 1.1rem;
10540 margin-bottom: 0.75rem;
10541 font-family: var(--font-mono);
10542 }
10543 .stripe-disclaimer-page .section ul {
10544 margin: 0;
10545 padding-left: 1.25rem;
10546 }
10547 .stripe-disclaimer-page .section li {
10548 margin-bottom: var(--space-2);
10549 line-height: 1.5;
10550 }
10551 .stripe-disclaimer-page .stripe-disclaimer-fee-lead {
10552 margin-bottom: 0.75rem;
10553 }
10554 .stripe-disclaimer-page .fee-example {
10555 background: var(--background);
10556 padding: var(--space-4) 1.25rem;
10557 margin: var(--space-4) 0;
10558 font-family: var(--font-mono);
10559 font-size: 0.9rem;
10560 }
10561 .stripe-disclaimer-page .fee-row {
10562 display: flex;
10563 justify-content: space-between;
10564 padding: 0.25rem 0;
10565 }
10566 .stripe-disclaimer-page .fee-row.highlight {
10567 font-weight: bold;
10568 border-top: 1px solid var(--border);
10569 margin-top: var(--space-2);
10570 padding-top: var(--space-2);
10571 }
10572 .stripe-disclaimer-page .fee-row .zero { color: var(--detail); }
10573 .stripe-disclaimer-page .stripe-disclaimer-note {
10574 font-size: 0.9rem;
10575 opacity: 0.8;
10576 }
10577 .stripe-disclaimer-page .acceptance {
10578 background: var(--background);
10579 padding: 1.25rem;
10580 margin: var(--space-5) 0;
10581 }
10582 .stripe-disclaimer-page .checkbox-group {
10583 display: flex;
10584 align-items: flex-start;
10585 gap: 0.75rem;
10586 }
10587 .stripe-disclaimer-page .checkbox-group input[type="checkbox"] {
10588 margin-top: 0.25rem;
10589 flex-shrink: 0;
10590 }
10591 .stripe-disclaimer-page .checkbox-group label {
10592 line-height: 1.5;
10593 cursor: pointer;
10594 }
10595 .stripe-disclaimer-page .button-row {
10596 display: flex;
10597 gap: var(--space-4);
10598 margin-top: var(--space-5);
10599 }
10600 .stripe-disclaimer-page .button-row button { flex: 1; }
10601 .stripe-disclaimer-page button:disabled {
10602 opacity: 0.5;
10603 cursor: not-allowed;
10604 }
10605 .stripe-disclaimer-page .note {
10606 font-size: 0.85rem;
10607 opacity: 0.6;
10608 margin-top: var(--space-4);
10609 text-align: center;
10610 }
10611
10612 /* ===========================================
10613 LONG-TAIL CLEANUP — shared utilities promoted from the final inline-style sweep.
10614 Each rule replaces ≥2 inline-style instances across templates.
10615 =========================================== */
10616
10617 /* Tab-spinner loading indicator (used by 3+ dashboards). */
10618 .tab-spinner-indicator { margin-left: var(--space-4); }
10619
10620 /* Inline-block secondary action link styled as a button. */
10621 .btn-link {
10622 display: inline-block;
10623 padding: var(--space-2) var(--space-4);
10624 text-decoration: none;
10625 }
10626 .btn-link--sm { padding: var(--space-2) var(--space-4); }
10627
10628 /* Username-availability spinner (wizards + standalone account form). */
10629 .username-spinner { font-size: 0.85rem; }
10630
10631 /* Centered foot-link beneath wizard cards. */
10632 .foot-link--centered { margin-top: var(--space-4); text-align: center; }
10633
10634 /* Health-page status dots. */
10635 .health-indicator-dot { width: 8px; height: 8px; margin-right: 0.4rem; }
10636 .health-error-text { color: var(--health-error); }
10637
10638 /* Inline error fragments (login_error, error_fragment) toggle this on. */
10639 .error-message.is-active { display: block; }
10640
10641 /* Cart count badge in nav. */
10642 .cart-badge-count { font-size: 0.8em; }
10643
10644 /* Empty-row inside a data table. */
10645 .table-empty-row { text-align: center; opacity: 0.6; }
10646
10647 /* Discover grid: card wrapper + body anchor. */
10648 .discover-grid-card { position: relative; }
10649 .discover-card-link {
10650 text-decoration: none;
10651 color: inherit;
10652 display: flex;
10653 flex-direction: column;
10654 flex: 1;
10655 }
10656 .discover-filter-checkbox {
10657 display: flex;
10658 align-items: center;
10659 gap: var(--space-2);
10660 cursor: pointer;
10661 font-size: 0.9rem;
10662 }
10663
10664 /* Tag suggestion list. */
10665 .tag-suggest-label {
10666 font-size: 0.8rem;
10667 opacity: 0.7;
10668 margin-bottom: var(--space-2);
10669 }
10670 .tag-suggest-pill {
10671 background: var(--surface-muted);
10672 border: 1px solid var(--border);
10673 padding: 0.15rem 0.4rem;
10674 font-size: 0.8rem;
10675 cursor: pointer;
10676 margin: 0.1rem;
10677 }
10678
10679 /* Dashboard-export header layout + Export-all CTA. */
10680 .dashboard-export-header {
10681 display: flex;
10682 justify-content: space-between;
10683 align-items: flex-start;
10684 }
10685 .export-all-btn {
10686 white-space: nowrap;
10687 margin-top: var(--space-2);
10688 }
10689
10690 /* Tiny inline action button (admin-metrics, dashboard-item share). */
10691 .dashboard-item-share-btn {
10692 font-size: 0.8rem;
10693 padding: 0.15rem 0.5rem;
10694 opacity: 0.6;
10695 }
10696
10697 /* Monospaced page sub-headers. */
10698 .section-mono-meta {
10699 font-family: var(--font-mono);
10700 font-size: 0.85rem;
10701 opacity: 0.6;
10702 margin-bottom: var(--space-5);
10703 }
10704 .section-mono-hint {
10705 font-family: var(--font-mono);
10706 font-size: 0.9rem;
10707 margin-top: var(--space-2);
10708 }
10709
10710 /* Email-result single-card page. */
10711 .email-result-wrap {
10712 max-width: 600px;
10713 margin: 50px auto;
10714 padding: 20px;
10715 }
10716
10717 /* Admin lottery form (admin-waitlist). */
10718 .lottery-form {
10719 display: flex;
10720 gap: var(--space-4);
10721 align-items: flex-end;
10722 }
10723
10724 /* Login screen: "or" divider + passkey button + error slot. */
10725 .login-divider {
10726 text-align: center;
10727 margin: var(--space-5) 0 var(--space-4);
10728 opacity: 0.5;
10729 font-size: 0.85rem;
10730 }
10731 .login-passkey-btn { width: 100%; }
10732 .login-passkey-error { margin-top: var(--space-2); }
10733
10734 /* Upload-progress sibling text (item_audio_upload). */
10735 .upload-speed-text {
10736 font-size: 0.8rem;
10737 opacity: 0.6;
10738 margin-top: 0.25rem;
10739 }
10740
10741 /* Faded "Following" follow-button state. */
10742 .follow-btn.is-selected { opacity: 0.7; }
10743
10744 /* Project blog footer. */
10745 .project-blog-footer {
10746 margin-top: 4rem;
10747 padding-top: 2rem;
10748 border-top: 1px solid var(--border);
10749 opacity: 0.6;
10750 }
10751 .project-blog-footer a { color: var(--detail); }
10752
10753 /* Compact alert / paragraph margin variants used 2+ times. */
10754 .alert.mb-4 { margin-bottom: var(--space-4); }
10755
10756 /* Paywall trust line. */
10757 .paywall-trust {
10758 font-size: 0.85rem;
10759 opacity: 0.7;
10760 margin-top: var(--space-4);
10761 line-height: 1.4;
10762 }
10763
10764 /* Confirm-delete: button background already covered by .danger class —
10765 wizard step uses `.primary` and inlines the danger background; we just
10766 change the class instead. No CSS rule needed here. */
10767
10768 /* Paywall-style centered narrow form-group used inside project_paywall. */
10769 .form-group--centered-narrow {
10770 max-width: 240px;
10771 margin: var(--space-4) auto;
10772 }
10773
10774 /* Inline-form margin-left for adjacent pills (collection.html private badge). */
10775 .badge--inline-l { margin-left: var(--space-2); }
10776
10777 /* ===== Team page ===== */
10778
10779 .team-page { max-width: 56rem; margin: 0 auto; }
10780 .team-intro {
10781 font-size: 1.05rem;
10782 line-height: 1.55;
10783 margin: 0 0 var(--space-6);
10784 opacity: 0.85;
10785 }
10786 .team-section { margin-top: var(--space-8); }
10787 .team-section + .team-section { margin-top: var(--space-7); }
10788 .team-empty {
10789 font-size: 0.95rem;
10790 opacity: 0.65;
10791 font-style: italic;
10792 }
10793 .team-card-experience {
10794 margin: var(--space-3) 0 var(--space-2);
10795 line-height: 1.5;
10796 }
10797 .team-card-links {
10798 margin: var(--space-2) 0;
10799 font-size: 0.95rem;
10800 }
10801 .team-card-link { font-weight: 500; }
10802 .team-card-bio {
10803 margin-top: var(--space-3);
10804 border-top: 1px solid var(--color-border);
10805 padding-top: var(--space-3);
10806 }
10807 .team-card-bio > summary {
10808 cursor: pointer;
10809 font-weight: 500;
10810 font-size: 0.95rem;
10811 list-style: none;
10812 }
10813 .team-card-bio > summary::-webkit-details-marker { display: none; }
10814 .team-card-bio > summary::before {
10815 content: "+ ";
10816 display: inline-block;
10817 width: 1.2em;
10818 opacity: 0.6;
10819 }
10820 .team-card-bio[open] > summary::before { content: ""; }
10821 .team-card-bio > p {
10822 margin-top: var(--space-3);
10823 line-height: 1.6;
10824 }
10825
10826 /* ── SyncKit billing panel ──
10827 Per-app accordion shown inside the SyncKit dashboard tab (both user and
10828 project levels). The .synckit-billing root carries pricing constants as
10829 data-attrs that static/synckit-billing.js reads to mirror monthly_price_cents.
10830 */
10831 .synckit-billing {
10832 background: var(--surface-raised);
10833 border: 1px solid var(--border);
10834 border-radius: 3px;
10835 padding: var(--space-2) var(--space-3);
10836 min-width: 220px;
10837 }
10838 .synckit-billing-summary {
10839 cursor: pointer;
10840 display: flex;
10841 align-items: center;
10842 gap: var(--space-3);
10843 font-size: 0.875rem;
10844 }
10845 .synckit-billing-toggle { margin-left: auto; color: var(--text-muted, #777); }
10846 .synckit-billing-status {
10847 display: inline-block;
10848 padding: 2px var(--space-2);
10849 border-radius: 2px;
10850 font-size: 0.75rem;
10851 font-weight: 600;
10852 }
10853 .synckit-billing-status--draft { background: var(--surface-muted); }
10854 .synckit-billing-status--active { background: var(--success-bg); color: var(--success); }
10855 .synckit-billing-status--suspended_unpaid { background: var(--warning-bg); color: var(--warning); }
10856 .synckit-billing-status--canceled { background: var(--danger-bg); color: var(--danger); }
10857 .synckit-billing-price { font-weight: 600; }
10858 .synckit-billing-body {
10859 padding-top: var(--space-3);
10860 display: flex;
10861 flex-direction: column;
10862 gap: var(--space-4);
10863 }
10864 .synckit-billing-section { display: flex; flex-direction: column; gap: var(--space-2); }
10865 .synckit-billing-subheading { font-size: 0.875rem; margin: 0; font-weight: 600; }
10866 .synckit-knob-row {
10867 display: flex;
10868 align-items: center;
10869 gap: var(--space-2);
10870 flex-wrap: wrap;
10871 }
10872 .synckit-knob-row label { min-width: 110px; }
10873 .synckit-knob-row input[type="range"] { flex: 1 1 160px; min-width: 120px; }
10874 .synckit-radio { display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; }
10875 .synckit-billing-summary-line {
10876 display: flex;
10877 align-items: baseline;
10878 gap: var(--space-2);
10879 padding-top: var(--space-2);
10880 border-top: 1px solid var(--border);
10881 }
10882 .synckit-price-preview { font-size: 1.125rem; font-weight: 600; }
10883 .synckit-billing-actions { display: flex; gap: var(--space-2); }
10884 .synckit-billing-manage { flex-direction: row; gap: var(--space-2); }
10885 .synckit-billing-status-msg { font-size: 0.875rem; min-height: 1.25em; }
10886 .synckit-billing-status-msg--info { color: var(--text-muted, #777); }
10887 .synckit-billing-status-msg--error { color: var(--danger); }
10888 .synckit-billing-period { margin: 0; }
10889 .synckit-gauge { display: flex; flex-direction: column; gap: 2px; }
10890 .synckit-gauge-label {
10891 display: flex;
10892 justify-content: space-between;
10893 font-size: 0.8125rem;
10894 }
10895 .synckit-gauge-value { color: var(--text-muted, #777); }
10896 .synckit-gauge-fill--warn { background: var(--warning); }
10897 .synckit-gauge-fill--danger { background: var(--danger); }
10898
10899 /* Cost-allocation widget on /pricing — "Where your tier fee goes". */
10900 .cost-allocation { margin-top: 0.5rem; }
10901 .cost-allocation-intro {
10902 font-size: 0.95rem;
10903 opacity: 0.85;
10904 margin-bottom: 1.5rem;
10905 max-width: 60ch;
10906 }
10907 .cost-row {
10908 display: grid;
10909 grid-template-columns: 12rem 1fr;
10910 gap: 1rem;
10911 align-items: center;
10912 margin-bottom: 1rem;
10913 }
10914 .cost-row-label {
10915 font-family: var(--font-mono);
10916 font-size: 0.9rem;
10917 }
10918 .cost-row-label strong { font-family: var(--font-heading); font-size: 1.05rem; display: block; }
10919 .cost-bar {
10920 display: flex;
10921 height: 2.25rem;
10922 border-radius: 4px;
10923 overflow: hidden;
10924 border: 1px solid var(--border, rgba(0,0,0,0.12));
10925 }
10926 .cost-bar-seg {
10927 display: flex;
10928 align-items: center;
10929 justify-content: center;
10930 font-family: var(--font-mono);
10931 font-size: 0.75rem;
10932 color: #fff;
10933 cursor: help;
10934 padding: 0 0.25rem;
10935 overflow: hidden;
10936 white-space: nowrap;
10937 }
10938 .cost-bar-seg-stripe { background: #5b6f8a; }
10939 .cost-bar-seg-storage { background: #7d8c5e; }
10940 .cost-bar-seg-support { background: #8b6b4a; }
10941 .cost-bar-seg-engineering { background: #6b4a8b; }
10942 .cost-bar-seg-reserves { background: #4a6b8b; }
10943 .cost-bar-seg-earnback { background: #8b8b4a; }
10944 .cost-legend {
10945 display: flex;
10946 flex-wrap: wrap;
10947 gap: 0.5rem 1.25rem;
10948 margin-top: 1.5rem;
10949 font-size: 0.85rem;
10950 }
10951 .cost-legend-item { display: flex; align-items: center; gap: 0.4rem; }
10952 .cost-legend-swatch {
10953 display: inline-block;
10954 width: 0.85rem;
10955 height: 0.85rem;
10956 border-radius: 2px;
10957 }
10958 @media (max-width: 640px) {
10959 .cost-row { grid-template-columns: 1fr; gap: 0.4rem; }
10960 .cost-bar-seg { font-size: 0; }
10961 }
10962