@aspect-ops/exon-ui 0.2.1 → 0.3.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 (75) hide show
  1. package/dist/components/AspectRatio/AspectRatio.svelte +1 -0
  2. package/dist/components/CTASection/CTASection.svelte +298 -0
  3. package/dist/components/CTASection/CTASection.svelte.d.ts +15 -0
  4. package/dist/components/CTASection/index.d.ts +2 -0
  5. package/dist/components/CTASection/index.js +1 -0
  6. package/dist/components/Card/FlipCard.svelte +155 -0
  7. package/dist/components/Card/FlipCard.svelte.d.ts +13 -0
  8. package/dist/components/Card/index.d.ts +1 -0
  9. package/dist/components/Card/index.js +1 -0
  10. package/dist/components/Container/Container.svelte +1 -0
  11. package/dist/components/DataTable/DataTable.svelte +460 -0
  12. package/dist/components/DataTable/DataTable.svelte.d.ts +49 -0
  13. package/dist/components/DataTable/index.d.ts +2 -0
  14. package/dist/components/DataTable/index.js +1 -0
  15. package/dist/components/DoughnutChart/DoughnutChart.svelte +20 -2
  16. package/dist/components/GlobalHeader/GlobalHeader.svelte +692 -0
  17. package/dist/components/GlobalHeader/GlobalHeader.svelte.d.ts +3 -0
  18. package/dist/components/GlobalHeader/index.d.ts +2 -0
  19. package/dist/components/GlobalHeader/index.js +1 -0
  20. package/dist/components/Hero/Hero.svelte +306 -0
  21. package/dist/components/Hero/Hero.svelte.d.ts +18 -0
  22. package/dist/components/Hero/index.d.ts +2 -0
  23. package/dist/components/Hero/index.js +1 -0
  24. package/dist/components/Icon/Icon.svelte +15 -18
  25. package/dist/components/Icon/Icon.svelte.d.ts +2 -1
  26. package/dist/components/LogoCloud/LogoCloud.svelte +333 -0
  27. package/dist/components/LogoCloud/LogoCloud.svelte.d.ts +20 -0
  28. package/dist/components/LogoCloud/index.d.ts +2 -0
  29. package/dist/components/LogoCloud/index.js +1 -0
  30. package/dist/components/Menu/MenuContent.svelte +1 -0
  31. package/dist/components/Menu/MenuSubContent.svelte +1 -0
  32. package/dist/components/Mermaid/Mermaid.svelte +121 -7
  33. package/dist/components/Mermaid/Mermaid.svelte.d.ts +10 -0
  34. package/dist/components/PageHeader/PageHeader.svelte +140 -0
  35. package/dist/components/PageHeader/PageHeader.svelte.d.ts +30 -0
  36. package/dist/components/PageHeader/index.d.ts +1 -0
  37. package/dist/components/PageHeader/index.js +1 -0
  38. package/dist/components/ServiceCard/ServiceCard.svelte +359 -0
  39. package/dist/components/ServiceCard/ServiceCard.svelte.d.ts +16 -0
  40. package/dist/components/ServiceCard/index.d.ts +1 -0
  41. package/dist/components/ServiceCard/index.js +1 -0
  42. package/dist/components/SplitSection/SplitSection.svelte +194 -0
  43. package/dist/components/SplitSection/SplitSection.svelte.d.ts +15 -0
  44. package/dist/components/SplitSection/index.d.ts +1 -0
  45. package/dist/components/SplitSection/index.js +1 -0
  46. package/dist/components/StatCircle/StatCircle.svelte +172 -0
  47. package/dist/components/StatCircle/StatCircle.svelte.d.ts +19 -0
  48. package/dist/components/StatCircle/index.d.ts +1 -0
  49. package/dist/components/StatCircle/index.js +1 -0
  50. package/dist/components/StatsCard/StatsCard.svelte +301 -0
  51. package/dist/components/StatsCard/StatsCard.svelte.d.ts +32 -0
  52. package/dist/components/StatsCard/index.d.ts +2 -0
  53. package/dist/components/StatsCard/index.js +1 -0
  54. package/dist/components/StatusBadge/StatusBadge.svelte +221 -0
  55. package/dist/components/StatusBadge/StatusBadge.svelte.d.ts +22 -0
  56. package/dist/components/StatusBadge/index.d.ts +2 -0
  57. package/dist/components/StatusBadge/index.js +1 -0
  58. package/dist/components/StatusBanner/StatusBanner.svelte +325 -0
  59. package/dist/components/StatusBanner/StatusBanner.svelte.d.ts +13 -0
  60. package/dist/components/StatusBanner/index.d.ts +1 -0
  61. package/dist/components/StatusBanner/index.js +1 -0
  62. package/dist/components/TestimonialCard/TestimonialCard.svelte +290 -0
  63. package/dist/components/TestimonialCard/TestimonialCard.svelte.d.ts +14 -0
  64. package/dist/components/TestimonialCard/index.d.ts +1 -0
  65. package/dist/components/TestimonialCard/index.js +1 -0
  66. package/dist/components/Timeline/Timeline.svelte +444 -0
  67. package/dist/components/Timeline/Timeline.svelte.d.ts +19 -0
  68. package/dist/components/Timeline/index.d.ts +2 -0
  69. package/dist/components/Timeline/index.js +1 -0
  70. package/dist/index.d.ts +24 -2
  71. package/dist/index.js +16 -1
  72. package/dist/types/data-display.d.ts +72 -0
  73. package/dist/types/feedback.d.ts +10 -0
  74. package/dist/types/index.d.ts +2 -2
  75. package/package.json +3 -2
