@salmexio/ui 0.3.1 → 1.0.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.
- package/README.md +52 -3
- package/dist/dialogs/ContextMenu/ContextMenu.svelte +96 -93
- package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +3 -2
- package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts.map +1 -1
- package/dist/dialogs/Modal/Modal.svelte +112 -102
- package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
- package/dist/feedback/Alert/Alert.svelte +115 -221
- package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
- package/dist/feedback/ProgressBar/ProgressBar.svelte +246 -0
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +40 -0
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -0
- package/dist/feedback/ProgressBar/index.d.ts +2 -0
- package/dist/feedback/ProgressBar/index.d.ts.map +1 -0
- package/dist/feedback/ProgressBar/index.js +1 -0
- package/dist/feedback/Skeleton/Skeleton.svelte +153 -0
- package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +37 -0
- package/dist/feedback/Skeleton/Skeleton.svelte.d.ts.map +1 -0
- package/dist/feedback/Skeleton/index.d.ts +2 -0
- package/dist/feedback/Skeleton/index.d.ts.map +1 -0
- package/dist/feedback/Skeleton/index.js +1 -0
- package/dist/feedback/Spinner/Spinner.svelte +88 -154
- package/dist/feedback/Spinner/Spinner.svelte.d.ts +5 -3
- package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -1
- package/dist/feedback/Toast/Toaster.svelte +431 -0
- package/dist/feedback/Toast/Toaster.svelte.d.ts +22 -0
- package/dist/feedback/Toast/Toaster.svelte.d.ts.map +1 -0
- package/dist/feedback/Toast/index.d.ts +4 -0
- package/dist/feedback/Toast/index.d.ts.map +1 -0
- package/dist/feedback/Toast/index.js +2 -0
- package/dist/feedback/Toast/toastStore.d.ts +34 -0
- package/dist/feedback/Toast/toastStore.d.ts.map +1 -0
- package/dist/feedback/Toast/toastStore.js +43 -0
- package/dist/feedback/index.d.ts +4 -0
- package/dist/feedback/index.d.ts.map +1 -1
- package/dist/feedback/index.js +3 -0
- package/dist/forms/Checkbox/Checkbox.svelte +82 -103
- package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
- package/dist/forms/Select/Select.svelte +136 -177
- package/dist/forms/Select/Select.svelte.d.ts +1 -1
- package/dist/forms/Slider/Slider.svelte +356 -0
- package/dist/forms/Slider/Slider.svelte.d.ts +50 -0
- package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -0
- package/dist/forms/Slider/index.d.ts +2 -0
- package/dist/forms/Slider/index.d.ts.map +1 -0
- package/dist/forms/Slider/index.js +1 -0
- package/dist/forms/TextInput/TextInput.svelte +148 -164
- package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
- package/dist/forms/Textarea/Textarea.svelte +615 -0
- package/dist/forms/Textarea/Textarea.svelte.d.ts +47 -0
- package/dist/forms/Textarea/Textarea.svelte.d.ts.map +1 -0
- package/dist/forms/Textarea/index.d.ts +2 -0
- package/dist/forms/Textarea/index.d.ts.map +1 -0
- package/dist/forms/Textarea/index.js +1 -0
- package/dist/forms/Toggle/Toggle.svelte +239 -0
- package/dist/forms/Toggle/Toggle.svelte.d.ts +39 -0
- package/dist/forms/Toggle/Toggle.svelte.d.ts.map +1 -0
- package/dist/forms/Toggle/index.d.ts +2 -0
- package/dist/forms/Toggle/index.d.ts.map +1 -0
- package/dist/forms/Toggle/index.js +1 -0
- package/dist/forms/index.d.ts +3 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +3 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/layout/Card/Card.svelte +64 -40
- package/dist/layout/Card/Card.svelte.d.ts +1 -1
- package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
- package/dist/layout/Container/Container.svelte +71 -71
- package/dist/layout/Container/Container.svelte.d.ts +2 -2
- package/dist/navigation/CommandPalette/CommandPalette.svelte +410 -181
- package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +8 -3
- package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts.map +1 -1
- package/dist/navigation/Tabs/Tabs.svelte +94 -178
- package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
- package/dist/primitives/Badge/Badge.svelte +85 -223
- package/dist/primitives/Badge/Badge.svelte.d.ts +2 -2
- package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -1
- package/dist/primitives/Button/Button.svelte +138 -208
- package/dist/primitives/Button/Button.svelte.d.ts +3 -3
- package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
- package/dist/primitives/Tooltip/Tooltip.svelte +260 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +36 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/index.d.ts +2 -0
- package/dist/primitives/Tooltip/index.d.ts.map +1 -0
- package/dist/primitives/Tooltip/index.js +1 -0
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +1 -0
- package/dist/styles/tokens.css +200 -259
- package/package.json +5 -5
- package/dist/windowing/Window/Window.svelte +0 -602
- package/dist/windowing/Window/Window.svelte.d.ts +0 -65
- package/dist/windowing/Window/Window.svelte.d.ts.map +0 -1
- package/dist/windowing/Window/index.d.ts +0 -2
- package/dist/windowing/Window/index.d.ts.map +0 -1
- package/dist/windowing/Window/index.js +0 -1
- package/dist/windowing/WindowManager/WindowManager.svelte +0 -410
- package/dist/windowing/WindowManager/WindowManager.svelte.d.ts +0 -38
- package/dist/windowing/WindowManager/WindowManager.svelte.d.ts.map +0 -1
- package/dist/windowing/WindowManager/index.d.ts +0 -2
- package/dist/windowing/WindowManager/index.d.ts.map +0 -1
- package/dist/windowing/WindowManager/index.js +0 -1
- package/dist/windowing/index.d.ts +0 -5
- package/dist/windowing/index.d.ts.map +0 -1
- package/dist/windowing/index.js +0 -3
- package/dist/windowing/windowStore.svelte.d.ts +0 -49
- package/dist/windowing/windowStore.svelte.d.ts.map +0 -1
- package/dist/windowing/windowStore.svelte.js +0 -170
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Modal
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Neo-Brutalist Dark — Dialog with glass surface, subtle border, clean header.
|
|
5
5
|
Follows WAI-ARIA Dialog (Modal) pattern: focus trap, restore focus on close,
|
|
6
6
|
aria-labelledby, aria-describedby, aria-modal. Escape and backdrop close.
|
|
7
7
|
For full inert support (background not focusable), render modal in a portal
|
|
@@ -88,10 +88,10 @@ function setInitialFocus() {
|
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
if (!dialogElement) return;
|
|
91
|
-
const titleEl = dialogElement.querySelector<HTMLElement>('.
|
|
92
|
-
const body = dialogElement.querySelector('.
|
|
91
|
+
const titleEl = dialogElement.querySelector<HTMLElement>('.sx-modal-title-wrap');
|
|
92
|
+
const body = dialogElement.querySelector('.sx-modal-body');
|
|
93
93
|
const first = body?.querySelector<HTMLElement>(FOCUSABLE);
|
|
94
|
-
const closeBtn = dialogElement.querySelector<HTMLElement>('.
|
|
94
|
+
const closeBtn = dialogElement.querySelector<HTMLElement>('.sx-modal-close');
|
|
95
95
|
|
|
96
96
|
if (initialFocusStrategy === 'title' && titleEl) {
|
|
97
97
|
titleEl.focus();
|
|
@@ -163,7 +163,7 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
163
163
|
{#if open}
|
|
164
164
|
<!-- Backdrop -->
|
|
165
165
|
<div
|
|
166
|
-
class="
|
|
166
|
+
class="sx-modal-backdrop sx-modal-position-{position}"
|
|
167
167
|
role="presentation"
|
|
168
168
|
onclick={handleBackdropClick}
|
|
169
169
|
onkeydown={() => {}}
|
|
@@ -171,7 +171,7 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
171
171
|
<div
|
|
172
172
|
bind:this={dialogElement}
|
|
173
173
|
id={modalId}
|
|
174
|
-
class="
|
|
174
|
+
class="sx-modal-container sx-modal-{size} sx-modal-scroll-{scrollBehavior} {className}"
|
|
175
175
|
role="dialog"
|
|
176
176
|
aria-modal="true"
|
|
177
177
|
aria-labelledby={titleId}
|
|
@@ -179,18 +179,18 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
179
179
|
data-testid={testId}
|
|
180
180
|
>
|
|
181
181
|
{#if header || title || showCloseButton}
|
|
182
|
-
<div class="
|
|
183
|
-
<div id={titleId} class="
|
|
182
|
+
<div class="sx-modal-header">
|
|
183
|
+
<div id={titleId} class="sx-modal-title-wrap" tabindex="-1">
|
|
184
184
|
{#if header}
|
|
185
185
|
{@render header()}
|
|
186
186
|
{:else if title}
|
|
187
|
-
<h2 class="
|
|
187
|
+
<h2 class="sx-modal-title">{title}</h2>
|
|
188
188
|
{/if}
|
|
189
189
|
</div>
|
|
190
190
|
{#if showCloseButton && !preventClose}
|
|
191
191
|
<button
|
|
192
192
|
type="button"
|
|
193
|
-
class="
|
|
193
|
+
class="sx-modal-close"
|
|
194
194
|
onclick={handleClose}
|
|
195
195
|
aria-label={closeLabel}
|
|
196
196
|
>
|
|
@@ -203,12 +203,12 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
203
203
|
</div>
|
|
204
204
|
{/if}
|
|
205
205
|
{#if children}
|
|
206
|
-
<div id={descriptionId} class="
|
|
206
|
+
<div id={descriptionId} class="sx-modal-body">
|
|
207
207
|
{@render children()}
|
|
208
208
|
</div>
|
|
209
209
|
{/if}
|
|
210
210
|
{#if footer}
|
|
211
|
-
<div class="
|
|
211
|
+
<div class="sx-modal-footer">
|
|
212
212
|
{@render footer()}
|
|
213
213
|
</div>
|
|
214
214
|
{/if}
|
|
@@ -217,28 +217,32 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
217
217
|
{/if}
|
|
218
218
|
|
|
219
219
|
<style>
|
|
220
|
-
|
|
220
|
+
/* ========================================
|
|
221
|
+
BACKDROP
|
|
222
|
+
======================================== */
|
|
223
|
+
.sx-modal-backdrop {
|
|
221
224
|
position: fixed;
|
|
222
225
|
inset: 0;
|
|
223
|
-
z-index: var(--
|
|
226
|
+
z-index: var(--sx-z-modal-backdrop, 1040);
|
|
224
227
|
display: flex;
|
|
225
228
|
justify-content: center;
|
|
226
|
-
padding: var(--
|
|
227
|
-
background:
|
|
229
|
+
padding: var(--sx-space-6);
|
|
230
|
+
background: rgba(10, 10, 15, 0.7);
|
|
231
|
+
backdrop-filter: blur(4px);
|
|
228
232
|
overflow-y: auto;
|
|
229
|
-
animation:
|
|
233
|
+
animation: sx-modal-fade-in var(--sx-transition-base);
|
|
230
234
|
}
|
|
231
235
|
|
|
232
|
-
.
|
|
236
|
+
.sx-modal-position-center {
|
|
233
237
|
align-items: center;
|
|
234
238
|
}
|
|
235
239
|
|
|
236
|
-
.
|
|
240
|
+
.sx-modal-position-top {
|
|
237
241
|
align-items: flex-start;
|
|
238
242
|
padding-top: 3rem;
|
|
239
243
|
}
|
|
240
244
|
|
|
241
|
-
@keyframes
|
|
245
|
+
@keyframes sx-modal-fade-in {
|
|
242
246
|
from {
|
|
243
247
|
opacity: 0;
|
|
244
248
|
}
|
|
@@ -247,178 +251,184 @@ const closeLabel = $derived(closeBtnAriaLabel ?? 'Close dialog');
|
|
|
247
251
|
}
|
|
248
252
|
}
|
|
249
253
|
|
|
250
|
-
|
|
254
|
+
/* ========================================
|
|
255
|
+
CONTAINER
|
|
256
|
+
======================================== */
|
|
257
|
+
.sx-modal-container {
|
|
251
258
|
position: relative;
|
|
252
259
|
display: flex;
|
|
253
260
|
flex-direction: column;
|
|
254
261
|
width: 100%;
|
|
255
262
|
max-height: calc(100vh - 2rem);
|
|
256
|
-
background:
|
|
257
|
-
border:
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
background: var(--sx-color-surface);
|
|
264
|
+
border: 1px solid var(--sx-color-border-strong);
|
|
265
|
+
border-radius: var(--sx-radius-lg);
|
|
266
|
+
box-shadow: var(--sx-shadow-xl);
|
|
267
|
+
animation: sx-modal-scale-in 200ms ease-out;
|
|
260
268
|
overflow: hidden;
|
|
261
269
|
}
|
|
262
270
|
|
|
263
|
-
@keyframes
|
|
271
|
+
@keyframes sx-modal-scale-in {
|
|
264
272
|
from {
|
|
265
273
|
opacity: 0;
|
|
266
|
-
transform: scale(0.
|
|
274
|
+
transform: scale(0.95);
|
|
267
275
|
}
|
|
268
276
|
to {
|
|
269
277
|
opacity: 1;
|
|
270
|
-
transform: scale(1)
|
|
278
|
+
transform: scale(1);
|
|
271
279
|
}
|
|
272
280
|
}
|
|
273
281
|
|
|
274
|
-
|
|
282
|
+
/* ========================================
|
|
283
|
+
SIZES
|
|
284
|
+
======================================== */
|
|
285
|
+
.sx-modal-sm {
|
|
275
286
|
max-width: 24rem;
|
|
276
287
|
}
|
|
277
|
-
.
|
|
288
|
+
.sx-modal-md {
|
|
278
289
|
max-width: 28rem;
|
|
279
290
|
}
|
|
280
|
-
.
|
|
291
|
+
.sx-modal-lg {
|
|
281
292
|
max-width: 32rem;
|
|
282
293
|
}
|
|
283
|
-
.
|
|
294
|
+
.sx-modal-xl {
|
|
284
295
|
max-width: 40rem;
|
|
285
296
|
}
|
|
286
|
-
.
|
|
297
|
+
.sx-modal-full {
|
|
287
298
|
max-width: 56rem;
|
|
288
299
|
}
|
|
289
300
|
|
|
290
|
-
|
|
301
|
+
/* ========================================
|
|
302
|
+
SCROLL BEHAVIOR
|
|
303
|
+
======================================== */
|
|
304
|
+
.sx-modal-scroll-inside {
|
|
291
305
|
max-height: calc(100vh - 4rem);
|
|
292
306
|
}
|
|
293
307
|
|
|
294
|
-
.
|
|
308
|
+
.sx-modal-scroll-inside .sx-modal-body {
|
|
295
309
|
overflow-y: auto;
|
|
296
310
|
}
|
|
297
311
|
|
|
298
|
-
/*
|
|
299
|
-
|
|
312
|
+
/* ========================================
|
|
313
|
+
HEADER
|
|
314
|
+
======================================== */
|
|
315
|
+
.sx-modal-header {
|
|
300
316
|
display: flex;
|
|
301
317
|
align-items: center;
|
|
302
318
|
justify-content: space-between;
|
|
303
|
-
gap: var(--
|
|
304
|
-
padding: var(--
|
|
305
|
-
background:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
rgb(var(--salmex-titlebar-bold))
|
|
309
|
-
);
|
|
310
|
-
color: rgb(var(--salmex-chalk-white));
|
|
311
|
-
border-bottom: 3px solid rgb(var(--salmex-button-dark-edge));
|
|
319
|
+
gap: var(--sx-space-4);
|
|
320
|
+
padding: var(--sx-space-4);
|
|
321
|
+
background: var(--sx-color-surface-2);
|
|
322
|
+
border-bottom: 1px solid var(--sx-color-border);
|
|
323
|
+
border-radius: calc(var(--sx-radius-lg) - 1px) calc(var(--sx-radius-lg) - 1px) 0 0;
|
|
312
324
|
flex-shrink: 0;
|
|
313
|
-
font-family: var(--salmex-font-display);
|
|
314
325
|
}
|
|
315
326
|
|
|
316
|
-
|
|
317
|
-
background: linear-gradient(
|
|
318
|
-
90deg,
|
|
319
|
-
rgb(0 100 220),
|
|
320
|
-
rgb(0 140 255)
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
.salmex-modal-title-wrap {
|
|
327
|
+
.sx-modal-title-wrap {
|
|
325
328
|
flex: 1;
|
|
326
329
|
min-width: 0;
|
|
327
330
|
outline: none;
|
|
328
331
|
}
|
|
329
332
|
|
|
330
|
-
.
|
|
331
|
-
outline: 2px solid
|
|
333
|
+
.sx-modal-title-wrap:focus-visible {
|
|
334
|
+
outline: 2px solid var(--sx-color-cyan);
|
|
332
335
|
outline-offset: 2px;
|
|
333
336
|
}
|
|
334
337
|
|
|
335
|
-
.
|
|
338
|
+
.sx-modal-title {
|
|
336
339
|
margin: 0;
|
|
337
|
-
font-
|
|
338
|
-
font-
|
|
339
|
-
|
|
340
|
-
letter-spacing: 0.5px;
|
|
340
|
+
font-family: var(--sx-font-display);
|
|
341
|
+
font-size: var(--sx-text-lg);
|
|
342
|
+
font-weight: 600;
|
|
341
343
|
line-height: 1.3;
|
|
344
|
+
color: var(--sx-color-text);
|
|
342
345
|
}
|
|
343
346
|
|
|
344
|
-
|
|
347
|
+
/* ========================================
|
|
348
|
+
CLOSE BUTTON
|
|
349
|
+
======================================== */
|
|
350
|
+
.sx-modal-close {
|
|
345
351
|
display: flex;
|
|
346
352
|
align-items: center;
|
|
347
353
|
justify-content: center;
|
|
348
354
|
width: 32px;
|
|
349
355
|
height: 32px;
|
|
350
356
|
padding: 0;
|
|
351
|
-
background:
|
|
352
|
-
border:
|
|
353
|
-
|
|
357
|
+
background: transparent;
|
|
358
|
+
border: 1px solid transparent;
|
|
359
|
+
border-radius: var(--sx-radius-sm);
|
|
360
|
+
color: var(--sx-color-text-secondary);
|
|
354
361
|
cursor: pointer;
|
|
355
362
|
flex-shrink: 0;
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
2px 2px 0 rgb(0 0 0 / 0.3);
|
|
360
|
-
transition: all var(--salmex-transition-fast);
|
|
363
|
+
transition:
|
|
364
|
+
color var(--sx-transition-fast),
|
|
365
|
+
background var(--sx-transition-fast);
|
|
361
366
|
}
|
|
362
367
|
|
|
363
|
-
.
|
|
364
|
-
background:
|
|
368
|
+
.sx-modal-close:hover {
|
|
369
|
+
background: var(--sx-color-surface-3);
|
|
370
|
+
color: var(--sx-color-text);
|
|
365
371
|
}
|
|
366
372
|
|
|
367
|
-
.
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
inset 1px 1px 0 rgb(var(--salmex-button-shadow)),
|
|
371
|
-
1px 1px 0 rgb(0 0 0 / 0.3);
|
|
372
|
-
transform: translate(1px, 1px);
|
|
373
|
+
.sx-modal-close:active {
|
|
374
|
+
background: var(--sx-color-surface-3);
|
|
375
|
+
color: var(--sx-color-text);
|
|
373
376
|
}
|
|
374
377
|
|
|
375
|
-
.
|
|
376
|
-
outline:
|
|
377
|
-
|
|
378
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
379
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
|
|
380
|
-
2px 2px 0 rgb(0 0 0 / 0.3),
|
|
381
|
-
0 0 0 2px rgb(var(--salmex-midnight-black)),
|
|
382
|
-
0 0 0 5px rgb(var(--salmex-crown-yellow));
|
|
378
|
+
.sx-modal-close:focus-visible {
|
|
379
|
+
outline: 2px solid var(--sx-color-cyan);
|
|
380
|
+
outline-offset: 2px;
|
|
383
381
|
}
|
|
384
382
|
|
|
385
|
-
|
|
386
|
-
|
|
383
|
+
/* ========================================
|
|
384
|
+
BODY
|
|
385
|
+
======================================== */
|
|
386
|
+
.sx-modal-body {
|
|
387
|
+
padding: var(--sx-space-6);
|
|
387
388
|
flex: 1;
|
|
388
389
|
min-height: 0;
|
|
389
|
-
|
|
390
|
-
color: rgb(var(--salmex-text-primary));
|
|
390
|
+
color: var(--sx-color-text-secondary);
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
|
|
393
|
+
/* ========================================
|
|
394
|
+
FOOTER
|
|
395
|
+
======================================== */
|
|
396
|
+
.sx-modal-footer {
|
|
394
397
|
display: flex;
|
|
395
398
|
align-items: center;
|
|
396
399
|
justify-content: flex-end;
|
|
397
|
-
gap: var(--
|
|
398
|
-
padding: var(--
|
|
399
|
-
border-top:
|
|
400
|
-
|
|
400
|
+
gap: var(--sx-space-3);
|
|
401
|
+
padding: var(--sx-space-4);
|
|
402
|
+
border-top: 1px solid var(--sx-color-border);
|
|
403
|
+
border-radius: 0 0 calc(var(--sx-radius-lg) - 1px) calc(var(--sx-radius-lg) - 1px);
|
|
404
|
+
background: var(--sx-color-surface-2);
|
|
401
405
|
flex-shrink: 0;
|
|
402
406
|
}
|
|
403
407
|
|
|
408
|
+
/* ========================================
|
|
409
|
+
REDUCED MOTION
|
|
410
|
+
======================================== */
|
|
404
411
|
@media (prefers-reduced-motion: reduce) {
|
|
405
|
-
.
|
|
406
|
-
.
|
|
412
|
+
.sx-modal-backdrop,
|
|
413
|
+
.sx-modal-container {
|
|
407
414
|
animation: none;
|
|
408
415
|
}
|
|
409
416
|
}
|
|
410
417
|
|
|
418
|
+
/* ========================================
|
|
419
|
+
MOBILE
|
|
420
|
+
======================================== */
|
|
411
421
|
@media (max-width: 640px) {
|
|
412
|
-
.
|
|
422
|
+
.sx-modal-backdrop {
|
|
413
423
|
padding: 0;
|
|
414
424
|
align-items: flex-end;
|
|
415
425
|
}
|
|
416
426
|
|
|
417
|
-
.
|
|
427
|
+
.sx-modal-position-top {
|
|
418
428
|
padding-top: 0;
|
|
419
429
|
}
|
|
420
430
|
|
|
421
|
-
.
|
|
431
|
+
.sx-modal-container {
|
|
422
432
|
max-width: 100%;
|
|
423
433
|
max-height: 90vh;
|
|
424
434
|
margin: 0;
|
|
@@ -31,7 +31,7 @@ interface Props {
|
|
|
31
31
|
/**
|
|
32
32
|
* Modal
|
|
33
33
|
*
|
|
34
|
-
*
|
|
34
|
+
* Neo-Brutalist Dark — Dialog with glass surface, subtle border, clean header.
|
|
35
35
|
* Follows WAI-ARIA Dialog (Modal) pattern: focus trap, restore focus on close,
|
|
36
36
|
* aria-labelledby, aria-describedby, aria-modal. Escape and backdrop close.
|
|
37
37
|
* For full inert support (background not focusable), render modal in a portal
|