@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.
- package/LICENSE +21 -21
- package/README.md +21 -21
- package/bin/lib/add.mjs +126 -126
- package/bin/lib/catalog.mjs +169 -169
- package/bin/lib/project.mjs +90 -90
- package/bin/omniaui.mjs +69 -69
- package/dist/code-block.css +25 -25
- package/dist/components-extra.css +916 -914
- package/dist/components.css +6559 -6469
- package/dist/components.min.css +1 -1
- package/dist/data-table.d.ts +9 -9
- package/dist/data-table.js +505 -505
- package/dist/docs-ui.css +267 -265
- package/dist/oc-theme.css +69 -69
- package/dist/parts/app-accordion-accent.css +60 -60
- package/dist/parts/app-alpha-tabs.css +68 -68
- package/dist/parts/app-busy-overlay.css +25 -25
- package/dist/parts/app-column-menu.css +85 -85
- package/dist/parts/app-confirm-dialog.css +70 -70
- package/dist/parts/app-cookie-consent.css +63 -63
- package/dist/parts/app-data-table.css +174 -174
- package/dist/parts/app-greeting.css +47 -47
- package/dist/parts/app-list-toolbar.css +81 -81
- package/dist/parts/app-page-header.css +54 -54
- package/dist/parts/app-severity-card.css +91 -91
- package/dist/parts/app-sidebar-dark.css +15 -15
- package/dist/parts/app-sortable-row.css +52 -52
- package/dist/parts/app-stat-card.css +68 -68
- package/dist/parts/app-table-actions.css +71 -71
- package/dist/parts/app-table-compact.css +54 -54
- package/dist/parts/app-top-progress.css +68 -68
- package/dist/parts/app-tree.css +104 -104
- package/dist/parts/app-upgrade-banner.css +90 -90
- package/dist/parts/app-version-banner.css +80 -80
- package/dist/parts/data-chart-line.css +167 -167
- package/dist/parts/forms-affix-input.css +75 -75
- package/dist/parts/forms-barcode-input.css +75 -75
- package/dist/parts/forms-chip-filter.css +91 -91
- package/dist/parts/forms-color-select.css +97 -89
- package/dist/parts/forms-decimal-input.css +51 -51
- package/dist/parts/forms-filter-counts.css +94 -94
- package/dist/parts/forms-language-select.css +89 -76
- package/dist/parts/forms-number-input.css +98 -95
- package/dist/parts/forms-password-requirements.css +55 -55
- package/dist/parts/forms-phone-input.css +85 -85
- package/dist/parts/forms-time-input.css +74 -74
- package/dist/parts/forms-toggle-field.css +69 -69
- package/dist/parts/media-art.css +21 -21
- package/dist/parts/media-attachment.css +160 -160
- package/dist/parts/media-browser-frame.css +73 -73
- package/dist/parts/media-card.css +83 -83
- package/dist/parts/media-chat-composer.css +90 -90
- package/dist/parts/media-doc-viewer.css +151 -151
- package/dist/parts/media-emoji-picker.css +88 -88
- package/dist/parts/media-entity-card.css +52 -52
- package/dist/parts/media-flip-card.css +78 -78
- package/dist/parts/media-image-zoom.css +68 -68
- package/dist/parts/media-lightbox.css +131 -131
- package/dist/parts/media-message-thread.css +136 -136
- package/dist/parts/media-message.css +160 -160
- package/dist/parts/media-row.css +78 -78
- package/dist/parts/media-stack-card.css +82 -82
- package/dist/parts/media-terminal-log.css +76 -76
- package/dist/parts/media-thumb.css +71 -71
- package/dist/parts/site-fact-list.css +25 -25
- package/dist/parts/site-link-arrow.css +34 -34
- package/dist/parts/site-marquee.css +34 -34
- package/dist/parts/site-next-teaser.css +75 -75
- package/dist/parts/site-price-card.css +91 -75
- package/dist/parts/site-product-mark.css +66 -66
- package/dist/parts/site-project-card.css +111 -111
- package/dist/parts/site-prose.css +124 -124
- package/dist/parts/site-stack-list.css +48 -48
- package/dist/parts/site-timeline.css +54 -54
- package/dist/showcase.css +404 -404
- package/package.json +69 -69
- package/snippets/accordion-accent.html +24 -24
- package/snippets/accordion.html +11 -11
- package/snippets/affix-input.html +30 -30
- package/snippets/alert-dialog.html +22 -22
- package/snippets/alert.html +5 -5
- package/snippets/alpha-tabs.html +37 -37
- package/snippets/aspect-ratio.html +15 -15
- package/snippets/attachment.html +43 -43
- package/snippets/avatar.html +6 -6
- package/snippets/back-link.html +5 -5
- package/snippets/badge.html +5 -5
- package/snippets/barcode-input.html +18 -18
- package/snippets/breadcrumb.html +6 -6
- package/snippets/browser-frame.html +18 -18
- package/snippets/busy-overlay.html +31 -31
- package/snippets/button-group.html +21 -21
- package/snippets/button.html +8 -8
- package/snippets/calendar.html +43 -43
- package/snippets/card.html +17 -17
- package/snippets/carousel.html +21 -21
- package/snippets/chart-line.html +46 -46
- package/snippets/chart.html +27 -27
- package/snippets/chat-composer.html +21 -21
- package/snippets/checkbox.html +5 -5
- package/snippets/checklist.html +23 -23
- package/snippets/chip-filter.html +14 -14
- package/snippets/code-window.html +20 -20
- package/snippets/collapsible.html +19 -19
- package/snippets/color-field.html +13 -13
- package/snippets/color-select.html +18 -18
- package/snippets/column-menu.html +38 -38
- package/snippets/combobox.html +19 -19
- package/snippets/command.html +24 -24
- package/snippets/confirm-dialog.html +32 -32
- package/snippets/context-menu.html +25 -25
- package/snippets/cookie-consent.html +70 -70
- package/snippets/copy-field.html +19 -19
- package/snippets/counter.html +2 -2
- package/snippets/data-table.html +151 -151
- package/snippets/date-picker.html +32 -32
- package/snippets/decimal-input.html +20 -20
- package/snippets/definition-list.html +20 -20
- package/snippets/demo-panel.html +18 -18
- package/snippets/doc-viewer.html +58 -58
- package/snippets/drawer.html +30 -30
- package/snippets/dropdown-menu.html +27 -27
- package/snippets/dropdown.html +9 -9
- package/snippets/dropzone.html +13 -13
- package/snippets/emoji-picker.html +51 -51
- package/snippets/empty-state.html +17 -17
- package/snippets/entity-card.html +26 -26
- package/snippets/expandable-table.html +26 -26
- package/snippets/fact-list.html +14 -14
- package/snippets/filter-counts.html +30 -30
- package/snippets/flip-card.html +22 -22
- package/snippets/form-field.html +6 -6
- package/snippets/greeting.html +22 -22
- package/snippets/heading.html +14 -14
- package/snippets/hover-card.html +18 -18
- package/snippets/image-zoom.html +30 -30
- package/snippets/input-group.html +10 -10
- package/snippets/input.html +5 -5
- package/snippets/item.html +26 -26
- package/snippets/kbd.html +13 -13
- package/snippets/label.html +9 -9
- package/snippets/language-select.html +26 -26
- package/snippets/launcher-card.html +14 -14
- package/snippets/lightbox.html +50 -50
- package/snippets/link-arrow.html +10 -10
- package/snippets/list-toolbar.html +33 -33
- package/snippets/marquee.html +15 -15
- package/snippets/media-card.html +28 -28
- package/snippets/media-row.html +21 -21
- package/snippets/media-thumb.html +12 -12
- package/snippets/menubar.html +30 -30
- package/snippets/message-thread.html +123 -123
- package/snippets/message.html +51 -51
- package/snippets/modal.html +15 -15
- package/snippets/native-select.html +15 -15
- package/snippets/navmenu.html +23 -23
- package/snippets/next-teaser.html +15 -15
- package/snippets/number-input.html +27 -27
- package/snippets/otp-input.html +9 -9
- package/snippets/page-header.html +24 -24
- package/snippets/pagination.html +6 -6
- package/snippets/password-input.html +24 -24
- package/snippets/password-requirements.html +30 -30
- package/snippets/phone-input.html +22 -22
- package/snippets/popover.html +15 -15
- package/snippets/price-card.html +34 -34
- package/snippets/product-mark.html +13 -13
- package/snippets/progress.html +4 -4
- package/snippets/project-card.html +23 -23
- package/snippets/prose.html +54 -54
- package/snippets/radio.html +17 -17
- package/snippets/recovery-codes.html +20 -20
- package/snippets/resizable.html +16 -16
- package/snippets/scroll-area.html +20 -20
- package/snippets/search.html +8 -8
- package/snippets/segmented.html +11 -11
- package/snippets/select.html +7 -7
- package/snippets/separator.html +15 -15
- package/snippets/severity-card.html +35 -35
- package/snippets/sheet.html +32 -32
- package/snippets/sidebar-docs.html +24 -24
- package/snippets/sidebar.html +55 -55
- package/snippets/site-footer.html +6 -6
- package/snippets/site-header.html +26 -26
- package/snippets/skeleton.html +4 -4
- package/snippets/slider.html +17 -17
- package/snippets/sortable-row.html +31 -31
- package/snippets/spinner.html +14 -14
- package/snippets/stack-card.html +17 -17
- package/snippets/stack-list.html +16 -16
- package/snippets/stat-card.html +24 -24
- package/snippets/stepper.html +13 -13
- package/snippets/switch.html +6 -6
- package/snippets/table-actions.html +39 -39
- package/snippets/table-compact.html +24 -24
- package/snippets/table.html +29 -29
- package/snippets/tabs.html +9 -9
- package/snippets/tag-input.html +60 -17
- package/snippets/terminal-log.html +23 -23
- package/snippets/textarea.html +3 -3
- package/snippets/theme-switch.html +6 -6
- package/snippets/time-input.html +26 -26
- package/snippets/timeline.html +28 -28
- package/snippets/toast-stack.html +10 -10
- package/snippets/toast.html +36 -36
- package/snippets/toc.html +13 -13
- package/snippets/toggle-field.html +20 -20
- package/snippets/toggle.html +22 -22
- package/snippets/tooltip.html +4 -4
- package/snippets/top-progress.html +12 -12
- package/snippets/tree.html +38 -38
- package/snippets/upgrade-banner.html +28 -28
- package/snippets/user.html +15 -15
- package/snippets/version-banner.html +15 -15
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
/* File: packages/ui/src/parts/forms-time-input.css
|
|
2
|
-
Map: 24h text field (HH:mm) -> invalid state -> slot list (radio chips) -> slot states -> --sm
|
|
3
|
-
Time input: a short text field with pattern="HH:mm" and a <datalist> of suggested slots,
|
|
4
|
-
plus an optional slot list (radio chips) to pick a time without typing. No JavaScript needed. */
|
|
5
|
-
|
|
6
|
-
/* Field: add next to .oc-input. Narrow, centered digits. */
|
|
7
|
-
.oc-time-input {
|
|
8
|
-
inline-size: 6.5rem;
|
|
9
|
-
text-align: center;
|
|
10
|
-
font-variant-numeric: tabular-nums;
|
|
11
|
-
letter-spacing: 0.04em;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/* Wrong format (e.g. 25:00) after the user typed: native pattern check. */
|
|
15
|
-
.oc-time-input:user-invalid { border-color: var(--oc-destructive); }
|
|
16
|
-
|
|
17
|
-
/* Slot list: a wrapping grid of radio chips (role="radiogroup"). */
|
|
18
|
-
.oc-time-slots {
|
|
19
|
-
display: grid;
|
|
20
|
-
grid-template-columns: repeat(auto-fill, minmax(4.25rem, 1fr));
|
|
21
|
-
gap: 0.375rem;
|
|
22
|
-
/* Fill the row (also inside flex parents) so auto-fill can create several columns. */
|
|
23
|
-
inline-size: 100%;
|
|
24
|
-
max-block-size: 12rem;
|
|
25
|
-
overflow-y: auto;
|
|
26
|
-
padding: 0.25rem;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* One slot: a label that wraps a hidden radio input. */
|
|
30
|
-
.oc-time-slot {
|
|
31
|
-
position: relative;
|
|
32
|
-
padding: 0.375rem 0.25rem;
|
|
33
|
-
border: 1px solid var(--oc-border);
|
|
34
|
-
border-radius: calc(var(--oc-radius) - 2px);
|
|
35
|
-
color: var(--oc-foreground);
|
|
36
|
-
font-size: 0.8rem;
|
|
37
|
-
font-variant-numeric: tabular-nums;
|
|
38
|
-
text-align: center;
|
|
39
|
-
cursor: pointer;
|
|
40
|
-
transition: background var(--oc-transition-fast), border-color var(--oc-transition-fast);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* The radio stays in the tab order (keyboard works) but is invisible. */
|
|
44
|
-
.oc-time-slot input {
|
|
45
|
-
position: absolute;
|
|
46
|
-
inset: 0;
|
|
47
|
-
margin: 0;
|
|
48
|
-
opacity: 0;
|
|
49
|
-
cursor: pointer;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.oc-time-slot:hover { background: var(--oc-surface); }
|
|
53
|
-
|
|
54
|
-
.oc-time-slot:has(input:checked) {
|
|
55
|
-
border-color: var(--oc-primary);
|
|
56
|
-
background: var(--oc-primary);
|
|
57
|
-
color: var(--oc-primary-foreground);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.oc-time-slot:has(input:focus-visible) {
|
|
61
|
-
outline: 2px solid var(--oc-ring);
|
|
62
|
-
outline-offset: 1px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* Booked / unavailable slot. */
|
|
66
|
-
.oc-time-slot:has(input:disabled) {
|
|
67
|
-
opacity: 0.45;
|
|
68
|
-
text-decoration: line-through;
|
|
69
|
-
cursor: not-allowed;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* Small slots for dense layouts. */
|
|
73
|
-
.oc-time-slots--sm { grid-template-columns: repeat(auto-fill, minmax(3.5rem, 1fr)); }
|
|
74
|
-
.oc-time-slots--sm .oc-time-slot { padding-block: 0.25rem; font-size: 0.72rem; }
|
|
1
|
+
/* File: packages/ui/src/parts/forms-time-input.css
|
|
2
|
+
Map: 24h text field (HH:mm) -> invalid state -> slot list (radio chips) -> slot states -> --sm
|
|
3
|
+
Time input: a short text field with pattern="HH:mm" and a <datalist> of suggested slots,
|
|
4
|
+
plus an optional slot list (radio chips) to pick a time without typing. No JavaScript needed. */
|
|
5
|
+
|
|
6
|
+
/* Field: add next to .oc-input. Narrow, centered digits. */
|
|
7
|
+
.oc-time-input {
|
|
8
|
+
inline-size: 6.5rem;
|
|
9
|
+
text-align: center;
|
|
10
|
+
font-variant-numeric: tabular-nums;
|
|
11
|
+
letter-spacing: 0.04em;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Wrong format (e.g. 25:00) after the user typed: native pattern check. */
|
|
15
|
+
.oc-time-input:user-invalid { border-color: var(--oc-destructive); }
|
|
16
|
+
|
|
17
|
+
/* Slot list: a wrapping grid of radio chips (role="radiogroup"). */
|
|
18
|
+
.oc-time-slots {
|
|
19
|
+
display: grid;
|
|
20
|
+
grid-template-columns: repeat(auto-fill, minmax(4.25rem, 1fr));
|
|
21
|
+
gap: 0.375rem;
|
|
22
|
+
/* Fill the row (also inside flex parents) so auto-fill can create several columns. */
|
|
23
|
+
inline-size: 100%;
|
|
24
|
+
max-block-size: 12rem;
|
|
25
|
+
overflow-y: auto;
|
|
26
|
+
padding: 0.25rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* One slot: a label that wraps a hidden radio input. */
|
|
30
|
+
.oc-time-slot {
|
|
31
|
+
position: relative;
|
|
32
|
+
padding: 0.375rem 0.25rem;
|
|
33
|
+
border: 1px solid var(--oc-border);
|
|
34
|
+
border-radius: calc(var(--oc-radius) - 2px);
|
|
35
|
+
color: var(--oc-foreground);
|
|
36
|
+
font-size: 0.8rem;
|
|
37
|
+
font-variant-numeric: tabular-nums;
|
|
38
|
+
text-align: center;
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
transition: background var(--oc-transition-fast), border-color var(--oc-transition-fast);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* The radio stays in the tab order (keyboard works) but is invisible. */
|
|
44
|
+
.oc-time-slot input {
|
|
45
|
+
position: absolute;
|
|
46
|
+
inset: 0;
|
|
47
|
+
margin: 0;
|
|
48
|
+
opacity: 0;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.oc-time-slot:hover { background: var(--oc-surface); }
|
|
53
|
+
|
|
54
|
+
.oc-time-slot:has(input:checked) {
|
|
55
|
+
border-color: var(--oc-primary);
|
|
56
|
+
background: var(--oc-primary);
|
|
57
|
+
color: var(--oc-primary-foreground);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.oc-time-slot:has(input:focus-visible) {
|
|
61
|
+
outline: 2px solid var(--oc-ring);
|
|
62
|
+
outline-offset: 1px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Booked / unavailable slot. */
|
|
66
|
+
.oc-time-slot:has(input:disabled) {
|
|
67
|
+
opacity: 0.45;
|
|
68
|
+
text-decoration: line-through;
|
|
69
|
+
cursor: not-allowed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Small slots for dense layouts. */
|
|
73
|
+
.oc-time-slots--sm { grid-template-columns: repeat(auto-fill, minmax(3.5rem, 1fr)); }
|
|
74
|
+
.oc-time-slots--sm .oc-time-slot { padding-block: 0.25rem; font-size: 0.72rem; }
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
/* File: packages/ui/src/parts/forms-toggle-field.css
|
|
2
|
-
Map: row (label wraps text + switch) -> text block (label + description) -> states -> --card / --reverse
|
|
3
|
-
Toggle field: a settings row with a title, a description and a switch.
|
|
4
|
-
The whole row is a <label>, so clicking the text flips the switch. The switch inside is a
|
|
5
|
-
<span class="oc-switch"> (a label inside a label is not valid HTML). */
|
|
6
|
-
|
|
7
|
-
/* Row: text on the left, switch on the right. */
|
|
8
|
-
.oc-toggle-field {
|
|
9
|
-
display: flex;
|
|
10
|
-
align-items: center;
|
|
11
|
-
justify-content: space-between;
|
|
12
|
-
gap: 1rem;
|
|
13
|
-
padding-block: 0.5rem;
|
|
14
|
-
cursor: pointer;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/* Text block. */
|
|
18
|
-
.oc-toggle-field-text {
|
|
19
|
-
display: grid;
|
|
20
|
-
gap: 0.125rem;
|
|
21
|
-
min-inline-size: 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.oc-toggle-field-label {
|
|
25
|
-
color: var(--oc-foreground);
|
|
26
|
-
font-size: 0.875rem;
|
|
27
|
-
font-weight: 500;
|
|
28
|
-
line-height: 1.3;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.oc-toggle-field-description {
|
|
32
|
-
color: var(--oc-muted-foreground);
|
|
33
|
-
font-size: 0.8rem;
|
|
34
|
-
line-height: 1.4;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Disabled switch: dim the row and show it can't be used. */
|
|
38
|
-
.oc-toggle-field:has(input:disabled) {
|
|
39
|
-
opacity: 0.55;
|
|
40
|
-
cursor: not-allowed;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.oc-toggle-field:has(input:disabled) .oc-switch { cursor: not-allowed; }
|
|
44
|
-
|
|
45
|
-
/* Card: bordered box; the border turns primary while the switch is on. */
|
|
46
|
-
.oc-toggle-field--card {
|
|
47
|
-
padding: 0.875rem 1rem;
|
|
48
|
-
border: 1px solid var(--oc-border);
|
|
49
|
-
border-radius: var(--oc-radius);
|
|
50
|
-
background: var(--oc-card);
|
|
51
|
-
transition: border-color var(--oc-transition-fast), background var(--oc-transition-fast);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.oc-toggle-field--card:hover { background: var(--oc-surface); }
|
|
55
|
-
|
|
56
|
-
.oc-toggle-field--card:has(input:checked) {
|
|
57
|
-
border-color: color-mix(in srgb, var(--oc-primary) 55%, var(--oc-border));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.oc-toggle-field--card:has(input:focus-visible) {
|
|
61
|
-
outline: 2px solid var(--oc-ring);
|
|
62
|
-
outline-offset: 2px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* Reverse: switch first, text after it. */
|
|
66
|
-
.oc-toggle-field--reverse {
|
|
67
|
-
flex-direction: row-reverse;
|
|
68
|
-
justify-content: flex-end;
|
|
69
|
-
}
|
|
1
|
+
/* File: packages/ui/src/parts/forms-toggle-field.css
|
|
2
|
+
Map: row (label wraps text + switch) -> text block (label + description) -> states -> --card / --reverse
|
|
3
|
+
Toggle field: a settings row with a title, a description and a switch.
|
|
4
|
+
The whole row is a <label>, so clicking the text flips the switch. The switch inside is a
|
|
5
|
+
<span class="oc-switch"> (a label inside a label is not valid HTML). */
|
|
6
|
+
|
|
7
|
+
/* Row: text on the left, switch on the right. */
|
|
8
|
+
.oc-toggle-field {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
gap: 1rem;
|
|
13
|
+
padding-block: 0.5rem;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Text block. */
|
|
18
|
+
.oc-toggle-field-text {
|
|
19
|
+
display: grid;
|
|
20
|
+
gap: 0.125rem;
|
|
21
|
+
min-inline-size: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.oc-toggle-field-label {
|
|
25
|
+
color: var(--oc-foreground);
|
|
26
|
+
font-size: 0.875rem;
|
|
27
|
+
font-weight: 500;
|
|
28
|
+
line-height: 1.3;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.oc-toggle-field-description {
|
|
32
|
+
color: var(--oc-muted-foreground);
|
|
33
|
+
font-size: 0.8rem;
|
|
34
|
+
line-height: 1.4;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Disabled switch: dim the row and show it can't be used. */
|
|
38
|
+
.oc-toggle-field:has(input:disabled) {
|
|
39
|
+
opacity: 0.55;
|
|
40
|
+
cursor: not-allowed;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.oc-toggle-field:has(input:disabled) .oc-switch { cursor: not-allowed; }
|
|
44
|
+
|
|
45
|
+
/* Card: bordered box; the border turns primary while the switch is on. */
|
|
46
|
+
.oc-toggle-field--card {
|
|
47
|
+
padding: 0.875rem 1rem;
|
|
48
|
+
border: 1px solid var(--oc-border);
|
|
49
|
+
border-radius: var(--oc-radius);
|
|
50
|
+
background: var(--oc-card);
|
|
51
|
+
transition: border-color var(--oc-transition-fast), background var(--oc-transition-fast);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.oc-toggle-field--card:hover { background: var(--oc-surface); }
|
|
55
|
+
|
|
56
|
+
.oc-toggle-field--card:has(input:checked) {
|
|
57
|
+
border-color: color-mix(in srgb, var(--oc-primary) 55%, var(--oc-border));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.oc-toggle-field--card:has(input:focus-visible) {
|
|
61
|
+
outline: 2px solid var(--oc-ring);
|
|
62
|
+
outline-offset: 2px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Reverse: switch first, text after it. */
|
|
66
|
+
.oc-toggle-field--reverse {
|
|
67
|
+
flex-direction: row-reverse;
|
|
68
|
+
justify-content: flex-end;
|
|
69
|
+
}
|
package/dist/parts/media-art.css
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/* File: packages/ui/src/parts/media-art.css | Map: base placeholder -> palette variants (--2 … --6)
|
|
2
|
-
Placeholder artwork for media demos: a soft palette gradient instead of an image file.
|
|
3
|
-
Use it wherever an <img> would go: <div class="oc-media-art oc-media-art--3" role="img" aria-label="…"></div>.
|
|
4
|
-
Only Omnia palette tokens, so no hex and no external image URLs. */
|
|
5
|
-
|
|
6
|
-
.oc-media-art {
|
|
7
|
-
display: block;
|
|
8
|
-
inline-size: 100%;
|
|
9
|
-
block-size: 100%;
|
|
10
|
-
/* Light spot top-left + diagonal gradient; the two colors come from the variant. */
|
|
11
|
-
background:
|
|
12
|
-
radial-gradient(circle at 28% 30%, oklch(from var(--color-white-50) l c h / 0.35), transparent 45%),
|
|
13
|
-
linear-gradient(135deg, var(--oc-media-art-from, var(--color-vividblue-60)), var(--oc-media-art-to, var(--color-purple-50)));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/* Variants: just another pair of palette colors. */
|
|
17
|
-
.oc-media-art--2 { --oc-media-art-from: var(--color-teal-50); --oc-media-art-to: var(--color-skycyan-50); }
|
|
18
|
-
.oc-media-art--3 { --oc-media-art-from: var(--color-orange-60); --oc-media-art-to: var(--color-red-50); }
|
|
19
|
-
.oc-media-art--4 { --oc-media-art-from: var(--color-green-40); --oc-media-art-to: var(--color-teal-70); }
|
|
20
|
-
.oc-media-art--5 { --oc-media-art-from: var(--color-magenta-50); --oc-media-art-to: var(--color-indigo-50); }
|
|
21
|
-
.oc-media-art--6 { --oc-media-art-from: var(--color-yellow-60); --oc-media-art-to: var(--color-peru-60); }
|
|
1
|
+
/* File: packages/ui/src/parts/media-art.css | Map: base placeholder -> palette variants (--2 … --6)
|
|
2
|
+
Placeholder artwork for media demos: a soft palette gradient instead of an image file.
|
|
3
|
+
Use it wherever an <img> would go: <div class="oc-media-art oc-media-art--3" role="img" aria-label="…"></div>.
|
|
4
|
+
Only Omnia palette tokens, so no hex and no external image URLs. */
|
|
5
|
+
|
|
6
|
+
.oc-media-art {
|
|
7
|
+
display: block;
|
|
8
|
+
inline-size: 100%;
|
|
9
|
+
block-size: 100%;
|
|
10
|
+
/* Light spot top-left + diagonal gradient; the two colors come from the variant. */
|
|
11
|
+
background:
|
|
12
|
+
radial-gradient(circle at 28% 30%, oklch(from var(--color-white-50) l c h / 0.35), transparent 45%),
|
|
13
|
+
linear-gradient(135deg, var(--oc-media-art-from, var(--color-vividblue-60)), var(--oc-media-art-to, var(--color-purple-50)));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Variants: just another pair of palette colors. */
|
|
17
|
+
.oc-media-art--2 { --oc-media-art-from: var(--color-teal-50); --oc-media-art-to: var(--color-skycyan-50); }
|
|
18
|
+
.oc-media-art--3 { --oc-media-art-from: var(--color-orange-60); --oc-media-art-to: var(--color-red-50); }
|
|
19
|
+
.oc-media-art--4 { --oc-media-art-from: var(--color-green-40); --oc-media-art-to: var(--color-teal-70); }
|
|
20
|
+
.oc-media-art--5 { --oc-media-art-from: var(--color-magenta-50); --oc-media-art-to: var(--color-indigo-50); }
|
|
21
|
+
.oc-media-art--6 { --oc-media-art-from: var(--color-yellow-60); --oc-media-art-to: var(--color-peru-60); }
|
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
/* File: packages/ui/src/parts/media-attachment.css | Map: list -> file chip (icon by type, name, size, open/remove) -> type tones
|
|
2
|
-
-> uploading progress + error -> image preview (in a message) -> thumbnail chip (in a composer) -> reduced motion
|
|
3
|
-
Attachment: a file chip or an image preview inside a chat message or a composer. The icon tile shows the extension and is
|
|
4
|
-
tinted per type (--pdf, --doc, --sheet, --zip, --image). Based on the attachment picker of the Korrekt question chat. */
|
|
5
|
-
|
|
6
|
-
.oc-attachment-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
|
|
7
|
-
.oc-attachment-list--stack { flex-direction: column; flex-wrap: nowrap; }
|
|
8
|
-
|
|
9
|
-
/* ---- File chip ---- */
|
|
10
|
-
.oc-attachment {
|
|
11
|
-
--oc-attachment-tone: var(--oc-muted-foreground);
|
|
12
|
-
position: relative;
|
|
13
|
-
display: flex;
|
|
14
|
-
align-items: center;
|
|
15
|
-
gap: 0.6rem;
|
|
16
|
-
min-inline-size: 0;
|
|
17
|
-
max-inline-size: 20rem;
|
|
18
|
-
padding: 0.4rem 0.5rem 0.4rem 0.4rem;
|
|
19
|
-
overflow: hidden;
|
|
20
|
-
border: 1px solid var(--oc-border);
|
|
21
|
-
border-radius: calc(var(--oc-radius) + 2px);
|
|
22
|
-
background: var(--oc-card);
|
|
23
|
-
color: var(--oc-foreground);
|
|
24
|
-
font-size: 0.8rem;
|
|
25
|
-
line-height: 1.3;
|
|
26
|
-
text-decoration: none;
|
|
27
|
-
transition: background var(--oc-transition-normal), border-color var(--oc-transition-normal);
|
|
28
|
-
}
|
|
29
|
-
.oc-attachment-list--stack > .oc-attachment,
|
|
30
|
-
.oc-attachment-list--stack > li > .oc-attachment { max-inline-size: none; }
|
|
31
|
-
a.oc-attachment:hover { border-color: var(--oc-border-strong, var(--oc-border)); background: var(--oc-surface-strong); }
|
|
32
|
-
a.oc-attachment:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
|
|
33
|
-
|
|
34
|
-
/* Icon tile: a page with a folded corner, the extension in the type tone */
|
|
35
|
-
.oc-attachment__icon {
|
|
36
|
-
flex: none;
|
|
37
|
-
display: grid;
|
|
38
|
-
place-items: end center;
|
|
39
|
-
inline-size: 2.1rem;
|
|
40
|
-
block-size: 2.5rem;
|
|
41
|
-
padding-block-end: 0.3rem;
|
|
42
|
-
overflow: hidden;
|
|
43
|
-
border-radius: 0.3rem;
|
|
44
|
-
background:
|
|
45
|
-
linear-gradient(225deg, color-mix(in oklch, var(--oc-attachment-tone) 35%, var(--oc-card)) 0.45rem, transparent 0.45rem),
|
|
46
|
-
color-mix(in oklch, var(--oc-attachment-tone) 14%, var(--oc-card));
|
|
47
|
-
color: var(--oc-attachment-tone);
|
|
48
|
-
font-size: 0.6rem;
|
|
49
|
-
font-weight: 750;
|
|
50
|
-
letter-spacing: 0.03em;
|
|
51
|
-
clip-path: polygon(0 0, calc(100% - 0.45rem) 0, 100% 0.45rem, 100% 100%, 0 100%);
|
|
52
|
-
}
|
|
53
|
-
.oc-attachment__icon:has(> :is(img, .oc-media-art)) { padding: 0; clip-path: none; }
|
|
54
|
-
.oc-attachment__icon > :is(img, .oc-media-art) { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
55
|
-
.oc-attachment__body { display: grid; flex: 1 1 auto; min-inline-size: 0; }
|
|
56
|
-
.oc-attachment__name { overflow: hidden; font-weight: 600; white-space: nowrap; text-overflow: ellipsis; }
|
|
57
|
-
.oc-attachment__size { color: var(--oc-muted-foreground); font-size: 0.72rem; font-variant-numeric: tabular-nums; }
|
|
58
|
-
|
|
59
|
-
.oc-attachment__remove {
|
|
60
|
-
position: relative;
|
|
61
|
-
z-index: 1;
|
|
62
|
-
flex: none;
|
|
63
|
-
display: grid;
|
|
64
|
-
place-items: center;
|
|
65
|
-
inline-size: 1.6rem;
|
|
66
|
-
block-size: 1.6rem;
|
|
67
|
-
padding: 0;
|
|
68
|
-
border: 0;
|
|
69
|
-
border-radius: 50%;
|
|
70
|
-
background: transparent;
|
|
71
|
-
color: var(--oc-muted-foreground);
|
|
72
|
-
font-size: 0.8rem;
|
|
73
|
-
cursor: pointer;
|
|
74
|
-
}
|
|
75
|
-
.oc-attachment__remove:hover { background: oklch(from var(--oc-destructive) l c h / 0.12); color: var(--oc-destructive); }
|
|
76
|
-
.oc-attachment__remove:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
|
|
77
|
-
|
|
78
|
-
/* ---- Type tones (theme tokens, so both color schemes stay readable) ---- */
|
|
79
|
-
.oc-attachment--pdf { --oc-attachment-tone: var(--oc-destructive); }
|
|
80
|
-
.oc-attachment--doc { --oc-attachment-tone: var(--oc-chart-1, var(--oc-primary)); }
|
|
81
|
-
.oc-attachment--sheet { --oc-attachment-tone: var(--oc-success); }
|
|
82
|
-
.oc-attachment--zip { --oc-attachment-tone: var(--oc-warning); }
|
|
83
|
-
.oc-attachment--image { --oc-attachment-tone: var(--oc-chart-4, var(--oc-primary)); }
|
|
84
|
-
|
|
85
|
-
/* ---- Upload state: a thin progress line along the bottom (--oc-attachment-progress) and an error state ---- */
|
|
86
|
-
.oc-attachment--uploading::after {
|
|
87
|
-
content: "";
|
|
88
|
-
position: absolute;
|
|
89
|
-
inset-inline-start: 0;
|
|
90
|
-
inset-block-end: 0;
|
|
91
|
-
inline-size: var(--oc-attachment-progress, 40%);
|
|
92
|
-
block-size: 3px;
|
|
93
|
-
background: var(--oc-primary);
|
|
94
|
-
transition: inline-size var(--oc-transition-normal);
|
|
95
|
-
}
|
|
96
|
-
.oc-attachment--uploading .oc-attachment__size { color: var(--oc-primary); }
|
|
97
|
-
.oc-attachment--error { border-color: oklch(from var(--oc-destructive) l c h / 0.55); }
|
|
98
|
-
.oc-attachment--error .oc-attachment__size { color: var(--oc-destructive); }
|
|
99
|
-
|
|
100
|
-
/* ---- Image preview inside a message: the picture with an optional caption ---- */
|
|
101
|
-
.oc-attachment-image {
|
|
102
|
-
position: relative;
|
|
103
|
-
display: block;
|
|
104
|
-
inline-size: min(100%, 18rem);
|
|
105
|
-
overflow: hidden;
|
|
106
|
-
border: 1px solid var(--oc-border);
|
|
107
|
-
border-radius: calc(var(--oc-radius) + 2px);
|
|
108
|
-
background: var(--oc-muted);
|
|
109
|
-
color: var(--color-white-50);
|
|
110
|
-
text-decoration: none;
|
|
111
|
-
}
|
|
112
|
-
.oc-attachment-image > :is(img, .oc-media-art) {
|
|
113
|
-
display: block;
|
|
114
|
-
inline-size: 100%;
|
|
115
|
-
block-size: auto;
|
|
116
|
-
max-block-size: 14rem;
|
|
117
|
-
aspect-ratio: 4 / 3;
|
|
118
|
-
object-fit: cover;
|
|
119
|
-
}
|
|
120
|
-
.oc-attachment-image__caption {
|
|
121
|
-
position: absolute;
|
|
122
|
-
inset: auto 0 0;
|
|
123
|
-
padding: 1.25rem 0.6rem 0.4rem;
|
|
124
|
-
overflow: hidden;
|
|
125
|
-
background: linear-gradient(transparent, oklch(from var(--color-black-60) l c h / 0.6));
|
|
126
|
-
font-size: 0.72rem;
|
|
127
|
-
font-weight: 600;
|
|
128
|
-
white-space: nowrap;
|
|
129
|
-
text-overflow: ellipsis;
|
|
130
|
-
}
|
|
131
|
-
a.oc-attachment-image:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
|
|
132
|
-
a.oc-attachment-image:hover > :is(img, .oc-media-art) { filter: brightness(1.05); }
|
|
133
|
-
|
|
134
|
-
/* ---- Thumbnail chip (pasted screenshot in a composer): square image with a remove button on top ---- */
|
|
135
|
-
.oc-attachment-thumb {
|
|
136
|
-
position: relative;
|
|
137
|
-
flex: none;
|
|
138
|
-
inline-size: 4rem;
|
|
139
|
-
block-size: 4rem;
|
|
140
|
-
overflow: hidden;
|
|
141
|
-
border: 1px solid var(--oc-border);
|
|
142
|
-
border-radius: calc(var(--oc-radius) + 2px);
|
|
143
|
-
background: var(--oc-muted);
|
|
144
|
-
}
|
|
145
|
-
.oc-attachment-thumb > :is(img, .oc-media-art) { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
146
|
-
.oc-attachment-thumb > .oc-attachment__remove {
|
|
147
|
-
position: absolute;
|
|
148
|
-
inset-block-start: 0.2rem;
|
|
149
|
-
inset-inline-end: 0.2rem;
|
|
150
|
-
inline-size: 1.35rem;
|
|
151
|
-
block-size: 1.35rem;
|
|
152
|
-
background: oklch(from var(--color-black-60) l c h / 0.6);
|
|
153
|
-
color: var(--color-white-50);
|
|
154
|
-
font-size: 0.65rem;
|
|
155
|
-
}
|
|
156
|
-
.oc-attachment-thumb > .oc-attachment__remove:hover { background: var(--oc-destructive); color: var(--color-white-50); }
|
|
157
|
-
|
|
158
|
-
@media (prefers-reduced-motion: reduce) {
|
|
159
|
-
.oc-attachment, .oc-attachment--uploading::after { transition: none; }
|
|
160
|
-
}
|
|
1
|
+
/* File: packages/ui/src/parts/media-attachment.css | Map: list -> file chip (icon by type, name, size, open/remove) -> type tones
|
|
2
|
+
-> uploading progress + error -> image preview (in a message) -> thumbnail chip (in a composer) -> reduced motion
|
|
3
|
+
Attachment: a file chip or an image preview inside a chat message or a composer. The icon tile shows the extension and is
|
|
4
|
+
tinted per type (--pdf, --doc, --sheet, --zip, --image). Based on the attachment picker of the Korrekt question chat. */
|
|
5
|
+
|
|
6
|
+
.oc-attachment-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
|
|
7
|
+
.oc-attachment-list--stack { flex-direction: column; flex-wrap: nowrap; }
|
|
8
|
+
|
|
9
|
+
/* ---- File chip ---- */
|
|
10
|
+
.oc-attachment {
|
|
11
|
+
--oc-attachment-tone: var(--oc-muted-foreground);
|
|
12
|
+
position: relative;
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
gap: 0.6rem;
|
|
16
|
+
min-inline-size: 0;
|
|
17
|
+
max-inline-size: 20rem;
|
|
18
|
+
padding: 0.4rem 0.5rem 0.4rem 0.4rem;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
border: 1px solid var(--oc-border);
|
|
21
|
+
border-radius: calc(var(--oc-radius) + 2px);
|
|
22
|
+
background: var(--oc-card);
|
|
23
|
+
color: var(--oc-foreground);
|
|
24
|
+
font-size: 0.8rem;
|
|
25
|
+
line-height: 1.3;
|
|
26
|
+
text-decoration: none;
|
|
27
|
+
transition: background var(--oc-transition-normal), border-color var(--oc-transition-normal);
|
|
28
|
+
}
|
|
29
|
+
.oc-attachment-list--stack > .oc-attachment,
|
|
30
|
+
.oc-attachment-list--stack > li > .oc-attachment { max-inline-size: none; }
|
|
31
|
+
a.oc-attachment:hover { border-color: var(--oc-border-strong, var(--oc-border)); background: var(--oc-surface-strong); }
|
|
32
|
+
a.oc-attachment:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
|
|
33
|
+
|
|
34
|
+
/* Icon tile: a page with a folded corner, the extension in the type tone */
|
|
35
|
+
.oc-attachment__icon {
|
|
36
|
+
flex: none;
|
|
37
|
+
display: grid;
|
|
38
|
+
place-items: end center;
|
|
39
|
+
inline-size: 2.1rem;
|
|
40
|
+
block-size: 2.5rem;
|
|
41
|
+
padding-block-end: 0.3rem;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
border-radius: 0.3rem;
|
|
44
|
+
background:
|
|
45
|
+
linear-gradient(225deg, color-mix(in oklch, var(--oc-attachment-tone) 35%, var(--oc-card)) 0.45rem, transparent 0.45rem),
|
|
46
|
+
color-mix(in oklch, var(--oc-attachment-tone) 14%, var(--oc-card));
|
|
47
|
+
color: var(--oc-attachment-tone);
|
|
48
|
+
font-size: 0.6rem;
|
|
49
|
+
font-weight: 750;
|
|
50
|
+
letter-spacing: 0.03em;
|
|
51
|
+
clip-path: polygon(0 0, calc(100% - 0.45rem) 0, 100% 0.45rem, 100% 100%, 0 100%);
|
|
52
|
+
}
|
|
53
|
+
.oc-attachment__icon:has(> :is(img, .oc-media-art)) { padding: 0; clip-path: none; }
|
|
54
|
+
.oc-attachment__icon > :is(img, .oc-media-art) { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
55
|
+
.oc-attachment__body { display: grid; flex: 1 1 auto; min-inline-size: 0; }
|
|
56
|
+
.oc-attachment__name { overflow: hidden; font-weight: 600; white-space: nowrap; text-overflow: ellipsis; }
|
|
57
|
+
.oc-attachment__size { color: var(--oc-muted-foreground); font-size: 0.72rem; font-variant-numeric: tabular-nums; }
|
|
58
|
+
|
|
59
|
+
.oc-attachment__remove {
|
|
60
|
+
position: relative;
|
|
61
|
+
z-index: 1;
|
|
62
|
+
flex: none;
|
|
63
|
+
display: grid;
|
|
64
|
+
place-items: center;
|
|
65
|
+
inline-size: 1.6rem;
|
|
66
|
+
block-size: 1.6rem;
|
|
67
|
+
padding: 0;
|
|
68
|
+
border: 0;
|
|
69
|
+
border-radius: 50%;
|
|
70
|
+
background: transparent;
|
|
71
|
+
color: var(--oc-muted-foreground);
|
|
72
|
+
font-size: 0.8rem;
|
|
73
|
+
cursor: pointer;
|
|
74
|
+
}
|
|
75
|
+
.oc-attachment__remove:hover { background: oklch(from var(--oc-destructive) l c h / 0.12); color: var(--oc-destructive); }
|
|
76
|
+
.oc-attachment__remove:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 1px; }
|
|
77
|
+
|
|
78
|
+
/* ---- Type tones (theme tokens, so both color schemes stay readable) ---- */
|
|
79
|
+
.oc-attachment--pdf { --oc-attachment-tone: var(--oc-destructive); }
|
|
80
|
+
.oc-attachment--doc { --oc-attachment-tone: var(--oc-chart-1, var(--oc-primary)); }
|
|
81
|
+
.oc-attachment--sheet { --oc-attachment-tone: var(--oc-success); }
|
|
82
|
+
.oc-attachment--zip { --oc-attachment-tone: var(--oc-warning); }
|
|
83
|
+
.oc-attachment--image { --oc-attachment-tone: var(--oc-chart-4, var(--oc-primary)); }
|
|
84
|
+
|
|
85
|
+
/* ---- Upload state: a thin progress line along the bottom (--oc-attachment-progress) and an error state ---- */
|
|
86
|
+
.oc-attachment--uploading::after {
|
|
87
|
+
content: "";
|
|
88
|
+
position: absolute;
|
|
89
|
+
inset-inline-start: 0;
|
|
90
|
+
inset-block-end: 0;
|
|
91
|
+
inline-size: var(--oc-attachment-progress, 40%);
|
|
92
|
+
block-size: 3px;
|
|
93
|
+
background: var(--oc-primary);
|
|
94
|
+
transition: inline-size var(--oc-transition-normal);
|
|
95
|
+
}
|
|
96
|
+
.oc-attachment--uploading .oc-attachment__size { color: var(--oc-primary); }
|
|
97
|
+
.oc-attachment--error { border-color: oklch(from var(--oc-destructive) l c h / 0.55); }
|
|
98
|
+
.oc-attachment--error .oc-attachment__size { color: var(--oc-destructive); }
|
|
99
|
+
|
|
100
|
+
/* ---- Image preview inside a message: the picture with an optional caption ---- */
|
|
101
|
+
.oc-attachment-image {
|
|
102
|
+
position: relative;
|
|
103
|
+
display: block;
|
|
104
|
+
inline-size: min(100%, 18rem);
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
border: 1px solid var(--oc-border);
|
|
107
|
+
border-radius: calc(var(--oc-radius) + 2px);
|
|
108
|
+
background: var(--oc-muted);
|
|
109
|
+
color: var(--color-white-50);
|
|
110
|
+
text-decoration: none;
|
|
111
|
+
}
|
|
112
|
+
.oc-attachment-image > :is(img, .oc-media-art) {
|
|
113
|
+
display: block;
|
|
114
|
+
inline-size: 100%;
|
|
115
|
+
block-size: auto;
|
|
116
|
+
max-block-size: 14rem;
|
|
117
|
+
aspect-ratio: 4 / 3;
|
|
118
|
+
object-fit: cover;
|
|
119
|
+
}
|
|
120
|
+
.oc-attachment-image__caption {
|
|
121
|
+
position: absolute;
|
|
122
|
+
inset: auto 0 0;
|
|
123
|
+
padding: 1.25rem 0.6rem 0.4rem;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
background: linear-gradient(transparent, oklch(from var(--color-black-60) l c h / 0.6));
|
|
126
|
+
font-size: 0.72rem;
|
|
127
|
+
font-weight: 600;
|
|
128
|
+
white-space: nowrap;
|
|
129
|
+
text-overflow: ellipsis;
|
|
130
|
+
}
|
|
131
|
+
a.oc-attachment-image:focus-visible { outline: 2px solid var(--oc-ring); outline-offset: 2px; }
|
|
132
|
+
a.oc-attachment-image:hover > :is(img, .oc-media-art) { filter: brightness(1.05); }
|
|
133
|
+
|
|
134
|
+
/* ---- Thumbnail chip (pasted screenshot in a composer): square image with a remove button on top ---- */
|
|
135
|
+
.oc-attachment-thumb {
|
|
136
|
+
position: relative;
|
|
137
|
+
flex: none;
|
|
138
|
+
inline-size: 4rem;
|
|
139
|
+
block-size: 4rem;
|
|
140
|
+
overflow: hidden;
|
|
141
|
+
border: 1px solid var(--oc-border);
|
|
142
|
+
border-radius: calc(var(--oc-radius) + 2px);
|
|
143
|
+
background: var(--oc-muted);
|
|
144
|
+
}
|
|
145
|
+
.oc-attachment-thumb > :is(img, .oc-media-art) { inline-size: 100%; block-size: 100%; object-fit: cover; }
|
|
146
|
+
.oc-attachment-thumb > .oc-attachment__remove {
|
|
147
|
+
position: absolute;
|
|
148
|
+
inset-block-start: 0.2rem;
|
|
149
|
+
inset-inline-end: 0.2rem;
|
|
150
|
+
inline-size: 1.35rem;
|
|
151
|
+
block-size: 1.35rem;
|
|
152
|
+
background: oklch(from var(--color-black-60) l c h / 0.6);
|
|
153
|
+
color: var(--color-white-50);
|
|
154
|
+
font-size: 0.65rem;
|
|
155
|
+
}
|
|
156
|
+
.oc-attachment-thumb > .oc-attachment__remove:hover { background: var(--oc-destructive); color: var(--color-white-50); }
|
|
157
|
+
|
|
158
|
+
@media (prefers-reduced-motion: reduce) {
|
|
159
|
+
.oc-attachment, .oc-attachment--uploading::after { transition: none; }
|
|
160
|
+
}
|