gardenjs 1.6.8 → 1.7.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.
Files changed (47) hide show
  1. package/.prettierrc +16 -5
  2. package/README.md +1 -1
  3. package/dist/assets/frame-BOcgZVOc.js +9 -0
  4. package/dist/assets/index-BDdBNVTh.css +19 -0
  5. package/dist/assets/index-DFG9gkdS.js +46 -0
  6. package/dist/assets/props-COK33XqS.js +2 -0
  7. package/dist/frame.html +2 -2
  8. package/dist/index.html +3 -3
  9. package/eslint.config.js +14 -1
  10. package/package.json +3 -1
  11. package/src/client/GardenApp.svelte +105 -92
  12. package/src/client/GardenFrame.svelte +25 -3
  13. package/src/client/assets/scss/main.scss +0 -1
  14. package/src/client/components/panes/HorizontalSplitPane.svelte +28 -24
  15. package/src/client/components/panes/VerticalSplitPane.svelte +118 -0
  16. package/src/client/components/sidebar/Sidebar.svelte +8 -11
  17. package/src/client/components/stage/Stage.svelte +76 -1
  18. package/src/client/components/stage/panel/PanelCode.svelte +7 -1
  19. package/src/client/components/stage/panel/PanelComponent.svelte +0 -1
  20. package/src/client/components/stage/panel/PanelDescription.svelte +6 -0
  21. package/src/client/components/stage/panel/PanelExamplesNav.svelte +38 -12
  22. package/src/client/components/stage/panel/ParamsPane.svelte +201 -0
  23. package/src/client/components/stage/panel/controls/ArrayControl.svelte +242 -0
  24. package/src/client/components/stage/panel/controls/BooleanControl.svelte +142 -0
  25. package/src/client/components/stage/panel/controls/ColorPickerControl.svelte +185 -0
  26. package/src/client/components/stage/panel/controls/DateControl.svelte +64 -0
  27. package/src/client/components/stage/panel/controls/DatetimeControl.svelte +64 -0
  28. package/src/client/components/stage/panel/controls/JsonControl.svelte +29 -0
  29. package/src/client/components/stage/panel/controls/MultiselectControl.svelte +354 -0
  30. package/src/client/components/stage/panel/controls/NumberControl.svelte +31 -0
  31. package/src/client/components/stage/panel/controls/ObjectControl.svelte +148 -0
  32. package/src/client/components/stage/panel/controls/RangeControl.svelte +156 -0
  33. package/src/client/components/stage/panel/controls/SelectControl.svelte +233 -0
  34. package/src/client/components/stage/panel/controls/TextInputControl.svelte +85 -0
  35. package/src/client/components/stage/panel/controls/TimeControl.svelte +64 -0
  36. package/src/client/components/stage/panel/controls/button.scss +15 -0
  37. package/src/client/components/stage/panel/controls/button_unset.scss +35 -0
  38. package/src/client/components/stage/panel/controls/input.scss +15 -0
  39. package/src/client/components/topbar/Topbar.svelte +8 -0
  40. package/src/client/logic/localStore.js +23 -0
  41. package/src/client/logic/sidebar.svelte.js +55 -0
  42. package/src/client/logic/stage.js +2 -63
  43. package/dist/assets/frame-B7ff1vAd.js +0 -9
  44. package/dist/assets/index-DfGHKcnI.css +0 -19
  45. package/dist/assets/index-WI1a7nYK.js +0 -46
  46. package/dist/assets/props-DKVIKFn7.js +0 -2
  47. package/src/client/assets/scss/base/input-number.css +0 -11
