lostcoords-ui 0.4.1 → 0.6.0
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.
- checksums.yaml +4 -4
- data/README.md +364 -96
- data/app/assets/tailwind/lostcoords/ui/avatar.css +6 -6
- data/app/assets/tailwind/lostcoords/ui/base.css +45 -0
- data/app/assets/tailwind/lostcoords/ui/card.css +23 -22
- data/app/assets/tailwind/lostcoords/ui/choice.css +39 -0
- data/app/assets/tailwind/lostcoords/ui/code-block.css +10 -0
- data/app/assets/tailwind/lostcoords/ui/{disclosure.css → collapsible.css} +6 -6
- data/app/assets/tailwind/lostcoords/ui/components/code-block.css +5 -0
- data/app/assets/tailwind/lostcoords/ui/components/collapsible.css +5 -0
- data/app/assets/tailwind/lostcoords/ui/components/dialog.css +9 -0
- data/app/assets/tailwind/lostcoords/ui/components/emoji-picker.css +5 -0
- data/app/assets/tailwind/lostcoords/ui/components/menu.css +5 -0
- data/app/assets/tailwind/lostcoords/ui/components/prose.css +3 -0
- data/app/assets/tailwind/lostcoords/ui/components/table.css +3 -0
- data/app/assets/tailwind/lostcoords/ui/components/toast.css +5 -0
- data/app/assets/tailwind/lostcoords/ui/components/tooltip.css +4 -0
- data/app/assets/tailwind/lostcoords/ui/components.css +12 -0
- data/app/assets/tailwind/lostcoords/ui/copy-button.css +9 -9
- data/app/assets/tailwind/lostcoords/ui/core.css +21 -0
- data/app/assets/tailwind/lostcoords/ui/dialog.css +17 -17
- data/app/assets/tailwind/lostcoords/ui/emoji-picker.css +86 -88
- data/app/assets/tailwind/lostcoords/ui/field.css +2 -2
- data/app/assets/tailwind/lostcoords/ui/glass.css +9 -8
- data/app/assets/tailwind/lostcoords/ui/layout.css +2 -2
- data/app/assets/tailwind/lostcoords/ui/popover.css +14 -14
- data/app/assets/tailwind/lostcoords/ui/prose.css +66 -0
- data/app/assets/tailwind/lostcoords/ui/sheet.css +62 -63
- data/app/assets/tailwind/lostcoords/ui/squircle.css +7 -27
- data/app/assets/tailwind/lostcoords/ui/table.css +51 -0
- data/app/assets/tailwind/lostcoords/ui/theme.css +209 -225
- data/app/assets/tailwind/lostcoords/ui/toast.css +23 -0
- data/app/assets/tailwind/lostcoords/ui/tooltip.css +51 -0
- data/app/assets/tailwind/lostcoords/ui/typography.css +31 -61
- data/app/assets/tailwind/lostcoords/ui/ui.css +2 -21
- data/app/assets/tailwind/lostcoords/ui/utilities.css +14 -22
- data/app/helpers/lostcoords/ui/badge_helper.rb +67 -110
- data/app/helpers/lostcoords/ui/button_helper.rb +44 -35
- data/app/helpers/lostcoords/ui/card_helper.rb +9 -52
- data/app/helpers/lostcoords/ui/choice_helper.rb +87 -0
- data/app/helpers/lostcoords/ui/code_block_helper.rb +22 -0
- data/app/helpers/lostcoords/ui/collapsible_helper.rb +9 -0
- data/app/helpers/lostcoords/ui/copy_button_helper.rb +7 -7
- data/app/helpers/lostcoords/ui/description_list_helper.rb +12 -0
- data/app/helpers/lostcoords/ui/dialog_helper.rb +15 -17
- data/app/helpers/lostcoords/ui/emoji_picker_helper.rb +6 -0
- data/app/helpers/lostcoords/ui/feedback_helper.rb +25 -6
- data/app/helpers/lostcoords/ui/form_helper.rb +36 -59
- data/app/helpers/lostcoords/ui/glass_helper.rb +7 -7
- data/app/helpers/lostcoords/ui/layout_helper.rb +13 -11
- data/app/helpers/lostcoords/ui/menu_helper.rb +45 -10
- data/app/helpers/lostcoords/ui/navigation_helper.rb +144 -0
- data/app/helpers/lostcoords/ui/primitives_helper.rb +39 -61
- data/app/helpers/lostcoords/ui/reading_helper.rb +2 -2
- data/app/helpers/lostcoords/ui/render_attributes_helper.rb +17 -1
- data/app/helpers/lostcoords/ui/sheet_helper.rb +7 -45
- data/app/helpers/lostcoords/ui/structures_helper.rb +26 -125
- data/app/helpers/lostcoords/ui/table_helper.rb +11 -0
- data/app/helpers/lostcoords/ui/tailwind_helper.rb +13 -4
- data/app/helpers/lostcoords/ui/toast_helper.rb +22 -0
- data/app/helpers/lostcoords/ui/tooltip_helper.rb +17 -0
- data/app/helpers/lostcoords/ui/typography_helper.rb +41 -11
- data/app/javascript/lostcoords/ui/controllers/lc_code_block_controller.js +23 -0
- data/app/javascript/lostcoords/ui/controllers/{disclosure_controller.js → lc_collapsible_controller.js} +4 -4
- data/app/javascript/lostcoords/ui/controllers/{confirm_dialog_controller.js → lc_confirm_dialog_controller.js} +4 -4
- data/app/javascript/lostcoords/ui/controllers/{modal_controller.js → lc_dialog_controller.js} +1 -1
- data/app/javascript/lostcoords/ui/controllers/{emoji_picker_controller.js → lc_emoji_picker_controller.js} +38 -10
- data/app/javascript/lostcoords/ui/controllers/lc_kbd_controller.js +12 -0
- data/app/javascript/lostcoords/ui/controllers/{row_menu_controller.js → lc_menu_controller.js} +25 -3
- data/app/javascript/lostcoords/ui/controllers/{ui_popover_controller.js → lc_popover_controller.js} +1 -1
- data/app/javascript/lostcoords/ui/controllers/{ui_selection_controller.js → lc_selection_controller.js} +7 -15
- data/app/javascript/lostcoords/ui/controllers/{sheet_controller.js → lc_sheet_controller.js} +17 -17
- data/app/javascript/lostcoords/ui/controllers/lc_shortcut_controller.js +45 -0
- data/app/javascript/lostcoords/ui/controllers/lc_tabs_controller.js +42 -0
- data/app/javascript/lostcoords/ui/controllers/{toast_controller.js → lc_toast_controller.js} +2 -2
- data/app/javascript/lostcoords/ui/controllers/lc_toast_region_controller.js +62 -0
- data/app/javascript/lostcoords/ui/controllers/lc_tooltip_controller.js +54 -0
- data/app/javascript/lostcoords/ui/helpers/catalog_picker.js +77 -25
- data/app/javascript/lostcoords/ui/helpers/context_dialog.js +6 -6
- data/app/javascript/lostcoords/ui/helpers/dialog.js +2 -2
- data/app/javascript/lostcoords/ui/helpers/dismiss_stack.js +30 -7
- data/app/javascript/lostcoords/ui/helpers/floating_panel.js +7 -8
- data/app/javascript/lostcoords/ui/helpers/menu_keys.js +19 -18
- data/app/javascript/lostcoords/ui/helpers/roving_focus.js +175 -0
- data/app/javascript/lostcoords/ui/helpers/sheet_motion.js +4 -4
- data/app/javascript/lostcoords/ui/helpers/shortcuts.js +162 -0
- data/app/javascript/lostcoords/ui/helpers/top_layer.js +48 -10
- data/app/javascript/lostcoords/ui/index.js +57 -0
- data/app/views/lostcoords/ui/components/_emoji_picker.html.erb +46 -46
- data/app/views/lostcoords/ui/components/_emoji_picker_grid.html.erb +3 -3
- data/app/views/lostcoords/ui/components/_lc_code_block.html.erb +18 -0
- data/app/views/lostcoords/ui/components/_lc_collapsible.html.erb +5 -0
- data/app/views/lostcoords/ui/components/_lc_dialog.html.erb +11 -8
- data/app/views/lostcoords/ui/components/_lc_floating_panel.html.erb +8 -0
- data/config/importmap.rb +10 -2
- data/config/locales/en.yml +23 -0
- data/config/locales/es.yml +23 -0
- data/config/locales/ja.yml +23 -0
- data/lib/lostcoords/ui/action_view.rb +6 -3
- data/lib/lostcoords/ui/builders.rb +2 -2
- data/lib/lostcoords/ui/form_builder.rb +126 -0
- data/lib/lostcoords/ui/parts.rb +154 -0
- data/lib/lostcoords/ui/stylesheets.rb +25 -0
- data/lib/lostcoords/ui/tokens.rb +24 -1
- data/lib/lostcoords/ui/version.rb +1 -1
- data/lib/tasks/lostcoords_ui.rake +11 -0
- metadata +54 -21
- data/app/assets/tailwind/lostcoords/ui/reading.css +0 -60
- data/app/views/lostcoords/ui/components/_form_alert.html.erb +0 -4
- data/app/views/lostcoords/ui/components/_lc_disclosure.html.erb +0 -5
- data/app/views/lostcoords/ui/components/_skeleton.html.erb +0 -4
- data/app/views/lostcoords/ui/components/_spinner.html.erb +0 -10
- data/app/views/lostcoords/ui/components/_ui_floating_panel.html.erb +0 -8
- data/config/helper_renames.json +0 -113
- data/script/migrate_helpers.rb +0 -136
- /data/app/javascript/lostcoords/ui/controllers/{ui_copy_controller.js → lc_copy_controller.js} +0 -0
- /data/app/javascript/lostcoords/ui/controllers/{ui_toggle_controller.js → lc_toggle_controller.js} +0 -0
|
@@ -1,49 +1,47 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
.emoji-picker {
|
|
2
|
+
.lc-emoji-picker {
|
|
3
3
|
display: flex;
|
|
4
4
|
gap: 6px;
|
|
5
5
|
flex-wrap: wrap;
|
|
6
6
|
align-items: center;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
--emoji-sheet-z: calc(100 + 30);
|
|
10
|
-
--emoji-cell: 2.25rem;
|
|
8
|
+
--lc-emoji-cell: 2.25rem;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
/* ---- Trigger + quick choices -------------------------------------- */
|
|
14
|
-
.emoji-picker__choice,
|
|
15
|
-
.emoji-picker__trigger {
|
|
12
|
+
.lc-emoji-picker__choice,
|
|
13
|
+
.lc-emoji-picker__trigger {
|
|
16
14
|
display: inline-grid;
|
|
17
15
|
place-items: center;
|
|
18
16
|
inline-size: 44px;
|
|
19
17
|
block-size: 44px;
|
|
20
18
|
border-radius: var(--radius-2xl, 1rem);
|
|
21
|
-
border: 1px solid var(--
|
|
22
|
-
background: var(--
|
|
23
|
-
color: var(--
|
|
19
|
+
border: 1px solid var(--border);
|
|
20
|
+
background: var(--background);
|
|
21
|
+
color: var(--foreground);
|
|
24
22
|
cursor: pointer;
|
|
25
23
|
font-size: var(--text-xl, 1.25rem);
|
|
26
24
|
line-height: 1;
|
|
27
25
|
transition:
|
|
28
26
|
border-color 0.15s,
|
|
29
27
|
background 0.15s,
|
|
30
|
-
transform 0.15s var(--ease-out),
|
|
28
|
+
transform 0.15s var(--lc-ease-out),
|
|
31
29
|
box-shadow 0.15s;
|
|
32
30
|
|
|
33
|
-
&:hover { border-color: var(--
|
|
31
|
+
&:hover { border-color: var(--muted-foreground); }
|
|
34
32
|
|
|
35
33
|
&[aria-current="true"] {
|
|
36
|
-
border-color: var(--
|
|
37
|
-
background: var(--
|
|
34
|
+
border-color: var(--primary);
|
|
35
|
+
background: color-mix(in oklab, var(--primary) 12%, var(--background));
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
.emoji-picker__trigger {
|
|
42
|
-
color: var(--
|
|
39
|
+
.lc-emoji-picker__trigger {
|
|
40
|
+
color: var(--muted-foreground);
|
|
43
41
|
font-weight: var(--font-weight-normal, 400);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
.emoji-picker__more {
|
|
44
|
+
.lc-emoji-picker__more {
|
|
47
45
|
position: relative;
|
|
48
46
|
display: inline-flex;
|
|
49
47
|
}
|
|
@@ -58,11 +56,11 @@
|
|
|
58
56
|
dims everything beneath it — including the app nav. The allow-discrete
|
|
59
57
|
transitions keep it in the top layer while it eases out, so it fades
|
|
60
58
|
both ways instead of snapping away on close. */
|
|
61
|
-
.emoji-picker__popover::backdrop {
|
|
62
|
-
background: var(--scrim);
|
|
59
|
+
.lc-emoji-picker__popover::backdrop {
|
|
60
|
+
background: var(--lc-scrim);
|
|
63
61
|
opacity: 0;
|
|
64
62
|
transition:
|
|
65
|
-
opacity 220ms var(--ease-out),
|
|
63
|
+
opacity 220ms var(--lc-ease-out),
|
|
66
64
|
display 220ms allow-discrete,
|
|
67
65
|
overlay 220ms allow-discrete;
|
|
68
66
|
|
|
@@ -72,7 +70,7 @@
|
|
|
72
70
|
/* Only the phone sheet dims the page; the desktop popover rides the top
|
|
73
71
|
layer too (so nothing paints over it) but floats over an undimmed page. */
|
|
74
72
|
@media (width < 40rem) {
|
|
75
|
-
.emoji-picker__popover:popover-open::backdrop {
|
|
73
|
+
.lc-emoji-picker__popover:popover-open::backdrop {
|
|
76
74
|
opacity: 1;
|
|
77
75
|
|
|
78
76
|
@starting-style { opacity: 0; }
|
|
@@ -82,22 +80,22 @@
|
|
|
82
80
|
/* Phones get a solid sheet; on desktop the host paints the popover as a
|
|
83
81
|
floating surface (glass in wariwari), so the gem leaves it unpainted. */
|
|
84
82
|
@media (width < 40rem) {
|
|
85
|
-
.emoji-picker__popover {
|
|
86
|
-
border: 1px solid var(--glass-edge, var(--
|
|
83
|
+
.lc-emoji-picker__popover {
|
|
84
|
+
border: 1px solid var(--lc-glass-edge, var(--border));
|
|
87
85
|
border-block-end: 0;
|
|
88
|
-
background: var(--
|
|
89
|
-
box-shadow: 0 -12px 40px -12px color-mix(in oklab, var(--
|
|
86
|
+
background: var(--background);
|
|
87
|
+
box-shadow: 0 -12px 40px -12px color-mix(in oklab, var(--foreground) 45%, transparent);
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
.emoji-picker__popover {
|
|
91
|
+
.lc-emoji-picker__popover {
|
|
94
92
|
position: fixed;
|
|
95
93
|
inset: auto 0 0;
|
|
96
94
|
margin: 0;
|
|
97
|
-
z-index: var(--
|
|
95
|
+
z-index: var(--lc-z-overlay);
|
|
98
96
|
display: none;
|
|
99
97
|
max-inline-size: none;
|
|
100
|
-
color: var(--
|
|
98
|
+
color: var(--foreground);
|
|
101
99
|
flex-direction: column;
|
|
102
100
|
inline-size: 100%;
|
|
103
101
|
max-block-size: min(72svh, 34rem);
|
|
@@ -107,7 +105,7 @@
|
|
|
107
105
|
overscroll-behavior: contain;
|
|
108
106
|
transform: translateY(100%);
|
|
109
107
|
transition:
|
|
110
|
-
transform 260ms var(--ease-out-expo),
|
|
108
|
+
transform 260ms var(--lc-ease-out-expo),
|
|
111
109
|
display 260ms allow-discrete,
|
|
112
110
|
overlay 260ms allow-discrete;
|
|
113
111
|
|
|
@@ -125,7 +123,7 @@
|
|
|
125
123
|
|
|
126
124
|
/* Fallback for browsers without the Popover API: class-driven display. */
|
|
127
125
|
@supports not selector(:popover-open) {
|
|
128
|
-
.emoji-picker__popover[data-open] {
|
|
126
|
+
.lc-emoji-picker__popover[data-open] {
|
|
129
127
|
display: flex;
|
|
130
128
|
transform: translateY(0);
|
|
131
129
|
}
|
|
@@ -135,7 +133,7 @@
|
|
|
135
133
|
is large; the host's sheet draws the pill.
|
|
136
134
|
touch-action: none lets a vertical drag pull the sheet down rather than
|
|
137
135
|
scroll. Drag-to-dismiss is wired by the sheet controller. */
|
|
138
|
-
.emoji-picker__handle {
|
|
136
|
+
.lc-emoji-picker__handle {
|
|
139
137
|
flex: 0 0 auto;
|
|
140
138
|
display: grid;
|
|
141
139
|
place-items: center;
|
|
@@ -145,10 +143,10 @@
|
|
|
145
143
|
cursor: grab;
|
|
146
144
|
}
|
|
147
145
|
|
|
148
|
-
.emoji-picker__handle:active { cursor: grabbing; }
|
|
146
|
+
.lc-emoji-picker__handle:active { cursor: grabbing; }
|
|
149
147
|
|
|
150
148
|
/* ---- Search row --------------------------------------------------- */
|
|
151
|
-
.emoji-picker__search {
|
|
149
|
+
.lc-emoji-picker__search {
|
|
152
150
|
flex: 0 0 auto;
|
|
153
151
|
display: flex;
|
|
154
152
|
gap: 0.5rem;
|
|
@@ -156,35 +154,35 @@
|
|
|
156
154
|
padding: 0.75rem 0.75rem 0.5rem;
|
|
157
155
|
}
|
|
158
156
|
|
|
159
|
-
.emoji-picker__search-field {
|
|
157
|
+
.lc-emoji-picker__search-field {
|
|
160
158
|
position: relative;
|
|
161
159
|
flex: 1 1 auto;
|
|
162
160
|
display: flex;
|
|
163
161
|
align-items: center;
|
|
164
162
|
}
|
|
165
163
|
|
|
166
|
-
.emoji-picker__search-icon {
|
|
164
|
+
.lc-emoji-picker__search-icon {
|
|
167
165
|
position: absolute;
|
|
168
166
|
inset-inline-start: 14px;
|
|
169
167
|
inline-size: 18px;
|
|
170
168
|
block-size: 18px;
|
|
171
|
-
color: var(--
|
|
169
|
+
color: var(--muted-foreground);
|
|
172
170
|
pointer-events: none;
|
|
173
171
|
}
|
|
174
172
|
|
|
175
|
-
.emoji-picker__search-input {
|
|
173
|
+
.lc-emoji-picker__search-input {
|
|
176
174
|
inline-size: 100%;
|
|
177
175
|
min-block-size: 44px;
|
|
178
176
|
padding-inline: 40px 1rem;
|
|
179
177
|
border: 1px solid transparent;
|
|
180
178
|
border-radius: 999px;
|
|
181
|
-
background: var(--
|
|
182
|
-
color: var(--
|
|
179
|
+
background: var(--muted);
|
|
180
|
+
color: var(--foreground);
|
|
183
181
|
font: inherit;
|
|
184
182
|
font-size: 1rem;
|
|
185
183
|
transition: border-color 150ms ease-out, box-shadow 150ms ease-out;
|
|
186
184
|
|
|
187
|
-
&::placeholder { color: var(--
|
|
185
|
+
&::placeholder { color: var(--muted-foreground); }
|
|
188
186
|
&::-webkit-search-cancel-button {
|
|
189
187
|
/* stylelint-disable-next-line property-no-vendor-prefix -- WebKit search decoration */
|
|
190
188
|
-webkit-appearance: none;
|
|
@@ -193,35 +191,35 @@
|
|
|
193
191
|
|
|
194
192
|
&:focus {
|
|
195
193
|
outline: none;
|
|
196
|
-
box-shadow: var(--focus-halo, 0 0 0 2px color-mix(in oklab, var(--
|
|
194
|
+
box-shadow: var(--focus-halo, 0 0 0 2px color-mix(in oklab, var(--primary) 50%, transparent));
|
|
197
195
|
}
|
|
198
196
|
}
|
|
199
197
|
|
|
200
198
|
/* ---- Skin-tone control ------------------------------------------- */
|
|
201
|
-
.emoji-picker__tones {
|
|
199
|
+
.lc-emoji-picker__tones {
|
|
202
200
|
position: relative;
|
|
203
201
|
flex: 0 0 auto;
|
|
204
202
|
}
|
|
205
203
|
|
|
206
|
-
.emoji-picker__tone-toggle {
|
|
204
|
+
.lc-emoji-picker__tone-toggle {
|
|
207
205
|
display: inline-grid;
|
|
208
206
|
place-items: center;
|
|
209
207
|
inline-size: 44px;
|
|
210
208
|
block-size: 44px;
|
|
211
209
|
border: none;
|
|
212
210
|
border-radius: 999px;
|
|
213
|
-
background: var(--
|
|
211
|
+
background: var(--muted);
|
|
214
212
|
cursor: pointer;
|
|
215
213
|
font-size: var(--text-lg, 1.125rem);
|
|
216
214
|
line-height: 1;
|
|
217
215
|
transition: background 150ms ease-out;
|
|
218
216
|
|
|
219
|
-
&:hover { background: var(--
|
|
217
|
+
&:hover { background: var(--accent); }
|
|
220
218
|
|
|
221
|
-
&[aria-expanded="true"] { background: var(--
|
|
219
|
+
&[aria-expanded="true"] { background: color-mix(in oklab, var(--primary) 12%, var(--background)); }
|
|
222
220
|
}
|
|
223
221
|
|
|
224
|
-
.emoji-picker__tone-menu {
|
|
222
|
+
.lc-emoji-picker__tone-menu {
|
|
225
223
|
position: absolute;
|
|
226
224
|
inset-block-end: calc(100% + 6px);
|
|
227
225
|
inset-inline-end: 0;
|
|
@@ -234,7 +232,7 @@
|
|
|
234
232
|
&[hidden] { display: none; }
|
|
235
233
|
}
|
|
236
234
|
|
|
237
|
-
.emoji-picker__tone {
|
|
235
|
+
.lc-emoji-picker__tone {
|
|
238
236
|
display: inline-grid;
|
|
239
237
|
place-items: center;
|
|
240
238
|
inline-size: 36px;
|
|
@@ -246,16 +244,16 @@
|
|
|
246
244
|
font-size: var(--text-lg, 1.125rem);
|
|
247
245
|
line-height: 1;
|
|
248
246
|
|
|
249
|
-
&:hover { background: var(--
|
|
247
|
+
&:hover { background: var(--muted); }
|
|
250
248
|
|
|
251
|
-
&[aria-current="true"] { background: var(--
|
|
249
|
+
&[aria-current="true"] { background: color-mix(in oklab, var(--primary) 12%, var(--background)); }
|
|
252
250
|
}
|
|
253
251
|
|
|
254
252
|
/* ---- Category tab navigation ------------------------------------- */
|
|
255
253
|
|
|
256
254
|
/* Category tabs: a segmented track, like the app's tab strips — a paper-2
|
|
257
255
|
track with the active tab raised on a paper thumb. */
|
|
258
|
-
.emoji-picker__tabs {
|
|
256
|
+
.lc-emoji-picker__tabs {
|
|
259
257
|
flex: 0 0 auto;
|
|
260
258
|
display: flex;
|
|
261
259
|
gap: 2px;
|
|
@@ -264,12 +262,12 @@
|
|
|
264
262
|
overflow-x: auto;
|
|
265
263
|
scrollbar-width: none;
|
|
266
264
|
border-radius: var(--radius-2xl, 1rem);
|
|
267
|
-
background: var(--
|
|
265
|
+
background: var(--muted);
|
|
268
266
|
|
|
269
267
|
&::-webkit-scrollbar { display: none; }
|
|
270
268
|
}
|
|
271
269
|
|
|
272
|
-
.emoji-picker__tab {
|
|
270
|
+
.lc-emoji-picker__tab {
|
|
273
271
|
flex: 0 0 auto;
|
|
274
272
|
display: inline-grid;
|
|
275
273
|
place-items: center;
|
|
@@ -288,13 +286,13 @@
|
|
|
288
286
|
|
|
289
287
|
&[aria-current="true"] {
|
|
290
288
|
opacity: 1;
|
|
291
|
-
background: var(--
|
|
292
|
-
box-shadow: var(--shadow-sm);
|
|
289
|
+
background: var(--background);
|
|
290
|
+
box-shadow: var(--lc-shadow-sm);
|
|
293
291
|
}
|
|
294
292
|
}
|
|
295
293
|
|
|
296
294
|
/* ---- Scrollable body --------------------------------------------- */
|
|
297
|
-
.emoji-picker__body {
|
|
295
|
+
.lc-emoji-picker__body {
|
|
298
296
|
position: relative;
|
|
299
297
|
flex: 1 1 auto;
|
|
300
298
|
overflow-y: auto;
|
|
@@ -309,15 +307,15 @@
|
|
|
309
307
|
@media (prefers-reduced-motion: reduce) { scroll-behavior: auto; }
|
|
310
308
|
}
|
|
311
309
|
|
|
312
|
-
.emoji-picker__category + .emoji-picker__category,
|
|
313
|
-
.emoji-picker__recent + .emoji-picker__catalog,
|
|
314
|
-
.emoji-picker__results + * {
|
|
310
|
+
.lc-emoji-picker__category + .lc-emoji-picker__category,
|
|
311
|
+
.lc-emoji-picker__recent + .lc-emoji-picker__catalog,
|
|
312
|
+
.lc-emoji-picker__results + * {
|
|
315
313
|
margin-block-start: 0.5rem;
|
|
316
314
|
}
|
|
317
315
|
|
|
318
316
|
/* Heads scroll with their section: the tab track already marks the current
|
|
319
317
|
category, and a sticky band would sit as a stripe across the panel. */
|
|
320
|
-
.emoji-picker__category-head {
|
|
318
|
+
.lc-emoji-picker__category-head {
|
|
321
319
|
display: flex;
|
|
322
320
|
align-items: baseline;
|
|
323
321
|
justify-content: space-between;
|
|
@@ -328,19 +326,19 @@
|
|
|
328
326
|
margin: 0;
|
|
329
327
|
font-size: var(--text-sm, 0.875rem);
|
|
330
328
|
font-weight: var(--font-weight-semibold, 600);
|
|
331
|
-
color: var(--
|
|
329
|
+
color: var(--muted-foreground);
|
|
332
330
|
}
|
|
333
331
|
|
|
334
332
|
.count {
|
|
335
|
-
font-family: var(--font-
|
|
333
|
+
font-family: var(--font-sans, system-ui);
|
|
336
334
|
font-size: var(--text-xs, 0.75rem);
|
|
337
|
-
color: var(--
|
|
335
|
+
color: var(--muted-foreground);
|
|
338
336
|
}
|
|
339
337
|
}
|
|
340
338
|
|
|
341
|
-
.emoji-picker__grid {
|
|
339
|
+
.lc-emoji-picker__grid {
|
|
342
340
|
display: grid;
|
|
343
|
-
grid-template-columns: repeat(auto-fill, minmax(var(--emoji-cell), 1fr));
|
|
341
|
+
grid-template-columns: repeat(auto-fill, minmax(var(--lc-emoji-cell), 1fr));
|
|
344
342
|
gap: 2px;
|
|
345
343
|
padding-block-start: 4px;
|
|
346
344
|
|
|
@@ -356,45 +354,45 @@
|
|
|
356
354
|
font-size: var(--text-xl, 1.25rem);
|
|
357
355
|
line-height: 1;
|
|
358
356
|
padding: 0;
|
|
359
|
-
transition: background 0.1s, transform 0.1s var(--ease-out);
|
|
357
|
+
transition: background 0.1s, transform 0.1s var(--lc-ease-out);
|
|
360
358
|
|
|
361
359
|
&:hover,
|
|
362
360
|
&:focus-visible {
|
|
363
|
-
background: var(--
|
|
361
|
+
background: var(--muted);
|
|
364
362
|
transform: scale(1.12);
|
|
365
363
|
outline: none;
|
|
366
364
|
}
|
|
367
365
|
|
|
368
|
-
&[aria-current="true"] { background: var(--
|
|
366
|
+
&[aria-current="true"] { background: color-mix(in oklab, var(--primary) 12%, var(--background)); }
|
|
369
367
|
}
|
|
370
368
|
}
|
|
371
369
|
|
|
372
370
|
/* Section that owns the sticky header needs the scroll anchor, not the grid */
|
|
373
|
-
.emoji-picker__category,
|
|
374
|
-
.emoji-picker__recent,
|
|
375
|
-
.emoji-picker__results {
|
|
371
|
+
.lc-emoji-picker__category,
|
|
372
|
+
.lc-emoji-picker__recent,
|
|
373
|
+
.lc-emoji-picker__results {
|
|
376
374
|
scroll-margin-block-start: 0;
|
|
377
375
|
}
|
|
378
376
|
|
|
379
|
-
.emoji-picker__empty {
|
|
377
|
+
.lc-emoji-picker__empty {
|
|
380
378
|
margin: 0;
|
|
381
379
|
padding: 1rem 0.5rem;
|
|
382
|
-
color: var(--
|
|
380
|
+
color: var(--muted-foreground);
|
|
383
381
|
font-size: 1rem;
|
|
384
382
|
text-align: center;
|
|
385
383
|
}
|
|
386
384
|
|
|
387
385
|
/* ---- Search mode: swap catalog for a single ranked result list ---- */
|
|
388
|
-
.emoji-picker__popover:not([data-searching]) .emoji-picker__results { display: none; }
|
|
386
|
+
.lc-emoji-picker__popover:not([data-searching]) .lc-emoji-picker__results { display: none; }
|
|
389
387
|
|
|
390
|
-
.emoji-picker__popover[data-searching] {
|
|
391
|
-
.emoji-picker__tabs,
|
|
392
|
-
.emoji-picker__recent,
|
|
393
|
-
.emoji-picker__catalog { display: none; }
|
|
388
|
+
.lc-emoji-picker__popover[data-searching] {
|
|
389
|
+
.lc-emoji-picker__tabs,
|
|
390
|
+
.lc-emoji-picker__recent,
|
|
391
|
+
.lc-emoji-picker__catalog { display: none; }
|
|
394
392
|
}
|
|
395
393
|
|
|
396
394
|
/* ---- Preview footer ---------------------------------------------- */
|
|
397
|
-
.emoji-picker__preview {
|
|
395
|
+
.lc-emoji-picker__preview {
|
|
398
396
|
flex: 0 0 auto;
|
|
399
397
|
display: flex;
|
|
400
398
|
gap: 0.5rem;
|
|
@@ -403,15 +401,15 @@
|
|
|
403
401
|
padding: 0.25rem 1rem 0.75rem;
|
|
404
402
|
}
|
|
405
403
|
|
|
406
|
-
.emoji-picker__preview-emoji {
|
|
404
|
+
.lc-emoji-picker__preview-emoji {
|
|
407
405
|
font-size: 1.5rem;
|
|
408
406
|
line-height: 1;
|
|
409
407
|
}
|
|
410
408
|
|
|
411
|
-
.emoji-picker__preview-name {
|
|
409
|
+
.lc-emoji-picker__preview-name {
|
|
412
410
|
overflow: hidden;
|
|
413
411
|
font-size: 1rem;
|
|
414
|
-
color: var(--
|
|
412
|
+
color: var(--muted-foreground);
|
|
415
413
|
text-overflow: ellipsis;
|
|
416
414
|
white-space: nowrap;
|
|
417
415
|
}
|
|
@@ -422,7 +420,7 @@
|
|
|
422
420
|
|
|
423
421
|
/* ==================================================================== */
|
|
424
422
|
@media (width >= 40rem) {
|
|
425
|
-
.emoji-picker__popover {
|
|
423
|
+
.lc-emoji-picker__popover {
|
|
426
424
|
position: absolute;
|
|
427
425
|
inset-block: calc(100% + 8px) auto;
|
|
428
426
|
inset-inline: 0 auto;
|
|
@@ -433,8 +431,8 @@
|
|
|
433
431
|
transform: translateY(-4px) scale(0.98);
|
|
434
432
|
opacity: 0;
|
|
435
433
|
transition:
|
|
436
|
-
opacity 160ms var(--ease-out-expo),
|
|
437
|
-
transform 160ms var(--ease-out-expo),
|
|
434
|
+
opacity 160ms var(--lc-ease-out-expo),
|
|
435
|
+
transform 160ms var(--lc-ease-out-expo),
|
|
438
436
|
display 160ms allow-discrete,
|
|
439
437
|
overlay 160ms allow-discrete;
|
|
440
438
|
|
|
@@ -452,11 +450,11 @@
|
|
|
452
450
|
@media (prefers-reduced-motion: reduce) { transition: none; }
|
|
453
451
|
}
|
|
454
452
|
|
|
455
|
-
.emoji-picker__handle { display: none; }
|
|
453
|
+
.lc-emoji-picker__handle { display: none; }
|
|
456
454
|
|
|
457
|
-
main:has(.emoji-picker__popover[data-open]),
|
|
458
|
-
.emoji-picker:has(.emoji-picker__popover[data-open]) {
|
|
459
|
-
z-index:
|
|
455
|
+
main:has(.lc-emoji-picker__popover[data-open]),
|
|
456
|
+
.lc-emoji-picker:has(.lc-emoji-picker__popover[data-open]) {
|
|
457
|
+
z-index: var(--lc-z-overlay);
|
|
460
458
|
}
|
|
461
459
|
}
|
|
462
460
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/* Glass — the floating control layer, used the way iOS uses it: only on
|
|
2
2
|
chrome that floats over content (the nav pills, the phone CTA dock, menus
|
|
3
3
|
and popovers), never on cards or sections. Menus lift further, on
|
|
4
|
-
--shadow-lg. Written once here because Safari
|
|
4
|
+
--lc-shadow-lg. Written once here because Safari
|
|
5
5
|
drops custom properties inside -webkit-backdrop-filter, so the blur needs
|
|
6
6
|
literal values, and because the solid fallbacks need @supports and
|
|
7
7
|
prefers-reduced-transparency. glass_class is the only writer of the name. */
|
|
8
8
|
@layer components {
|
|
9
9
|
/* The emoji and currency pickers are glass only as desktop popovers; on
|
|
10
10
|
phones they're bottom sheets, whose rules come later in the cascade and repaint them solid. */
|
|
11
|
-
.glass {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
.lc-glass {
|
|
12
|
+
--_lc-glass-fill: var(--lc-glass-fill);
|
|
13
|
+
background: var(--_lc-glass-fill);
|
|
14
|
+
border: 1px solid var(--lc-glass-edge);
|
|
15
|
+
box-shadow: var(--lc-glass-shadow);
|
|
15
16
|
-webkit-backdrop-filter: blur(24px) saturate(160%);
|
|
16
17
|
backdrop-filter: blur(24px) saturate(160%);
|
|
17
18
|
|
|
@@ -23,13 +24,13 @@
|
|
|
23
24
|
backdrop-filter: blur(12px) saturate(180%);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
/* --glass-solid lets inverted (HUD) glass fall back to its own colour. */
|
|
27
|
+
/* --lc-glass-solid lets inverted (HUD) glass fall back to its own colour. */
|
|
27
28
|
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
28
|
-
|
|
29
|
+
--_lc-glass-fill: var(--lc-glass-solid, var(--background));
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
@media (prefers-reduced-transparency: reduce) {
|
|
32
|
-
|
|
33
|
+
--_lc-glass-fill: var(--lc-glass-solid, var(--background));
|
|
33
34
|
-webkit-backdrop-filter: none;
|
|
34
35
|
backdrop-filter: none;
|
|
35
36
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/* Closed is the exit pose, so closing animates too; allow-discrete holds
|
|
2
2
|
display/overlay until it ends. FloatingPanel sets [data-open]. */
|
|
3
|
-
@utility popover-shell {
|
|
3
|
+
@utility lc-popover-shell {
|
|
4
4
|
opacity: 0;
|
|
5
5
|
transform: translateY(--spacing(-1)) scale(0.98);
|
|
6
6
|
pointer-events: none;
|
|
7
7
|
transition:
|
|
8
|
-
opacity 160ms var(--ease-out-expo),
|
|
9
|
-
transform 160ms var(--ease-out-expo),
|
|
8
|
+
opacity 160ms var(--lc-ease-out-expo),
|
|
9
|
+
transform 160ms var(--lc-ease-out-expo),
|
|
10
10
|
display 160ms allow-discrete,
|
|
11
11
|
overlay 160ms allow-discrete;
|
|
12
12
|
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
@layer components {
|
|
26
|
-
/* Desktop: the .sheet becomes an anchored popover instead of a bottom sheet. */
|
|
26
|
+
/* Desktop: the .lc-sheet becomes an anchored popover instead of a bottom sheet. */
|
|
27
27
|
@media (width >= 40rem) {
|
|
28
|
-
.sheet--anchored {
|
|
29
|
-
@apply popover-shell;
|
|
28
|
+
.lc-sheet--anchored {
|
|
29
|
+
@apply lc-popover-shell;
|
|
30
30
|
|
|
31
31
|
display: none;
|
|
32
32
|
flex-direction: column;
|
|
@@ -48,27 +48,27 @@
|
|
|
48
48
|
/* Enter/exit for small overlays, whichever way they open: a [hidden] toggle
|
|
49
49
|
(amount calculator, colour picker), the Popover API (phone nav menus) or a
|
|
50
50
|
modal <dialog>. The closed state is the exit pose, so close animates too;
|
|
51
|
-
allow-discrete holds display/overlay until it ends. --pop-y sets the
|
|
51
|
+
allow-discrete holds display/overlay until it ends. --lc-pop-y sets the
|
|
52
52
|
direction: popovers drop from their trigger, dialogs rise. */
|
|
53
|
-
.popover-pop {
|
|
54
|
-
--pop-from: translateY(var(--pop-y, -0.25rem)) scale(0.96);
|
|
53
|
+
.lc-popover-pop {
|
|
54
|
+
--lc-pop-from: translateY(var(--lc-pop-y, -0.25rem)) scale(0.96);
|
|
55
55
|
|
|
56
|
-
transform-origin: var(--pop-origin, top);
|
|
56
|
+
transform-origin: var(--lc-pop-origin, top);
|
|
57
57
|
transition:
|
|
58
|
-
opacity 160ms var(--ease-out-expo),
|
|
59
|
-
transform 240ms var(--ease-out-expo),
|
|
58
|
+
opacity 160ms var(--lc-ease-out-expo),
|
|
59
|
+
transform 240ms var(--lc-ease-out-expo),
|
|
60
60
|
display 240ms allow-discrete,
|
|
61
61
|
overlay 240ms allow-discrete;
|
|
62
62
|
|
|
63
63
|
&:is([hidden], [popover]:not(:popover-open), dialog:not([open])) {
|
|
64
64
|
opacity: 0;
|
|
65
|
-
transform: var(--pop-from);
|
|
65
|
+
transform: var(--lc-pop-from);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
&:is(:not([hidden], [popover], dialog), :popover-open, dialog[open]) {
|
|
69
69
|
@starting-style {
|
|
70
70
|
opacity: 0;
|
|
71
|
-
transform: var(--pop-from);
|
|
71
|
+
transform: var(--lc-pop-from);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
@layer utilities {
|
|
2
|
+
.lc-prose {
|
|
3
|
+
--tw-prose-body: var(--muted-foreground);
|
|
4
|
+
--tw-prose-headings: var(--foreground);
|
|
5
|
+
--tw-prose-lead: var(--muted-foreground);
|
|
6
|
+
--tw-prose-links: var(--primary);
|
|
7
|
+
--tw-prose-bold: var(--foreground);
|
|
8
|
+
--tw-prose-counters: var(--muted-foreground);
|
|
9
|
+
--tw-prose-bullets: var(--muted-foreground);
|
|
10
|
+
--tw-prose-hr: var(--border);
|
|
11
|
+
--tw-prose-quotes: var(--foreground);
|
|
12
|
+
--tw-prose-quote-borders: var(--border);
|
|
13
|
+
--tw-prose-captions: var(--muted-foreground);
|
|
14
|
+
--tw-prose-code: var(--foreground);
|
|
15
|
+
--tw-prose-pre-code: var(--foreground);
|
|
16
|
+
--tw-prose-pre-bg: var(--muted);
|
|
17
|
+
--tw-prose-th-borders: var(--border);
|
|
18
|
+
--tw-prose-td-borders: var(--border);
|
|
19
|
+
|
|
20
|
+
& :where(p, ul, ol, dl, blockquote, pre, table, figure, hr):not(:where(.not-prose, .not-prose *)) {
|
|
21
|
+
margin-block: var(--lc-reading-flow, 1.25em) 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
& :where(h1, h2, h3, h4):not(:where(.not-prose, .not-prose *)) {
|
|
25
|
+
margin-block: calc(var(--lc-reading-flow, 1.25em) * 1.6) 0;
|
|
26
|
+
font-family: var(--font-display, inherit);
|
|
27
|
+
line-height: var(--lc-reading-heading-leading, 1.25);
|
|
28
|
+
text-wrap: balance;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
& :where(h1, h2, h3, h4) + :where(p, ul, ol):not(:where(.not-prose, .not-prose *)) {
|
|
32
|
+
margin-block-start: calc(var(--lc-reading-flow, 1.25em) * 0.5);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
& :where(li > p, li > ul, li > ol):not(:where(.not-prose, .not-prose *)) {
|
|
36
|
+
margin-block-start: calc(var(--lc-reading-flow, 1.25em) * 0.5);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
& > :where(:first-child):not(:where(.not-prose, .not-prose *)) {
|
|
40
|
+
margin-block-start: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:lang(ja) {
|
|
44
|
+
line-break: strict;
|
|
45
|
+
word-break: normal;
|
|
46
|
+
overflow-wrap: anywhere;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:lang(ja) :where(h1, h2, h3, h4):not(:where(.not-prose, .not-prose *)) {
|
|
50
|
+
line-height: var(--lc-reading-heading-leading, 1.4);
|
|
51
|
+
letter-spacing: normal;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@supports (word-break: auto-phrase) {
|
|
56
|
+
.lc-prose:lang(ja) :where(h1, h2, h3, h4):not(:where(.not-prose, .not-prose *)) {
|
|
57
|
+
word-break: auto-phrase;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@layer utilities {
|
|
63
|
+
.lc-prose :where(code):not(:where(pre code)) {
|
|
64
|
+
@apply lc-inline-code;
|
|
65
|
+
}
|
|
66
|
+
}
|