brand-shell 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.
@@ -0,0 +1,644 @@
1
+ /* Brand Shell — default theme (use CSS variables to override) */
2
+
3
+ :root {
4
+ --brand-primary: #2563eb;
5
+ --brand-bg: #0f172a;
6
+ --brand-text: #f1f5f9;
7
+ --brand-font: "Space Grotesk", "Inter", "Avenir Next", "Segoe UI", "SF Pro Text", ui-sans-serif, system-ui,
8
+ -apple-system, sans-serif;
9
+ --brand-link: #94a3b8;
10
+ --brand-space-sm: 0.5rem;
11
+ --brand-space-md: 1rem;
12
+ --brand-space-lg: 1.5rem;
13
+ --brand-space-xl: 2rem;
14
+ --brand-radius: 10px;
15
+ --brand-header-height: 4rem;
16
+ --brand-footer-padding: 2rem;
17
+ --brand-social-size: 2.5rem;
18
+ --brand-button-text: #f8fafc;
19
+ --brand-button-secondary: rgba(255, 255, 255, 0.12);
20
+ }
21
+
22
+ .brand-shell-header,
23
+ .brand-shell-header *,
24
+ .brand-shell-header *::before,
25
+ .brand-shell-header *::after,
26
+ .brand-shell-footer,
27
+ .brand-shell-footer *,
28
+ .brand-shell-footer *::before,
29
+ .brand-shell-footer *::after {
30
+ box-sizing: border-box;
31
+ }
32
+
33
+ /* Header */
34
+ .brand-shell-header {
35
+ --_bg: var(--brand-bg);
36
+ --_text: var(--brand-text);
37
+ --_font: var(--brand-font);
38
+ --_primary: var(--brand-primary);
39
+ --_link: var(--brand-link);
40
+ --_space: var(--brand-space-md);
41
+
42
+ position: relative;
43
+ overflow: hidden;
44
+ isolation: isolate;
45
+ font-family: var(--_font);
46
+ background:
47
+ linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0)),
48
+ var(--_bg);
49
+ color: var(--_text);
50
+ min-height: clamp(var(--brand-header-height), 5.5vw, 4.45rem);
51
+ display: flex;
52
+ align-items: center;
53
+ padding: clamp(0.48rem, 1.6vw, 0.72rem) clamp(0.8rem, 2.3vw, 1.28rem);
54
+ border-bottom: 1px solid rgba(148, 163, 184, 0.24);
55
+ box-shadow:
56
+ inset 0 1px 0 rgba(255, 255, 255, 0.08),
57
+ 0 12px 28px -22px rgba(2, 6, 23, 0.85);
58
+ backdrop-filter: blur(10px) saturate(120%);
59
+ box-sizing: border-box;
60
+ }
61
+
62
+ .brand-shell-header__inner {
63
+ width: 100%;
64
+ max-width: 76rem;
65
+ margin: 0 auto;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: space-between;
69
+ gap: clamp(0.75rem, 2.2vw, 1.35rem);
70
+ }
71
+
72
+ .brand-shell-header__actions {
73
+ display: flex;
74
+ align-items: center;
75
+ gap: clamp(0.55rem, 1.6vw, 1.15rem);
76
+ }
77
+
78
+ .brand-shell-header__ctas {
79
+ display: flex;
80
+ align-items: center;
81
+ flex-wrap: wrap;
82
+ gap: 0.45rem;
83
+ }
84
+
85
+ .brand-shell-header__name {
86
+ display: inline-flex;
87
+ align-items: center;
88
+ gap: 0.62rem;
89
+ font-size: clamp(1.08rem, 2.2vw, 1.35rem);
90
+ font-weight: 650;
91
+ color: var(--_text);
92
+ text-decoration: none;
93
+ letter-spacing: -0.025em;
94
+ white-space: nowrap;
95
+ transition: color 0.2s ease;
96
+ }
97
+
98
+ .brand-shell-header__name::before {
99
+ content: "";
100
+ width: 0.58rem;
101
+ height: 0.58rem;
102
+ border-radius: 999px;
103
+ background: var(--_primary);
104
+ box-shadow: 0 0 0 0.2rem rgba(148, 163, 184, 0.28);
105
+ flex-shrink: 0;
106
+ }
107
+
108
+ .brand-shell-header__name:hover {
109
+ color: var(--_primary);
110
+ }
111
+
112
+ .brand-shell-header__name:focus-visible {
113
+ outline: 2px solid var(--_primary);
114
+ outline-offset: 3px;
115
+ border-radius: var(--brand-radius);
116
+ }
117
+
118
+ .brand-shell-header__nav {
119
+ display: flex;
120
+ align-items: center;
121
+ min-width: 0;
122
+ }
123
+
124
+ .brand-shell-header__list {
125
+ list-style: none;
126
+ margin: 0;
127
+ padding: 0;
128
+ display: flex;
129
+ flex-wrap: wrap;
130
+ align-items: center;
131
+ gap: 0.3rem;
132
+ }
133
+
134
+ .brand-shell-header__social {
135
+ display: flex;
136
+ align-items: center;
137
+ flex-wrap: wrap;
138
+ gap: 0.44rem;
139
+ }
140
+
141
+ .brand-shell-header__social-link {
142
+ width: var(--brand-social-size);
143
+ height: var(--brand-social-size);
144
+ font-size: calc(var(--brand-social-size) * 0.46);
145
+ border-radius: 999px;
146
+ display: inline-flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ line-height: 1;
150
+ color: var(--_text);
151
+ border: 1px solid rgba(148, 163, 184, 0.26);
152
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.04));
153
+ transition:
154
+ background 0.2s ease,
155
+ color 0.2s ease,
156
+ border-color 0.2s ease,
157
+ transform 0.2s ease;
158
+ }
159
+
160
+ .brand-shell-header__social-link svg {
161
+ width: 1.08em;
162
+ height: 1.08em;
163
+ }
164
+
165
+ .brand-shell-header__social-link:hover {
166
+ background: rgba(148, 163, 184, 0.22);
167
+ border-color: rgba(148, 163, 184, 0.48);
168
+ color: var(--_primary);
169
+ transform: translateY(-1px);
170
+ }
171
+
172
+ .brand-shell-header__social-link:focus-visible {
173
+ outline: 2px solid var(--_primary);
174
+ outline-offset: 3px;
175
+ }
176
+
177
+ .brand-shell-header__link {
178
+ display: inline-flex;
179
+ align-items: center;
180
+ min-height: 2.1rem;
181
+ font-size: 0.93rem;
182
+ font-weight: 530;
183
+ line-height: 1.4;
184
+ color: var(--_link);
185
+ text-decoration: none;
186
+ padding: 0.38rem 0.72rem;
187
+ border-radius: 999px;
188
+ transition:
189
+ color 0.2s ease,
190
+ background 0.2s ease,
191
+ transform 0.2s ease;
192
+ }
193
+
194
+ .brand-shell-header__link:hover {
195
+ color: var(--_text);
196
+ background: rgba(148, 163, 184, 0.18);
197
+ transform: translateY(-1px);
198
+ }
199
+
200
+ .brand-shell-header__link:focus-visible {
201
+ outline: 2px solid var(--_primary);
202
+ outline-offset: 3px;
203
+ }
204
+
205
+ .brand-shell-header .brand-shell-button {
206
+ min-height: 2.45rem;
207
+ padding: 0.5rem 1rem;
208
+ border-radius: 999px;
209
+ font-size: 0.95rem;
210
+ font-weight: 600;
211
+ letter-spacing: -0.01em;
212
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
213
+ }
214
+
215
+ .brand-shell-header .brand-shell-button--primary {
216
+ border-color: transparent;
217
+ box-shadow:
218
+ inset 0 1px 0 rgba(255, 255, 255, 0.2),
219
+ 0 10px 22px -14px var(--_primary);
220
+ }
221
+
222
+ .brand-shell-header .brand-shell-button--primary:hover {
223
+ filter: brightness(1.09);
224
+ transform: translateY(-1px);
225
+ }
226
+
227
+ .brand-shell-header .brand-shell-button--secondary {
228
+ border-color: rgba(148, 163, 184, 0.38);
229
+ background: rgba(148, 163, 184, 0.1);
230
+ }
231
+
232
+ .brand-shell-header .brand-shell-button--secondary:hover {
233
+ border-color: rgba(148, 163, 184, 0.6);
234
+ background: rgba(148, 163, 184, 0.2);
235
+ transform: translateY(-1px);
236
+ }
237
+
238
+ .brand-shell-header .brand-shell-button--ghost {
239
+ background: rgba(148, 163, 184, 0.08);
240
+ }
241
+
242
+ .brand-shell-header .brand-shell-button--ghost:hover {
243
+ background: rgba(148, 163, 184, 0.18);
244
+ color: var(--_text);
245
+ transform: translateY(-1px);
246
+ }
247
+
248
+ .brand-shell-header .brand-shell-button:focus-visible {
249
+ outline-offset: 3px;
250
+ }
251
+
252
+ @media (max-width: 920px) {
253
+ .brand-shell-header__inner {
254
+ flex-wrap: wrap;
255
+ }
256
+
257
+ .brand-shell-header__actions {
258
+ width: 100%;
259
+ justify-content: space-between;
260
+ flex-wrap: wrap;
261
+ gap: 0.66rem;
262
+ }
263
+
264
+ .brand-shell-header__nav {
265
+ flex: 1 1 auto;
266
+ }
267
+
268
+ .brand-shell-header__social {
269
+ justify-content: flex-end;
270
+ }
271
+ }
272
+
273
+ @media (max-width: 640px) {
274
+ .brand-shell-header {
275
+ padding: 0.5rem 0.72rem;
276
+ }
277
+
278
+ .brand-shell-header,
279
+ .brand-shell-footer {
280
+ --brand-social-size: 2.2rem;
281
+ }
282
+
283
+ .brand-shell-header__inner {
284
+ align-items: stretch;
285
+ }
286
+
287
+ .brand-shell-header__actions {
288
+ width: 100%;
289
+ flex-direction: column;
290
+ align-items: stretch;
291
+ gap: 0.5rem;
292
+ }
293
+
294
+ .brand-shell-header__nav {
295
+ min-width: 0;
296
+ overflow-x: auto;
297
+ scrollbar-width: thin;
298
+ }
299
+
300
+ .brand-shell-header__list {
301
+ flex-wrap: nowrap;
302
+ width: max-content;
303
+ min-width: 100%;
304
+ padding-bottom: 0.12rem;
305
+ gap: 0.24rem;
306
+ }
307
+
308
+ .brand-shell-header__link {
309
+ min-height: 1.95rem;
310
+ font-size: 0.84rem;
311
+ padding: 0.32rem 0.6rem;
312
+ white-space: nowrap;
313
+ }
314
+
315
+ .brand-shell-header__ctas {
316
+ min-width: 0;
317
+ width: 100%;
318
+ display: grid;
319
+ gap: 0.45rem;
320
+ }
321
+
322
+ .brand-shell-header[data-brand-cta-layout="inline"] .brand-shell-header__ctas {
323
+ grid-template-columns: repeat(2, minmax(0, 1fr));
324
+ }
325
+
326
+ .brand-shell-header[data-brand-cta-layout="stacked"] .brand-shell-header__ctas {
327
+ grid-template-columns: 1fr;
328
+ }
329
+
330
+ .brand-shell-header[data-brand-cta-layout="inline"] .brand-shell-header__ctas > .brand-shell-button:only-child,
331
+ .brand-shell-footer[data-brand-cta-layout="inline"] .brand-shell-footer__ctas > .brand-shell-button:only-child {
332
+ grid-column: 1 / -1;
333
+ }
334
+
335
+ .brand-shell-header .brand-shell-button {
336
+ width: 100%;
337
+ min-height: 2.2rem;
338
+ padding: 0.45rem 0.85rem;
339
+ font-size: 0.9rem;
340
+ box-shadow: none;
341
+ }
342
+
343
+ .brand-shell-header .brand-shell-button--primary {
344
+ box-shadow: none;
345
+ }
346
+
347
+ .brand-shell-header__social {
348
+ justify-content: flex-start;
349
+ flex-wrap: nowrap;
350
+ gap: 0.36rem;
351
+ margin-top: 0.12rem;
352
+ padding-bottom: 0.12rem;
353
+ overflow-x: auto;
354
+ }
355
+ }
356
+
357
+ @media (max-width: 460px) {
358
+ .brand-shell-header__name {
359
+ font-size: 0.98rem;
360
+ }
361
+
362
+ .brand-shell-header .brand-shell-button {
363
+ font-size: 0.86rem;
364
+ }
365
+
366
+ }
367
+
368
+ @media (max-width: 340px) {
369
+ .brand-shell-header[data-brand-cta-layout="inline"] .brand-shell-header__ctas {
370
+ grid-template-columns: 1fr;
371
+ }
372
+ }
373
+
374
+ /* Footer */
375
+ .brand-shell-footer {
376
+ --_bg: var(--brand-bg);
377
+ --_text: var(--brand-text);
378
+ --_font: var(--brand-font);
379
+ --_primary: var(--brand-primary);
380
+ --_link: var(--brand-link);
381
+ --_space: var(--brand-space-md);
382
+
383
+ font-family: var(--_font);
384
+ background: var(--_bg);
385
+ color: var(--_text);
386
+ padding: var(--brand-footer-padding) var(--_space);
387
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
388
+ margin-top: auto;
389
+ box-sizing: border-box;
390
+ }
391
+
392
+ .brand-shell-footer__inner {
393
+ width: 100%;
394
+ max-width: 72rem;
395
+ margin: 0 auto;
396
+ display: flex;
397
+ flex-direction: column;
398
+ gap: var(--brand-space-md);
399
+ }
400
+
401
+ .brand-shell-footer__top {
402
+ display: flex;
403
+ flex-wrap: wrap;
404
+ align-items: flex-start;
405
+ justify-content: space-between;
406
+ gap: var(--brand-space-lg);
407
+ }
408
+
409
+ .brand-shell-footer__brand {
410
+ max-width: 22rem;
411
+ }
412
+
413
+ .brand-shell-footer__name {
414
+ font-size: 1rem;
415
+ font-weight: 600;
416
+ margin: 0 0 var(--brand-space-sm) 0;
417
+ }
418
+
419
+ .brand-shell-footer__nav {
420
+ display: flex;
421
+ align-items: center;
422
+ }
423
+
424
+ .brand-shell-footer__ctas {
425
+ display: flex;
426
+ align-items: center;
427
+ gap: var(--brand-space-sm);
428
+ flex-wrap: wrap;
429
+ }
430
+
431
+ .brand-shell-footer__list {
432
+ list-style: none;
433
+ margin: 0;
434
+ padding: 0;
435
+ display: flex;
436
+ flex-wrap: wrap;
437
+ gap: var(--brand-space-sm) var(--_space);
438
+ }
439
+
440
+ .brand-shell-footer__social {
441
+ display: flex;
442
+ align-items: center;
443
+ gap: var(--brand-space-sm);
444
+ }
445
+
446
+ .brand-shell-footer__social-link {
447
+ width: var(--brand-social-size);
448
+ height: var(--brand-social-size);
449
+ font-size: calc(var(--brand-social-size) * 0.5);
450
+ border-radius: 999px;
451
+ display: inline-flex;
452
+ align-items: center;
453
+ justify-content: center;
454
+ line-height: 1;
455
+ color: var(--_text);
456
+ background: rgba(255, 255, 255, 0.08);
457
+ transition: background 0.15s ease, color 0.15s ease;
458
+ }
459
+
460
+ .brand-shell-footer__social-link:hover {
461
+ background: rgba(255, 255, 255, 0.16);
462
+ color: var(--_primary);
463
+ }
464
+
465
+ .brand-shell-footer__social-link:focus-visible {
466
+ outline: 2px solid var(--_primary);
467
+ outline-offset: 2px;
468
+ }
469
+
470
+ .brand-shell-footer__link {
471
+ font-size: 0.9375rem;
472
+ line-height: 1.4;
473
+ color: var(--_link);
474
+ text-decoration: none;
475
+ padding: 0.35rem 0.6rem;
476
+ border-radius: var(--brand-radius);
477
+ transition: color 0.15s ease;
478
+ }
479
+
480
+ .brand-shell-footer__link:hover {
481
+ color: var(--_primary);
482
+ }
483
+
484
+ .brand-shell-footer__link:focus-visible {
485
+ outline: 2px solid var(--_primary);
486
+ outline-offset: 2px;
487
+ }
488
+
489
+ .brand-shell-footer__tagline {
490
+ font-size: 0.875rem;
491
+ color: var(--_link);
492
+ margin: 0;
493
+ line-height: 1.6;
494
+ }
495
+
496
+ .brand-shell-footer__copy {
497
+ font-size: 0.8125rem;
498
+ color: var(--_link);
499
+ margin: 0;
500
+ opacity: 0.9;
501
+ }
502
+
503
+ .brand-shell-button {
504
+ display: inline-flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ border-radius: 999px;
508
+ padding: 0.5rem 1.25rem;
509
+ min-height: 2.5rem;
510
+ font-size: 0.9375rem;
511
+ font-weight: 600;
512
+ line-height: 1.3;
513
+ border: 1px solid transparent;
514
+ transition: background 0.15s ease, color 0.15s ease, border 0.15s ease;
515
+ text-decoration: none;
516
+ }
517
+
518
+ .brand-shell-button--primary {
519
+ background: var(--_primary);
520
+ color: var(--brand-button-text);
521
+ border-color: var(--_primary);
522
+ }
523
+
524
+ .brand-shell-button--primary:hover {
525
+ filter: brightness(1.05);
526
+ }
527
+
528
+ .brand-shell-button--secondary {
529
+ background: transparent;
530
+ color: var(--_text);
531
+ border-color: var(--brand-button-secondary);
532
+ }
533
+
534
+ .brand-shell-button--secondary:hover {
535
+ border-color: rgba(255, 255, 255, 0.3);
536
+ }
537
+
538
+ .brand-shell-button--ghost {
539
+ background: transparent;
540
+ color: var(--_link);
541
+ }
542
+
543
+ .brand-shell-button--ghost:hover {
544
+ color: var(--_primary);
545
+ }
546
+
547
+ .brand-shell-button:focus-visible {
548
+ outline: 2px solid var(--_primary);
549
+ outline-offset: 2px;
550
+ }
551
+
552
+ @media (max-width: 640px) {
553
+ .brand-shell-footer {
554
+ padding: 1.35rem 0.9rem;
555
+ }
556
+
557
+ .brand-shell-footer__top {
558
+ flex-direction: column;
559
+ align-items: flex-start;
560
+ gap: var(--brand-space-md);
561
+ }
562
+
563
+ .brand-shell-footer__nav {
564
+ width: 100%;
565
+ overflow-x: auto;
566
+ scrollbar-width: thin;
567
+ }
568
+
569
+ .brand-shell-footer__list {
570
+ flex-wrap: nowrap;
571
+ width: max-content;
572
+ min-width: 100%;
573
+ padding-bottom: 0.15rem;
574
+ }
575
+
576
+ .brand-shell-footer__ctas {
577
+ min-width: 0;
578
+ width: 100%;
579
+ display: grid;
580
+ gap: 0.42rem;
581
+ }
582
+
583
+ .brand-shell-footer[data-brand-cta-layout="inline"] .brand-shell-footer__ctas {
584
+ grid-template-columns: repeat(2, minmax(0, 1fr));
585
+ }
586
+
587
+ .brand-shell-footer[data-brand-cta-layout="stacked"] .brand-shell-footer__ctas {
588
+ grid-template-columns: 1fr;
589
+ }
590
+
591
+ .brand-shell-footer .brand-shell-button {
592
+ width: 100%;
593
+ min-height: 2.2rem;
594
+ padding: 0.45rem 0.85rem;
595
+ font-size: 0.88rem;
596
+ box-shadow: none;
597
+ }
598
+
599
+ .brand-shell-footer__social {
600
+ width: 100%;
601
+ flex-wrap: nowrap;
602
+ overflow-x: auto;
603
+ gap: 0.4rem;
604
+ margin-top: 0.12rem;
605
+ }
606
+ }
607
+
608
+ @media (max-width: 460px) {
609
+ .brand-shell-footer .brand-shell-button {
610
+ font-size: 0.85rem;
611
+ }
612
+ }
613
+
614
+ @media (max-width: 340px) {
615
+ .brand-shell-footer[data-brand-cta-layout="inline"] .brand-shell-footer__ctas {
616
+ grid-template-columns: 1fr;
617
+ }
618
+ }
619
+
620
+ @media (prefers-reduced-motion: reduce) {
621
+ .brand-shell-header,
622
+ .brand-shell-footer,
623
+ .brand-shell-header__name,
624
+ .brand-shell-header__link,
625
+ .brand-shell-header__social-link,
626
+ .brand-shell-footer__link,
627
+ .brand-shell-footer__social-link,
628
+ .brand-shell-button {
629
+ transition-duration: 0.01ms;
630
+ }
631
+ }
632
+
633
+ @media (hover: none) {
634
+ .brand-shell-header__social-link:hover,
635
+ .brand-shell-header__link:hover,
636
+ .brand-shell-footer__social-link:hover,
637
+ .brand-shell-footer__link:hover,
638
+ .brand-shell-button--primary:hover,
639
+ .brand-shell-button--secondary:hover,
640
+ .brand-shell-button--ghost:hover {
641
+ transform: none;
642
+ filter: none;
643
+ }
644
+ }
@@ -0,0 +1,93 @@
1
+ import { i as BrandTheme, n as BrandDetails, r as BrandNavLink, t as BrandAction } from "./types-PQziYg7Z.mjs";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+
4
+ //#region src/Header.d.ts
5
+ interface HeaderProps {
6
+ details: BrandDetails;
7
+ theme?: BrandTheme | null;
8
+ className?: string;
9
+ }
10
+ declare function Header({
11
+ details,
12
+ theme,
13
+ className
14
+ }: HeaderProps): react_jsx_runtime0.JSX.Element;
15
+ //#endregion
16
+ //#region src/Footer.d.ts
17
+ interface FooterProps {
18
+ details: BrandDetails;
19
+ theme?: BrandTheme | null;
20
+ className?: string;
21
+ }
22
+ declare function Footer({
23
+ details,
24
+ theme,
25
+ className
26
+ }: FooterProps): react_jsx_runtime0.JSX.Element;
27
+ //#endregion
28
+ //#region src/core/social.d.ts
29
+ type SocialPlatform = "website" | "linkedin" | "email" | "github" | "twitter" | "discord";
30
+ interface SocialLink {
31
+ platform: SocialPlatform;
32
+ href: string;
33
+ label: string;
34
+ }
35
+ declare function detailsToSocialLinks(details: BrandDetails): SocialLink[];
36
+ //#endregion
37
+ //#region src/core/shell.d.ts
38
+ type LinkTarget = NonNullable<BrandNavLink["target"]>;
39
+ interface ShellNavLink extends BrandNavLink {
40
+ ariaLabel: string;
41
+ rel?: string;
42
+ target: LinkTarget;
43
+ }
44
+ interface ShellActionLink extends BrandAction {
45
+ ariaLabel: string;
46
+ rel?: string;
47
+ target: LinkTarget;
48
+ variant: NonNullable<BrandAction["variant"]>;
49
+ }
50
+ interface ShellViewModel {
51
+ navLinks: ShellNavLink[];
52
+ ctaLinks: ShellActionLink[];
53
+ socialLinks: SocialLink[];
54
+ }
55
+ type NormalizedActionLink = Omit<ShellActionLink, "variant"> & Pick<BrandAction, "variant">;
56
+ interface NormalizedBrandDetails extends Omit<BrandDetails, "navLinks" | "primaryAction" | "secondaryAction"> {
57
+ navLinks: ShellNavLink[];
58
+ primaryAction?: NormalizedActionLink;
59
+ secondaryAction?: NormalizedActionLink;
60
+ }
61
+ declare function normalizeNavLinks(navLinks?: BrandNavLink[]): ShellNavLink[];
62
+ declare function normalizeBrandDetails(details: BrandDetails): NormalizedBrandDetails;
63
+ declare function normalizeCtaLinks(primaryAction?: BrandAction, secondaryAction?: BrandAction): ShellActionLink[];
64
+ declare function buildShellViewModel(details: BrandDetails): ShellViewModel;
65
+ declare function normalizeGmailHref(gmail?: string): string | undefined;
66
+ //#endregion
67
+ //#region src/core/dev.d.ts
68
+ declare function shouldValidateInDev(): boolean;
69
+ //#endregion
70
+ //#region src/core/theme.d.ts
71
+ type ThemeVariables = Record<string, string>;
72
+ declare function themeToCssVariables(theme?: BrandTheme | null): ThemeVariables;
73
+ //#endregion
74
+ //#region src/core/validation.d.ts
75
+ interface BrandValidationResult<T> {
76
+ valid: boolean;
77
+ errors: string[];
78
+ normalized: T | null;
79
+ }
80
+ declare class BrandShellValidationError extends Error {
81
+ readonly context: string;
82
+ readonly errors: string[];
83
+ constructor(context: string, errors: string[]);
84
+ }
85
+ declare function validateBrandDetails(details: unknown): BrandValidationResult<NormalizedBrandDetails>;
86
+ declare function validateBrandTheme(theme: unknown): BrandValidationResult<BrandTheme | null>;
87
+ declare function assertValidBrandDetails(details: unknown, context?: string): asserts details is BrandDetails;
88
+ declare function assertValidBrandTheme(theme: unknown, context?: string): asserts theme is BrandTheme | null | undefined;
89
+ declare function normalizeBrandTheme(theme?: BrandTheme | null): BrandTheme | null;
90
+ declare function formatValidationErrors(context: string, errors: string[]): string;
91
+ //#endregion
92
+ export { type BrandAction, type BrandDetails, type BrandNavLink, BrandShellValidationError, type BrandTheme, type BrandValidationResult, Footer, Header, type LinkTarget, type NormalizedBrandDetails, type ShellActionLink, type ShellNavLink, type ShellViewModel, type SocialLink, type SocialPlatform, type ThemeVariables, assertValidBrandDetails, assertValidBrandTheme, buildShellViewModel, detailsToSocialLinks, formatValidationErrors, normalizeBrandDetails, normalizeBrandTheme, normalizeCtaLinks, normalizeGmailHref, normalizeNavLinks, shouldValidateInDev, themeToCssVariables, validateBrandDetails, validateBrandTheme };
93
+ //# sourceMappingURL=index.d.mts.map