max / makenotwork
2 files changed,
+437 insertions,
-26 deletions
| @@ -92,6 +92,31 @@ | |||
| 92 | 92 | /* Aliases used by git browser */ | |
| 93 | 93 | --secondary-bg: #f4f0eb; | |
| 94 | 94 | --text: #3d3530; | |
| 95 | + | ||
| 96 | + | /* Legacy aliases — defined to end silent var() fallback failures | |
| 97 | + | in inline-styled templates. Consolidate during phase 2.12. */ | |
| 98 | + | --accent: var(--highlight); | |
| 99 | + | --accent-color: var(--highlight); | |
| 100 | + | --border-color: var(--border); | |
| 101 | + | --background-color: var(--background); | |
| 102 | + | ||
| 103 | + | /* Spacing scale (charter: docs/design-system.md) */ | |
| 104 | + | --space-1: 0.25rem; | |
| 105 | + | --space-2: 0.5rem; | |
| 106 | + | --space-3: 0.75rem; | |
| 107 | + | --space-4: 1rem; | |
| 108 | + | --space-5: 1.5rem; | |
| 109 | + | --space-6: 2rem; | |
| 110 | + | ||
| 111 | + | /* Radius scale */ | |
| 112 | + | --radius-sm: 2px; | |
| 113 | + | --radius-md: 4px; | |
| 114 | + | --radius-round: 50%; | |
| 115 | + | ||
| 116 | + | /* Shadow scale */ | |
| 117 | + | --shadow-1: 0 1px 3px rgba(0, 0, 0, 0.06); | |
| 118 | + | --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.10); | |
| 119 | + | --shadow-3: 0 4px 12px rgba(0, 0, 0, 0.15); | |
| 95 | 120 | } | |
| 96 | 121 | ||
| 97 | 122 | /* Reset */ | |
| @@ -129,6 +154,11 @@ | |||
| 129 | 154 | font-size: 4.5rem; | |
| 130 | 155 | } | |
| 131 | 156 | ||
| 157 | + | .message-container { | |
| 158 | + | max-width: 500px; | |
| 159 | + | text-align: center; | |
| 160 | + | } | |
| 161 | + | ||
| 132 | 162 | .centered-wrapper { | |
| 133 | 163 | justify-content: center; | |
| 134 | 164 | text-align: center; | |
| @@ -244,6 +274,65 @@ | |||
| 244 | 274 | opacity: 0.8; | |
| 245 | 275 | } | |
| 246 | 276 | ||
| 277 | + | /* Disabled state for all button variants (charter rule). | |
| 278 | + | Applies whether disabled via attribute or aria-disabled. */ | |
| 279 | + | button:disabled, | |
| 280 | + | button[aria-disabled="true"], | |
| 281 | + | .btn-primary:disabled, | |
| 282 | + | .btn-secondary:disabled, | |
| 283 | + | .btn-danger:disabled { | |
| 284 | + | opacity: 0.5; | |
| 285 | + | cursor: not-allowed; | |
| 286 | + | } | |
| 287 | + | ||
| 288 | + | /* Button size + style modifiers (charter: docs/design-system.md). | |
| 289 | + | Use these on top of .btn-primary / -secondary / -danger. | |
| 290 | + | ||
| 291 | + | .btn--large — large CTA padding bump. | |
| 292 | + | .btn--icon — square icon-only / micro button (small padding, | |
| 293 | + | tight line-height). | |
| 294 | + | .btn--link — visually a link, semantically a button (no bg/ | |
| 295 | + | border, opacity-fade hover, mono). | |
| 296 | + | ||
| 297 | + | Some surfaces have tuned button variants that are NOT compositions | |
| 298 | + | of these modifiers and keep their own classes: | |
| 299 | + | .big-button — Young Serif 200×60 anchor on splash pages. | |
| 300 | + | .paywall-btn — wider primary CTA (anchor) on paywalls. | |
| 301 | + | .notify-btn — small inverted notify pill in dashboards. | |
| 302 | + | .order-btn — list reorder up/down (with active flash). | |
| 303 | + | .play-button — circular media-player play control. | |
| 304 | + | .speed-button — segment in media-player speed group. | |
| 305 | + | .shortcuts-help-btn — 1.5rem square help glyph in toolbars. | |
| 306 | + | .toast-retry-btn — inline bordered button inside a toast, | |
| 307 | + | uses currentColor to inherit toast tone. | |
| 308 | + | These are documented variants, not deprecation targets. */ | |
| 309 | + | .btn--large { | |
| 310 | + | padding: 1rem 2.25rem; | |
| 311 | + | font-size: 1.125rem; | |
| 312 | + | } | |
| 313 | + | ||
| 314 | + | .btn--icon { | |
| 315 | + | padding: var(--space-1) var(--space-2); | |
| 316 | + | font-size: 0.85rem; | |
| 317 | + | line-height: 1; | |
| 318 | + | min-width: 1.75rem; | |
| 319 | + | } | |
| 320 | + | ||
| 321 | + | .btn--link { | |
| 322 | + | background: none; | |
| 323 | + | color: var(--detail); | |
| 324 | + | border: none; | |
| 325 | + | padding: 0; | |
| 326 | + | font-family: var(--font-mono); | |
| 327 | + | font-size: 1rem; | |
| 328 | + | cursor: pointer; | |
| 329 | + | transition: opacity 0.2s ease; | |
| 330 | + | } | |
| 331 | + | ||
| 332 | + | .btn--link:hover { | |
| 333 | + | opacity: 0.6; | |
| 334 | + | } | |
| 335 | + | ||
| 247 | 336 | /* =========================================== | |
| 248 | 337 | FORMS | |
| 249 | 338 | =========================================== */ | |
| @@ -351,6 +440,51 @@ | |||
| 351 | 440 | margin-top: 0.5rem; | |
| 352 | 441 | } | |
| 353 | 442 | ||
| 443 | + | /* Field-level validation error, paired with .form-group--error. | |
| 444 | + | Canonical: `partials/_ui.html` ui::form_field macro. */ | |
| 445 | + | .form-group--error label { | |
| 446 | + | color: var(--error); | |
| 447 | + | } | |
| 448 | + | ||
| 449 | + | .form-group--error input, | |
| 450 | + | .form-group--error textarea, | |
| 451 | + | .form-group--error select { | |
| 452 | + | border-color: var(--error); | |
| 453 | + | } | |
| 454 | + | ||
| 455 | + | .field-error { | |
| 456 | + | font-size: 0.85rem; | |
| 457 | + | color: var(--error); | |
| 458 | + | margin-top: var(--space-2); | |
| 459 | + | } | |
| 460 | + | ||
| 461 | + | /* Loading skeleton placeholder. | |
| 462 | + | Canonical: `partials/_ui.html` ui::loading_skeleton macro. */ | |
| 463 | + | .loading-skeleton { | |
| 464 | + | background: var(--surface-muted); | |
| 465 | + | border-radius: var(--radius-md); | |
| 466 | + | animation: skeleton-pulse 1.2s ease-in-out infinite; | |
| 467 | + | } | |
| 468 | + | ||
| 469 | + | .loading-skeleton--row { | |
| 470 | + | height: 1.25rem; | |
| 471 | + | margin: var(--space-2) 0; | |
| 472 | + | } | |
| 473 | + | ||
| 474 | + | .loading-skeleton--card { | |
| 475 | + | height: 8rem; | |
| 476 | + | margin: var(--space-3) 0; | |
| 477 | + | } | |
| 478 | + | ||
| 479 | + | .loading-skeleton--list .loading-skeleton--row + .loading-skeleton--row { | |
| 480 | + | margin-top: var(--space-2); | |
| 481 | + | } | |
| 482 | + | ||
| 483 | + | @keyframes skeleton-pulse { | |
| 484 | + | 0%, 100% { opacity: 0.5; } | |
| 485 | + | 50% { opacity: 0.9; } | |
| 486 | + | } | |
| 487 | + | ||
| 354 | 488 | /* Checkbox group */ | |
| 355 | 489 | .checkbox-group { | |
| 356 | 490 | display: flex; | |
| @@ -450,7 +584,7 @@ | |||
| 450 | 584 | flex-shrink: 0; | |
| 451 | 585 | } | |
| 452 | 586 | ||
| 453 | - | .tab.active { | |
| 587 | + | .tab.is-selected { | |
| 454 | 588 | background: var(--light-background); | |
| 455 | 589 | opacity: 1; | |
| 456 | 590 | } | |
| @@ -487,7 +621,7 @@ | |||
| 487 | 621 | opacity: 1; | |
| 488 | 622 | } | |
| 489 | 623 | ||
| 490 | - | .tab-overflow-menu .tab.active { | |
| 624 | + | .tab-overflow-menu .tab.is-selected { | |
| 491 | 625 | opacity: 1; | |
| 492 | 626 | } | |
| 493 | 627 | ||
| @@ -595,14 +729,42 @@ | |||
| 595 | 729 | .text-xs { font-size: 0.8rem; } | |
| 596 | 730 | .muted { opacity: 0.7; } | |
| 597 | 731 | .dimmed { opacity: 0.6; } | |
| 732 | + | .dimmer { opacity: 0.5; } | |
| 598 | 733 | .meta { font-size: 0.85rem; opacity: 0.7; } | |
| 599 | 734 | .nowrap { white-space: nowrap; } | |
| 600 | 735 | .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; } | |
| 601 | 736 | .text-center { text-align: center; } | |
| 737 | + | .text-right { text-align: right; } | |
| 738 | + | .fw-bold { font-weight: bold; } | |
| 739 | + | .unstyled-link { text-decoration: none; color: inherit; } | |
| 740 | + | .square-cover { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; } | |
| 741 | + | ||
| 742 | + | /* Spacing utilities (mapped to --space-* scale). | |
| 743 | + | mt = margin-top, mb = margin-bottom, my = vertical, mx = horizontal, | |
| 744 | + | m0 = margin reset. Use sparingly; prefer parent layout primitives. */ | |
| 745 | + | .m-0 { margin: 0; } | |
| 746 | + | .mt-0 { margin-top: 0; } | |
| 747 | + | .mt-2 { margin-top: var(--space-2); } | |
| 748 | + | .mt-3 { margin-top: var(--space-3); } | |
| 749 | + | .mt-4 { margin-top: var(--space-4); } | |
| 750 | + | .mt-5 { margin-top: var(--space-5); } | |
| 751 | + | .mt-6 { margin-top: var(--space-6); } | |
| 752 | + | .mb-0 { margin-bottom: 0; } | |
| 753 | + | .mb-2 { margin-bottom: var(--space-2); } | |
| 754 | + | .mb-3 { margin-bottom: var(--space-3); } | |
| 755 | + | .mb-4 { margin-bottom: var(--space-4); } | |
| 756 | + | .mb-5 { margin-bottom: var(--space-5); } | |
| 757 | + | .mb-6 { margin-bottom: var(--space-6); } | |
| 602 | 758 | ||
| 603 | 759 | .small { padding: 0.25rem 0.6rem; font-size: 0.8rem; } | |
| 604 | 760 | ||
| 761 | + | /* Canonical empty-state primitive. Use modifiers for tight/sized contexts. | |
| 762 | + | Markup: <div class="empty-state">…</div> (optionally with .empty-state--compact | |
| 763 | + | inside dropdowns or .empty-state--chart inside a fixed-height chart slot). */ | |
| 605 | 764 | .empty-state { text-align: center; padding: 2rem; opacity: 0.6; } | |
| 765 | + | .empty-state--compact { padding: 0.75rem; font-size: 0.9rem; } | |
| 766 | + | .empty-state--chart { height: 200px; padding: 0; display: flex; align-items: center; justify-content: center; opacity: 0.5; } | |
| 767 | + | .empty-state-hint { font-family: var(--font-mono); font-size: 0.8rem; margin-top: 0.5rem; opacity: 0.6; } | |
| 606 | 768 | ||
| 607 | 769 | .tab-docs { | |
| 608 | 770 | display: flex; | |
| @@ -713,6 +875,16 @@ | |||
| 713 | 875 | CARDS | |
| 714 | 876 | =========================================== */ | |
| 715 | 877 | ||
| 878 | + | /* Canonical card primitive (charter: docs/design-system.md). | |
| 879 | + | Variants: | |
| 880 | + | .card — filled, hover-step (default content card). | |
| 881 | + | .card.card-muted — surface-muted fill, no hover (dashboard stat / analytics blocks). | |
| 882 | + | .card.card--bordered — bordered, padded, no fill (marketing cards: feature/tier/use-case). | |
| 883 | + | .card.card--selectable — radio-card pattern; pair with .is-selected. | |
| 884 | + | .card.card--grid — grid-cell card (discover grid). | |
| 885 | + | Legacy class names (.stat-card, .analytics-card, .feature-card, .tier-card, | |
| 886 | + | .use-case-card) are aliased to these recipes below — templates migrate at | |
| 887 | + | their own pace. */ | |
| 716 | 888 | .card { | |
| 717 | 889 | background: var(--light-background); | |
| 718 | 890 | padding: 1.5rem; | |
| @@ -727,11 +899,20 @@ | |||
| 727 | 899 | background: var(--surface-muted); | |
| 728 | 900 | } | |
| 729 | 901 | ||
| 730 | - | .card-muted { | |
| 902 | + | .card-muted, | |
| 903 | + | .stat-card, | |
| 904 | + | .analytics-card { | |
| 731 | 905 | background: var(--surface-muted); | |
| 732 | 906 | padding: 1.5rem; | |
| 733 | 907 | } | |
| 734 | 908 | ||
| 909 | + | .card--bordered { | |
| 910 | + | background: transparent; | |
| 911 | + | padding: 1rem; | |
| 912 | + | border: 1px solid var(--border); | |
| 913 | + | margin-bottom: 0; | |
| 914 | + | } | |
| 915 | + | ||
| 735 | 916 | .card-title { | |
| 736 | 917 | font-size: 1.2rem; | |
| 737 | 918 | margin-bottom: 0.5rem; | |
| @@ -786,10 +967,7 @@ | |||
| 786 | 967 | opacity: 0.7; | |
| 787 | 968 | } | |
| 788 | 969 | ||
| 789 | - | .stat-card { | |
| 790 | - | background: var(--surface-muted); | |
| 791 | - | padding: 1.5rem; | |
| 792 | - | } | |
| 970 | + | /* .stat-card base recipe defined above with .card-muted */ | |
| 793 | 971 | ||
| 794 | 972 | .stat-label { | |
| 795 | 973 | font-size: 0.85rem; | |
| @@ -920,6 +1098,3130 @@ | |||
| 920 | 1098 | display: none; | |
| 921 | 1099 | } | |
| 922 | 1100 | ||
| 1101 | + | /* Full-page error layout (templates/pages/error.html). Distinct from | |
| 1102 | + | the inline `.error-message` form-error class above; named to avoid | |
| 1103 | + | collision. */ | |
| 1104 | + | .error-page { | |
| 1105 | + | min-height: 100vh; | |
| 1106 | + | display: flex; | |
| 1107 | + | align-items: center; | |
| 1108 | + | justify-content: center; | |
| 1109 | + | padding: var(--space-6); | |
| 1110 | + | background: var(--background); | |
| 1111 | + | } | |
| 1112 | + | ||
| 1113 | + | .error-container { | |
| 1114 | + | text-align: center; | |
| 1115 | + | max-width: 560px; | |
| 1116 | + | } | |
| 1117 | + | ||
| 1118 | + | .error-status { | |
| 1119 | + | font-size: 0.85rem; | |
| 1120 | + | font-weight: 600; | |
| 1121 | + | letter-spacing: 0.08em; | |
| 1122 | + | text-transform: uppercase; | |
| 1123 | + | color: var(--text-muted); | |
| 1124 | + | margin-bottom: var(--space-4); | |
| 1125 | + | } | |
| 1126 | + | ||
| 1127 | + | .error-page-message { | |
| 1128 | + | font-size: 1.5rem; | |
| 1129 | + | line-height: 1.4; | |
| 1130 | + | color: var(--detail); | |
| 1131 | + | margin-bottom: var(--space-6); | |
| 1132 | + | } | |
| 1133 | + | ||
| 1134 | + | .error-actions { | |
| 1135 | + | display: flex; | |
| 1136 | + | gap: var(--space-4); | |
| 1137 | + | justify-content: center; | |
| 1138 | + | } | |
| 1139 | + | ||
| 1140 | + | .error-actions a.primary, | |
| 1141 | + | .error-actions a.secondary { | |
| 1142 | + | text-decoration: none; | |
| 1143 | + | } | |
| 1144 | + | ||
| 1145 | + | /* Minimal direct-purchase page (templates/pages/buy.html). Standalone | |
| 1146 | + | page used for link-in-bio sharing — no site chrome, just a card. | |
| 1147 | + | Scoped under .buy-page so the rules don't bleed into the rest of | |
| 1148 | + | the app. Tokenized; previously lived as a page-isolated <style>. */ | |
| 1149 | + | .buy-page { | |
| 1150 | + | min-height: 100vh; | |
| 1151 | + | display: flex; | |
| 1152 | + | align-items: center; | |
| 1153 | + | justify-content: center; | |
| 1154 | + | padding: var(--space-6); | |
| 1155 | + | } | |
| 1156 | + | ||
| 1157 | + | .buy-page .buy-card { | |
| 1158 | + | background: var(--light-background); | |
| 1159 | + | border-radius: 12px; | |
| 1160 | + | padding: var(--space-6); | |
| 1161 | + | max-width: 420px; | |
| 1162 | + | width: 100%; | |
| 1163 | + | box-shadow: var(--shadow-3); | |
| 1164 | + | } | |
| 1165 | + | ||
| 1166 | + | .buy-page .cover, | |
| 1167 | + | .buy-page .no-cover { | |
| 1168 | + | width: 100%; | |
| 1169 | + | aspect-ratio: 1; | |
| 1170 | + | max-height: 280px; | |
| 1171 | + | border-radius: 8px; | |
| 1172 | + | margin-bottom: var(--space-5); | |
| 1173 | + | background: var(--surface-raised); | |
| 1174 | + | } | |
| 1175 | + | ||
| 1176 | + | .buy-page .cover { | |
| 1177 | + | object-fit: cover; | |
| 1178 | + | } | |
| 1179 | + | ||
| 1180 | + | .buy-page .no-cover { | |
| 1181 | + | display: flex; | |
| 1182 | + | align-items: center; | |
| 1183 | + | justify-content: center; | |
| 1184 | + | font-size: 3rem; | |
| 1185 | + | opacity: 0.2; | |
| 1186 | + | } | |
| 1187 | + | ||
| 1188 | + | .buy-page h1 { | |
| 1189 | + | text-align: left; | |
| 1190 | + | font-size: 1.4rem; | |
| 1191 | + | margin-bottom: var(--space-1); | |
| 1192 | + | } | |
| 1193 | + | ||
| 1194 | + | .buy-page .creator { | |
| 1195 | + | font-family: var(--font-mono); | |
| 1196 | + | font-size: 0.85rem; | |
| 1197 | + | opacity: 0.6; | |
| 1198 | + | margin-bottom: var(--space-5); | |
| 1199 | + | } | |
| 1200 | + | ||
| 1201 | + | .buy-page .creator a { | |
| 1202 | + | color: inherit; | |
| 1203 | + | } | |
| 1204 | + | ||
| 1205 | + | .buy-page .price { | |
| 1206 | + | font-family: var(--font-mono); | |
| 1207 | + | font-size: 1.3rem; | |
| 1208 | + | margin-bottom: var(--space-5); | |
| 1209 | + | } | |
| 1210 | + | ||
| 1211 | + | .buy-page .description { | |
| 1212 | + | font-size: 0.9rem; | |
| 1213 | + | line-height: 1.5; | |
| 1214 | + | opacity: 0.8; | |
| 1215 | + | margin-bottom: var(--space-5); | |
| 1216 | + | max-height: 4.5em; | |
| 1217 | + | overflow: hidden; | |
| 1218 | + | } | |
| 1219 | + | ||
| 1220 | + | .buy-page .buy-btn { | |
| 1221 | + | display: block; | |
| 1222 | + | width: 100%; | |
| 1223 | + | padding: 14px; | |
| 1224 | + | background: var(--highlight); | |
| 1225 | + | color: var(--primary-light); | |
| 1226 | + | border: none; | |
| 1227 | + | border-radius: 6px; | |
| 1228 | + | font-size: 1rem; | |
| 1229 | + | font-weight: 600; | |
| 1230 | + | cursor: pointer; | |
| 1231 | + | text-align: center; | |
| 1232 | + | text-decoration: none; | |
| 1233 | + | transition: opacity 0.2s ease; | |
| 1234 | + | } | |
| 1235 | + | ||
| 1236 | + | .buy-page .buy-btn:hover { | |
| 1237 | + | opacity: 0.85; | |
| 1238 | + | } | |
| 1239 | + | ||
| 1240 | + | .buy-page .buy-btn:disabled { | |
| 1241 | + | opacity: 0.6; | |
| 1242 | + | cursor: wait; | |
| 1243 | + | } | |
| 1244 | + | ||
| 1245 | + | .buy-page .pwyw-input { | |
| 1246 | + | display: flex; | |
| 1247 | + | align-items: center; | |
| 1248 | + | gap: var(--space-1); | |
| 1249 | + | margin-bottom: var(--space-4); | |
| 1250 | + | } | |
| 1251 | + | ||
| 1252 | + | .buy-page .pwyw-input input { | |
| 1253 | + | width: 100px; | |
| 1254 | + | padding: 8px; | |
| 1255 | + | border: 1px solid var(--border); | |
| 1256 | + | border-radius: var(--radius-md); | |
| 1257 | + | font-size: 1rem; | |
| 1258 | + | } | |
| 1259 | + | ||
| 1260 | + | .buy-page .note { | |
| 1261 | + | font-size: 0.8rem; | |
| 1262 | + | opacity: 0.5; | |
| 1263 | + | text-align: center; | |
| 1264 | + | margin-top: var(--space-4); | |
| 1265 | + | } | |
| 1266 | + | ||
| 1267 | + | .buy-page .note a { | |
| 1268 | + | color: var(--highlight); | |
| 1269 | + | } | |
| 1270 | + | ||
| 1271 | + | .buy-page .footer { | |
| 1272 | + | text-align: center; | |
| 1273 | + | margin-top: var(--space-5); | |
| 1274 | + | padding-top: var(--space-4); | |
| 1275 | + | border-top: 1px solid var(--border); | |
| 1276 | + | font-size: 0.8rem; | |
| 1277 | + | opacity: 0.5; | |
| 1278 | + | } | |
| 1279 | + | ||
| 1280 | + | .buy-page .footer a { | |
| 1281 | + | color: inherit; | |
| 1282 | + | } | |
| 1283 | + | ||
| 1284 | + | /* Sectioned content (templates/pages/item.html, project.html, | |
| 1285 | + | library_downloads.html). Tab+panel pattern shared by all three | |
| 1286 | + | pages — kept global, NOT scoped under .item-page. */ | |
| 1287 | + | .section-tabs { | |
| 1288 | + | display: flex; | |
| 1289 | + | gap: 0; | |
| 1290 | + | border-bottom: 1px solid var(--border); | |
| 1291 | + | margin-bottom: var(--space-5); | |
| 1292 | + | } | |
| 1293 | + | ||
| 1294 | + | .section-tab { | |
| 1295 | + | background: none; | |
| 1296 | + | border: none; | |
| 1297 | + | padding: 0.6rem 1.2rem; | |
| 1298 | + | cursor: pointer; | |
| 1299 | + | font-size: 0.95rem; | |
| 1300 | + | opacity: 0.6; | |
| 1301 | + | border-bottom: 2px solid transparent; | |
| 1302 | + | font-family: var(--font-body); | |
| 1303 | + | color: var(--text); | |
| 1304 | + | } | |
| 1305 | + | ||
| 1306 | + | .section-tab.is-selected { | |
| 1307 | + | opacity: 1; | |
| 1308 | + | border-bottom-color: var(--detail); | |
| 1309 | + | } | |
| 1310 | + | ||
| 1311 | + | .section-tab:hover { opacity: 0.9; } | |
| 1312 | + | ||
| 1313 | + | /* .section-panel.active is a visibility toggle (display: none / block), | |
| 1314 | + | not a selection — kept as .active. */ | |
| 1315 | + | .section-panel { display: none; } | |
| 1316 | + | .section-panel.active { display: block; } | |
| 1317 | + | .section-panel p { margin-bottom: var(--space-4); } | |
| 1318 | + | .section-panel ul, | |
| 1319 | + | .section-panel ol { | |
| 1320 | + | margin-left: var(--space-5); | |
| 1321 | + | margin-bottom: var(--space-4); | |
| 1322 | + | } | |
| 1323 | + | .section-panel li { margin-bottom: var(--space-2); } | |
| 1324 | + | .section-panel h1, | |
| 1325 | + | .section-panel h2, | |
| 1326 | + | .section-panel h3 { | |
| 1327 | + | margin-top: var(--space-4); | |
| 1328 | + | margin-bottom: var(--space-2); | |
| 1329 | + | } | |
| 1330 | + | .section-panel pre { | |
| 1331 | + | background: var(--surface-muted); | |
| 1332 | + | padding: var(--space-4); | |
| 1333 | + | overflow-x: auto; |
Lines truncated
| @@ -1,7 +1,7 @@ | |||
| 1 | 1 | <div class="version-upload" id="version-upload" data-item-id="{{ item.id }}"> | |
| 2 | 2 | ||
| 3 | 3 | {% if versions.is_empty() %} | |
| 4 | - | <div style="text-align: center; padding: 2rem 1rem; opacity: 0.6;"> | |
| 4 | + | <div class="item-version-upload-empty"> | |
| 5 | 5 | <p>No versions uploaded yet. Create your first version below.</p> | |
| 6 | 6 | </div> | |
| 7 | 7 | {% else %} | |
| @@ -20,19 +20,19 @@ | |||
| 20 | 20 | {% for version in versions %} | |
| 21 | 21 | <tr> | |
| 22 | 22 | <td><span class="badge{% if version.is_current %} current{% endif %}">v{{ version.number }}</span></td> | |
| 23 | - | <td style="font-size: 0.85rem;">{% if let Some(label) = version.label %}{{ label }}{% endif %}</td> | |
| 24 | - | <td style="font-size: 0.85rem;">{% if version.has_file %}{% match version.file_name %}{% when Some with (name) %}{{ name }}{% when None %}1 file{% endmatch %}{% else %}<span style="opacity: 0.5;">No file</span>{% endif %}</td> | |
| 23 | + | <td class="item-version-upload-cell-sm">{% if let Some(label) = version.label %}{{ label }}{% endif %}</td> | |
| 24 | + | <td class="item-version-upload-cell-sm">{% if version.has_file %}{% match version.file_name %}{% when Some with (name) %}{{ name }}{% when None %}1 file{% endmatch %}{% else %}<span class="item-version-upload-no-file">No file</span>{% endif %}</td> | |
| 25 | 25 | <td>{{ version.size }}</td> | |
| 26 | 26 | <td>{{ version.downloads }}</td> | |
| 27 | 27 | <td> | |
| 28 | 28 | {% if version.has_file %} | |
| 29 | - | <button class="secondary download-version-btn" style="padding: 0.4rem 0.8rem; font-size: 0.85rem;" | |
| 29 | + | <button class="secondary download-version-btn item-version-upload-btn" | |
| 30 | 30 | data-version-id="{{ version.id }}">Download</button> | |
| 31 | 31 | {% else %} | |
| 32 | - | <button class="secondary upload-to-version-btn" style="padding: 0.4rem 0.8rem; font-size: 0.85rem;" | |
| 32 | + | <button class="secondary upload-to-version-btn item-version-upload-btn" | |
| 33 | 33 | data-version-id="{{ version.id }}">Upload File</button> | |
| 34 | 34 | {% endif %} | |
| 35 | - | <button class="secondary delete-version-btn" style="padding: 0.4rem 0.8rem; font-size: 0.85rem;" | |
| 35 | + | <button class="secondary delete-version-btn item-version-upload-btn" | |
| 36 | 36 | data-version-id="{{ version.id }}">Delete</button> | |
| 37 | 37 | </td> | |
| 38 | 38 | </tr> | |
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | 44 | <!-- New Version Form --> | |
| 45 | 45 | <div id="new-version-form"> | |
| 46 | - | <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;"> | |
| 46 | + | <div class="item-version-upload-grid"> | |
| 47 | 47 | <div class="form-group"> | |
| 48 | 48 | <label for="new-version-number">Version Number</label> | |
| 49 | 49 | <input type="text" id="new-version-number" placeholder="e.g., 1.0"> | |
| @@ -56,23 +56,23 @@ | |||
| 56 | 56 | ||
| 57 | 57 | <div class="form-group"> | |
| 58 | 58 | <label>Files</label> | |
| 59 | - | <div class="upload-hint" style="margin-bottom: 0.5rem;">Add one file per platform. Each gets its own label (e.g. "macOS (arm)", "Linux (x86_64)").</div> | |
| 59 | + | <div class="upload-hint item-version-upload-hint">Add one file per platform. Each gets its own label (e.g. "macOS (arm)", "Linux (x86_64)").</div> | |
| 60 | 60 | ||
| 61 | - | <table style="width: 100%; border-collapse: collapse;" id="version-file-table"> | |
| 61 | + | <table class="item-version-upload-file-table" id="version-file-table"> | |
| 62 | 62 | <thead> | |
| 63 | - | <tr style="text-align: left; font-size: 0.8rem; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.03em;"> | |
| 64 | - | <th style="padding: 0.4rem 0.5rem 0.4rem 0;">File</th> | |
| 65 | - | <th style="padding: 0.4rem 0.5rem;">Label</th> | |
| 66 | - | <th style="padding: 0.4rem 0.5rem; width: 40px;"></th> | |
| 63 | + | <tr> | |
| 64 | + | <th>File</th> | |
| 65 | + | <th>Label</th> | |
| 66 | + | <th></th> | |
| 67 | 67 | </tr> | |
| 68 | 68 | </thead> | |
| 69 | 69 | <tbody id="version-file-rows"></tbody> | |
| 70 | 70 | </table> | |
| 71 | 71 | ||
| 72 | - | <div style="margin-top: 0.5rem;"> | |
| 73 | - | <input type="file" id="version-file-input" style="display: none;" | |
| 72 | + | <div class="item-version-upload-add-row"> | |
| 73 | + | <input type="file" id="version-file-input" class="hidden" | |
| 74 | 74 | accept=".zip,.dmg,.exe,.appimage,.deb,.tar.gz,.clap,.vst3" multiple> | |
| 75 | - | <button type="button" class="secondary" id="add-version-file-btn" style="padding: 0.4rem 0.8rem;">Add Files</button> | |
| 75 | + | <button type="button" class="secondary item-version-upload-add-btn" id="add-version-file-btn">Add Files</button> | |
| 76 | 76 | </div> | |
| 77 | 77 | </div> | |
| 78 | 78 | ||
| @@ -84,7 +84,7 @@ | |||
| 84 | 84 | <div class="file-upload-area" id="existing-version-dropzone"> | |
| 85 | 85 | <div class="upload-text">Drop file to upload for this version</div> | |
| 86 | 86 | <div class="upload-hint">ZIP, DMG, EXE, AppImage, DEB, tar.gz, CLAP, VST3</div> | |
| 87 | - | <input type="file" id="existing-version-file-input" style="display: none;" | |
| 87 | + | <input type="file" id="existing-version-file-input" class="hidden" | |
| 88 | 88 | accept=".zip,.dmg,.exe,.appimage,.deb,.tar.gz,.clap,.vst3"> | |
| 89 | 89 | </div> | |
| 90 | 90 | <button class="secondary" id="cancel-existing-upload-btn">Cancel</button> | |
| @@ -92,7 +92,7 @@ | |||
| 92 | 92 | ||
| 93 | 93 | <!-- Shared upload progress/status (outside both forms so always visible) --> | |
| 94 | 94 | <div class="upload-progress hidden" id="version-upload-progress"> | |
| 95 | - | <div id="version-upload-queue" style="margin-bottom: 0.75rem;"></div> | |
| 95 | + | <div class="item-version-upload-queue" id="version-upload-queue"></div> | |
| 96 | 96 | <div class="progress-info"> | |
| 97 | 97 | <span id="version-upload-filename">filename.zip</span> | |
| 98 | 98 | <span id="version-upload-percent">0%</span> | |
| @@ -100,7 +100,7 @@ | |||
| 100 | 100 | <div class="progress-bar-container"> | |
| 101 | 101 | <div class="progress-bar" id="version-progress-bar" style="width: 0%;"></div> | |
| 102 | 102 | </div> | |
| 103 | - | <div id="version-upload-speed" style="font-size: 0.8rem; opacity: 0.6; margin-top: 0.25rem;"></div> | |
| 103 | + | <div class="item-version-upload-speed" id="version-upload-speed"></div> | |
| 104 | 104 | <button type="button" class="secondary" id="cancel-version-upload-btn">Cancel</button> | |
| 105 | 105 | </div> | |
| 106 | 106 |