Skip to main content

max / makenotwork

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