@birdycom/omniaui 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +21 -21
  3. package/bin/lib/add.mjs +126 -126
  4. package/bin/lib/catalog.mjs +169 -169
  5. package/bin/lib/project.mjs +90 -90
  6. package/bin/omniaui.mjs +69 -69
  7. package/dist/code-block.css +25 -25
  8. package/dist/components-extra.css +916 -914
  9. package/dist/components.css +6559 -6469
  10. package/dist/components.min.css +1 -1
  11. package/dist/data-table.d.ts +9 -9
  12. package/dist/data-table.js +505 -505
  13. package/dist/docs-ui.css +267 -265
  14. package/dist/oc-theme.css +69 -69
  15. package/dist/parts/app-accordion-accent.css +60 -60
  16. package/dist/parts/app-alpha-tabs.css +68 -68
  17. package/dist/parts/app-busy-overlay.css +25 -25
  18. package/dist/parts/app-column-menu.css +85 -85
  19. package/dist/parts/app-confirm-dialog.css +70 -70
  20. package/dist/parts/app-cookie-consent.css +63 -63
  21. package/dist/parts/app-data-table.css +174 -174
  22. package/dist/parts/app-greeting.css +47 -47
  23. package/dist/parts/app-list-toolbar.css +81 -81
  24. package/dist/parts/app-page-header.css +54 -54
  25. package/dist/parts/app-severity-card.css +91 -91
  26. package/dist/parts/app-sidebar-dark.css +15 -15
  27. package/dist/parts/app-sortable-row.css +52 -52
  28. package/dist/parts/app-stat-card.css +68 -68
  29. package/dist/parts/app-table-actions.css +71 -71
  30. package/dist/parts/app-table-compact.css +54 -54
  31. package/dist/parts/app-top-progress.css +68 -68
  32. package/dist/parts/app-tree.css +104 -104
  33. package/dist/parts/app-upgrade-banner.css +90 -90
  34. package/dist/parts/app-version-banner.css +80 -80
  35. package/dist/parts/data-chart-line.css +167 -167
  36. package/dist/parts/forms-affix-input.css +75 -75
  37. package/dist/parts/forms-barcode-input.css +75 -75
  38. package/dist/parts/forms-chip-filter.css +91 -91
  39. package/dist/parts/forms-color-select.css +97 -89
  40. package/dist/parts/forms-decimal-input.css +51 -51
  41. package/dist/parts/forms-filter-counts.css +94 -94
  42. package/dist/parts/forms-language-select.css +89 -76
  43. package/dist/parts/forms-number-input.css +98 -95
  44. package/dist/parts/forms-password-requirements.css +55 -55
  45. package/dist/parts/forms-phone-input.css +85 -85
  46. package/dist/parts/forms-time-input.css +74 -74
  47. package/dist/parts/forms-toggle-field.css +69 -69
  48. package/dist/parts/media-art.css +21 -21
  49. package/dist/parts/media-attachment.css +160 -160
  50. package/dist/parts/media-browser-frame.css +73 -73
  51. package/dist/parts/media-card.css +83 -83
  52. package/dist/parts/media-chat-composer.css +90 -90
  53. package/dist/parts/media-doc-viewer.css +151 -151
  54. package/dist/parts/media-emoji-picker.css +88 -88
  55. package/dist/parts/media-entity-card.css +52 -52
  56. package/dist/parts/media-flip-card.css +78 -78
  57. package/dist/parts/media-image-zoom.css +68 -68
  58. package/dist/parts/media-lightbox.css +131 -131
  59. package/dist/parts/media-message-thread.css +136 -136
  60. package/dist/parts/media-message.css +160 -160
  61. package/dist/parts/media-row.css +78 -78
  62. package/dist/parts/media-stack-card.css +82 -82
  63. package/dist/parts/media-terminal-log.css +76 -76
  64. package/dist/parts/media-thumb.css +71 -71
  65. package/dist/parts/site-fact-list.css +25 -25
  66. package/dist/parts/site-link-arrow.css +34 -34
  67. package/dist/parts/site-marquee.css +34 -34
  68. package/dist/parts/site-next-teaser.css +75 -75
  69. package/dist/parts/site-price-card.css +91 -75
  70. package/dist/parts/site-product-mark.css +66 -66
  71. package/dist/parts/site-project-card.css +111 -111
  72. package/dist/parts/site-prose.css +124 -124
  73. package/dist/parts/site-stack-list.css +48 -48
  74. package/dist/parts/site-timeline.css +54 -54
  75. package/dist/showcase.css +404 -404
  76. package/package.json +69 -69
  77. package/snippets/accordion-accent.html +24 -24
  78. package/snippets/accordion.html +11 -11
  79. package/snippets/affix-input.html +30 -30
  80. package/snippets/alert-dialog.html +22 -22
  81. package/snippets/alert.html +5 -5
  82. package/snippets/alpha-tabs.html +37 -37
  83. package/snippets/aspect-ratio.html +15 -15
  84. package/snippets/attachment.html +43 -43
  85. package/snippets/avatar.html +6 -6
  86. package/snippets/back-link.html +5 -5
  87. package/snippets/badge.html +5 -5
  88. package/snippets/barcode-input.html +18 -18
  89. package/snippets/breadcrumb.html +6 -6
  90. package/snippets/browser-frame.html +18 -18
  91. package/snippets/busy-overlay.html +31 -31
  92. package/snippets/button-group.html +21 -21
  93. package/snippets/button.html +8 -8
  94. package/snippets/calendar.html +43 -43
  95. package/snippets/card.html +17 -17
  96. package/snippets/carousel.html +21 -21
  97. package/snippets/chart-line.html +46 -46
  98. package/snippets/chart.html +27 -27
  99. package/snippets/chat-composer.html +21 -21
  100. package/snippets/checkbox.html +5 -5
  101. package/snippets/checklist.html +23 -23
  102. package/snippets/chip-filter.html +14 -14
  103. package/snippets/code-window.html +20 -20
  104. package/snippets/collapsible.html +19 -19
  105. package/snippets/color-field.html +13 -13
  106. package/snippets/color-select.html +18 -18
  107. package/snippets/column-menu.html +38 -38
  108. package/snippets/combobox.html +19 -19
  109. package/snippets/command.html +24 -24
  110. package/snippets/confirm-dialog.html +32 -32
  111. package/snippets/context-menu.html +25 -25
  112. package/snippets/cookie-consent.html +70 -70
  113. package/snippets/copy-field.html +19 -19
  114. package/snippets/counter.html +2 -2
  115. package/snippets/data-table.html +151 -151
  116. package/snippets/date-picker.html +32 -32
  117. package/snippets/decimal-input.html +20 -20
  118. package/snippets/definition-list.html +20 -20
  119. package/snippets/demo-panel.html +18 -18
  120. package/snippets/doc-viewer.html +58 -58
  121. package/snippets/drawer.html +30 -30
  122. package/snippets/dropdown-menu.html +27 -27
  123. package/snippets/dropdown.html +9 -9
  124. package/snippets/dropzone.html +13 -13
  125. package/snippets/emoji-picker.html +51 -51
  126. package/snippets/empty-state.html +17 -17
  127. package/snippets/entity-card.html +26 -26
  128. package/snippets/expandable-table.html +26 -26
  129. package/snippets/fact-list.html +14 -14
  130. package/snippets/filter-counts.html +30 -30
  131. package/snippets/flip-card.html +22 -22
  132. package/snippets/form-field.html +6 -6
  133. package/snippets/greeting.html +22 -22
  134. package/snippets/heading.html +14 -14
  135. package/snippets/hover-card.html +18 -18
  136. package/snippets/image-zoom.html +30 -30
  137. package/snippets/input-group.html +10 -10
  138. package/snippets/input.html +5 -5
  139. package/snippets/item.html +26 -26
  140. package/snippets/kbd.html +13 -13
  141. package/snippets/label.html +9 -9
  142. package/snippets/language-select.html +26 -26
  143. package/snippets/launcher-card.html +14 -14
  144. package/snippets/lightbox.html +50 -50
  145. package/snippets/link-arrow.html +10 -10
  146. package/snippets/list-toolbar.html +33 -33
  147. package/snippets/marquee.html +15 -15
  148. package/snippets/media-card.html +28 -28
  149. package/snippets/media-row.html +21 -21
  150. package/snippets/media-thumb.html +12 -12
  151. package/snippets/menubar.html +30 -30
  152. package/snippets/message-thread.html +123 -123
  153. package/snippets/message.html +51 -51
  154. package/snippets/modal.html +15 -15
  155. package/snippets/native-select.html +15 -15
  156. package/snippets/navmenu.html +23 -23
  157. package/snippets/next-teaser.html +15 -15
  158. package/snippets/number-input.html +27 -27
  159. package/snippets/otp-input.html +9 -9
  160. package/snippets/page-header.html +24 -24
  161. package/snippets/pagination.html +6 -6
  162. package/snippets/password-input.html +24 -24
  163. package/snippets/password-requirements.html +30 -30
  164. package/snippets/phone-input.html +22 -22
  165. package/snippets/popover.html +15 -15
  166. package/snippets/price-card.html +34 -34
  167. package/snippets/product-mark.html +13 -13
  168. package/snippets/progress.html +4 -4
  169. package/snippets/project-card.html +23 -23
  170. package/snippets/prose.html +54 -54
  171. package/snippets/radio.html +17 -17
  172. package/snippets/recovery-codes.html +20 -20
  173. package/snippets/resizable.html +16 -16
  174. package/snippets/scroll-area.html +20 -20
  175. package/snippets/search.html +8 -8
  176. package/snippets/segmented.html +11 -11
  177. package/snippets/select.html +7 -7
  178. package/snippets/separator.html +15 -15
  179. package/snippets/severity-card.html +35 -35
  180. package/snippets/sheet.html +32 -32
  181. package/snippets/sidebar-docs.html +24 -24
  182. package/snippets/sidebar.html +55 -55
  183. package/snippets/site-footer.html +6 -6
  184. package/snippets/site-header.html +26 -26
  185. package/snippets/skeleton.html +4 -4
  186. package/snippets/slider.html +17 -17
  187. package/snippets/sortable-row.html +31 -31
  188. package/snippets/spinner.html +14 -14
  189. package/snippets/stack-card.html +17 -17
  190. package/snippets/stack-list.html +16 -16
  191. package/snippets/stat-card.html +24 -24
  192. package/snippets/stepper.html +13 -13
  193. package/snippets/switch.html +6 -6
  194. package/snippets/table-actions.html +39 -39
  195. package/snippets/table-compact.html +24 -24
  196. package/snippets/table.html +29 -29
  197. package/snippets/tabs.html +9 -9
  198. package/snippets/tag-input.html +60 -17
  199. package/snippets/terminal-log.html +23 -23
  200. package/snippets/textarea.html +3 -3
  201. package/snippets/theme-switch.html +6 -6
  202. package/snippets/time-input.html +26 -26
  203. package/snippets/timeline.html +28 -28
  204. package/snippets/toast-stack.html +10 -10
  205. package/snippets/toast.html +36 -36
  206. package/snippets/toc.html +13 -13
  207. package/snippets/toggle-field.html +20 -20
  208. package/snippets/toggle.html +22 -22
  209. package/snippets/tooltip.html +4 -4
  210. package/snippets/top-progress.html +12 -12
  211. package/snippets/tree.html +38 -38
  212. package/snippets/upgrade-banner.html +28 -28
  213. package/snippets/user.html +15 -15
  214. package/snippets/version-banner.html +15 -15
