@birdycom/omniaui 0.11.0 → 0.11.2

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 +6565 -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 +410 -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,73 +1,73 @@
1
- /* File: packages/ui/src/parts/media-browser-frame.css | Map: frame -> chrome bar (dots, address pill, actions)
2
- -> view (screenshot slot, ratio) -> caption -> minimal / dark / tilt modifiers -> motion
3
- Browser frame: fake browser chrome around a screenshot or any live content (portfolio, product shots). */
4
-
5
- .oc-browser-frame {
6
- --oc-browser-frame-ratio: 16 / 10;
7
- display: grid;
8
- inline-size: 100%;
9
- margin: 0;
10
- overflow: hidden;
11
- border: 1px solid var(--oc-border);
12
- border-radius: calc(var(--oc-radius) + 4px);
13
- background: var(--oc-card);
14
- color: var(--oc-foreground);
15
- box-shadow: 0 30px 60px -30px oklch(from var(--color-black-60) l c h / 0.45);
16
- }
17
-
18
- /* ---- Chrome bar ---- */
19
- .oc-browser-frame__bar {
20
- display: flex;
21
- align-items: center;
22
- gap: 0.45rem;
23
- padding: 0.55rem 0.8rem;
24
- border-block-end: 1px solid var(--oc-border);
25
- background: var(--oc-muted);
26
- }
27
- .oc-browser-frame__bar > i { flex: none; inline-size: 0.65rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-red-50); }
28
- .oc-browser-frame__bar > i:nth-of-type(2) { background: var(--color-orange-60); }
29
- .oc-browser-frame__bar > i:nth-of-type(3) { background: var(--color-green-20); }
30
-
31
- /* Address pill with a lock; the text is cut off with "…" when the frame is narrow. */
32
- .oc-browser-frame__address {
33
- flex: 1;
34
- min-inline-size: 0;
35
- max-inline-size: 28rem;
36
- margin-inline: auto;
37
- padding: 0.2rem 0.75rem;
38
- overflow: hidden;
39
- border-radius: 999px;
40
- background: var(--oc-card);
41
- color: var(--oc-muted-foreground);
42
- font-size: 0.75rem;
43
- text-align: center;
44
- text-overflow: ellipsis;
45
- white-space: nowrap;
46
- }
47
- .oc-browser-frame__address::before { content: "\1F512\FE0E" / ""; margin-inline-end: 0.35rem; font-size: 0.65rem; opacity: 0.7; }
48
- /* Balance the dots on the left so the address stays centered. */
49
- .oc-browser-frame__actions { display: flex; gap: 0.35rem; min-inline-size: 2.4rem; justify-content: flex-end; color: var(--oc-muted-foreground); font-size: 0.8rem; }
50
-
51
- /* ---- View: the screenshot (or any content) ---- */
52
- .oc-browser-frame__view { position: relative; aspect-ratio: var(--oc-browser-frame-ratio); overflow: hidden; background: var(--oc-background); }
53
- .oc-browser-frame__view > :is(img, video, iframe, .oc-media-art) { display: block; inline-size: 100%; block-size: 100%; border: 0; object-fit: cover; object-position: top; }
54
- /* Free height: the content decides (live HTML inside the frame). */
55
- .oc-browser-frame--auto .oc-browser-frame__view { aspect-ratio: auto; }
56
-
57
- .oc-browser-frame__caption { padding: 0.6rem 0.9rem; border-block-start: 1px solid var(--oc-border); font-size: 0.8125rem; color: var(--oc-muted-foreground); }
58
-
59
- /* ---- Modifiers ---- */
60
- .oc-browser-frame--minimal .oc-browser-frame__address,
61
- .oc-browser-frame--minimal .oc-browser-frame__actions { display: none; }
62
- /* Dark chrome in both themes (light-dark() tokens resolve to their dark side). */
63
- .oc-browser-frame--dark { color-scheme: dark; }
64
-
65
- /* Tilt: a slight 3D angle that straightens on hover / focus. Static with reduced motion. */
66
- .oc-browser-frame--tilt { transform: perspective(80rem) rotateX(6deg) rotateY(-8deg); transform-origin: center; }
67
- @media (prefers-reduced-motion: no-preference) {
68
- .oc-browser-frame--tilt { transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
69
- .oc-browser-frame--tilt:is(:hover, :focus-within) { transform: none; }
70
- }
71
- @media (prefers-reduced-motion: reduce) {
72
- .oc-browser-frame--tilt { transform: none; }
73
- }
1
+ /* File: packages/ui/src/parts/media-browser-frame.css | Map: frame -> chrome bar (dots, address pill, actions)
2
+ -> view (screenshot slot, ratio) -> caption -> minimal / dark / tilt modifiers -> motion
3
+ Browser frame: fake browser chrome around a screenshot or any live content (portfolio, product shots). */
4
+
5
+ .oc-browser-frame {
6
+ --oc-browser-frame-ratio: 16 / 10;
7
+ display: grid;
8
+ inline-size: 100%;
9
+ margin: 0;
10
+ overflow: hidden;
11
+ border: 1px solid var(--oc-border);
12
+ border-radius: calc(var(--oc-radius) + 4px);
13
+ background: var(--oc-card);
14
+ color: var(--oc-foreground);
15
+ box-shadow: 0 30px 60px -30px oklch(from var(--color-black-60) l c h / 0.45);
16
+ }
17
+
18
+ /* ---- Chrome bar ---- */
19
+ .oc-browser-frame__bar {
20
+ display: flex;
21
+ align-items: center;
22
+ gap: 0.45rem;
23
+ padding: 0.55rem 0.8rem;
24
+ border-block-end: 1px solid var(--oc-border);
25
+ background: var(--oc-muted);
26
+ }
27
+ .oc-browser-frame__bar > i { flex: none; inline-size: 0.65rem; aspect-ratio: 1; border-radius: 50%; background: var(--color-red-50); }
28
+ .oc-browser-frame__bar > i:nth-of-type(2) { background: var(--color-orange-60); }
29
+ .oc-browser-frame__bar > i:nth-of-type(3) { background: var(--color-green-20); }
30
+
31
+ /* Address pill with a lock; the text is cut off with "…" when the frame is narrow. */
32
+ .oc-browser-frame__address {
33
+ flex: 1;
34
+ min-inline-size: 0;
35
+ max-inline-size: 28rem;
36
+ margin-inline: auto;
37
+ padding: 0.2rem 0.75rem;
38
+ overflow: hidden;
39
+ border-radius: 999px;
40
+ background: var(--oc-card);
41
+ color: var(--oc-muted-foreground);
42
+ font-size: 0.75rem;
43
+ text-align: center;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ }
47
+ .oc-browser-frame__address::before { content: "\1F512\FE0E" / ""; margin-inline-end: 0.35rem; font-size: 0.65rem; opacity: 0.7; }
48
+ /* Balance the dots on the left so the address stays centered. */
49
+ .oc-browser-frame__actions { display: flex; gap: 0.35rem; min-inline-size: 2.4rem; justify-content: flex-end; color: var(--oc-muted-foreground); font-size: 0.8rem; }
50
+
51
+ /* ---- View: the screenshot (or any content) ---- */
52
+ .oc-browser-frame__view { position: relative; aspect-ratio: var(--oc-browser-frame-ratio); overflow: hidden; background: var(--oc-background); }
53
+ .oc-browser-frame__view > :is(img, video, iframe, .oc-media-art) { display: block; inline-size: 100%; block-size: 100%; border: 0; object-fit: cover; object-position: top; }
54
+ /* Free height: the content decides (live HTML inside the frame). */
55
+ .oc-browser-frame--auto .oc-browser-frame__view { aspect-ratio: auto; }
56
+
57
+ .oc-browser-frame__caption { padding: 0.6rem 0.9rem; border-block-start: 1px solid var(--oc-border); font-size: 0.8125rem; color: var(--oc-muted-foreground); }
58
+
59
+ /* ---- Modifiers ---- */
60
+ .oc-browser-frame--minimal .oc-browser-frame__address,
61
+ .oc-browser-frame--minimal .oc-browser-frame__actions { display: none; }
62
+ /* Dark chrome in both themes (light-dark() tokens resolve to their dark side). */
63
+ .oc-browser-frame--dark { color-scheme: dark; }
64
+
65
+ /* Tilt: a slight 3D angle that straightens on hover / focus. Static with reduced motion. */
66
+ .oc-browser-frame--tilt { transform: perspective(80rem) rotateX(6deg) rotateY(-8deg); transform-origin: center; }
67
+ @media (prefers-reduced-motion: no-preference) {
68
+ .oc-browser-frame--tilt { transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
69
+ .oc-browser-frame--tilt:is(:hover, :focus-within) { transform: none; }
70
+ }
71
+ @media (prefers-reduced-motion: reduce) {
72
+ .oc-browser-frame--tilt { transform: none; }
73
+ }
@@ -1,83 +1,83 @@
1
- /* File: packages/ui/src/parts/media-card.css | Map: card grid -> body row (avatar | text | menu) -> title (stretched link)
2
- -> meta -> menu button -> compact modifier -> hover
3
- Media card: a .oc-media-thumb on top, then avatar + title + meta + an overflow menu button.
4
- The title link stretches over the whole card (::after), the menu button sits above it. */
5
-
6
- .oc-media-card {
7
- position: relative;
8
- display: grid;
9
- gap: 0.75rem;
10
- align-content: start;
11
- inline-size: 100%;
12
- color: var(--oc-foreground);
13
- }
14
-
15
- /* Avatar | text | menu. */
16
- .oc-media-card__body { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.75rem; align-items: start; }
17
- .oc-media-card__body:not(:has(.oc-media-card__avatar)) { grid-template-columns: minmax(0, 1fr) auto; }
18
-
19
- .oc-media-card__avatar {
20
- display: grid;
21
- place-items: center;
22
- inline-size: 2.25rem;
23
- aspect-ratio: 1;
24
- overflow: hidden;
25
- border-radius: 50%;
26
- background: var(--oc-muted);
27
- color: var(--oc-foreground);
28
- font-size: 0.8rem;
29
- font-weight: 600;
30
- }
31
- .oc-media-card__avatar > * { inline-size: 100%; block-size: 100%; object-fit: cover; }
32
-
33
- .oc-media-card__text { display: grid; gap: 0.2rem; min-inline-size: 0; }
34
-
35
- /* Two lines max, then "…". */
36
- .oc-media-card__title {
37
- margin: 0;
38
- font-size: 0.95rem;
39
- font-weight: 600;
40
- line-height: 1.35;
41
- display: -webkit-box;
42
- -webkit-box-orient: vertical;
43
- -webkit-line-clamp: 2;
44
- line-clamp: 2;
45
- overflow: hidden;
46
- }
47
- .oc-media-card__title > a { color: inherit; text-decoration: none; }
48
- .oc-media-card__title > a::after { content: ""; position: absolute; inset: 0; border-radius: var(--oc-radius); }
49
- .oc-media-card__title > a:focus-visible { outline: none; }
50
- .oc-media-card__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 4px; }
51
-
52
- .oc-media-card__meta { margin: 0; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
53
- .oc-media-card__meta > a { position: relative; z-index: 1; color: inherit; text-decoration: none; }
54
- .oc-media-card__meta > a:hover { color: var(--oc-foreground); }
55
-
56
- /* Overflow menu (⋮): above the stretched link, so it gets its own clicks. */
57
- .oc-media-card__menu {
58
- position: relative;
59
- z-index: 1;
60
- display: grid;
61
- place-items: center;
62
- inline-size: 2rem;
63
- aspect-ratio: 1;
64
- padding: 0;
65
- border: 0;
66
- border-radius: 50%;
67
- background: transparent;
68
- color: var(--oc-muted-foreground);
69
- font-size: 1.1rem;
70
- cursor: pointer;
71
- }
72
- .oc-media-card__menu:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
73
- .oc-media-card__menu:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
74
-
75
- /* Compact: smaller avatar and text, e.g. for a dense grid. */
76
- .oc-media-card--compact { gap: 0.5rem; }
77
- .oc-media-card--compact .oc-media-card__avatar { inline-size: 1.75rem; }
78
- .oc-media-card--compact .oc-media-card__title { font-size: 0.875rem; }
79
-
80
- /* Hovering the card zooms its thumb a little (the stretched link covers the thumb). */
81
- @media (prefers-reduced-motion: no-preference) {
82
- .oc-media-card:hover .oc-media-thumb > :is(img, video, .oc-media-art) { transform: scale(1.04); }
83
- }
1
+ /* File: packages/ui/src/parts/media-card.css | Map: card grid -> body row (avatar | text | menu) -> title (stretched link)
2
+ -> meta -> menu button -> compact modifier -> hover
3
+ Media card: a .oc-media-thumb on top, then avatar + title + meta + an overflow menu button.
4
+ The title link stretches over the whole card (::after), the menu button sits above it. */
5
+
6
+ .oc-media-card {
7
+ position: relative;
8
+ display: grid;
9
+ gap: 0.75rem;
10
+ align-content: start;
11
+ inline-size: 100%;
12
+ color: var(--oc-foreground);
13
+ }
14
+
15
+ /* Avatar | text | menu. */
16
+ .oc-media-card__body { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.75rem; align-items: start; }
17
+ .oc-media-card__body:not(:has(.oc-media-card__avatar)) { grid-template-columns: minmax(0, 1fr) auto; }
18
+
19
+ .oc-media-card__avatar {
20
+ display: grid;
21
+ place-items: center;
22
+ inline-size: 2.25rem;
23
+ aspect-ratio: 1;
24
+ overflow: hidden;
25
+ border-radius: 50%;
26
+ background: var(--oc-muted);
27
+ color: var(--oc-foreground);
28
+ font-size: 0.8rem;
29
+ font-weight: 600;
30
+ }
31
+ .oc-media-card__avatar > * { inline-size: 100%; block-size: 100%; object-fit: cover; }
32
+
33
+ .oc-media-card__text { display: grid; gap: 0.2rem; min-inline-size: 0; }
34
+
35
+ /* Two lines max, then "…". */
36
+ .oc-media-card__title {
37
+ margin: 0;
38
+ font-size: 0.95rem;
39
+ font-weight: 600;
40
+ line-height: 1.35;
41
+ display: -webkit-box;
42
+ -webkit-box-orient: vertical;
43
+ -webkit-line-clamp: 2;
44
+ line-clamp: 2;
45
+ overflow: hidden;
46
+ }
47
+ .oc-media-card__title > a { color: inherit; text-decoration: none; }
48
+ .oc-media-card__title > a::after { content: ""; position: absolute; inset: 0; border-radius: var(--oc-radius); }
49
+ .oc-media-card__title > a:focus-visible { outline: none; }
50
+ .oc-media-card__title > a:focus-visible::after { outline: 2px solid var(--oc-ring); outline-offset: 4px; }
51
+
52
+ .oc-media-card__meta { margin: 0; font-size: 0.8125rem; color: var(--oc-muted-foreground); }
53
+ .oc-media-card__meta > a { position: relative; z-index: 1; color: inherit; text-decoration: none; }
54
+ .oc-media-card__meta > a:hover { color: var(--oc-foreground); }
55
+
56
+ /* Overflow menu (⋮): above the stretched link, so it gets its own clicks. */
57
+ .oc-media-card__menu {
58
+ position: relative;
59
+ z-index: 1;
60
+ display: grid;
61
+ place-items: center;
62
+ inline-size: 2rem;
63
+ aspect-ratio: 1;
64
+ padding: 0;
65
+ border: 0;
66
+ border-radius: 50%;
67
+ background: transparent;
68
+ color: var(--oc-muted-foreground);
69
+ font-size: 1.1rem;
70
+ cursor: pointer;
71
+ }
72
+ .oc-media-card__menu:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
73
+ .oc-media-card__menu:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
74
+
75
+ /* Compact: smaller avatar and text, e.g. for a dense grid. */
76
+ .oc-media-card--compact { gap: 0.5rem; }
77
+ .oc-media-card--compact .oc-media-card__avatar { inline-size: 1.75rem; }
78
+ .oc-media-card--compact .oc-media-card__title { font-size: 0.875rem; }
79
+
80
+ /* Hovering the card zooms its thumb a little (the stretched link covers the thumb). */
81
+ @media (prefers-reduced-motion: no-preference) {
82
+ .oc-media-card:hover .oc-media-thumb > :is(img, video, .oc-media-art) { transform: scale(1.04); }
83
+ }
@@ -1,90 +1,90 @@
1
- /* File: packages/ui/src/parts/media-chat-composer.css | Map: frame (focus ring) -> textarea (grows with content)
2
- -> bar (tools | hint | send) -> tool buttons -> send button (disabled while empty) -> inline modifier
3
- Chat composer: a message field with a toolbar and a send button, in one rounded frame.
4
- The textarea grows with field-sizing; the send button looks disabled while the field is empty (:placeholder-shown). */
5
-
6
- .oc-chat-composer {
7
- display: grid;
8
- gap: 0.25rem;
9
- inline-size: 100%;
10
- padding: 0.5rem;
11
- border: 1px solid var(--oc-input);
12
- border-radius: calc(var(--oc-radius) + 6px);
13
- background: var(--oc-card);
14
- color: var(--oc-foreground);
15
- transition: border-color var(--oc-transition-fast), box-shadow var(--oc-transition-fast);
16
- }
17
- .oc-chat-composer:focus-within {
18
- border-color: var(--oc-ring);
19
- box-shadow: 0 0 0 3px color-mix(in oklch, var(--oc-ring) 20%, transparent);
20
- }
21
-
22
- /* The field itself has no frame: the composer is the frame. */
23
- .oc-chat-composer__input {
24
- inline-size: 100%;
25
- min-block-size: 2.5rem;
26
- max-block-size: 10rem;
27
- padding: 0.375rem 0.5rem;
28
- border: 0;
29
- outline: 0;
30
- resize: none;
31
- background: transparent;
32
- color: inherit;
33
- font: inherit;
34
- font-size: 0.9375rem;
35
- line-height: 1.5;
36
- field-sizing: content;
37
- }
38
- .oc-chat-composer__input::placeholder { color: var(--oc-muted-foreground); }
39
-
40
- /* Toolbar: tools left, hint in the middle, send right. */
41
- .oc-chat-composer__bar { display: flex; align-items: center; gap: 0.25rem; }
42
- .oc-chat-composer__tools { display: flex; align-items: center; gap: 0.125rem; }
43
- .oc-chat-composer__hint { margin-inline-start: auto; padding-inline: 0.5rem; font-size: 0.75rem; color: var(--oc-muted-foreground); }
44
-
45
- .oc-chat-composer__tool {
46
- display: inline-grid;
47
- place-items: center;
48
- inline-size: 2.25rem;
49
- aspect-ratio: 1;
50
- padding: 0;
51
- border: 0;
52
- border-radius: 50%;
53
- background: transparent;
54
- color: var(--oc-muted-foreground);
55
- font-size: 1.05rem;
56
- line-height: 1;
57
- cursor: pointer;
58
- }
59
- .oc-chat-composer__tool:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
60
- .oc-chat-composer__tool:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
61
-
62
- .oc-chat-composer__send {
63
- display: inline-grid;
64
- place-items: center;
65
- inline-size: 2.25rem;
66
- aspect-ratio: 1;
67
- margin-inline-start: auto;
68
- padding: 0;
69
- border: 0;
70
- border-radius: 50%;
71
- background: var(--oc-primary);
72
- color: var(--oc-primary-foreground);
73
- font-size: 1rem;
74
- cursor: pointer;
75
- transition: opacity var(--oc-transition-fast), transform var(--oc-transition-fast);
76
- }
77
- .oc-chat-composer__hint + .oc-chat-composer__send { margin-inline-start: 0; }
78
- .oc-chat-composer__send:hover { transform: scale(1.05); }
79
- .oc-chat-composer__send:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
80
- /* Empty field (placeholder visible) or a real disabled button: dimmed and not clickable. */
81
- .oc-chat-composer:has(.oc-chat-composer__input:placeholder-shown) .oc-chat-composer__send,
82
- .oc-chat-composer__send:disabled { opacity: 0.4; pointer-events: none; }
83
-
84
- /* Inline: one row — tools, field, send (for compact chat panels). */
85
- .oc-chat-composer--inline { grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; padding: 0.375rem; border-radius: 1.4rem; }
86
- .oc-chat-composer--inline .oc-chat-composer__bar { display: contents; }
87
- .oc-chat-composer--inline .oc-chat-composer__tools { grid-column: 1; grid-row: 1; }
88
- .oc-chat-composer--inline .oc-chat-composer__input { grid-column: 2; grid-row: 1; min-block-size: 2.25rem; padding-block: 0.4rem; }
89
- .oc-chat-composer--inline .oc-chat-composer__send { grid-column: 3; grid-row: 1; }
90
- .oc-chat-composer--inline .oc-chat-composer__hint { display: none; }
1
+ /* File: packages/ui/src/parts/media-chat-composer.css | Map: frame (focus ring) -> textarea (grows with content)
2
+ -> bar (tools | hint | send) -> tool buttons -> send button (disabled while empty) -> inline modifier
3
+ Chat composer: a message field with a toolbar and a send button, in one rounded frame.
4
+ The textarea grows with field-sizing; the send button looks disabled while the field is empty (:placeholder-shown). */
5
+
6
+ .oc-chat-composer {
7
+ display: grid;
8
+ gap: 0.25rem;
9
+ inline-size: 100%;
10
+ padding: 0.5rem;
11
+ border: 1px solid var(--oc-input);
12
+ border-radius: calc(var(--oc-radius) + 6px);
13
+ background: var(--oc-card);
14
+ color: var(--oc-foreground);
15
+ transition: border-color var(--oc-transition-fast), box-shadow var(--oc-transition-fast);
16
+ }
17
+ .oc-chat-composer:focus-within {
18
+ border-color: var(--oc-ring);
19
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--oc-ring) 20%, transparent);
20
+ }
21
+
22
+ /* The field itself has no frame: the composer is the frame. */
23
+ .oc-chat-composer__input {
24
+ inline-size: 100%;
25
+ min-block-size: 2.5rem;
26
+ max-block-size: 10rem;
27
+ padding: 0.375rem 0.5rem;
28
+ border: 0;
29
+ outline: 0;
30
+ resize: none;
31
+ background: transparent;
32
+ color: inherit;
33
+ font: inherit;
34
+ font-size: 0.9375rem;
35
+ line-height: 1.5;
36
+ field-sizing: content;
37
+ }
38
+ .oc-chat-composer__input::placeholder { color: var(--oc-muted-foreground); }
39
+
40
+ /* Toolbar: tools left, hint in the middle, send right. */
41
+ .oc-chat-composer__bar { display: flex; align-items: center; gap: 0.25rem; }
42
+ .oc-chat-composer__tools { display: flex; align-items: center; gap: 0.125rem; }
43
+ .oc-chat-composer__hint { margin-inline-start: auto; padding-inline: 0.5rem; font-size: 0.75rem; color: var(--oc-muted-foreground); }
44
+
45
+ .oc-chat-composer__tool {
46
+ display: inline-grid;
47
+ place-items: center;
48
+ inline-size: 2.25rem;
49
+ aspect-ratio: 1;
50
+ padding: 0;
51
+ border: 0;
52
+ border-radius: 50%;
53
+ background: transparent;
54
+ color: var(--oc-muted-foreground);
55
+ font-size: 1.05rem;
56
+ line-height: 1;
57
+ cursor: pointer;
58
+ }
59
+ .oc-chat-composer__tool:hover { background: var(--oc-surface-strong); color: var(--oc-foreground); }
60
+ .oc-chat-composer__tool:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
61
+
62
+ .oc-chat-composer__send {
63
+ display: inline-grid;
64
+ place-items: center;
65
+ inline-size: 2.25rem;
66
+ aspect-ratio: 1;
67
+ margin-inline-start: auto;
68
+ padding: 0;
69
+ border: 0;
70
+ border-radius: 50%;
71
+ background: var(--oc-primary);
72
+ color: var(--oc-primary-foreground);
73
+ font-size: 1rem;
74
+ cursor: pointer;
75
+ transition: opacity var(--oc-transition-fast), transform var(--oc-transition-fast);
76
+ }
77
+ .oc-chat-composer__hint + .oc-chat-composer__send { margin-inline-start: 0; }
78
+ .oc-chat-composer__send:hover { transform: scale(1.05); }
79
+ .oc-chat-composer__send:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
80
+ /* Empty field (placeholder visible) or a real disabled button: dimmed and not clickable. */
81
+ .oc-chat-composer:has(.oc-chat-composer__input:placeholder-shown) .oc-chat-composer__send,
82
+ .oc-chat-composer__send:disabled { opacity: 0.4; pointer-events: none; }
83
+
84
+ /* Inline: one row — tools, field, send (for compact chat panels). */
85
+ .oc-chat-composer--inline { grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; padding: 0.375rem; border-radius: 1.4rem; }
86
+ .oc-chat-composer--inline .oc-chat-composer__bar { display: contents; }
87
+ .oc-chat-composer--inline .oc-chat-composer__tools { grid-column: 1; grid-row: 1; }
88
+ .oc-chat-composer--inline .oc-chat-composer__input { grid-column: 2; grid-row: 1; min-block-size: 2.25rem; padding-block: 0.4rem; }
89
+ .oc-chat-composer--inline .oc-chat-composer__send { grid-column: 3; grid-row: 1; }
90
+ .oc-chat-composer--inline .oc-chat-composer__hint { display: none; }