@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,51 +1,51 @@
1
- <!-- OmniaUI component: emoji-picker — Compact popover grid of emoji buttons, anchored to its trigger. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/emoji-picker.html | Map: target field -> trigger -> popover (groups: label + grid of buttons) -> optional script
3
- Class API: button.oc-emoji-picker__trigger (popovertarget) · div.oc-emoji-picker[popover] (data-oc-emoji-target = selector of a field) >
4
- .oc-emoji-picker__label + .oc-emoji-picker__grid > button.oc-emoji-picker__item.
5
- Modifiers: .oc-emoji-picker--inline (always visible, no popover). Open / close / Esc / light dismiss: native popover.
6
- The optional script inserts the clicked emoji at the cursor of the target field and closes the panel.
7
- -->
8
- <div style="display:flex;gap:0.5rem;align-items:center">
9
- <input class="oc-input" id="oc-emoji-field" placeholder="Say something nice" style="inline-size:16rem">
10
- <button type="button" class="oc-emoji-picker__trigger" popovertarget="oc-emoji-demo" aria-label="Insert emoji">&#128578;</button>
11
- </div>
12
- <div class="oc-emoji-picker" id="oc-emoji-demo" popover data-oc-emoji-target="#oc-emoji-field" aria-label="Emoji">
13
- <p class="oc-emoji-picker__label">Smileys</p>
14
- <div class="oc-emoji-picker__grid">
15
- <button type="button" class="oc-emoji-picker__item">&#128512;</button><button type="button" class="oc-emoji-picker__item">&#128515;</button>
16
- <button type="button" class="oc-emoji-picker__item">&#128516;</button><button type="button" class="oc-emoji-picker__item">&#128513;</button>
17
- <button type="button" class="oc-emoji-picker__item">&#128514;</button><button type="button" class="oc-emoji-picker__item">&#128578;</button>
18
- <button type="button" class="oc-emoji-picker__item">&#128521;</button><button type="button" class="oc-emoji-picker__item">&#128525;</button>
19
- <button type="button" class="oc-emoji-picker__item">&#129300;</button><button type="button" class="oc-emoji-picker__item">&#128526;</button>
20
- <button type="button" class="oc-emoji-picker__item">&#128546;</button><button type="button" class="oc-emoji-picker__item">&#128564;</button>
21
- <button type="button" class="oc-emoji-picker__item">&#128559;</button><button type="button" class="oc-emoji-picker__item">&#129395;</button>
22
- <button type="button" class="oc-emoji-picker__item">&#128548;</button><button type="button" class="oc-emoji-picker__item">&#129303;</button>
23
- </div>
24
- <p class="oc-emoji-picker__label">Gestures</p>
25
- <div class="oc-emoji-picker__grid">
26
- <button type="button" class="oc-emoji-picker__item">&#128077;</button><button type="button" class="oc-emoji-picker__item">&#128078;</button>
27
- <button type="button" class="oc-emoji-picker__item">&#128079;</button><button type="button" class="oc-emoji-picker__item">&#128588;</button>
28
- <button type="button" class="oc-emoji-picker__item">&#128075;</button><button type="button" class="oc-emoji-picker__item">&#128591;</button>
29
- <button type="button" class="oc-emoji-picker__item">&#9996;&#65039;</button><button type="button" class="oc-emoji-picker__item">&#128170;</button>
30
- </div>
31
- <p class="oc-emoji-picker__label">Objects</p>
32
- <div class="oc-emoji-picker__grid">
33
- <button type="button" class="oc-emoji-picker__item">&#10084;&#65039;</button><button type="button" class="oc-emoji-picker__item">&#11088;</button>
34
- <button type="button" class="oc-emoji-picker__item">&#128293;</button><button type="button" class="oc-emoji-picker__item">&#127881;</button>
35
- <button type="button" class="oc-emoji-picker__item">&#9989;</button><button type="button" class="oc-emoji-picker__item">&#128640;</button>
36
- <button type="button" class="oc-emoji-picker__item">&#128161;</button><button type="button" class="oc-emoji-picker__item">&#9749;</button>
37
- </div>
38
- </div>
39
- <script>
40
- // Optional: put the clicked emoji at the cursor of the field in data-oc-emoji-target, then close the picker.
41
- document.addEventListener("click", (e) => {
42
- const item = e.target.closest(".oc-emoji-picker__item");
43
- const picker = item?.closest(".oc-emoji-picker");
44
- const field = picker?.dataset.ocEmojiTarget && document.querySelector(picker.dataset.ocEmojiTarget);
45
- if (!field) return;
46
- field.setRangeText(item.textContent, field.selectionStart ?? field.value.length, field.selectionEnd ?? field.value.length, "end");
47
- field.dispatchEvent(new Event("input", { bubbles: true }));
48
- picker.hidePopover?.();
49
- field.focus();
50
- });
51
- </script>
1
+ <!-- OmniaUI component: emoji-picker — Compact popover grid of emoji buttons, anchored to its trigger. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/emoji-picker.html | Map: target field -> trigger -> popover (groups: label + grid of buttons) -> optional script
3
+ Class API: button.oc-emoji-picker__trigger (popovertarget) · div.oc-emoji-picker[popover] (data-oc-emoji-target = selector of a field) >
4
+ .oc-emoji-picker__label + .oc-emoji-picker__grid > button.oc-emoji-picker__item.
5
+ Modifiers: .oc-emoji-picker--inline (always visible, no popover). Open / close / Esc / light dismiss: native popover.
6
+ The optional script inserts the clicked emoji at the cursor of the target field and closes the panel.
7
+ -->
8
+ <div style="display:flex;gap:0.5rem;align-items:center">
9
+ <input class="oc-input" id="oc-emoji-field" placeholder="Say something nice" style="inline-size:16rem">
10
+ <button type="button" class="oc-emoji-picker__trigger" popovertarget="oc-emoji-demo" aria-label="Insert emoji">&#128578;</button>
11
+ </div>
12
+ <div class="oc-emoji-picker" id="oc-emoji-demo" popover data-oc-emoji-target="#oc-emoji-field" aria-label="Emoji">
13
+ <p class="oc-emoji-picker__label">Smileys</p>
14
+ <div class="oc-emoji-picker__grid">
15
+ <button type="button" class="oc-emoji-picker__item">&#128512;</button><button type="button" class="oc-emoji-picker__item">&#128515;</button>
16
+ <button type="button" class="oc-emoji-picker__item">&#128516;</button><button type="button" class="oc-emoji-picker__item">&#128513;</button>
17
+ <button type="button" class="oc-emoji-picker__item">&#128514;</button><button type="button" class="oc-emoji-picker__item">&#128578;</button>
18
+ <button type="button" class="oc-emoji-picker__item">&#128521;</button><button type="button" class="oc-emoji-picker__item">&#128525;</button>
19
+ <button type="button" class="oc-emoji-picker__item">&#129300;</button><button type="button" class="oc-emoji-picker__item">&#128526;</button>
20
+ <button type="button" class="oc-emoji-picker__item">&#128546;</button><button type="button" class="oc-emoji-picker__item">&#128564;</button>
21
+ <button type="button" class="oc-emoji-picker__item">&#128559;</button><button type="button" class="oc-emoji-picker__item">&#129395;</button>
22
+ <button type="button" class="oc-emoji-picker__item">&#128548;</button><button type="button" class="oc-emoji-picker__item">&#129303;</button>
23
+ </div>
24
+ <p class="oc-emoji-picker__label">Gestures</p>
25
+ <div class="oc-emoji-picker__grid">
26
+ <button type="button" class="oc-emoji-picker__item">&#128077;</button><button type="button" class="oc-emoji-picker__item">&#128078;</button>
27
+ <button type="button" class="oc-emoji-picker__item">&#128079;</button><button type="button" class="oc-emoji-picker__item">&#128588;</button>
28
+ <button type="button" class="oc-emoji-picker__item">&#128075;</button><button type="button" class="oc-emoji-picker__item">&#128591;</button>
29
+ <button type="button" class="oc-emoji-picker__item">&#9996;&#65039;</button><button type="button" class="oc-emoji-picker__item">&#128170;</button>
30
+ </div>
31
+ <p class="oc-emoji-picker__label">Objects</p>
32
+ <div class="oc-emoji-picker__grid">
33
+ <button type="button" class="oc-emoji-picker__item">&#10084;&#65039;</button><button type="button" class="oc-emoji-picker__item">&#11088;</button>
34
+ <button type="button" class="oc-emoji-picker__item">&#128293;</button><button type="button" class="oc-emoji-picker__item">&#127881;</button>
35
+ <button type="button" class="oc-emoji-picker__item">&#9989;</button><button type="button" class="oc-emoji-picker__item">&#128640;</button>
36
+ <button type="button" class="oc-emoji-picker__item">&#128161;</button><button type="button" class="oc-emoji-picker__item">&#9749;</button>
37
+ </div>
38
+ </div>
39
+ <script>
40
+ // Optional: put the clicked emoji at the cursor of the field in data-oc-emoji-target, then close the picker.
41
+ document.addEventListener("click", (e) => {
42
+ const item = e.target.closest(".oc-emoji-picker__item");
43
+ const picker = item?.closest(".oc-emoji-picker");
44
+ const field = picker?.dataset.ocEmojiTarget && document.querySelector(picker.dataset.ocEmojiTarget);
45
+ if (!field) return;
46
+ field.setRangeText(item.textContent, field.selectionStart ?? field.value.length, field.selectionEnd ?? field.value.length, "end");
47
+ field.dispatchEvent(new Event("input", { bubbles: true }));
48
+ picker.hidePopover?.();
49
+ field.focus();
50
+ });
51
+ </script>
@@ -1,17 +1,17 @@
1
- <!-- OmniaUI component: empty-state - Icon, title, text and actions for lists without data. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- .oc-empty: Centered column wrapper
4
- .oc-empty-icon: Round icon holder (glyph, emoji or inline SVG)
5
- .oc-empty-title: Heading
6
- .oc-empty-text: Explanation
7
- .oc-empty-actions: Row for buttons (optional)
8
- -->
9
- <div class="oc-empty">
10
- <span class="oc-empty-icon" aria-hidden="true">+</span>
11
- <h3 class="oc-empty-title">No contacts yet</h3>
12
- <p class="oc-empty-text">Add your first contact to start tracking conversations and invoices.</p>
13
- <div class="oc-empty-actions">
14
- <button class="oc-btn" type="button">New contact</button>
15
- <button class="oc-btn oc-btn--outline" type="button">Import</button>
16
- </div>
17
- </div>
1
+ <!-- OmniaUI component: empty-state - Icon, title, text and actions for lists without data. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ .oc-empty: Centered column wrapper
4
+ .oc-empty-icon: Round icon holder (glyph, emoji or inline SVG)
5
+ .oc-empty-title: Heading
6
+ .oc-empty-text: Explanation
7
+ .oc-empty-actions: Row for buttons (optional)
8
+ -->
9
+ <div class="oc-empty">
10
+ <span class="oc-empty-icon" aria-hidden="true">+</span>
11
+ <h3 class="oc-empty-title">No contacts yet</h3>
12
+ <p class="oc-empty-text">Add your first contact to start tracking conversations and invoices.</p>
13
+ <div class="oc-empty-actions">
14
+ <button class="oc-btn" type="button">New contact</button>
15
+ <button class="oc-btn oc-btn--outline" type="button">Import</button>
16
+ </div>
17
+ </div>
@@ -1,26 +1,26 @@
1
- <!-- OmniaUI component: entity-card — Framed media cell (image, glyph, icon) next to a detail column with facts. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/entity-card.html | Map: card -> grid (frame | body: eyebrow, title, description, facts) -> footer
3
- Class API: article.oc-entity-card > .oc-entity-card__grid > .oc-entity-card__frame (img / svg / .oc-entity-card__glyph;
4
- --contain keeps a margin) + .oc-entity-card__body (.oc-entity-card__eyebrow, h3.oc-entity-card__title,
5
- p.oc-entity-card__description, dl.oc-entity-card__facts) · .oc-entity-card__footer (tags, actions; optional).
6
- Modifiers: .oc-entity-card--stacked (frame on top), --sm. Stacks by itself in containers under 22rem. No JavaScript.
7
- -->
8
- <article class="oc-entity-card" style="max-inline-size:34rem">
9
- <div class="oc-entity-card__grid">
10
- <div class="oc-entity-card__frame"><span class="oc-entity-card__glyph" aria-hidden="true">&#9765;</span></div>
11
- <div class="oc-entity-card__body">
12
- <p class="oc-entity-card__eyebrow">Symbol · Ancient Egypt</p>
13
- <h3 class="oc-entity-card__title">Ankh</h3>
14
- <p class="oc-entity-card__description">The sign of life. Often held by gods in temple reliefs.</p>
15
- <dl class="oc-entity-card__facts">
16
- <dt>Code</dt><dd>S34</dd>
17
- <dt>Period</dt><dd>Early Dynastic onwards</dd>
18
- <dt>Reading</dt><dd>ʿnḫ</dd>
19
- </dl>
20
- </div>
21
- </div>
22
- <div class="oc-entity-card__footer">
23
- <span class="oc-badge oc-badge--secondary">Life</span>
24
- <span class="oc-badge oc-badge--secondary">Amulet</span>
25
- </div>
26
- </article>
1
+ <!-- OmniaUI component: entity-card — Framed media cell (image, glyph, icon) next to a detail column with facts. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/entity-card.html | Map: card -> grid (frame | body: eyebrow, title, description, facts) -> footer
3
+ Class API: article.oc-entity-card > .oc-entity-card__grid > .oc-entity-card__frame (img / svg / .oc-entity-card__glyph;
4
+ --contain keeps a margin) + .oc-entity-card__body (.oc-entity-card__eyebrow, h3.oc-entity-card__title,
5
+ p.oc-entity-card__description, dl.oc-entity-card__facts) · .oc-entity-card__footer (tags, actions; optional).
6
+ Modifiers: .oc-entity-card--stacked (frame on top), --sm. Stacks by itself in containers under 22rem. No JavaScript.
7
+ -->
8
+ <article class="oc-entity-card" style="max-inline-size:34rem">
9
+ <div class="oc-entity-card__grid">
10
+ <div class="oc-entity-card__frame"><span class="oc-entity-card__glyph" aria-hidden="true">&#9765;</span></div>
11
+ <div class="oc-entity-card__body">
12
+ <p class="oc-entity-card__eyebrow">Symbol · Ancient Egypt</p>
13
+ <h3 class="oc-entity-card__title">Ankh</h3>
14
+ <p class="oc-entity-card__description">The sign of life. Often held by gods in temple reliefs.</p>
15
+ <dl class="oc-entity-card__facts">
16
+ <dt>Code</dt><dd>S34</dd>
17
+ <dt>Period</dt><dd>Early Dynastic onwards</dd>
18
+ <dt>Reading</dt><dd>ʿnḫ</dd>
19
+ </dl>
20
+ </div>
21
+ </div>
22
+ <div class="oc-entity-card__footer">
23
+ <span class="oc-badge oc-badge--secondary">Life</span>
24
+ <span class="oc-badge oc-badge--secondary">Amulet</span>
25
+ </div>
26
+ </article>
@@ -1,26 +1,26 @@
1
- <!-- OmniaUI component: expandable-table - Table that shows the first rows, "Show more" reveals the rest (CSS only). Needs @birdycom/omniaui CSS.
2
- Class API: .oc-expandable-table (wrapper) · .oc-expandable-table__row-dimmed (last visible row, faded) · .oc-expandable-table__row-more (hidden rows) ·
3
- .oc-expandable-table__wrap (+ --full) holds the toggle · label.oc-expandable-table__trigger.oc-btn > input.oc-expandable-table__toggle + .__more / .__less
4
- Generic toggle button: label.oc-btn.oc-btn--toggle > input[type=checkbox] + .oc-btn-toggle__off / .oc-btn-toggle__on ; reveal area: .oc-showmore > .oc-showmore__extra
5
- -->
6
- <div class="oc-expandable-table">
7
- <table class="oc-table-ref">
8
- <thead><tr><th>Class</th><th>Description</th></tr></thead>
9
- <tbody>
10
- <tr><td><code>.oc-btn</code></td><td>Primary button</td></tr>
11
- <tr><td><code>.oc-btn--secondary</code></td><td>Quiet button</td></tr>
12
- <tr class="oc-expandable-table__row-dimmed"><td><code>.oc-btn--outline</code></td><td>Outlined button</td></tr>
13
- <tr class="oc-expandable-table__row-more"><td><code>.oc-btn--ghost</code></td><td>Frameless button</td></tr>
14
- <tr class="oc-expandable-table__row-more"><td><code>.oc-btn--link</code></td><td>Looks like a link</td></tr>
15
- </tbody>
16
- </table>
17
- <div class="oc-expandable-table__wrap oc-expandable-table__wrap--full">
18
- <label class="oc-btn oc-btn--secondary oc-expandable-table__trigger"><input type="checkbox" class="oc-expandable-table__toggle"><span class="oc-expandable-table__more">Show more</span><span class="oc-expandable-table__less">Show less</span></label>
19
- </div>
20
- </div>
21
-
22
- <div class="oc-showmore">
23
- <p>Short text that is always visible.</p>
24
- <p class="oc-showmore__extra">Extra text that appears after pressing the button.</p>
25
- <label class="oc-btn oc-btn--outline oc-btn--toggle"><input type="checkbox"><span class="oc-btn-toggle__off">Show more</span><span class="oc-btn-toggle__on">Show less</span></label>
26
- </div>
1
+ <!-- OmniaUI component: expandable-table - Table that shows the first rows, "Show more" reveals the rest (CSS only). Needs @birdycom/omniaui CSS.
2
+ Class API: .oc-expandable-table (wrapper) · .oc-expandable-table__row-dimmed (last visible row, faded) · .oc-expandable-table__row-more (hidden rows) ·
3
+ .oc-expandable-table__wrap (+ --full) holds the toggle · label.oc-expandable-table__trigger.oc-btn > input.oc-expandable-table__toggle + .__more / .__less
4
+ Generic toggle button: label.oc-btn.oc-btn--toggle > input[type=checkbox] + .oc-btn-toggle__off / .oc-btn-toggle__on ; reveal area: .oc-showmore > .oc-showmore__extra
5
+ -->
6
+ <div class="oc-expandable-table">
7
+ <table class="oc-table-ref">
8
+ <thead><tr><th>Class</th><th>Description</th></tr></thead>
9
+ <tbody>
10
+ <tr><td><code>.oc-btn</code></td><td>Primary button</td></tr>
11
+ <tr><td><code>.oc-btn--secondary</code></td><td>Quiet button</td></tr>
12
+ <tr class="oc-expandable-table__row-dimmed"><td><code>.oc-btn--outline</code></td><td>Outlined button</td></tr>
13
+ <tr class="oc-expandable-table__row-more"><td><code>.oc-btn--ghost</code></td><td>Frameless button</td></tr>
14
+ <tr class="oc-expandable-table__row-more"><td><code>.oc-btn--link</code></td><td>Looks like a link</td></tr>
15
+ </tbody>
16
+ </table>
17
+ <div class="oc-expandable-table__wrap oc-expandable-table__wrap--full">
18
+ <label class="oc-btn oc-btn--secondary oc-expandable-table__trigger"><input type="checkbox" class="oc-expandable-table__toggle"><span class="oc-expandable-table__more">Show more</span><span class="oc-expandable-table__less">Show less</span></label>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="oc-showmore">
23
+ <p>Short text that is always visible.</p>
24
+ <p class="oc-showmore__extra">Extra text that appears after pressing the button.</p>
25
+ <label class="oc-btn oc-btn--outline oc-btn--toggle"><input type="checkbox"><span class="oc-btn-toggle__off">Show more</span><span class="oc-btn-toggle__on">Show less</span></label>
26
+ </div>
@@ -1,14 +1,14 @@
1
- <!-- OmniaUI component: fact-list - Key / value product facts in a card, a variant of the definition list. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/fact-list.html | Map: dl.oc-fact-list -> div rows (dt label + dd value)
3
- Class API (modifiers are extra classes / attributes on the same element):
4
- .oc-fact-list: The dl (card with a line between rows)
5
- Modifiers: --plain (no card), --compact, --stacked (value below label), --accent (values in the accent)
6
- Rows: <div><dt>Label</dt><dd>Value</dd></div>
7
- Slots: rows (label + value)
8
- -->
9
- <dl class="oc-fact-list">
10
- <div><dt>Platform</dt><dd>Web, desktop</dd></div>
11
- <div><dt>Built with</dt><dd>PHP 8.4, MySQL</dd></div>
12
- <div><dt>License</dt><dd>Subscription</dd></div>
13
- <div><dt>Status</dt><dd>Live since 2021</dd></div>
14
- </dl>
1
+ <!-- OmniaUI component: fact-list - Key / value product facts in a card, a variant of the definition list. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/fact-list.html | Map: dl.oc-fact-list -> div rows (dt label + dd value)
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-fact-list: The dl (card with a line between rows)
5
+ Modifiers: --plain (no card), --compact, --stacked (value below label), --accent (values in the accent)
6
+ Rows: <div><dt>Label</dt><dd>Value</dd></div>
7
+ Slots: rows (label + value)
8
+ -->
9
+ <dl class="oc-fact-list">
10
+ <div><dt>Platform</dt><dd>Web, desktop</dd></div>
11
+ <div><dt>Built with</dt><dd>PHP 8.4, MySQL</dd></div>
12
+ <div><dt>License</dt><dd>Subscription</dd></div>
13
+ <div><dt>Status</dt><dd>Live since 2021</dd></div>
14
+ </dl>
@@ -1,30 +1,30 @@
1
- <!-- OmniaUI component: filter-counts - View filter tiles with counts (active / deleted / all) - no JavaScript. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/filter-counts.html | Map: group (fieldset) -> one tile per view (radio + value + label + hint)
3
- Class API (modifiers are extra classes / attributes on the same element):
4
- .oc-filter-counts: Group of tiles (a <fieldset> or role="radiogroup"). Modifier: --compact (inline pills "Active 12").
5
- .oc-filter-counts-item: Tile label around one radio. Tones: --success, --destructive, --muted (default primary).
6
- .oc-filter-counts-value: The count (big number)
7
- .oc-filter-counts-label: Name of the view
8
- .oc-filter-counts-hint: Short description (hidden in --compact)
9
- States: checked (accent border + background), :focus-visible (outline), disabled (faded)
10
- -->
11
- <fieldset class="oc-filter-counts" aria-label="Show transactions">
12
- <label class="oc-filter-counts-item oc-filter-counts-item--success">
13
- <input type="radio" name="view" value="active" checked>
14
- <span class="oc-filter-counts-value">128</span>
15
- <span class="oc-filter-counts-label">Active</span>
16
- <span class="oc-filter-counts-hint">Visible in reports</span>
17
- </label>
18
- <label class="oc-filter-counts-item oc-filter-counts-item--destructive">
19
- <input type="radio" name="view" value="deleted">
20
- <span class="oc-filter-counts-value">6</span>
21
- <span class="oc-filter-counts-label">Deleted</span>
22
- <span class="oc-filter-counts-hint">Can be restored</span>
23
- </label>
24
- <label class="oc-filter-counts-item">
25
- <input type="radio" name="view" value="all">
26
- <span class="oc-filter-counts-value">134</span>
27
- <span class="oc-filter-counts-label">All</span>
28
- <span class="oc-filter-counts-hint">Everything together</span>
29
- </label>
30
- </fieldset>
1
+ <!-- OmniaUI component: filter-counts - View filter tiles with counts (active / deleted / all) - no JavaScript. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/filter-counts.html | Map: group (fieldset) -> one tile per view (radio + value + label + hint)
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-filter-counts: Group of tiles (a <fieldset> or role="radiogroup"). Modifier: --compact (inline pills "Active 12").
5
+ .oc-filter-counts-item: Tile label around one radio. Tones: --success, --destructive, --muted (default primary).
6
+ .oc-filter-counts-value: The count (big number)
7
+ .oc-filter-counts-label: Name of the view
8
+ .oc-filter-counts-hint: Short description (hidden in --compact)
9
+ States: checked (accent border + background), :focus-visible (outline), disabled (faded)
10
+ -->
11
+ <fieldset class="oc-filter-counts" aria-label="Show transactions">
12
+ <label class="oc-filter-counts-item oc-filter-counts-item--success">
13
+ <input type="radio" name="view" value="active" checked>
14
+ <span class="oc-filter-counts-value">128</span>
15
+ <span class="oc-filter-counts-label">Active</span>
16
+ <span class="oc-filter-counts-hint">Visible in reports</span>
17
+ </label>
18
+ <label class="oc-filter-counts-item oc-filter-counts-item--destructive">
19
+ <input type="radio" name="view" value="deleted">
20
+ <span class="oc-filter-counts-value">6</span>
21
+ <span class="oc-filter-counts-label">Deleted</span>
22
+ <span class="oc-filter-counts-hint">Can be restored</span>
23
+ </label>
24
+ <label class="oc-filter-counts-item">
25
+ <input type="radio" name="view" value="all">
26
+ <span class="oc-filter-counts-value">134</span>
27
+ <span class="oc-filter-counts-label">All</span>
28
+ <span class="oc-filter-counts-hint">Everything together</span>
29
+ </label>
30
+ </fieldset>
@@ -1,22 +1,22 @@
1
- <!-- OmniaUI component: flip-card — 3D flip card (front / back) on a checkbox toggle or on hover and focus. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/flip-card.html | Map: card -> hidden checkbox -> inner -> front face (+ flip label) -> back face (+ flip label)
3
- Class API: .oc-flip-card > input.oc-flip-card__toggle[type=checkbox] (optional) + .oc-flip-card__inner >
4
- .oc-flip-card__face--front / --back (.oc-flip-card__title, .oc-flip-card__text, label.oc-flip-card__flip for the checkbox).
5
- Modifiers: .oc-flip-card--hover (flip on hover / focus; give the card tabindex="0"), .oc-flip-card--vertical.
6
- States: checkbox :checked or .is-flipped. Reduced motion: no 3D turn, the faces cross-fade. No JavaScript.
7
- -->
8
- <div class="oc-flip-card" style="max-inline-size:18rem">
9
- <input type="checkbox" class="oc-flip-card__toggle" id="oc-flip-demo">
10
- <div class="oc-flip-card__inner">
11
- <div class="oc-flip-card__face oc-flip-card__face--front">
12
- <p class="oc-flip-card__text">Translate</p>
13
- <h3 class="oc-flip-card__title">la mariposa</h3>
14
- <label class="oc-flip-card__flip" for="oc-flip-demo">Show answer</label>
15
- </div>
16
- <div class="oc-flip-card__face oc-flip-card__face--back">
17
- <p class="oc-flip-card__text">Spanish → English</p>
18
- <h3 class="oc-flip-card__title">the butterfly</h3>
19
- <label class="oc-flip-card__flip" for="oc-flip-demo">Back to question</label>
20
- </div>
21
- </div>
22
- </div>
1
+ <!-- OmniaUI component: flip-card — 3D flip card (front / back) on a checkbox toggle or on hover and focus. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/flip-card.html | Map: card -> hidden checkbox -> inner -> front face (+ flip label) -> back face (+ flip label)
3
+ Class API: .oc-flip-card > input.oc-flip-card__toggle[type=checkbox] (optional) + .oc-flip-card__inner >
4
+ .oc-flip-card__face--front / --back (.oc-flip-card__title, .oc-flip-card__text, label.oc-flip-card__flip for the checkbox).
5
+ Modifiers: .oc-flip-card--hover (flip on hover / focus; give the card tabindex="0"), .oc-flip-card--vertical.
6
+ States: checkbox :checked or .is-flipped. Reduced motion: no 3D turn, the faces cross-fade. No JavaScript.
7
+ -->
8
+ <div class="oc-flip-card" style="max-inline-size:18rem">
9
+ <input type="checkbox" class="oc-flip-card__toggle" id="oc-flip-demo">
10
+ <div class="oc-flip-card__inner">
11
+ <div class="oc-flip-card__face oc-flip-card__face--front">
12
+ <p class="oc-flip-card__text">Translate</p>
13
+ <h3 class="oc-flip-card__title">la mariposa</h3>
14
+ <label class="oc-flip-card__flip" for="oc-flip-demo">Show answer</label>
15
+ </div>
16
+ <div class="oc-flip-card__face oc-flip-card__face--back">
17
+ <p class="oc-flip-card__text">Spanish → English</p>
18
+ <h3 class="oc-flip-card__title">the butterfly</h3>
19
+ <label class="oc-flip-card__flip" for="oc-flip-demo">Back to question</label>
20
+ </div>
21
+ </div>
22
+ </div>
@@ -1,6 +1,6 @@
1
- <!-- OmniaUI component: form-field — Form field with label, description and error. Needs @birdycom/omniaui CSS. -->
2
- <div class="oc-field">
3
- <label class="oc-field-label" for="email">Email</label>
4
- <input class="oc-input" id="email" type="email" placeholder="you@example.com" aria-describedby="email-help">
5
- <p class="oc-field-description" id="email-help">We never share your email.</p>
6
- </div>
1
+ <!-- OmniaUI component: form-field — Form field with label, description and error. Needs @birdycom/omniaui CSS. -->
2
+ <div class="oc-field">
3
+ <label class="oc-field-label" for="email">Email</label>
4
+ <input class="oc-input" id="email" type="email" placeholder="you@example.com" aria-describedby="email-help">
5
+ <p class="oc-field-description" id="email-help">We never share your email.</p>
6
+ </div>
@@ -1,22 +1,22 @@
1
- <!-- OmniaUI component: greeting - Dashboard header with a time-of-day greeting, the date and actions. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/greeting.html | Map: header -> icon tile -> body (eyebrow, title with name, date) -> actions
3
- Class API (modifiers are extra classes / attributes on the same element):
4
- .oc-greeting: Header row. Modifiers: --morning / --afternoon / --evening (tint, chosen by your app or wrapper), --lg.
5
- .oc-greeting-icon: Tinted icon tile (sun, moon)
6
- .oc-greeting-body / -eyebrow / -title / -name: Text column, small label, heading and the highlighted name
7
- time.oc-greeting-date: Today's date (datetime attribute)
8
- .oc-greeting-actions: Buttons at the end
9
- Slots: icon, eyebrow, title, date, actions
10
- -->
11
- <header class="oc-greeting oc-greeting--morning">
12
- <span class="oc-greeting-icon" aria-hidden="true"><svg class="" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg></span>
13
- <div class="oc-greeting-body">
14
- <p class="oc-greeting-eyebrow">Dashboard</p>
15
- <h1 class="oc-greeting-title">Good morning, <span class="oc-greeting-name">Ada</span></h1>
16
- <time class="oc-greeting-date" datetime="2026-10-15">Thursday 15 October 2026</time>
17
- </div>
18
- <div class="oc-greeting-actions">
19
- <a class="oc-btn oc-btn--outline oc-btn--sm" href="#">Agenda</a>
20
- <button class="oc-btn oc-btn--sm" type="button">New project</button>
21
- </div>
22
- </header>
1
+ <!-- OmniaUI component: greeting - Dashboard header with a time-of-day greeting, the date and actions. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/greeting.html | Map: header -> icon tile -> body (eyebrow, title with name, date) -> actions
3
+ Class API (modifiers are extra classes / attributes on the same element):
4
+ .oc-greeting: Header row. Modifiers: --morning / --afternoon / --evening (tint, chosen by your app or wrapper), --lg.
5
+ .oc-greeting-icon: Tinted icon tile (sun, moon)
6
+ .oc-greeting-body / -eyebrow / -title / -name: Text column, small label, heading and the highlighted name
7
+ time.oc-greeting-date: Today's date (datetime attribute)
8
+ .oc-greeting-actions: Buttons at the end
9
+ Slots: icon, eyebrow, title, date, actions
10
+ -->
11
+ <header class="oc-greeting oc-greeting--morning">
12
+ <span class="oc-greeting-icon" aria-hidden="true"><svg class="" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg></span>
13
+ <div class="oc-greeting-body">
14
+ <p class="oc-greeting-eyebrow">Dashboard</p>
15
+ <h1 class="oc-greeting-title">Good morning, <span class="oc-greeting-name">Ada</span></h1>
16
+ <time class="oc-greeting-date" datetime="2026-10-15">Thursday 15 October 2026</time>
17
+ </div>
18
+ <div class="oc-greeting-actions">
19
+ <a class="oc-btn oc-btn--outline oc-btn--sm" href="#">Agenda</a>
20
+ <button class="oc-btn oc-btn--sm" type="button">New project</button>
21
+ </div>
22
+ </header>
@@ -1,14 +1,14 @@
1
- <!-- OmniaUI component: heading - Page or section title with a muted description. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- .oc-heading: Wrapper (title + description). Modifier: --sm for a section heading.
4
- .oc-heading-title: Title (use h1-h3 as fits the outline)
5
- .oc-heading-description: Muted description (optional)
6
- -->
7
- <div class="oc-heading">
8
- <h2 class="oc-heading-title">Profile</h2>
9
- <p class="oc-heading-description">Update your name and e-mail address.</p>
10
- </div>
11
- <div class="oc-heading oc-heading--sm">
12
- <h3 class="oc-heading-title">Password</h3>
13
- <p class="oc-heading-description">Use a long, random password.</p>
14
- </div>
1
+ <!-- OmniaUI component: heading - Page or section title with a muted description. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ .oc-heading: Wrapper (title + description). Modifier: --sm for a section heading.
4
+ .oc-heading-title: Title (use h1-h3 as fits the outline)
5
+ .oc-heading-description: Muted description (optional)
6
+ -->
7
+ <div class="oc-heading">
8
+ <h2 class="oc-heading-title">Profile</h2>
9
+ <p class="oc-heading-description">Update your name and e-mail address.</p>
10
+ </div>
11
+ <div class="oc-heading oc-heading--sm">
12
+ <h3 class="oc-heading-title">Password</h3>
13
+ <p class="oc-heading-description">Use a long, random password.</p>
14
+ </div>
@@ -1,18 +1,18 @@
1
- <!-- OmniaUI component: hover-card - Hover card: preview on hover/focus via interestfor + popover, CSS hover fallback. Needs @birdycom/omniaui CSS.
2
- Class API (modifiers are extra classes / attributes on the same element):
3
- .oc-hover-card: inline wrapper (anchor scope)
4
- .oc-hover-card-trigger: the link/button (add interestfor="id" for the popover engine)
5
- .oc-hover-card-content: the card (id, popover, role="tooltip" or region). Sizes: --sm. Wrapper modifier: .oc-hover-card--top
6
- -->
7
- <span class="oc-hover-card">
8
- <a class="oc-hover-card-trigger" href="#omniacss" interestfor="oc-hc-demo">@omniacss</a>
9
- <div class="oc-hover-card-content" id="oc-hc-demo" popover>
10
- <div class="oc-item oc-item--sm" style="padding:0">
11
- <div class="oc-item-media oc-item-media--icon"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg></div>
12
- <div class="oc-item-content">
13
- <p class="oc-item-title">OmniaCSS</p>
14
- <p class="oc-item-description">CSS-first components and utilities. Light, dark and no build step.</p>
15
- </div>
16
- </div>
17
- </div>
18
- </span>
1
+ <!-- OmniaUI component: hover-card - Hover card: preview on hover/focus via interestfor + popover, CSS hover fallback. Needs @birdycom/omniaui CSS.
2
+ Class API (modifiers are extra classes / attributes on the same element):
3
+ .oc-hover-card: inline wrapper (anchor scope)
4
+ .oc-hover-card-trigger: the link/button (add interestfor="id" for the popover engine)
5
+ .oc-hover-card-content: the card (id, popover, role="tooltip" or region). Sizes: --sm. Wrapper modifier: .oc-hover-card--top
6
+ -->
7
+ <span class="oc-hover-card">
8
+ <a class="oc-hover-card-trigger" href="#omniacss" interestfor="oc-hc-demo">@omniacss</a>
9
+ <div class="oc-hover-card-content" id="oc-hc-demo" popover>
10
+ <div class="oc-item oc-item--sm" style="padding:0">
11
+ <div class="oc-item-media oc-item-media--icon"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg></div>
12
+ <div class="oc-item-content">
13
+ <p class="oc-item-title">OmniaCSS</p>
14
+ <p class="oc-item-description">CSS-first components and utilities. Light, dark and no build step.</p>
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </span>
@@ -1,30 +1,30 @@
1
- <!-- OmniaUI component: image-zoom — Zoom and pan viewport with CSS-only zoom levels. Needs @birdycom/omniaui CSS.
2
- File: packages/ui/snippets/image-zoom.html | Map: root -> toolbar (radio chips) -> viewport -> canvas (img)
3
- Class API: .oc-image-zoom > .oc-image-zoom__toolbar (.oc-image-zoom__label, label.oc-image-zoom__level > input[type=radio][value]) ·
4
- .oc-image-zoom__viewport (tabindex=0, scroll = pan) > .oc-image-zoom__canvas > img / svg / .oc-media-art.
5
- Zoom levels: radio values 1, 1.5, 2, 3, 4 (picked up with :has()), or a fixed class .oc-image-zoom--150 / --200 / --300,
6
- or style="--oc-zoom: 2.5". Ratio: 16 / 9 default, .oc-image-zoom--square / --photo or --oc-image-zoom-ratio.
7
- Pan: scrollbars, mouse wheel (Shift = sideways), touch drag, or arrow keys on the focused viewport. No JavaScript.
8
- -->
9
- <div class="oc-image-zoom">
10
- <div class="oc-image-zoom__toolbar" role="radiogroup" aria-label="Zoom level">
11
- <span class="oc-image-zoom__label">Zoom</span>
12
- <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="1" checked>100%</label>
13
- <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="1.5">150%</label>
14
- <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="2">200%</label>
15
- <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="3">300%</label>
16
- </div>
17
- <div class="oc-image-zoom__viewport" tabindex="0" role="region" aria-label="Harbour map, scroll to pan">
18
- <div class="oc-image-zoom__canvas">
19
- <div class="oc-media-art oc-media-art--2">
20
- <svg viewBox="0 0 160 90" role="img" aria-label="Harbour map" style="display:block;inline-size:100%;block-size:100%;color:var(--color-white-50)">
21
- <path d="M0 15H160M0 30H160M0 45H160M0 60H160M0 75H160M20 0V90M40 0V90M60 0V90M80 0V90M100 0V90M120 0V90M140 0V90" fill="none" stroke="currentColor" stroke-opacity=".35" stroke-width=".3"/>
22
- <path d="M10 70C40 50 60 80 90 55S140 30 150 20" fill="none" stroke="currentColor" stroke-width="1.2"/>
23
- <circle cx="90" cy="55" r="3" fill="currentColor"/>
24
- <text x="95" y="52" font-size="5" fill="currentColor">Harbour</text>
25
- <text x="12" y="76" font-size="2" fill="currentColor">Small print: zoom in to read this line.</text>
26
- </svg>
27
- </div>
28
- </div>
29
- </div>
30
- </div>
1
+ <!-- OmniaUI component: image-zoom — Zoom and pan viewport with CSS-only zoom levels. Needs @birdycom/omniaui CSS.
2
+ File: packages/ui/snippets/image-zoom.html | Map: root -> toolbar (radio chips) -> viewport -> canvas (img)
3
+ Class API: .oc-image-zoom > .oc-image-zoom__toolbar (.oc-image-zoom__label, label.oc-image-zoom__level > input[type=radio][value]) ·
4
+ .oc-image-zoom__viewport (tabindex=0, scroll = pan) > .oc-image-zoom__canvas > img / svg / .oc-media-art.
5
+ Zoom levels: radio values 1, 1.5, 2, 3, 4 (picked up with :has()), or a fixed class .oc-image-zoom--150 / --200 / --300,
6
+ or style="--oc-zoom: 2.5". Ratio: 16 / 9 default, .oc-image-zoom--square / --photo or --oc-image-zoom-ratio.
7
+ Pan: scrollbars, mouse wheel (Shift = sideways), touch drag, or arrow keys on the focused viewport. No JavaScript.
8
+ -->
9
+ <div class="oc-image-zoom">
10
+ <div class="oc-image-zoom__toolbar" role="radiogroup" aria-label="Zoom level">
11
+ <span class="oc-image-zoom__label">Zoom</span>
12
+ <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="1" checked>100%</label>
13
+ <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="1.5">150%</label>
14
+ <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="2">200%</label>
15
+ <label class="oc-image-zoom__level"><input type="radio" name="oc-zoom-demo" value="3">300%</label>
16
+ </div>
17
+ <div class="oc-image-zoom__viewport" tabindex="0" role="region" aria-label="Harbour map, scroll to pan">
18
+ <div class="oc-image-zoom__canvas">
19
+ <div class="oc-media-art oc-media-art--2">
20
+ <svg viewBox="0 0 160 90" role="img" aria-label="Harbour map" style="display:block;inline-size:100%;block-size:100%;color:var(--color-white-50)">
21
+ <path d="M0 15H160M0 30H160M0 45H160M0 60H160M0 75H160M20 0V90M40 0V90M60 0V90M80 0V90M100 0V90M120 0V90M140 0V90" fill="none" stroke="currentColor" stroke-opacity=".35" stroke-width=".3"/>
22
+ <path d="M10 70C40 50 60 80 90 55S140 30 150 20" fill="none" stroke="currentColor" stroke-width="1.2"/>
23
+ <circle cx="90" cy="55" r="3" fill="currentColor"/>
24
+ <text x="95" y="52" font-size="5" fill="currentColor">Harbour</text>
25
+ <text x="12" y="76" font-size="2" fill="currentColor">Small print: zoom in to read this line.</text>
26
+ </svg>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>