@@ -1,78 +1,78 @@
1
- /* File: packages/ui/src/parts/media-row.css | Map: list -> row grid (thumb | text | menu) -> title (stretched link) + meta
2
- -> menu button -> numbered playlist (CSS counter) -> current item -> hover -> small screens
3
- Media row: a compact horizontal item for "up next" lists and playlists. The thumb is a .oc-media-thumb. */
4
-
5
- .oc-media-row-list { display: grid; gap: 0.25rem; margin: 0; padding: 0; list-style: none; inline-size: 100%; counter-reset: oc-media-row; }
6
-
7
- .oc-media-row {
8
- position: relative;
9
- display: grid;
10
- grid-template-columns: 10rem minmax(0, 1fr) auto;
11
- gap: 0.75rem;
12
- align-items: start;
13
- padding: 0.375rem;
14
- border-radius: var(--oc-radius);
15
- color: var(--oc-foreground);
16
- }
17
- .oc-media-row:hover { background: var(--oc-surface); }
18
- .oc-media-row > .oc-media-thumb { border-radius: calc(var(--oc-radius) - 2px); }
19
-
20
- .oc-media-row__text { display: grid; gap: 0.2rem; min-inline-size: 0; }
21
- .oc-media-row__title {
22
- margin: 0;
23
- font-size: 0.875rem;
24
- font-weight: 600;
25
- line-height: 1.35;
26
- display: -webkit-box;
27
- -webkit-box-orient: vertical;
28
- -webkit-line-clamp: 2;
29
- line-clamp: 2;
30
- overflow: hidden;
31
- }
32
- .oc-media-row__title > a { color: inherit; text-decoration: none; }
33
- .oc-media-row__title > a::after { content: ""; position: absolute; inset: 0; border-radius: var(--oc-radius); }
34
- .oc-media-row__title > a:focus-visible { outline: none; }
35
- .oc-media-row__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
36
- .oc-media-row__meta { margin: 0; font-size: 0.75rem; color: var(--oc-muted-foreground); }
37
-
38
- /* ⋮ button above the stretched link. */
39
- .oc-media-row__menu {
40
- position: relative;
41
- z-index: 1;
42
- display: grid;
43
- place-items: center;
44
- inline-size: 1.75rem;
45
- aspect-ratio: 1;
46
- padding: 0;
47
- border: 0;
48
- border-radius: 50%;
49
- background: transparent;
50
- color: var(--oc-muted-foreground);
51
- cursor: pointer;
52
- }
53
- .oc-media-row__menu:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
54
- .oc-media-row__menu:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
55
-
56
- /* Numbered playlist: an extra first column with a CSS counter (no number in the markup). */
57
- .oc-media-row-list--numbered > .oc-media-row { counter-increment: oc-media-row; grid-template-columns: 1.5rem 8rem minmax(0, 1fr) auto; align-items: center; }
58
- .oc-media-row-list--numbered > .oc-media-row::before {
59
- content: counter(oc-media-row);
60
- font-size: 0.8125rem;
61
- font-variant-numeric: tabular-nums;
62
- text-align: center;
63
- color: var(--oc-muted-foreground);
64
- }
65
-
66
- /* Current item (aria-current="true"): tinted row and a play mark instead of the number. */
67
- .oc-media-row[aria-current="true"] { background: color-mix(in oklch, var(--oc-primary) 12%, transparent); }
68
- .oc-media-row-list--numbered > .oc-media-row[aria-current="true"]::before { content: "\25B6" / "Now playing"; color: var(--oc-primary); }
69
-
70
- @media (prefers-reduced-motion: no-preference) {
71
- .oc-media-row:hover .oc-media-thumb > :is(img, video, .oc-media-art) { transform: scale(1.04); }
72
- }
73
-
74
- /* Narrow containers: smaller thumb. */
75
- @media (max-width: 30rem) {
76
- .oc-media-row { grid-template-columns: 7.5rem minmax(0, 1fr) auto; }
77
- .oc-media-row-list--numbered > .oc-media-row { grid-template-columns: 1.25rem 6.5rem minmax(0, 1fr) auto; }
78
- }
1
+ /* File: packages/ui/src/parts/media-row.css | Map: list -> row grid (thumb | text | menu) -> title (stretched link) + meta
2
+ -> menu button -> numbered playlist (CSS counter) -> current item -> hover -> small screens
3
+ Media row: a compact horizontal item for "up next" lists and playlists. The thumb is a .oc-media-thumb. */
4
+
5
+ .oc-media-row-list { display: grid; gap: 0.25rem; margin: 0; padding: 0; list-style: none; inline-size: 100%; counter-reset: oc-media-row; }
6
+
7
+ .oc-media-row {
8
+ position: relative;
9
+ display: grid;
10
+ grid-template-columns: 10rem minmax(0, 1fr) auto;
11
+ gap: 0.75rem;
12
+ align-items: start;
13
+ padding: 0.375rem;
14
+ border-radius: var(--oc-radius);
15
+ color: var(--oc-foreground);
16
+ }
17
+ .oc-media-row:hover { background: var(--oc-surface); }
18
+ .oc-media-row > .oc-media-thumb { border-radius: calc(var(--oc-radius) - 2px); }
19
+
20
+ .oc-media-row__text { display: grid; gap: 0.2rem; min-inline-size: 0; }
21
+ .oc-media-row__title {
22
+ margin: 0;
23
+ font-size: 0.875rem;
24
+ font-weight: 600;
25
+ line-height: 1.35;
26
+ display: -webkit-box;
27
+ -webkit-box-orient: vertical;
28
+ -webkit-line-clamp: 2;
29
+ line-clamp: 2;
30
+ overflow: hidden;
31
+ }
32
+ .oc-media-row__title > a { color: inherit; text-decoration: none; }
33
+ .oc-media-row__title > a::after { content: ""; position: absolute; inset: 0; border-radius: var(--oc-radius); }
34
+ .oc-media-row__title > a:focus-visible { outline: none; }
35
+ .oc-media-row__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
36
+ .oc-media-row__meta { margin: 0; font-size: 0.75rem; color: var(--oc-muted-foreground); }
37
+
38
+ /* ⋮ button above the stretched link. */
39
+ .oc-media-row__menu {
40
+ position: relative;
41
+ z-index: 1;
42
+ display: grid;
43
+ place-items: center;
44
+ inline-size: 1.75rem;
45
+ aspect-ratio: 1;
46
+ padding: 0;
47
+ border: 0;
48
+ border-radius: 50%;
49
+ background: transparent;
50
+ color: var(--oc-muted-foreground);
51
+ cursor: pointer;
52
+ }
53
+ .oc-media-row__menu:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
54
+ .oc-media-row__menu:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
55
+
56
+ /* Numbered playlist: an extra first column with a CSS counter (no number in the markup). */
57
+ .oc-media-row-list--numbered > .oc-media-row { counter-increment: oc-media-row; grid-template-columns: 1.5rem 8rem minmax(0, 1fr) auto; align-items: center; }
58
+ .oc-media-row-list--numbered > .oc-media-row::before {
59
+ content: counter(oc-media-row);
60
+ font-size: 0.8125rem;
61
+ font-variant-numeric: tabular-nums;
62
+ text-align: center;
63
+ color: var(--oc-muted-foreground);
64
+ }
65
+
66
+ /* Current item (aria-current="true"): tinted row and a play mark instead of the number. */
67
+ .oc-media-row[aria-current="true"] { background: color-mix(in oklch, var(--oc-primary) 12%, transparent); }
68
+ .oc-media-row-list--numbered > .oc-media-row[aria-current="true"]::before { content: "\25B6" / "Now playing"; color: var(--oc-primary); }
69
+
70
+ @media (prefers-reduced-motion: no-preference) {
71
+ .oc-media-row:hover .oc-media-thumb > :is(img, video, .oc-media-art) { transform: scale(1.04); }
72
+ }
73
+
74
+ /* Narrow containers: smaller thumb. */
75
+ @media (max-width: 30rem) {
76
+ .oc-media-row { grid-template-columns: 7.5rem minmax(0, 1fr) auto; }
77
+ .oc-media-row-list--numbered > .oc-media-row { grid-template-columns: 1.25rem 6.5rem minmax(0, 1fr) auto; }
78
+ }
@@ -1,82 +1,82 @@
1
- /* File: packages/ui/src/parts/media-stack-card.css | Map: card -> deck (two layers behind via ::before / ::after)
2
- -> count badge -> panel modifier -> body (title link + meta) -> hover spread -> motion
3
- Stack card: a playlist / course cover that looks like a small pile of cards, with a "12 videos" badge. */
4
-
5
- .oc-stack-card {
6
- position: relative;
7
- display: grid;
8
- gap: 0.75rem;
9
- align-content: start;
10
- inline-size: 100%;
11
- padding-block-start: 0.6rem; /* room for the layers peeking out above */
12
- color: var(--oc-foreground);
13
- }
14
-
15
- /* The deck: the cover plus two layers drawn behind it. */
16
- .oc-stack-card__deck { position: relative; isolation: isolate; }
17
- .oc-stack-card__deck::before,
18
- .oc-stack-card__deck::after {
19
- content: "";
20
- position: absolute;
21
- inset-inline: 0.75rem;
22
- inset-block: -0.3rem auto;
23
- block-size: 100%;
24
- z-index: -1;
25
- border-radius: var(--oc-radius);
26
- background: color-mix(in oklch, var(--oc-muted-foreground) 35%, var(--oc-card));
27
- transition: translate var(--oc-transition-normal), rotate var(--oc-transition-normal);
28
- }
29
- .oc-stack-card__deck::after {
30
- inset-inline: 1.5rem;
31
- inset-block-start: -0.6rem;
32
- z-index: -2;
33
- background: color-mix(in oklch, var(--oc-muted-foreground) 18%, var(--oc-card));
34
- }
35
-
36
- /* Count badge: bottom right on the cover ("12 videos"). */
37
- .oc-stack-card__count {
38
- position: absolute;
39
- inset-block-end: 0.45rem;
40
- inset-inline-end: 0.45rem;
41
- display: inline-flex;
42
- align-items: center;
43
- gap: 0.3rem;
44
- padding: 0.15rem 0.45rem;
45
- border-radius: 0.3rem;
46
- background: oklch(from var(--color-black-60) l c h / 0.78);
47
- color: var(--color-white-50);
48
- font-size: 0.75rem;
49
- font-weight: 600;
50
- font-variant-numeric: tabular-nums;
51
- }
52
-
53
- /* Panel: the count becomes a dark side panel over the right third of the cover. */
54
- .oc-stack-card--panel .oc-stack-card__count {
55
- inset-block: 0;
56
- inset-inline-end: 0;
57
- inline-size: 38%;
58
- flex-direction: column;
59
- justify-content: center;
60
- border-radius: 0 var(--oc-radius) var(--oc-radius) 0;
61
- background: oklch(from var(--color-black-60) l c h / 0.72);
62
- backdrop-filter: blur(6px);
63
- font-size: 0.875rem;
64
- }
65
-
66
- /* Body: title (link covers the card) + meta. */
67
- .oc-stack-card__title { margin: 0; font-size: 0.95rem; font-weight: 600; line-height: 1.35; }
68
- .oc-stack-card__title > a { color: inherit; text-decoration: none; }
69
- .oc-stack-card__title > a::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: var(--oc-radius); }
70
- .oc-stack-card__title > a:focus-visible { outline: none; }
71
- .oc-stack-card__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 4px; }
72
- .oc-stack-card__meta { margin: 0.2rem 0 0; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
73
-
74
- /* Hover: the layers fan out a little. */
75
- @media (prefers-reduced-motion: no-preference) {
76
- .oc-stack-card:hover .oc-stack-card__deck::before { translate: 0 -0.2rem; rotate: -1.5deg; }
77
- .oc-stack-card:hover .oc-stack-card__deck::after { translate: 0 -0.35rem; rotate: 2deg; }
78
- }
79
- @media (prefers-reduced-motion: reduce) {
80
- .oc-stack-card__deck::before,
81
- .oc-stack-card__deck::after { transition: none; }
82
- }
1
+ /* File: packages/ui/src/parts/media-stack-card.css | Map: card -> deck (two layers behind via ::before / ::after)
2
+ -> count badge -> panel modifier -> body (title link + meta) -> hover spread -> motion
3
+ Stack card: a playlist / course cover that looks like a small pile of cards, with a "12 videos" badge. */
4
+
5
+ .oc-stack-card {
6
+ position: relative;
7
+ display: grid;
8
+ gap: 0.75rem;
9
+ align-content: start;
10
+ inline-size: 100%;
11
+ padding-block-start: 0.6rem; /* room for the layers peeking out above */
12
+ color: var(--oc-foreground);
13
+ }
14
+
15
+ /* The deck: the cover plus two layers drawn behind it. */
16
+ .oc-stack-card__deck { position: relative; isolation: isolate; }
17
+ .oc-stack-card__deck::before,
18
+ .oc-stack-card__deck::after {
19
+ content: "";
20
+ position: absolute;
21
+ inset-inline: 0.75rem;
22
+ inset-block: -0.3rem auto;
23
+ block-size: 100%;
24
+ z-index: -1;
25
+ border-radius: var(--oc-radius);
26
+ background: color-mix(in oklch, var(--oc-muted-foreground) 35%, var(--oc-card));
27
+ transition: translate var(--oc-transition-normal), rotate var(--oc-transition-normal);
28
+ }
29
+ .oc-stack-card__deck::after {
30
+ inset-inline: 1.5rem;
31
+ inset-block-start: -0.6rem;
32
+ z-index: -2;
33
+ background: color-mix(in oklch, var(--oc-muted-foreground) 18%, var(--oc-card));
34
+ }
35
+
36
+ /* Count badge: bottom right on the cover ("12 videos"). */
37
+ .oc-stack-card__count {
38
+ position: absolute;
39
+ inset-block-end: 0.45rem;
40
+ inset-inline-end: 0.45rem;
41
+ display: inline-flex;
42
+ align-items: center;
43
+ gap: 0.3rem;
44
+ padding: 0.15rem 0.45rem;
45
+ border-radius: 0.3rem;
46
+ background: oklch(from var(--color-black-60) l c h / 0.78);
47
+ color: var(--color-white-50);
48
+ font-size: 0.75rem;
49
+ font-weight: 600;
50
+ font-variant-numeric: tabular-nums;
51
+ }
52
+
53
+ /* Panel: the count becomes a dark side panel over the right third of the cover. */
54
+ .oc-stack-card--panel .oc-stack-card__count {
55
+ inset-block: 0;
56
+ inset-inline-end: 0;
57
+ inline-size: 38%;
58
+ flex-direction: column;
59
+ justify-content: center;
60
+ border-radius: 0 var(--oc-radius) var(--oc-radius) 0;
61
+ background: oklch(from var(--color-black-60) l c h / 0.72);
62
+ backdrop-filter: blur(6px);
63
+ font-size: 0.875rem;
64
+ }
65
+
66
+ /* Body: title (link covers the card) + meta. */
67
+ .oc-stack-card__title { margin: 0; font-size: 0.95rem; font-weight: 600; line-height: 1.35; }
68
+ .oc-stack-card__title > a { color: inherit; text-decoration: none; }
69
+ .oc-stack-card__title > a::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: var(--oc-radius); }
70
+ .oc-stack-card__title > a:focus-visible { outline: none; }
71
+ .oc-stack-card__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 4px; }
72
+ .oc-stack-card__meta { margin: 0.2rem 0 0; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
73
+
74
+ /* Hover: the layers fan out a little. */
75
+ @media (prefers-reduced-motion: no-preference) {
76
+ .oc-stack-card:hover .oc-stack-card__deck::before { translate: 0 -0.2rem; rotate: -1.5deg; }
77
+ .oc-stack-card:hover .oc-stack-card__deck::after { translate: 0 -0.35rem; rotate: 2deg; }
78
+ }
79
+ @media (prefers-reduced-motion: reduce) {
80
+ .oc-stack-card__deck::before,
81
+ .oc-stack-card__deck::after { transition: none; }
82
+ }
@@ -1,76 +1,76 @@
1
- /* File: packages/ui/src/parts/media-terminal-log.css | Map: frame (always dark) -> title bar (traffic lights, title, live dot)
2
- -> body (scrolling log) -> line grid (time | level | message) -> level colors -> prompt + blinking cursor -> motion
3
- Terminal log: a console window for build / scan output. color-scheme: dark makes every light-dark() token
4
- inside resolve to its dark value, so the terminal stays dark in the light theme too. */
5
-
6
- .oc-terminal-log {
7
- color-scheme: dark;
8
- inline-size: 100%;
9
- overflow: hidden;
10
- border: 1px solid var(--oc-border);
11
- border-radius: calc(var(--oc-radius) + 4px);
12
- background: var(--color-shallowblue-95);
13
- color: var(--oc-foreground);
14
- box-shadow: 0 24px 48px -24px oklch(from var(--color-black-60) l c h / 0.6);
15
- }
16
-
17
- /* ---- Title bar ---- */
18
- .oc-terminal-log__bar { display: flex; align-items: center; gap: 0.45rem; padding: 0.65rem 0.9rem; border-block-end: 1px solid var(--oc-border); background: var(--color-shallowblue-90); }
19
- .oc-terminal-log__bar > i { inline-size: 0.7rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-red-50); }
20
- .oc-terminal-log__bar > i:nth-of-type(2) { background: var(--color-orange-60); }
21
- .oc-terminal-log__bar > i:nth-of-type(3) { background: var(--color-green-20); }
22
- .oc-terminal-log__title { margin-inline: 0.5rem auto; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
23
- .oc-terminal-log__status { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.75rem; color: var(--oc-muted-foreground); }
24
- .oc-terminal-log__status::before { content: ""; inline-size: 0.5rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-green-20); }
25
-
26
- /* ---- Body: monospace, scrolls when it gets long ---- */
27
- .oc-terminal-log__body {
28
- display: grid;
29
- gap: 0.15rem;
30
- max-block-size: var(--oc-terminal-log-height, 18rem);
31
- margin: 0;
32
- padding: 0.9rem 1rem;
33
- overflow: auto;
34
- font-family: ui-monospace, "Cascadia Code", "Fira Code", Menlo, Consolas, monospace;
35
- font-size: 0.8125rem;
36
- line-height: 1.6;
37
- scrollbar-width: thin;
38
- }
39
- .oc-terminal-log__body:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: -2px; }
40
-
41
- /* One line: time | level | message. Long messages wrap under the message column. */
42
- .oc-terminal-log__line { display: grid; grid-template-columns: auto 3.5rem minmax(0, 1fr); gap: 0.75rem; margin: 0; }
43
- .oc-terminal-log__line:not(:has(.oc-terminal-log__time)) { grid-template-columns: 3.5rem minmax(0, 1fr); }
44
- .oc-terminal-log__time { color: var(--color-stormblue-40); font-variant-numeric: tabular-nums; }
45
- .oc-terminal-log__level { font-weight: 700; text-transform: uppercase; }
46
- .oc-terminal-log__msg { overflow-wrap: anywhere; white-space: pre-wrap; }
47
-
48
- /* Level colors (palette tokens, readable on the dark background). */
49
- .oc-terminal-log__line--info .oc-terminal-log__level { color: var(--color-skycyan-50); }
50
- .oc-terminal-log__line--success .oc-terminal-log__level { color: var(--color-green-20); }
51
- .oc-terminal-log__line--warn .oc-terminal-log__level { color: var(--color-orange-50); }
52
- .oc-terminal-log__line--error .oc-terminal-log__level,
53
- .oc-terminal-log__line--error .oc-terminal-log__msg { color: var(--color-red-40); }
54
- .oc-terminal-log__line--debug { opacity: 0.6; }
55
- .oc-terminal-log__line--debug .oc-terminal-log__level { color: var(--color-purple-30); }
56
-
57
- /* Prompt line: "$ " + text + a block cursor. */
58
- .oc-terminal-log__prompt { margin: 0.25rem 0 0; color: var(--oc-foreground); }
59
- .oc-terminal-log__prompt::before { content: "$ "; color: var(--color-green-20); }
60
- .oc-terminal-log__prompt::after {
61
- content: "";
62
- display: inline-block;
63
- inline-size: 0.55em;
64
- block-size: 1.1em;
65
- margin-inline-start: 0.15em;
66
- vertical-align: text-bottom;
67
- background: currentColor;
68
- }
69
-
70
- /* Blinking cursor and pulsing live dot only when motion is welcome; otherwise they stay still. */
71
- @media (prefers-reduced-motion: no-preference) {
72
- .oc-terminal-log__prompt::after { animation: oc-terminal-log-blink 1.1s steps(1) infinite; }
73
- .oc-terminal-log__status::before { animation: oc-terminal-log-pulse 1.6s ease-in-out infinite; }
74
- }
75
- @keyframes oc-terminal-log-blink { 50% { opacity: 0; } }
76
- @keyframes oc-terminal-log-pulse { 50% { opacity: 0.35; } }
1
+ /* File: packages/ui/src/parts/media-terminal-log.css | Map: frame (always dark) -> title bar (traffic lights, title, live dot)
2
+ -> body (scrolling log) -> line grid (time | level | message) -> level colors -> prompt + blinking cursor -> motion
3
+ Terminal log: a console window for build / scan output. color-scheme: dark makes every light-dark() token
4
+ inside resolve to its dark value, so the terminal stays dark in the light theme too. */
5
+
6
+ .oc-terminal-log {
7
+ color-scheme: dark;
8
+ inline-size: 100%;
9
+ overflow: hidden;
10
+ border: 1px solid var(--oc-border);
11
+ border-radius: calc(var(--oc-radius) + 4px);
12
+ background: var(--color-shallowblue-95);
13
+ color: var(--oc-foreground);
14
+ box-shadow: 0 24px 48px -24px oklch(from var(--color-black-60) l c h / 0.6);
15
+ }
16
+
17
+ /* ---- Title bar ---- */
18
+ .oc-terminal-log__bar { display: flex; align-items: center; gap: 0.45rem; padding: 0.65rem 0.9rem; border-block-end: 1px solid var(--oc-border); background: var(--color-shallowblue-90); }
19
+ .oc-terminal-log__bar > i { inline-size: 0.7rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-red-50); }
20
+ .oc-terminal-log__bar > i:nth-of-type(2) { background: var(--color-orange-60); }
21
+ .oc-terminal-log__bar > i:nth-of-type(3) { background: var(--color-green-20); }
22
+ .oc-terminal-log__title { margin-inline: 0.5rem auto; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
23
+ .oc-terminal-log__status { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.75rem; color: var(--oc-muted-foreground); }
24
+ .oc-terminal-log__status::before { content: ""; inline-size: 0.5rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-green-20); }
25
+
26
+ /* ---- Body: monospace, scrolls when it gets long ---- */
27
+ .oc-terminal-log__body {
28
+ display: grid;
29
+ gap: 0.15rem;
30
+ max-block-size: var(--oc-terminal-log-height, 18rem);
31
+ margin: 0;
32
+ padding: 0.9rem 1rem;
33
+ overflow: auto;
34
+ font-family: ui-monospace, "Cascadia Code", "Fira Code", Menlo, Consolas, monospace;
35
+ font-size: 0.8125rem;
36
+ line-height: 1.6;
37
+ scrollbar-width: thin;
38
+ }
39
+ .oc-terminal-log__body:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: -2px; }
40
+
41
+ /* One line: time | level | message. Long messages wrap under the message column. */
42
+ .oc-terminal-log__line { display: grid; grid-template-columns: auto 3.5rem minmax(0, 1fr); gap: 0.75rem; margin: 0; }
43
+ .oc-terminal-log__line:not(:has(.oc-terminal-log__time)) { grid-template-columns: 3.5rem minmax(0, 1fr); }
44
+ .oc-terminal-log__time { color: var(--color-stormblue-40); font-variant-numeric: tabular-nums; }
45
+ .oc-terminal-log__level { font-weight: 700; text-transform: uppercase; }
46
+ .oc-terminal-log__msg { overflow-wrap: anywhere; white-space: pre-wrap; }
47
+
48
+ /* Level colors (palette tokens, readable on the dark background). */
49
+ .oc-terminal-log__line--info .oc-terminal-log__level { color: var(--color-skycyan-50); }
50
+ .oc-terminal-log__line--success .oc-terminal-log__level { color: var(--color-green-20); }
51
+ .oc-terminal-log__line--warn .oc-terminal-log__level { color: var(--color-orange-50); }
52
+ .oc-terminal-log__line--error .oc-terminal-log__level,
53
+ .oc-terminal-log__line--error .oc-terminal-log__msg { color: var(--color-red-40); }
54
+ .oc-terminal-log__line--debug { opacity: 0.6; }
55
+ .oc-terminal-log__line--debug .oc-terminal-log__level { color: var(--color-purple-30); }
56
+
57
+ /* Prompt line: "$ " + text + a block cursor. */
58
+ .oc-terminal-log__prompt { margin: 0.25rem 0 0; color: var(--oc-foreground); }
59
+ .oc-terminal-log__prompt::before { content: "$ "; color: var(--color-green-20); }
60
+ .oc-terminal-log__prompt::after {
61
+ content: "";
62
+ display: inline-block;
63
+ inline-size: 0.55em;
64
+ block-size: 1.1em;
65
+ margin-inline-start: 0.15em;
66
+ vertical-align: text-bottom;
67
+ background: currentColor;
68
+ }
69
+
70
+ /* Blinking cursor and pulsing live dot only when motion is welcome; otherwise they stay still. */
71
+ @media (prefers-reduced-motion: no-preference) {
72
+ .oc-terminal-log__prompt::after { animation: oc-terminal-log-blink 1.1s steps(1) infinite; }
73
+ .oc-terminal-log__status::before { animation: oc-terminal-log-pulse 1.6s ease-in-out infinite; }
74
+ }
75
+ @keyframes oc-terminal-log-blink { 50% { opacity: 0; } }
76
+ @keyframes oc-terminal-log-pulse { 50% { opacity: 0.35; } }
@@ -1,71 +1,71 @@
1
- /* File: packages/ui/src/parts/media-thumb.css | Map: thumb box (16:9) -> media fill + hover -> badge (top)
2
- -> duration (bottom right) -> watch progress (native <progress>) -> ratio modifiers -> watched state -> motion
3
- Media thumb: a video preview tile. Works as <a> or <div>; put an <img> (or .oc-media-art) inside. */
4
-
5
- .oc-media-thumb {
6
- position: relative;
7
- display: block;
8
- aspect-ratio: 16 / 9;
9
- overflow: hidden;
10
- border-radius: var(--oc-radius);
11
- background: var(--oc-muted);
12
- color: var(--color-white-50);
13
- isolation: isolate;
14
- }
15
- .oc-media-thumb:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
16
-
17
- /* The picture fills the box. */
18
- .oc-media-thumb > :is(img, video, .oc-media-art) {
19
- position: absolute;
20
- inset: 0;
21
- inline-size: 100%;
22
- block-size: 100%;
23
- object-fit: cover;
24
- z-index: -1;
25
- }
26
-
27
- /* Small dark labels on top of the picture. */
28
- .oc-media-thumb__badge,
29
- .oc-media-thumb__duration {
30
- position: absolute;
31
- padding: 0.1rem 0.4rem;
32
- border-radius: 0.3rem;
33
- background: oklch(from var(--color-black-60) l c h / 0.78);
34
- font-size: 0.75rem;
35
- font-weight: 600;
36
- line-height: 1.4;
37
- font-variant-numeric: tabular-nums;
38
- }
39
- .oc-media-thumb__badge { inset-block-start: 0.4rem; inset-inline-start: 0.4rem; }
40
- .oc-media-thumb__badge--live { background: var(--color-red-60); }
41
- .oc-media-thumb__duration { inset-block-end: 0.45rem; inset-inline-end: 0.45rem; }
42
- /* With a progress bar the duration moves up a little. */
43
- .oc-media-thumb:has(.oc-media-thumb__progress) .oc-media-thumb__duration { inset-block-end: 0.7rem; }
44
-
45
- /* Watch progress: a native <progress value max>, drawn as a thin bar on the bottom edge. */
46
- .oc-media-thumb__progress {
47
- position: absolute;
48
- inset: auto 0 0;
49
- inline-size: 100%;
50
- block-size: 0.25rem;
51
- border: 0;
52
- appearance: none;
53
- background: oklch(from var(--color-white-50) l c h / 0.35);
54
- color: var(--color-red-60);
55
- }
56
- .oc-media-thumb__progress::-webkit-progress-bar { background: transparent; }
57
- .oc-media-thumb__progress::-webkit-progress-value { background: var(--color-red-60); }
58
- .oc-media-thumb__progress::-moz-progress-bar { background: var(--color-red-60); }
59
-
60
- /* Ratios. */
61
- .oc-media-thumb--square { aspect-ratio: 1 / 1; }
62
- .oc-media-thumb--portrait { aspect-ratio: 9 / 16; }
63
-
64
- /* Already watched: the picture fades a bit. */
65
- .oc-media-thumb.is-watched > :is(img, video, .oc-media-art) { opacity: 0.6; }
66
-
67
- /* Gentle zoom on hover, only when motion is welcome. */
68
- @media (prefers-reduced-motion: no-preference) {
69
- .oc-media-thumb > :is(img, video, .oc-media-art) { transition: transform var(--oc-transition-normal); }
70
- .oc-media-thumb:hover > :is(img, video, .oc-media-art) { transform: scale(1.04); }
71
- }
1
+ /* File: packages/ui/src/parts/media-thumb.css | Map: thumb box (16:9) -> media fill + hover -> badge (top)
2
+ -> duration (bottom right) -> watch progress (native <progress>) -> ratio modifiers -> watched state -> motion
3
+ Media thumb: a video preview tile. Works as <a> or <div>; put an <img> (or .oc-media-art) inside. */
4
+
5
+ .oc-media-thumb {
6
+ position: relative;
7
+ display: block;
8
+ aspect-ratio: 16 / 9;
9
+ overflow: hidden;
10
+ border-radius: var(--oc-radius);
11
+ background: var(--oc-muted);
12
+ color: var(--color-white-50);
13
+ isolation: isolate;
14
+ }
15
+ .oc-media-thumb:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
16
+
17
+ /* The picture fills the box. */
18
+ .oc-media-thumb > :is(img, video, .oc-media-art) {
19
+ position: absolute;
20
+ inset: 0;
21
+ inline-size: 100%;
22
+ block-size: 100%;
23
+ object-fit: cover;
24
+ z-index: -1;
25
+ }
26
+
27
+ /* Small dark labels on top of the picture. */
28
+ .oc-media-thumb__badge,
29
+ .oc-media-thumb__duration {
30
+ position: absolute;
31
+ padding: 0.1rem 0.4rem;
32
+ border-radius: 0.3rem;
33
+ background: oklch(from var(--color-black-60) l c h / 0.78);
34
+ font-size: 0.75rem;
35
+ font-weight: 600;
36
+ line-height: 1.4;
37
+ font-variant-numeric: tabular-nums;
38
+ }
39
+ .oc-media-thumb__badge { inset-block-start: 0.4rem; inset-inline-start: 0.4rem; }
40
+ .oc-media-thumb__badge--live { background: var(--color-red-60); }
41
+ .oc-media-thumb__duration { inset-block-end: 0.45rem; inset-inline-end: 0.45rem; }
42
+ /* With a progress bar the duration moves up a little. */
43
+ .oc-media-thumb:has(.oc-media-thumb__progress) .oc-media-thumb__duration { inset-block-end: 0.7rem; }
44
+
45
+ /* Watch progress: a native <progress value max>, drawn as a thin bar on the bottom edge. */
46
+ .oc-media-thumb__progress {
47
+ position: absolute;
48
+ inset: auto 0 0;
49
+ inline-size: 100%;
50
+ block-size: 0.25rem;
51
+ border: 0;
52
+ appearance: none;
53
+ background: oklch(from var(--color-white-50) l c h / 0.35);
54
+ color: var(--color-red-60);
55
+ }
56
+ .oc-media-thumb__progress::-webkit-progress-bar { background: transparent; }
57
+ .oc-media-thumb__progress::-webkit-progress-value { background: var(--color-red-60); }
58
+ .oc-media-thumb__progress::-moz-progress-bar { background: var(--color-red-60); }
59
+
60
+ /* Ratios. */
61
+ .oc-media-thumb--square { aspect-ratio: 1 / 1; }
62
+ .oc-media-thumb--portrait { aspect-ratio: 9 / 16; }
63
+
64
+ /* Already watched: the picture fades a bit. */
65
+ .oc-media-thumb.is-watched > :is(img, video, .oc-media-art) { opacity: 0.6; }
66
+
67
+ /* Gentle zoom on hover, only when motion is welcome. */
68
+ @media (prefers-reduced-motion: no-preference) {
69
+ .oc-media-thumb > :is(img, video, .oc-media-art) { transition: transform var(--oc-transition-normal); }
70
+ .oc-media-thumb:hover > :is(img, video, .oc-media-art) { transform: scale(1.04); }
71
+ }