@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,333 @@
1
+ <script lang="ts">
2
+ export interface LogoItem {
3
+ src: string;
4
+ alt: string;
5
+ href?: string;
6
+ }
7
+
8
+ export interface LogoCloudProps {
9
+ logos: LogoItem[];
10
+ columns?: 2 | 3 | 4 | 5 | 6;
11
+ size?: 'sm' | 'md' | 'lg';
12
+ variant?: 'grid' | 'scroll' | 'marquee';
13
+ grayscale?: boolean;
14
+ hoverEffect?: 'scale' | 'lift' | 'glow' | 'color' | 'none';
15
+ gap?: 'sm' | 'md' | 'lg' | 'xl';
16
+ title?: string;
17
+ subtitle?: string;
18
+ class?: string;
19
+ }
20
+
21
+ let {
22
+ logos,
23
+ columns = 4,
24
+ size = 'md',
25
+ variant = 'grid',
26
+ grayscale = false,
27
+ hoverEffect = 'scale',
28
+ gap = 'md',
29
+ title,
30
+ subtitle,
31
+ class: className = ''
32
+ }: LogoCloudProps = $props();
33
+
34
+ const sizeMap = {
35
+ sm: '2rem',
36
+ md: '3rem',
37
+ lg: '4rem'
38
+ };
39
+
40
+ const gapMap = {
41
+ sm: '1rem',
42
+ md: '2rem',
43
+ lg: '3rem',
44
+ xl: '4rem'
45
+ };
46
+
47
+ // For marquee variant, duplicate logos for seamless infinite scroll
48
+ const displayLogos = $derived(variant === 'marquee' ? [...logos, ...logos] : logos);
49
+ </script>
50
+
51
+ <div class="logo-cloud-wrapper {className}">
52
+ {#if title || subtitle}
53
+ <div class="logo-cloud-header">
54
+ {#if title}
55
+ <h2 class="logo-cloud-title">{title}</h2>
56
+ {/if}
57
+ {#if subtitle}
58
+ <p class="logo-cloud-subtitle">{subtitle}</p>
59
+ {/if}
60
+ </div>
61
+ {/if}
62
+
63
+ <div
64
+ class="logo-cloud logo-cloud--{variant} logo-cloud--{size} logo-cloud--gap-{gap} logo-cloud--hover-{hoverEffect}"
65
+ class:logo-cloud--grayscale={grayscale}
66
+ style="--logo-cloud-height: {sizeMap[size]}; --logo-cloud-gap: {gapMap[
67
+ gap
68
+ ]}; --logo-cloud-columns: {columns};"
69
+ aria-label={title || 'Partner logos'}
70
+ role="region"
71
+ >
72
+ <div class="logo-cloud-container">
73
+ {#each displayLogos as logo, index}
74
+ <div class="logo-cloud-item" aria-hidden={variant === 'marquee' && index >= logos.length}>
75
+ {#if logo.href}
76
+ <a href={logo.href} class="logo-cloud-link" target="_blank" rel="noopener noreferrer">
77
+ <img
78
+ src={logo.src}
79
+ alt={logo.alt}
80
+ class="logo-cloud-image"
81
+ loading="lazy"
82
+ decoding="async"
83
+ />
84
+ </a>
85
+ {:else}
86
+ <img
87
+ src={logo.src}
88
+ alt={logo.alt}
89
+ class="logo-cloud-image"
90
+ loading="lazy"
91
+ decoding="async"
92
+ />
93
+ {/if}
94
+ </div>
95
+ {/each}
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ <style>
101
+ .logo-cloud-wrapper {
102
+ width: 100%;
103
+ }
104
+
105
+ .logo-cloud-header {
106
+ text-align: center;
107
+ margin-bottom: 3rem;
108
+ }
109
+
110
+ .logo-cloud-title {
111
+ font-size: 2rem;
112
+ font-weight: 700;
113
+ margin: 0 0 0.5rem 0;
114
+ color: var(--logo-cloud-title-color, var(--text-primary, #1a1a1a));
115
+ }
116
+
117
+ .logo-cloud-subtitle {
118
+ font-size: 1rem;
119
+ margin: 0;
120
+ color: var(--logo-cloud-subtitle-color, var(--text-secondary, #666));
121
+ }
122
+
123
+ .logo-cloud {
124
+ width: 100%;
125
+ --logo-cloud-gap: 2rem;
126
+ --logo-cloud-height: 3rem;
127
+ --logo-cloud-columns: 4;
128
+ --logo-cloud-grayscale-opacity: 0.6;
129
+ --logo-cloud-transition: all 0.3s ease;
130
+ }
131
+
132
+ /* Grid variant */
133
+ .logo-cloud--grid .logo-cloud-container {
134
+ display: grid;
135
+ grid-template-columns: repeat(2, 1fr);
136
+ gap: var(--logo-cloud-gap);
137
+ align-items: center;
138
+ justify-items: center;
139
+ }
140
+
141
+ @media (min-width: 768px) {
142
+ .logo-cloud--grid .logo-cloud-container {
143
+ grid-template-columns: repeat(var(--logo-cloud-columns), 1fr);
144
+ }
145
+ }
146
+
147
+ /* Scroll variant */
148
+ .logo-cloud--scroll {
149
+ overflow-x: auto;
150
+ -webkit-overflow-scrolling: touch;
151
+ scrollbar-width: thin;
152
+ scrollbar-color: var(--scrollbar-thumb, #ccc) var(--scrollbar-track, #f0f0f0);
153
+ }
154
+
155
+ .logo-cloud--scroll .logo-cloud-container {
156
+ display: flex;
157
+ gap: var(--logo-cloud-gap);
158
+ padding-bottom: 1rem;
159
+ min-width: min-content;
160
+ }
161
+
162
+ .logo-cloud--scroll::-webkit-scrollbar {
163
+ height: 0.5rem;
164
+ }
165
+
166
+ .logo-cloud--scroll::-webkit-scrollbar-track {
167
+ background: var(--scrollbar-track, #f0f0f0);
168
+ border-radius: 0.25rem;
169
+ }
170
+
171
+ .logo-cloud--scroll::-webkit-scrollbar-thumb {
172
+ background: var(--scrollbar-thumb, #ccc);
173
+ border-radius: 0.25rem;
174
+ }
175
+
176
+ .logo-cloud--scroll::-webkit-scrollbar-thumb:hover {
177
+ background: var(--scrollbar-thumb-hover, #999);
178
+ }
179
+
180
+ /* Marquee variant */
181
+ .logo-cloud--marquee {
182
+ overflow: hidden;
183
+ position: relative;
184
+ }
185
+
186
+ .logo-cloud--marquee .logo-cloud-container {
187
+ display: flex;
188
+ gap: var(--logo-cloud-gap);
189
+ animation: marquee 30s linear infinite;
190
+ width: fit-content;
191
+ }
192
+
193
+ @keyframes marquee {
194
+ 0% {
195
+ transform: translateX(0);
196
+ }
197
+ 100% {
198
+ transform: translateX(-50%);
199
+ }
200
+ }
201
+
202
+ .logo-cloud--marquee:hover .logo-cloud-container,
203
+ .logo-cloud--marquee:focus-within .logo-cloud-container {
204
+ animation-play-state: paused;
205
+ }
206
+
207
+ @media (prefers-reduced-motion: reduce) {
208
+ .logo-cloud--marquee .logo-cloud-container {
209
+ animation: none;
210
+ }
211
+ }
212
+
213
+ /* Logo items */
214
+ .logo-cloud-item {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ transition: var(--logo-cloud-transition);
219
+ flex-shrink: 0;
220
+ }
221
+
222
+ .logo-cloud--scroll .logo-cloud-item,
223
+ .logo-cloud--marquee .logo-cloud-item {
224
+ min-width: calc(var(--logo-cloud-height) * 2);
225
+ }
226
+
227
+ .logo-cloud-link {
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: center;
231
+ text-decoration: none;
232
+ width: 100%;
233
+ height: 100%;
234
+ transition: var(--logo-cloud-transition);
235
+ }
236
+
237
+ .logo-cloud-link:focus {
238
+ outline: 2px solid var(--focus-ring-color, #0066ff);
239
+ outline-offset: 0.25rem;
240
+ border-radius: 0.25rem;
241
+ }
242
+
243
+ .logo-cloud-image {
244
+ height: var(--logo-cloud-height);
245
+ width: auto;
246
+ max-width: 100%;
247
+ object-fit: contain;
248
+ transition: var(--logo-cloud-transition);
249
+ }
250
+
251
+ /* Grayscale mode */
252
+ .logo-cloud--grayscale .logo-cloud-image {
253
+ filter: grayscale(100%);
254
+ opacity: var(--logo-cloud-grayscale-opacity);
255
+ }
256
+
257
+ .logo-cloud--grayscale .logo-cloud-item:hover .logo-cloud-image,
258
+ .logo-cloud--grayscale .logo-cloud-link:hover .logo-cloud-image,
259
+ .logo-cloud--grayscale .logo-cloud-link:focus .logo-cloud-image {
260
+ filter: grayscale(0%);
261
+ opacity: 1;
262
+ }
263
+
264
+ /* Hover effects */
265
+ /* Scale effect */
266
+ .logo-cloud--hover-scale .logo-cloud-item:hover .logo-cloud-image,
267
+ .logo-cloud--hover-scale .logo-cloud-link:hover .logo-cloud-image,
268
+ .logo-cloud--hover-scale .logo-cloud-link:focus .logo-cloud-image {
269
+ transform: scale(1.1);
270
+ }
271
+
272
+ /* Lift effect */
273
+ .logo-cloud--hover-lift .logo-cloud-item:hover,
274
+ .logo-cloud--hover-lift .logo-cloud-link:hover,
275
+ .logo-cloud--hover-lift .logo-cloud-link:focus {
276
+ transform: translateY(-0.5rem);
277
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
278
+ }
279
+
280
+ /* Glow effect */
281
+ .logo-cloud--hover-glow .logo-cloud-item:hover .logo-cloud-image,
282
+ .logo-cloud--hover-glow .logo-cloud-link:hover .logo-cloud-image,
283
+ .logo-cloud--hover-glow .logo-cloud-link:focus .logo-cloud-image {
284
+ filter: drop-shadow(0 0 1rem rgba(0, 102, 255, 0.3));
285
+ }
286
+
287
+ /* Color effect (similar to grayscale but forces it) */
288
+ .logo-cloud--hover-color .logo-cloud-image {
289
+ filter: grayscale(100%);
290
+ opacity: var(--logo-cloud-grayscale-opacity);
291
+ }
292
+
293
+ .logo-cloud--hover-color .logo-cloud-item:hover .logo-cloud-image,
294
+ .logo-cloud--hover-color .logo-cloud-link:hover .logo-cloud-image,
295
+ .logo-cloud--hover-color .logo-cloud-link:focus .logo-cloud-image {
296
+ filter: grayscale(0%);
297
+ opacity: 1;
298
+ }
299
+
300
+ /* None effect - no additional styles needed */
301
+ .logo-cloud--hover-none .logo-cloud-item:hover,
302
+ .logo-cloud--hover-none .logo-cloud-link:hover {
303
+ transform: none;
304
+ box-shadow: none;
305
+ }
306
+
307
+ /* Dark mode support */
308
+ @media (prefers-color-scheme: dark) {
309
+ .logo-cloud-title {
310
+ color: var(--logo-cloud-title-color, var(--text-primary, #ffffff));
311
+ }
312
+
313
+ .logo-cloud-subtitle {
314
+ color: var(--logo-cloud-subtitle-color, var(--text-secondary, #a0a0a0));
315
+ }
316
+
317
+ .logo-cloud--scroll {
318
+ scrollbar-color: var(--scrollbar-thumb, #555) var(--scrollbar-track, #2a2a2a);
319
+ }
320
+
321
+ .logo-cloud--scroll::-webkit-scrollbar-track {
322
+ background: var(--scrollbar-track, #2a2a2a);
323
+ }
324
+
325
+ .logo-cloud--scroll::-webkit-scrollbar-thumb {
326
+ background: var(--scrollbar-thumb, #555);
327
+ }
328
+
329
+ .logo-cloud--scroll::-webkit-scrollbar-thumb:hover {
330
+ background: var(--scrollbar-thumb-hover, #777);
331
+ }
332
+ }
333
+ </style>
@@ -0,0 +1,20 @@
1
+ export interface LogoItem {
2
+ src: string;
3
+ alt: string;
4
+ href?: string;
5
+ }
6
+ export interface LogoCloudProps {
7
+ logos: LogoItem[];
8
+ columns?: 2 | 3 | 4 | 5 | 6;
9
+ size?: 'sm' | 'md' | 'lg';
10
+ variant?: 'grid' | 'scroll' | 'marquee';
11
+ grayscale?: boolean;
12
+ hoverEffect?: 'scale' | 'lift' | 'glow' | 'color' | 'none';
13
+ gap?: 'sm' | 'md' | 'lg' | 'xl';
14
+ title?: string;
15
+ subtitle?: string;
16
+ class?: string;
17
+ }
18
+ declare const LogoCloud: import("svelte").Component<LogoCloudProps, {}, "">;
19
+ type LogoCloud = ReturnType<typeof LogoCloud>;
20
+ export default LogoCloud;
@@ -0,0 +1,2 @@
1
+ export { default as LogoCloud } from './LogoCloud.svelte';
2
+ export type { LogoItem, LogoCloudProps } from './LogoCloud.svelte';
@@ -0,0 +1 @@
1
+ export { default as LogoCloud } from './LogoCloud.svelte';
@@ -36,6 +36,7 @@
36
36
  z-index: 50;
37
37
  min-width: 8rem;
38
38
  max-width: 20rem;
39
+ overflow: hidden;
39
40
  }
40
41
 
41
42
  /* Animation states */
@@ -25,6 +25,7 @@
25
25
  z-index: 51;
26
26
  min-width: 8rem;
27
27
  max-width: 20rem;
28
+ overflow: hidden;
28
29
  }
29
30
 
30
31
  /* Animation states */
@@ -15,6 +15,17 @@
15
15
  clusterBkg?: string;
16
16
  titleColor?: string;
17
17
  edgeLabelBackground?: string;
18
+ textColor?: string;
19
+ // Sequence diagram specific
20
+ actorLineColor?: string;
21
+ signalColor?: string;
22
+ signalTextColor?: string;
23
+ labelTextColor?: string;
24
+ actorTextColor?: string;
25
+ messageTextColor?: string;
26
+ loopTextColor?: string;
27
+ activationBorderColor?: string;
28
+ sequenceNumberColor?: string;
18
29
  }
19
30
 
20
31
  interface Props {
@@ -28,17 +39,61 @@
28
39
  children?: Snippet;
29
40
  }
30
41
 
31
- // Default ExonPro theme
32
- const defaultTheme: ThemeVariables = {
42
+ // Light theme colors
43
+ const lightTheme: ThemeVariables = {
33
44
  primaryColor: '#4654A3',
34
- primaryTextColor: '#270949',
45
+ primaryTextColor: '#ffffff',
35
46
  primaryBorderColor: '#4654A3',
36
- lineColor: '#270949',
47
+ lineColor: '#4b5563',
37
48
  secondaryColor: '#FF3131',
38
- tertiaryColor: '#f3f4f6'
49
+ tertiaryColor: '#f3f4f6',
50
+ textColor: '#000000',
51
+ // Sequence diagram - dark colors for light backgrounds
52
+ actorLineColor: '#4b5563',
53
+ signalColor: '#374151',
54
+ signalTextColor: '#000000',
55
+ labelTextColor: '#000000',
56
+ actorTextColor: '#ffffff',
57
+ messageTextColor: '#000000',
58
+ loopTextColor: '#000000',
59
+ activationBorderColor: '#4b5563',
60
+ sequenceNumberColor: '#ffffff'
39
61
  };
40
62
 
41
- let { code, theme = defaultTheme, class: className = '', children }: Props = $props();
63
+ // Dark theme colors
64
+ const darkTheme: ThemeVariables = {
65
+ primaryColor: '#4654A3',
66
+ primaryTextColor: '#ffffff',
67
+ primaryBorderColor: '#4654A3',
68
+ lineColor: '#9ca3af',
69
+ secondaryColor: '#FF3131',
70
+ tertiaryColor: '#1f2937',
71
+ textColor: '#7dd3fc',
72
+ // Sequence diagram - sky blue colors for dark backgrounds
73
+ actorLineColor: '#38bdf8',
74
+ signalColor: '#38bdf8',
75
+ signalTextColor: '#7dd3fc',
76
+ labelTextColor: '#7dd3fc',
77
+ actorTextColor: '#ffffff',
78
+ messageTextColor: '#7dd3fc',
79
+ loopTextColor: '#7dd3fc',
80
+ activationBorderColor: '#38bdf8',
81
+ sequenceNumberColor: '#ffffff'
82
+ };
83
+
84
+ // Detect theme
85
+ function getThemeColors(): ThemeVariables {
86
+ if (typeof window === 'undefined') return lightTheme;
87
+
88
+ const isDark =
89
+ document.documentElement.classList.contains('dark') ||
90
+ document.body.classList.contains('dark') ||
91
+ window.matchMedia('(prefers-color-scheme: dark)').matches;
92
+
93
+ return isDark ? darkTheme : lightTheme;
94
+ }
95
+
96
+ let { code, theme, class: className = '', children }: Props = $props();
42
97
 
43
98
  let containerRef: HTMLDivElement | undefined = $state();
44
99
  let slotRef: HTMLDivElement | undefined = $state();
@@ -62,11 +117,15 @@
62
117
  const mermaidModule = await import('mermaid');
63
118
  const mermaid = mermaidModule.default;
64
119
 
120
+ // Detect theme and merge with custom theme
121
+ const detectedTheme = getThemeColors();
122
+ const mergedTheme = { ...detectedTheme, ...theme };
123
+
65
124
  // Initialize mermaid with theme
66
125
  mermaid.initialize({
67
126
  startOnLoad: false,
68
127
  theme: 'base',
69
- themeVariables: { ...defaultTheme, ...theme },
128
+ themeVariables: mergedTheme,
70
129
  securityLevel: 'loose',
71
130
  fontFamily: 'inherit'
72
131
  });
@@ -203,4 +262,59 @@
203
262
  max-width: 100%;
204
263
  height: auto;
205
264
  }
265
+
266
+ /* Force text colors in dark mode for all diagrams (flowchart + sequence) */
267
+ :global(.dark) .mermaid-diagram :global(svg text),
268
+ :global(.dark) .mermaid-diagram :global(svg .messageText),
269
+ :global(body.dark) .mermaid-diagram :global(svg text),
270
+ :global(body.dark) .mermaid-diagram :global(svg .messageText),
271
+ :global(html.dark) .mermaid-diagram :global(svg text),
272
+ :global(html.dark) .mermaid-diagram :global(svg .messageText) {
273
+ fill: #7dd3fc !important;
274
+ }
275
+
276
+ /* Force line colors in dark mode for all diagrams */
277
+ :global(.dark) .mermaid-diagram :global(svg .messageLine0),
278
+ :global(.dark) .mermaid-diagram :global(svg .messageLine1),
279
+ :global(.dark) .mermaid-diagram :global(svg line),
280
+ :global(.dark) .mermaid-diagram :global(svg path),
281
+ :global(.dark) .mermaid-diagram :global(svg .edgePath path),
282
+ :global(.dark) .mermaid-diagram :global(svg .flowchart-link),
283
+ :global(body.dark) .mermaid-diagram :global(svg .messageLine0),
284
+ :global(body.dark) .mermaid-diagram :global(svg .messageLine1),
285
+ :global(body.dark) .mermaid-diagram :global(svg line),
286
+ :global(body.dark) .mermaid-diagram :global(svg path),
287
+ :global(body.dark) .mermaid-diagram :global(svg .edgePath path),
288
+ :global(body.dark) .mermaid-diagram :global(svg .flowchart-link),
289
+ :global(html.dark) .mermaid-diagram :global(svg .messageLine0),
290
+ :global(html.dark) .mermaid-diagram :global(svg .messageLine1),
291
+ :global(html.dark) .mermaid-diagram :global(svg line),
292
+ :global(html.dark) .mermaid-diagram :global(svg path),
293
+ :global(html.dark) .mermaid-diagram :global(svg .edgePath path),
294
+ :global(html.dark) .mermaid-diagram :global(svg .flowchart-link) {
295
+ stroke: #38bdf8 !important;
296
+ }
297
+
298
+ /* Flowchart edge labels */
299
+ :global(.dark) .mermaid-diagram :global(svg .edgeLabel),
300
+ :global(body.dark) .mermaid-diagram :global(svg .edgeLabel),
301
+ :global(html.dark) .mermaid-diagram :global(svg .edgeLabel) {
302
+ color: #7dd3fc !important;
303
+ }
304
+
305
+ :global(.dark) .mermaid-diagram :global(svg .edgeLabel text),
306
+ :global(body.dark) .mermaid-diagram :global(svg .edgeLabel text),
307
+ :global(html.dark) .mermaid-diagram :global(svg .edgeLabel text) {
308
+ fill: #7dd3fc !important;
309
+ }
310
+
311
+ /* Keep actor text and node text white for readability */
312
+ :global(.dark) .mermaid-diagram :global(svg .actor text),
313
+ :global(.dark) .mermaid-diagram :global(svg .node text),
314
+ :global(body.dark) .mermaid-diagram :global(svg .actor text),
315
+ :global(body.dark) .mermaid-diagram :global(svg .node text),
316
+ :global(html.dark) .mermaid-diagram :global(svg .actor text),
317
+ :global(html.dark) .mermaid-diagram :global(svg .node text) {
318
+ fill: #ffffff !important;
319
+ }
206
320
  </style>
@@ -12,6 +12,16 @@ interface ThemeVariables {
12
12
  clusterBkg?: string;
13
13
  titleColor?: string;
14
14
  edgeLabelBackground?: string;
15
+ textColor?: string;
16
+ actorLineColor?: string;
17
+ signalColor?: string;
18
+ signalTextColor?: string;
19
+ labelTextColor?: string;
20
+ actorTextColor?: string;
21
+ messageTextColor?: string;
22
+ loopTextColor?: string;
23
+ activationBorderColor?: string;
24
+ sequenceNumberColor?: string;
15
25
  }
16
26
  interface Props {
17
27
  /** Mermaid diagram code. If not provided, uses slot content */
@@ -0,0 +1,140 @@
1
+ <script lang="ts">
2
+ import Avatar from '../Avatar/Avatar.svelte';
3
+
4
+ interface Props {
5
+ /**
6
+ * Greeting text to display (e.g., "Welcome back,")
7
+ * @default "Welcome back,"
8
+ */
9
+ greeting?: string;
10
+ /**
11
+ * User name to display prominently
12
+ */
13
+ userName: string;
14
+ /**
15
+ * Avatar image source URL
16
+ */
17
+ avatarSrc?: string;
18
+ /**
19
+ * Custom initials for avatar (overrides auto-generated from userName)
20
+ */
21
+ avatarInitials?: string;
22
+ /**
23
+ * Additional CSS classes
24
+ */
25
+ class?: string;
26
+ /**
27
+ * Action icons snippet (e.g., notification bell, sync icon)
28
+ */
29
+ actions?: import('svelte').Snippet;
30
+ }
31
+
32
+ let {
33
+ greeting = 'Welcome back,',
34
+ userName,
35
+ avatarSrc,
36
+ avatarInitials,
37
+ class: className = '',
38
+ actions
39
+ }: Props = $props();
40
+
41
+ // Use custom initials if provided, otherwise derive from userName
42
+ const displayName = $derived(avatarInitials || userName);
43
+ </script>
44
+
45
+ <header class="page-header {className}">
46
+ <div class="page-header__content">
47
+ <div class="page-header__greeting">
48
+ <span class="page-header__greeting-text">{greeting}</span>
49
+ <h1 class="page-header__name">{userName}</h1>
50
+ </div>
51
+
52
+ <div class="page-header__actions-wrapper">
53
+ {#if actions}
54
+ <div class="page-header__actions">
55
+ {@render actions()}
56
+ </div>
57
+ {/if}
58
+
59
+ <Avatar src={avatarSrc} name={displayName} size="md" class="page-header__avatar" />
60
+ </div>
61
+ </div>
62
+ </header>
63
+
64
+ <style>
65
+ .page-header {
66
+ font-family: inherit;
67
+ padding: var(--space-md, 1rem) var(--space-lg, 1.5rem);
68
+ }
69
+
70
+ .page-header__content {
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: space-between;
74
+ gap: var(--space-md, 1rem);
75
+ flex-wrap: wrap;
76
+ }
77
+
78
+ .page-header__greeting {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: var(--space-xs, 0.25rem);
82
+ min-width: 0;
83
+ flex: 1;
84
+ }
85
+
86
+ .page-header__greeting-text {
87
+ font-size: 0.875rem;
88
+ line-height: 1.25rem;
89
+ color: var(--color-text-muted, #6b7280);
90
+ }
91
+
92
+ .page-header__name {
93
+ font-size: 1.5rem;
94
+ line-height: 2rem;
95
+ font-weight: 700;
96
+ color: var(--color-text, #1f2937);
97
+ margin: 0;
98
+ overflow: hidden;
99
+ text-overflow: ellipsis;
100
+ }
101
+
102
+ .page-header__actions-wrapper {
103
+ display: flex;
104
+ align-items: center;
105
+ gap: var(--space-sm, 0.5rem);
106
+ flex-shrink: 0;
107
+ }
108
+
109
+ .page-header__actions {
110
+ display: flex;
111
+ align-items: center;
112
+ gap: var(--space-xs, 0.25rem);
113
+ }
114
+
115
+ .page-header__avatar {
116
+ flex-shrink: 0;
117
+ }
118
+
119
+ /* Dark mode support (F11) */
120
+ :global([data-theme='dark']) .page-header__greeting-text {
121
+ color: var(--color-text-muted, #9ca3af);
122
+ }
123
+
124
+ :global([data-theme='dark']) .page-header__name {
125
+ color: var(--color-text, #f9fafb);
126
+ }
127
+
128
+ /* Responsive - stack on very narrow screens */
129
+ @media (max-width: 360px) {
130
+ .page-header__content {
131
+ flex-direction: column;
132
+ align-items: flex-start;
133
+ gap: var(--space-sm, 0.5rem);
134
+ }
135
+
136
+ .page-header__actions-wrapper {
137
+ align-self: flex-end;
138
+ }
139
+ }
140
+ </style>