@@ -0,0 +1,185 @@
1
+ <script>
2
+ let { value, onChange } = $props()
3
+
4
+ function colorToHex(color) {
5
+ if (!color) return '#000000'
6
+
7
+ const str = String(color).trim()
8
+
9
+ if (/^#[0-9A-Fa-f]{6}$/.test(str)) return str
10
+
11
+ if (/^#[0-9A-Fa-f]{3}$/.test(str)) {
12
+ return '#' + str[1] + str[1] + str[2] + str[2] + str[3] + str[3]
13
+ }
14
+
15
+ const temp = document.createElement('div')
16
+ temp.style.color = str
17
+ document.body.appendChild(temp)
18
+ const computed = window.getComputedStyle(temp).color
19
+ document.body.removeChild(temp)
20
+
21
+ const match = computed.match(/^rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/)
22
+ if (match) {
23
+ const [, r, g, b] = match
24
+ return (
25
+ '#' +
26
+ [r, g, b].map((n) => parseInt(n).toString(16).padStart(2, '0')).join('')
27
+ )
28
+ }
29
+
30
+ return '#000000'
31
+ }
32
+
33
+ function hasTransparency(color) {
34
+ if (!color) return false
35
+ const str = String(color).trim().toLowerCase()
36
+ return /rgba\s*\(/.test(str) || /hsla\s*\(/.test(str)
37
+ }
38
+
39
+ function handleColorPickerClick() {
40
+ if (isUnset) {
41
+ onChange('#000000')
42
+ }
43
+ }
44
+
45
+ function handleTextInput(e) {
46
+ const newValue = e.currentTarget.value.trim()
47
+ if (newValue === '') {
48
+ onChange(undefined)
49
+ } else {
50
+ onChange(newValue)
51
+ }
52
+ }
53
+
54
+ let isUnset = $derived(!value || value === undefined || value === null)
55
+ let hexValue = $derived(colorToHex(value))
56
+ let showPreview = $derived(hasTransparency(value))
57
+ </script>
58
+
59
+ <div class="row">
60
+ <div class="color-picker-wrapper" class:picker-unset={isUnset}>
61
+ <input
62
+ class="input"
63
+ type="color"
64
+ value={hexValue}
65
+ onfocus={handleColorPickerClick}
66
+ oninput={(e) => onChange(e.currentTarget.value)}
67
+ />
68
+ </div>
69
+ {#if showPreview}
70
+ <div
71
+ class="alpha-preview"
72
+ style:background-color={value || '#000000'}
73
+ ></div>
74
+ {/if}
75
+ <input
76
+ class="input"
77
+ type="text"
78
+ value={value || ''}
79
+ oninput={handleTextInput}
80
+ />
81
+ <div class="unset-area">
82
+ {#if isUnset}
83
+ <span class="unset-info">is not set</span>
84
+ {:else}
85
+ <button class="btn_unset" onclick={() => onChange(undefined)}>
86
+ <svg
87
+ class="close"
88
+ xmlns="http://www.w3.org/2000/svg"
89
+ width="12"
90
+ height="12"
91
+ viewBox="0 0 24 24"
92
+ fill="none"
93
+ stroke="currentColor"
94
+ stroke-width="2"
95
+ stroke-linecap="round"
96
+ stroke-linejoin="round"><path d="M18 6L6 18M6 6l12 12" /></svg
97
+ >
98
+ unset
99
+ </button>
100
+ {/if}
101
+ </div>
102
+ </div>
103
+
104
+ <style>
105
+ @import './button_unset.scss';
106
+ @import './input.scss';
107
+
108
+ .row {
109
+ display: flex;
110
+ gap: 0.5rem;
111
+ align-items: center;
112
+ }
113
+
114
+ .color-picker-wrapper {
115
+ position: relative;
116
+ width: 2.5rem;
117
+ height: 1.469rem;
118
+ /* border: 1px solid var(--c-primary); */
119
+ border-radius: 0.125rem;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .color-picker-wrapper.picker-unset {
124
+ border: 1px solid var(--c-primary);
125
+ }
126
+
127
+ .color-picker-wrapper.picker-unset input[type='color'] {
128
+ opacity: 0;
129
+ }
130
+
131
+ .color-picker-wrapper.picker-unset::before {
132
+ content: '';
133
+ position: absolute;
134
+ top: 0;
135
+ left: 0;
136
+ width: 100%;
137
+ height: 100%;
138
+ background: linear-gradient(
139
+ 150deg,
140
+ transparent calc(50% - 1px),
141
+ red calc(50% - 1px),
142
+ red calc(50% + 1px),
143
+ transparent calc(50% + 1px)
144
+ );
145
+ pointer-events: none;
146
+ z-index: 1;
147
+ }
148
+
149
+ input[type='color'] {
150
+ width: 100%;
151
+ height: 100%;
152
+ padding: 0;
153
+ border: none;
154
+ border-radius: 0.125rem;
155
+ cursor: pointer;
156
+ }
157
+
158
+ .input {
159
+ max-width: 12.5rem;
160
+ }
161
+ .alpha-preview {
162
+ width: 2.5rem;
163
+ height: 1.469rem;
164
+ border-radius: 0.125rem;
165
+ background-image:
166
+ linear-gradient(45deg, var(--c-basic-100) 25%, transparent 25%),
167
+ linear-gradient(-45deg, var(--c-basic-100) 25%, transparent 25%),
168
+ linear-gradient(45deg, transparent 75%, var(--c-basic-100) 75%),
169
+ linear-gradient(-45deg, transparent 75%, var(--c-basic-100) 75%);
170
+ background-size: 8px 8px;
171
+ background-position:
172
+ 0 0,
173
+ 0 4px,
174
+ 4px -4px,
175
+ -4px 0px;
176
+ overflow: hidden;
177
+ }
178
+ input[type='color']::-webkit-color-swatch-wrapper {
179
+ padding: 0;
180
+ }
181
+ input[type='color']::-webkit-color-swatch {
182
+ border: none;
183
+ border-radius: 0.063rem;
184
+ }
185
+ </style>
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ let {
3
+ value,
4
+ onChange,
5
+ }: { value: string; onChange: (value: string) => void } = $props()
6
+
7
+ let isUnset = $derived(!value || value === undefined || value === null)
8
+ </script>
9
+
10
+ <div class="row">
11
+ <input
12
+ class="input"
13
+ type="date"
14
+ value={value ?? ''}
15
+ onchange={(e) => {
16
+ const newValue = (e.currentTarget as HTMLInputElement).value
17
+ onChange(newValue || (undefined as any))
18
+ }}
19
+ />
20
+ <div class="unset-area">
21
+ {#if isUnset}
22
+ <span class="unset-info">is not set</span>
23
+ {:else}
24
+ <button class="btn_unset" onclick={() => onChange(undefined as any)}>
25
+ <svg
26
+ class="close"
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ width="12"
29
+ height="12"
30
+ viewBox="0 0 24 24"
31
+ fill="none"
32
+ stroke="currentColor"
33
+ stroke-width="2"
34
+ stroke-linecap="round"
35
+ stroke-linejoin="round"
36
+ >
37
+ <path d="M18 6L6 18M6 6l12 12" />
38
+ </svg>
39
+ unset
40
+ </button>
41
+ {/if}
42
+ </div>
43
+ </div>
44
+
45
+ <style lang="scss">
46
+ @use './input.scss';
47
+ @use './button_unset.scss';
48
+
49
+ .row {
50
+ display: flex;
51
+ gap: 0.5rem;
52
+ align-items: center;
53
+ }
54
+
55
+ input[type='date'] {
56
+ cursor: pointer;
57
+ flex: 1;
58
+ }
59
+
60
+ input[type='date']::-webkit-calendar-picker-indicator {
61
+ cursor: pointer;
62
+ color: var(--c-primary);
63
+ }
64
+ </style>
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ let {
3
+ value,
4
+ onChange,
5
+ }: { value: string; onChange: (value: string) => void } = $props()
6
+
7
+ let isUnset = $derived(!value || value === undefined || value === null)
8
+ </script>
9
+
10
+ <div class="row">
11
+ <input
12
+ class="input"
13
+ type="datetime-local"
14
+ value={value ?? ''}
15
+ onchange={(e) => {
16
+ const newValue = (e.currentTarget as HTMLInputElement).value
17
+ onChange(newValue || (undefined as any))
18
+ }}
19
+ />
20
+ <div class="unset-area">
21
+ {#if isUnset}
22
+ <span class="unset-info">is not set</span>
23
+ {:else}
24
+ <button class="btn_unset" onclick={() => onChange(undefined as any)}>
25
+ <svg
26
+ class="close"
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ width="12"
29
+ height="12"
30
+ viewBox="0 0 24 24"
31
+ fill="none"
32
+ stroke="currentColor"
33
+ stroke-width="2"
34
+ stroke-linecap="round"
35
+ stroke-linejoin="round"
36
+ >
37
+ <path d="M18 6L6 18M6 6l12 12" />
38
+ </svg>
39
+ unset
40
+ </button>
41
+ {/if}
42
+ </div>
43
+ </div>
44
+
45
+ <style lang="scss">
46
+ @use './input.scss';
47
+ @use './button_unset.scss';
48
+
49
+ .row {
50
+ display: flex;
51
+ gap: 0.5rem;
52
+ align-items: center;
53
+ }
54
+
55
+ input[type='datetime-local'] {
56
+ cursor: pointer;
57
+ flex: 1;
58
+ }
59
+
60
+ input[type='datetime-local']::-webkit-calendar-picker-indicator {
61
+ cursor: pointer;
62
+ color: var(--c-primary);
63
+ }
64
+ </style>
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ let {
3
+ value,
4
+ onChange,
5
+ }: {
6
+ value: string
7
+ onChange: (value: string) => void
8
+ } = $props()
9
+ </script>
10
+
11
+ <textarea
12
+ class="input textarea"
13
+ rows="10"
14
+ value={JSON.stringify(value ?? '', null, 2)}
15
+ onchange={(e) => {
16
+ onChange(JSON.parse(e.currentTarget.value ?? ''))
17
+ }}
18
+ ></textarea>
19
+
20
+ <style lang="scss">
21
+ @use './input.scss';
22
+
23
+ .textarea {
24
+ resize: vertical;
25
+ height: auto;
26
+ line-height: 1.4;
27
+ padding: 0.375rem 0.5rem;
28
+ }
29
+ </style>
@@ -0,0 +1,354 @@
1
+ <script lang="ts">
2
+ let {
3
+ value,
4
+ onChange,
5
+ options = [],
6
+ control = 'dropdown',
7
+ }: {
8
+ value: string[]
9
+ onChange: (value: string[]) => void
10
+ options?: string[] | { label: string; value: string }[]
11
+ control?: 'dropdown' | 'checkboxes'
12
+ } = $props()
13
+
14
+ let isUnset = $derived(
15
+ value === undefined || value === null || value.length === 0
16
+ )
17
+
18
+ let normalizedOptions = $derived(
19
+ options.map((opt) =>
20
+ typeof opt === 'string' ? { label: opt, value: opt } : opt
21
+ )
22
+ )
23
+
24
+ let isOpen = $state(false)
25
+
26
+ function toggleOption(optionValue: string) {
27
+ const newValue = value?.includes(optionValue)
28
+ ? value.filter((v) => v !== optionValue)
29
+ : [...(value || []), optionValue]
30
+ onChange(newValue.length > 0 ? newValue : [])
31
+ }
32
+
33
+ function handleUnset() {
34
+ onChange([])
35
+ isOpen = false
36
+ }
37
+ </script>
38
+
39
+ {#if control === 'dropdown'}
40
+ <div class="row">
41
+ <div class="select-wrapper">
42
+ <button
43
+ class="select-button"
44
+ onclick={() => (isOpen = !isOpen)}
45
+ type="button"
46
+ >
47
+ <span class="selected-text">
48
+ {#if isUnset}
49
+ <span class="placeholder">Select...</span>
50
+ {:else}
51
+ {value.length} selected
52
+ {/if}
53
+ </span>
54
+ <svg
55
+ class="arrow"
56
+ class:open={isOpen}
57
+ xmlns="http://www.w3.org/2000/svg"
58
+ width="12"
59
+ height="12"
60
+ viewBox="0 0 24 24"
61
+ fill="none"
62
+ stroke="currentColor"
63
+ stroke-width="2"
64
+ stroke-linecap="round"
65
+ stroke-linejoin="round"
66
+ >
67
+ <polyline points="6 9 12 15 18 9"></polyline>
68
+ </svg>
69
+ </button>
70
+ {#if isOpen}
71
+ <div class="dropdown">
72
+ {#each normalizedOptions as option (option.value)}
73
+ <label class="dropdown-item">
74
+ <input
75
+ type="checkbox"
76
+ checked={value?.includes(option.value) || false}
77
+ onchange={() => toggleOption(option.value)}
78
+ />
79
+ <span>{option.label}</span>
80
+ </label>
81
+ {/each}
82
+ </div>
83
+ {/if}
84
+ </div>
85
+ <div class="unset-area">
86
+ {#if !isUnset}
87
+ <button class="btn_unset" onclick={handleUnset}>
88
+ <svg
89
+ class="close"
90
+ xmlns="http://www.w3.org/2000/svg"
91
+ width="12"
92
+ height="12"
93
+ viewBox="0 0 24 24"
94
+ fill="none"
95
+ stroke="currentColor"
96
+ stroke-width="2"
97
+ stroke-linecap="round"
98
+ stroke-linejoin="round"
99
+ >
100
+ <path d="M18 6L6 18M6 6l12 12" />
101
+ </svg>
102
+ unset
103
+ </button>
104
+ {:else}
105
+ <span class="unset-info">is not set</span>
106
+ {/if}
107
+ </div>
108
+ </div>
109
+ {:else if control === 'checkboxes'}
110
+ <div class="checkboxes-container">
111
+ {#each normalizedOptions as option (option.value)}
112
+ <label class="checkbox-item">
113
+ <input
114
+ type="checkbox"
115
+ checked={value?.includes(option.value) || false}
116
+ onchange={() => toggleOption(option.value)}
117
+ />
118
+ <span>{option.label}</span>
119
+ </label>
120
+ {/each}
121
+ </div>
122
+ <div class="unset-area">
123
+ {#if !isUnset}
124
+ <button class="btn_unset checkboxes-btn-unset" onclick={handleUnset}>
125
+ <svg
126
+ class="close"
127
+ xmlns="http://www.w3.org/2000/svg"
128
+ width="12"
129
+ height="12"
130
+ viewBox="0 0 24 24"
131
+ fill="none"
132
+ stroke="currentColor"
133
+ stroke-width="2"
134
+ stroke-linecap="round"
135
+ stroke-linejoin="round"
136
+ >
137
+ <path d="M18 6L6 18M6 6l12 12" />
138
+ </svg>
139
+ unset
140
+ </button>
141
+ {:else}
142
+ <div class="unset-info checkboxes-unset">is not set</div>
143
+ {/if}
144
+ </div>
145
+ {/if}
146
+
147
+ <style lang="scss">
148
+ @use './button_unset.scss';
149
+
150
+ .row {
151
+ display: flex;
152
+ gap: 0.5rem;
153
+ align-items: center;
154
+ }
155
+
156
+ .select-wrapper {
157
+ flex: 1;
158
+ position: relative;
159
+ }
160
+
161
+ .select-button {
162
+ width: 100%;
163
+ height: 1.5rem;
164
+ padding: 0.125rem 0.5rem;
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: space-between;
168
+ border: 1px solid var(--c-primary);
169
+ border-radius: 0.125rem;
170
+ background-color: var(--c-basic-0);
171
+ font-size: 0.938rem;
172
+ color: var(--c-basic-800);
173
+ cursor: pointer;
174
+ }
175
+
176
+ .select-button:focus {
177
+ outline: none;
178
+ background-color: var(--c-primary-bg);
179
+ box-shadow: 0 0 0 1px var(--c-primary);
180
+ }
181
+
182
+ .selected-text {
183
+ flex: 1;
184
+ text-align: left;
185
+ }
186
+
187
+ .placeholder {
188
+ color: var(--c-basic-500);
189
+ }
190
+
191
+ .arrow {
192
+ transition: transform 0.2s;
193
+ color: var(--c-basic-600);
194
+ }
195
+
196
+ .arrow.open {
197
+ transform: rotate(180deg);
198
+ }
199
+
200
+ .dropdown {
201
+ position: absolute;
202
+ top: calc(100% + 2px);
203
+ left: 0;
204
+ right: 0;
205
+ max-height: 200px;
206
+ overflow-y: auto;
207
+ background: var(--c-basic-0);
208
+ border: 1px solid var(--c-primary);
209
+ border-radius: 0.125rem;
210
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
211
+ z-index: 100;
212
+ }
213
+
214
+ .dropdown-item {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 0.5rem;
218
+ padding: 0.375rem 0.5rem;
219
+ cursor: pointer;
220
+ font-size: 0.938rem;
221
+ color: var(--c-basic-700);
222
+ }
223
+
224
+ .dropdown-item:hover {
225
+ background-color: var(--c-primary-bg);
226
+ color: var(--c-basic-800);
227
+ }
228
+
229
+ .dropdown-item span {
230
+ user-select: none;
231
+ }
232
+
233
+ .dropdown-item input[type='checkbox'] {
234
+ cursor: pointer;
235
+ margin: 0;
236
+ width: 1.125rem;
237
+ height: 1.125rem;
238
+ border: 1px solid var(--c-primary);
239
+ background-color: var(--c-basic-0);
240
+ }
241
+
242
+ @supports (appearance: none) {
243
+ .dropdown-item input[type='checkbox'] {
244
+ appearance: none;
245
+ position: relative;
246
+ border-radius: 0.125rem;
247
+ transition: all 0.15s ease;
248
+ }
249
+
250
+ .dropdown-item input[type='checkbox']:hover {
251
+ border-color: var(--c-primary);
252
+ }
253
+
254
+ .dropdown-item input[type='checkbox']:checked {
255
+ border-color: var(--c-primary);
256
+ background: var(--c-primary);
257
+ }
258
+
259
+ .dropdown-item input[type='checkbox']:checked::before {
260
+ content: '';
261
+ position: absolute;
262
+ top: 50%;
263
+ left: 50%;
264
+ transform: translate(-50%, -50%) rotate(45deg);
265
+ width: 0.313rem;
266
+ height: 0.563rem;
267
+ border: 0.125rem solid var(--c-basic-0);
268
+ border-top: 0;
269
+ border-left: 0;
270
+ }
271
+
272
+ .dropdown-item input[type='checkbox']:focus {
273
+ outline: none;
274
+ box-shadow: 0 0 0 1px var(--c-primary);
275
+ }
276
+ }
277
+
278
+ .checkboxes-container {
279
+ display: flex;
280
+ flex-direction: column;
281
+ gap: 0.5rem;
282
+ }
283
+
284
+ .checkbox-item {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 0.5rem;
288
+ cursor: pointer;
289
+ font-size: 0.938rem;
290
+ color: var(--c-basic-700);
291
+ }
292
+
293
+ .checkbox-item:hover {
294
+ color: var(--c-basic-800);
295
+ }
296
+
297
+ .checkbox-item span {
298
+ user-select: none;
299
+ }
300
+
301
+ .checkbox-item input[type='checkbox'] {
302
+ cursor: pointer;
303
+ margin: 0;
304
+ width: 1.125rem;
305
+ height: 1.125rem;
306
+ border: 1px solid var(--c-primary);
307
+ background-color: var(--c-basic-0);
308
+ }
309
+
310
+ @supports (appearance: none) {
311
+ .checkbox-item input[type='checkbox'] {
312
+ appearance: none;
313
+ position: relative;
314
+ border-radius: 0.125rem;
315
+ transition: all 0.15s ease;
316
+ }
317
+
318
+ .checkbox-item input[type='checkbox']:hover {
319
+ border-color: var(--c-primary);
320
+ }
321
+
322
+ .checkbox-item input[type='checkbox']:checked {
323
+ border-color: var(--c-primary);
324
+ background: var(--c-primary);
325
+ }
326
+
327
+ .checkbox-item input[type='checkbox']:checked::before {
328
+ content: '';
329
+ position: absolute;
330
+ top: 50%;
331
+ left: 50%;
332
+ transform: translate(-50%, -50%) rotate(45deg);
333
+ width: 0.313rem;
334
+ height: 0.563rem;
335
+ border: 0.125rem solid var(--c-basic-0);
336
+ border-top: 0;
337
+ border-left: 0;
338
+ }
339
+
340
+ .checkbox-item input[type='checkbox']:focus {
341
+ outline: none;
342
+ box-shadow: 0 0 0 1px var(--c-primary);
343
+ }
344
+ }
345
+
346
+ .checkboxes-unset,
347
+ .checkboxes-btn-unset {
348
+ margin: 0.75rem 0 0;
349
+ }
350
+
351
+ .checkboxes-unset {
352
+ line-height: 1.25rem;
353
+ }
354
+ </style>