@@ -0,0 +1,692 @@
1
+ <script lang="ts">
2
+ import { onMount, onDestroy } from 'svelte';
3
+
4
+ export interface NavItem {
5
+ label: string;
6
+ href?: string;
7
+ children?: NavItem[];
8
+ icon?: string;
9
+ }
10
+
11
+ export interface GlobalHeaderProps {
12
+ logo?: string | import('svelte').Snippet;
13
+ logoHref?: string;
14
+ navItems: NavItem[];
15
+ variant?: 'default' | 'transparent' | 'floating';
16
+ sticky?: boolean;
17
+ showOnScroll?: boolean;
18
+ mobileBreakpoint?: number;
19
+ class?: string;
20
+ actions?: import('svelte').Snippet;
21
+ mobileMenu?: import('svelte').Snippet;
22
+ }
23
+
24
+ interface Props extends GlobalHeaderProps {
25
+ logo?: string | import('svelte').Snippet;
26
+ actions?: import('svelte').Snippet;
27
+ mobileMenu?: import('svelte').Snippet;
28
+ }
29
+
30
+ let {
31
+ logo,
32
+ logoHref = '/',
33
+ navItems,
34
+ variant = 'default',
35
+ sticky = true,
36
+ showOnScroll = false,
37
+ mobileBreakpoint = 768,
38
+ class: className = '',
39
+ actions,
40
+ mobileMenu
41
+ }: Props = $props();
42
+
43
+ let mobileMenuOpen = $state(false);
44
+ let openDropdown = $state<number | null>(null);
45
+ let isScrollingUp = $state(true);
46
+ let lastScrollY = $state(0);
47
+ let headerElement: HTMLElement | null = $state(null);
48
+
49
+ function toggleMobileMenu() {
50
+ mobileMenuOpen = !mobileMenuOpen;
51
+ if (mobileMenuOpen) {
52
+ document.body.style.overflow = 'hidden';
53
+ } else {
54
+ document.body.style.overflow = '';
55
+ }
56
+ }
57
+
58
+ function closeMobileMenu() {
59
+ mobileMenuOpen = false;
60
+ document.body.style.overflow = '';
61
+ }
62
+
63
+ function toggleDropdown(index: number) {
64
+ openDropdown = openDropdown === index ? null : index;
65
+ }
66
+
67
+ function closeDropdown() {
68
+ openDropdown = null;
69
+ }
70
+
71
+ function handleKeydown(event: KeyboardEvent) {
72
+ if (event.key === 'Escape') {
73
+ if (mobileMenuOpen) {
74
+ closeMobileMenu();
75
+ }
76
+ if (openDropdown !== null) {
77
+ closeDropdown();
78
+ }
79
+ }
80
+ }
81
+
82
+ function handleScroll() {
83
+ if (!showOnScroll) return;
84
+
85
+ const currentScrollY = window.scrollY;
86
+
87
+ if (currentScrollY > lastScrollY && currentScrollY > 100) {
88
+ // Scrolling down
89
+ isScrollingUp = false;
90
+ } else if (currentScrollY < lastScrollY) {
91
+ // Scrolling up
92
+ isScrollingUp = true;
93
+ }
94
+
95
+ lastScrollY = currentScrollY;
96
+ }
97
+
98
+ onMount(() => {
99
+ if (showOnScroll) {
100
+ window.addEventListener('scroll', handleScroll, { passive: true });
101
+ }
102
+ });
103
+
104
+ onDestroy(() => {
105
+ if (showOnScroll) {
106
+ window.removeEventListener('scroll', handleScroll);
107
+ }
108
+ document.body.style.overflow = '';
109
+ });
110
+
111
+ const variantClass = $derived(
112
+ variant === 'transparent'
113
+ ? 'global-header--transparent'
114
+ : variant === 'floating'
115
+ ? 'global-header--floating'
116
+ : ''
117
+ );
118
+
119
+ const stickyClass = $derived(sticky ? 'global-header--sticky' : '');
120
+ const scrollClass = $derived(showOnScroll && !isScrollingUp ? 'global-header--hidden' : '');
121
+ </script>
122
+
123
+ <svelte:window onkeydown={handleKeydown} />
124
+
125
+ <header
126
+ bind:this={headerElement}
127
+ class="global-header {variantClass} {stickyClass} {scrollClass} {className}"
128
+ >
129
+ <div class="global-header__container">
130
+ {#if logo}
131
+ <a href={logoHref} class="global-header__logo">
132
+ {#if typeof logo === 'string'}
133
+ <img src={logo} alt="Logo" class="global-header__logo-img" />
134
+ {:else}
135
+ {@render logo()}
136
+ {/if}
137
+ </a>
138
+ {/if}
139
+
140
+ <nav class="global-header__nav" aria-label="Main navigation">
141
+ <ul class="global-header__nav-list">
142
+ {#each navItems as item, index}
143
+ <li class="global-header__nav-item">
144
+ {#if item.children && item.children.length > 0}
145
+ <button
146
+ type="button"
147
+ class="global-header__nav-link global-header__nav-link--dropdown"
148
+ onclick={() => toggleDropdown(index)}
149
+ aria-expanded={openDropdown === index}
150
+ aria-haspopup="true"
151
+ >
152
+ {#if item.icon}
153
+ <span class="global-header__nav-icon">{item.icon}</span>
154
+ {/if}
155
+ {item.label}
156
+ <span class="global-header__dropdown-arrow" aria-hidden="true">▼</span>
157
+ </button>
158
+
159
+ {#if openDropdown === index}
160
+ <ul class="global-header__dropdown" role="menu">
161
+ {#each item.children as child}
162
+ <li role="none">
163
+ <a
164
+ href={child.href || '#'}
165
+ class="global-header__dropdown-item"
166
+ role="menuitem"
167
+ onclick={closeDropdown}
168
+ >
169
+ {#if child.icon}
170
+ <span class="global-header__nav-icon">{child.icon}</span>
171
+ {/if}
172
+ {child.label}
173
+ </a>
174
+ </li>
175
+ {/each}
176
+ </ul>
177
+ {/if}
178
+ {:else}
179
+ <a href={item.href || '#'} class="global-header__nav-link">
180
+ {#if item.icon}
181
+ <span class="global-header__nav-icon">{item.icon}</span>
182
+ {/if}
183
+ {item.label}
184
+ </a>
185
+ {/if}
186
+ </li>
187
+ {/each}
188
+ </ul>
189
+ </nav>
190
+
191
+ {#if actions}
192
+ <div class="global-header__actions">
193
+ {@render actions()}
194
+ </div>
195
+ {/if}
196
+
197
+ <button
198
+ type="button"
199
+ class="global-header__hamburger"
200
+ onclick={toggleMobileMenu}
201
+ aria-expanded={mobileMenuOpen}
202
+ aria-controls="global-header-mobile-menu"
203
+ aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
204
+ >
205
+ <span
206
+ class="global-header__hamburger-icon"
207
+ class:global-header__hamburger-icon--open={mobileMenuOpen}
208
+ >
209
+ <span></span>
210
+ <span></span>
211
+ <span></span>
212
+ </span>
213
+ </button>
214
+ </div>
215
+
216
+ {#if mobileMenuOpen}
217
+ <div
218
+ id="global-header-mobile-menu"
219
+ class="global-header__mobile-menu"
220
+ class:global-header__mobile-menu--open={mobileMenuOpen}
221
+ >
222
+ {#if mobileMenu}
223
+ {@render mobileMenu()}
224
+ {:else}
225
+ <nav class="global-header__mobile-nav" aria-label="Mobile navigation">
226
+ <ul class="global-header__mobile-nav-list">
227
+ {#each navItems as item}
228
+ <li class="global-header__mobile-nav-item">
229
+ {#if item.children && item.children.length > 0}
230
+ <div class="global-header__mobile-nav-group">
231
+ <span class="global-header__mobile-nav-label">
232
+ {#if item.icon}
233
+ <span class="global-header__nav-icon">{item.icon}</span>
234
+ {/if}
235
+ {item.label}
236
+ </span>
237
+ <ul class="global-header__mobile-nav-sublist">
238
+ {#each item.children as child}
239
+ <li>
240
+ <a
241
+ href={child.href || '#'}
242
+ class="global-header__mobile-nav-link"
243
+ onclick={closeMobileMenu}
244
+ >
245
+ {#if child.icon}
246
+ <span class="global-header__nav-icon">{child.icon}</span>
247
+ {/if}
248
+ {child.label}
249
+ </a>
250
+ </li>
251
+ {/each}
252
+ </ul>
253
+ </div>
254
+ {:else}
255
+ <a
256
+ href={item.href || '#'}
257
+ class="global-header__mobile-nav-link"
258
+ onclick={closeMobileMenu}
259
+ >
260
+ {#if item.icon}
261
+ <span class="global-header__nav-icon">{item.icon}</span>
262
+ {/if}
263
+ {item.label}
264
+ </a>
265
+ {/if}
266
+ </li>
267
+ {/each}
268
+ </ul>
269
+
270
+ {#if actions}
271
+ <div class="global-header__mobile-actions">
272
+ {@render actions()}
273
+ </div>
274
+ {/if}
275
+ </nav>
276
+ {/if}
277
+ </div>
278
+ <button
279
+ type="button"
280
+ class="global-header__overlay"
281
+ aria-label="Close menu"
282
+ onclick={closeMobileMenu}
283
+ ></button>
284
+ {/if}
285
+ </header>
286
+
287
+ <style>
288
+ .global-header {
289
+ --header-bg: var(--color-bg, #ffffff);
290
+ --header-height: 4rem;
291
+ --header-text-color: var(--color-text, #1f2937);
292
+ --header-border-color: var(--color-border, #e5e7eb);
293
+ --header-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
294
+ --header-z-index: 100;
295
+
296
+ position: relative;
297
+ background: var(--header-bg);
298
+ border-bottom: 1px solid var(--header-border-color);
299
+ font-family: inherit;
300
+ z-index: var(--header-z-index);
301
+ transition: transform var(--transition-normal, 250ms ease);
302
+ }
303
+
304
+ .global-header--sticky {
305
+ position: sticky;
306
+ top: 0;
307
+ }
308
+
309
+ .global-header--transparent {
310
+ background: transparent;
311
+ border-bottom: 1px solid transparent;
312
+ --header-shadow: none;
313
+ }
314
+
315
+ .global-header--floating {
316
+ margin: var(--space-md, 1rem);
317
+ border-radius: var(--radius-lg, 0.5rem);
318
+ box-shadow: var(--header-shadow);
319
+ border: 1px solid var(--header-border-color);
320
+ }
321
+
322
+ .global-header--hidden {
323
+ transform: translateY(-100%);
324
+ }
325
+
326
+ .global-header__container {
327
+ display: flex;
328
+ align-items: center;
329
+ justify-content: space-between;
330
+ gap: var(--space-md, 1rem);
331
+ max-width: var(--max-width, 80rem);
332
+ margin: 0 auto;
333
+ padding: 0 var(--space-md, 1rem);
334
+ height: var(--header-height);
335
+ }
336
+
337
+ .global-header__logo {
338
+ display: flex;
339
+ align-items: center;
340
+ flex-shrink: 0;
341
+ color: var(--header-text-color);
342
+ text-decoration: none;
343
+ }
344
+
345
+ .global-header__logo:focus-visible {
346
+ outline: 2px solid var(--color-primary, #3b82f6);
347
+ outline-offset: 2px;
348
+ border-radius: var(--radius-sm, 0.25rem);
349
+ }
350
+
351
+ .global-header__logo-img {
352
+ max-height: 2.5rem;
353
+ height: auto;
354
+ width: auto;
355
+ }
356
+
357
+ .global-header__nav {
358
+ display: none;
359
+ flex: 1;
360
+ justify-content: center;
361
+ }
362
+
363
+ .global-header__nav-list {
364
+ display: flex;
365
+ align-items: center;
366
+ gap: var(--space-xs, 0.25rem);
367
+ list-style: none;
368
+ margin: 0;
369
+ padding: 0;
370
+ }
371
+
372
+ .global-header__nav-item {
373
+ position: relative;
374
+ }
375
+
376
+ .global-header__nav-link {
377
+ display: flex;
378
+ align-items: center;
379
+ gap: var(--space-xs, 0.25rem);
380
+ padding: var(--space-sm, 0.5rem) var(--space-md, 1rem);
381
+ color: var(--header-text-color);
382
+ text-decoration: none;
383
+ font-size: var(--text-sm, 0.875rem);
384
+ font-weight: 500;
385
+ border-radius: var(--radius-md, 0.375rem);
386
+ transition: all var(--transition-fast, 150ms ease);
387
+ white-space: nowrap;
388
+ background: transparent;
389
+ border: none;
390
+ cursor: pointer;
391
+ font-family: inherit;
392
+ /* Touch target minimum */
393
+ min-height: var(--touch-target-min, 44px);
394
+ }
395
+
396
+ .global-header__nav-link:hover {
397
+ background: var(--color-bg-subtle, rgba(0, 0, 0, 0.05));
398
+ color: var(--color-primary, #3b82f6);
399
+ }
400
+
401
+ .global-header__nav-link:focus-visible {
402
+ outline: 2px solid var(--color-primary, #3b82f6);
403
+ outline-offset: 2px;
404
+ }
405
+
406
+ .global-header__nav-link--dropdown {
407
+ width: 100%;
408
+ text-align: left;
409
+ }
410
+
411
+ .global-header__nav-icon {
412
+ display: inline-flex;
413
+ align-items: center;
414
+ }
415
+
416
+ .global-header__dropdown-arrow {
417
+ margin-left: var(--space-xs, 0.25rem);
418
+ font-size: 0.625rem;
419
+ transition: transform var(--transition-fast, 150ms ease);
420
+ }
421
+
422
+ .global-header__nav-link[aria-expanded='true'] .global-header__dropdown-arrow {
423
+ transform: rotate(180deg);
424
+ }
425
+
426
+ .global-header__dropdown {
427
+ position: absolute;
428
+ top: calc(100% + 0.25rem);
429
+ left: 0;
430
+ min-width: 12rem;
431
+ background: var(--color-bg, #ffffff);
432
+ border: 1px solid var(--header-border-color);
433
+ border-radius: var(--radius-md, 0.375rem);
434
+ box-shadow:
435
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
436
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
437
+ list-style: none;
438
+ margin: 0;
439
+ padding: var(--space-xs, 0.25rem);
440
+ z-index: calc(var(--header-z-index) + 1);
441
+ animation: dropdown-fade-in 150ms ease-out;
442
+ }
443
+
444
+ .global-header__dropdown-item {
445
+ display: flex;
446
+ align-items: center;
447
+ gap: var(--space-xs, 0.25rem);
448
+ padding: var(--space-sm, 0.5rem) var(--space-md, 1rem);
449
+ color: var(--header-text-color);
450
+ text-decoration: none;
451
+ font-size: var(--text-sm, 0.875rem);
452
+ border-radius: var(--radius-sm, 0.25rem);
453
+ transition: background var(--transition-fast, 150ms ease);
454
+ white-space: nowrap;
455
+ /* Touch target minimum */
456
+ min-height: var(--touch-target-min, 44px);
457
+ }
458
+
459
+ .global-header__dropdown-item:hover {
460
+ background: var(--color-bg-subtle, rgba(0, 0, 0, 0.05));
461
+ color: var(--color-primary, #3b82f6);
462
+ }
463
+
464
+ .global-header__dropdown-item:focus-visible {
465
+ outline: 2px solid var(--color-primary, #3b82f6);
466
+ outline-offset: -2px;
467
+ }
468
+
469
+ .global-header__actions {
470
+ display: none;
471
+ align-items: center;
472
+ gap: var(--space-sm, 0.5rem);
473
+ }
474
+
475
+ .global-header__hamburger {
476
+ display: flex;
477
+ align-items: center;
478
+ justify-content: center;
479
+ /* Touch target minimum */
480
+ min-width: var(--touch-target-min, 44px);
481
+ min-height: var(--touch-target-min, 44px);
482
+ padding: var(--space-sm, 0.5rem);
483
+ background: transparent;
484
+ border: none;
485
+ cursor: pointer;
486
+ -webkit-tap-highlight-color: transparent;
487
+ }
488
+
489
+ .global-header__hamburger:focus-visible {
490
+ outline: 2px solid var(--color-primary, #3b82f6);
491
+ outline-offset: 2px;
492
+ border-radius: var(--radius-sm, 0.25rem);
493
+ }
494
+
495
+ .global-header__hamburger-icon {
496
+ position: relative;
497
+ width: 1.5rem;
498
+ height: 1.25rem;
499
+ }
500
+
501
+ .global-header__hamburger-icon span {
502
+ position: absolute;
503
+ left: 0;
504
+ width: 100%;
505
+ height: 2px;
506
+ background: var(--header-text-color);
507
+ border-radius: var(--radius-full, 9999px);
508
+ transition: all var(--transition-fast, 150ms ease);
509
+ }
510
+
511
+ .global-header__hamburger-icon span:nth-child(1) {
512
+ top: 0;
513
+ }
514
+
515
+ .global-header__hamburger-icon span:nth-child(2) {
516
+ top: 50%;
517
+ transform: translateY(-50%);
518
+ }
519
+
520
+ .global-header__hamburger-icon span:nth-child(3) {
521
+ bottom: 0;
522
+ }
523
+
524
+ .global-header__hamburger-icon--open span:nth-child(1) {
525
+ top: 50%;
526
+ transform: translateY(-50%) rotate(45deg);
527
+ }
528
+
529
+ .global-header__hamburger-icon--open span:nth-child(2) {
530
+ opacity: 0;
531
+ }
532
+
533
+ .global-header__hamburger-icon--open span:nth-child(3) {
534
+ bottom: 50%;
535
+ transform: translateY(50%) rotate(-45deg);
536
+ }
537
+
538
+ .global-header__mobile-menu {
539
+ position: fixed;
540
+ top: 0;
541
+ right: 0;
542
+ bottom: 0;
543
+ width: min(80vw, 20rem);
544
+ background: var(--color-bg, #ffffff);
545
+ border-left: 1px solid var(--header-border-color);
546
+ padding: var(--space-lg, 1.5rem);
547
+ overflow-y: auto;
548
+ z-index: calc(var(--header-z-index) + 2);
549
+ animation: slide-in 200ms ease-out;
550
+ font-family: inherit;
551
+ }
552
+
553
+ .global-header__overlay {
554
+ position: fixed;
555
+ inset: 0;
556
+ background: rgba(0, 0, 0, 0.4);
557
+ z-index: calc(var(--header-z-index) + 1);
558
+ animation: fade-in 200ms ease-out;
559
+ cursor: pointer;
560
+ }
561
+
562
+ .global-header__mobile-nav-list {
563
+ list-style: none;
564
+ margin: 0;
565
+ padding: 0;
566
+ display: flex;
567
+ flex-direction: column;
568
+ gap: var(--space-xs, 0.25rem);
569
+ }
570
+
571
+ .global-header__mobile-nav-item {
572
+ display: flex;
573
+ flex-direction: column;
574
+ }
575
+
576
+ .global-header__mobile-nav-link {
577
+ display: flex;
578
+ align-items: center;
579
+ gap: var(--space-sm, 0.5rem);
580
+ padding: var(--space-md, 1rem);
581
+ color: var(--header-text-color);
582
+ text-decoration: none;
583
+ font-size: var(--text-base, 1rem);
584
+ border-radius: var(--radius-md, 0.375rem);
585
+ transition: background var(--transition-fast, 150ms ease);
586
+ /* Touch target minimum */
587
+ min-height: var(--touch-target-min, 44px);
588
+ }
589
+
590
+ .global-header__mobile-nav-link:hover {
591
+ background: var(--color-bg-subtle, rgba(0, 0, 0, 0.05));
592
+ }
593
+
594
+ .global-header__mobile-nav-link:focus-visible {
595
+ outline: 2px solid var(--color-primary, #3b82f6);
596
+ outline-offset: -2px;
597
+ }
598
+
599
+ .global-header__mobile-nav-group {
600
+ display: flex;
601
+ flex-direction: column;
602
+ gap: var(--space-xs, 0.25rem);
603
+ }
604
+
605
+ .global-header__mobile-nav-label {
606
+ display: flex;
607
+ align-items: center;
608
+ gap: var(--space-sm, 0.5rem);
609
+ padding: var(--space-md, 1rem);
610
+ font-weight: 600;
611
+ font-size: var(--text-sm, 0.875rem);
612
+ text-transform: uppercase;
613
+ letter-spacing: 0.05em;
614
+ color: var(--color-text-muted, #6b7280);
615
+ }
616
+
617
+ .global-header__mobile-nav-sublist {
618
+ list-style: none;
619
+ margin: 0;
620
+ padding-left: var(--space-md, 1rem);
621
+ display: flex;
622
+ flex-direction: column;
623
+ gap: var(--space-xs, 0.25rem);
624
+ }
625
+
626
+ .global-header__mobile-actions {
627
+ margin-top: var(--space-lg, 1.5rem);
628
+ padding-top: var(--space-lg, 1.5rem);
629
+ border-top: 1px solid var(--header-border-color);
630
+ display: flex;
631
+ flex-direction: column;
632
+ gap: var(--space-sm, 0.5rem);
633
+ }
634
+
635
+ @keyframes slide-in {
636
+ from {
637
+ transform: translateX(100%);
638
+ }
639
+ to {
640
+ transform: translateX(0);
641
+ }
642
+ }
643
+
644
+ @keyframes fade-in {
645
+ from {
646
+ opacity: 0;
647
+ }
648
+ to {
649
+ opacity: 1;
650
+ }
651
+ }
652
+
653
+ @keyframes dropdown-fade-in {
654
+ from {
655
+ opacity: 0;
656
+ transform: translateY(-0.5rem);
657
+ }
658
+ to {
659
+ opacity: 1;
660
+ transform: translateY(0);
661
+ }
662
+ }
663
+
664
+ /* Desktop breakpoint */
665
+ @media (min-width: 768px) {
666
+ .global-header__nav {
667
+ display: flex;
668
+ }
669
+
670
+ .global-header__actions {
671
+ display: flex;
672
+ }
673
+
674
+ .global-header__hamburger {
675
+ display: none;
676
+ }
677
+
678
+ .global-header__mobile-menu,
679
+ .global-header__overlay {
680
+ display: none;
681
+ }
682
+ }
683
+
684
+ /* Dark mode support */
685
+ @media (prefers-color-scheme: dark) {
686
+ .global-header {
687
+ --header-bg: var(--color-bg-dark, #1f2937);
688
+ --header-text-color: var(--color-text-dark, #f9fafb);
689
+ --header-border-color: var(--color-border-dark, #374151);
690
+ }
691
+ }
692
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const GlobalHeader: import("svelte").Component<any, {}, "">;
2
+ type GlobalHeader = ReturnType<typeof GlobalHeader>;
3
+ export default GlobalHeader;
@@ -0,0 +1,2 @@
1
+ export { default as GlobalHeader } from './GlobalHeader.svelte';
2
+ export type { GlobalHeaderProps, NavItem } from './GlobalHeader.svelte';
@@ -0,0 +1 @@
1
+ export { default as GlobalHeader } from './GlobalHeader.svelte';