@hyvnt/hyvui 0.2.0 → 0.4.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 (181) hide show
  1. package/README.md +294 -253
  2. package/dist/components/ambient/ArcaneVein.svelte +151 -0
  3. package/dist/components/ambient/ArcaneVein.svelte.d.ts +31 -0
  4. package/dist/components/ambient/BrassFiligree.svelte +109 -0
  5. package/dist/components/ambient/BrassFiligree.svelte.d.ts +20 -0
  6. package/dist/components/ambient/CornerBrackets.svelte +91 -87
  7. package/dist/components/ambient/CornerBrackets.svelte.d.ts +8 -0
  8. package/dist/components/ambient/CrystalShard.svelte +151 -0
  9. package/dist/components/ambient/CrystalShard.svelte.d.ts +19 -0
  10. package/dist/components/ambient/DataStream.svelte +117 -94
  11. package/dist/components/ambient/DataStream.svelte.d.ts +6 -0
  12. package/dist/components/ambient/EnergyArc.svelte +189 -0
  13. package/dist/components/ambient/EnergyArc.svelte.d.ts +32 -0
  14. package/dist/components/ambient/GlyphMark.svelte +75 -69
  15. package/dist/components/ambient/GlyphMark.svelte.d.ts +6 -0
  16. package/dist/components/ambient/GridOverlay.svelte +34 -28
  17. package/dist/components/ambient/GridOverlay.svelte.d.ts +8 -0
  18. package/dist/components/ambient/HexGrid.svelte +119 -0
  19. package/dist/components/ambient/HexGrid.svelte.d.ts +21 -0
  20. package/dist/components/ambient/ParallaxLayer.svelte +45 -41
  21. package/dist/components/ambient/ParallaxLayer.svelte.d.ts +7 -0
  22. package/dist/components/ambient/ScanBand.svelte +103 -91
  23. package/dist/components/ambient/ScanBand.svelte.d.ts +8 -0
  24. package/dist/components/ambient/ShimmerCloud.svelte +180 -0
  25. package/dist/components/ambient/ShimmerCloud.svelte.d.ts +21 -0
  26. package/dist/components/ambient/SignalRing.svelte +106 -100
  27. package/dist/components/ambient/SignalRing.svelte.d.ts +6 -0
  28. package/dist/components/ambient/ThreadLine.svelte +78 -78
  29. package/dist/components/ambient/ThreadLine.svelte.d.ts +7 -0
  30. package/dist/components/ambient/Vignette.svelte +30 -26
  31. package/dist/components/ambient/Vignette.svelte.d.ts +6 -0
  32. package/dist/components/depth/DepthLayer.svelte +30 -27
  33. package/dist/components/depth/DepthLayer.svelte.d.ts +8 -0
  34. package/dist/components/depth/DepthStage.svelte +67 -62
  35. package/dist/components/depth/DepthStage.svelte.d.ts +8 -0
  36. package/dist/components/depth/FloatCard.svelte +129 -104
  37. package/dist/components/depth/FloatCard.svelte.d.ts +8 -0
  38. package/dist/components/depth/HorizonGrid.svelte +241 -160
  39. package/dist/components/depth/HorizonGrid.svelte.d.ts +9 -0
  40. package/dist/components/depth/Plinth.svelte +62 -57
  41. package/dist/components/depth/Plinth.svelte.d.ts +10 -0
  42. package/dist/components/display/Avatar.svelte +69 -69
  43. package/dist/components/display/Avatar.svelte.d.ts +5 -0
  44. package/dist/components/display/Badge.svelte +75 -63
  45. package/dist/components/display/Badge.svelte.d.ts +6 -0
  46. package/dist/components/display/Blockquote.svelte +35 -34
  47. package/dist/components/display/Blockquote.svelte.d.ts +4 -0
  48. package/dist/components/display/CodeBlock.svelte +76 -76
  49. package/dist/components/display/CodeBlock.svelte.d.ts +5 -0
  50. package/dist/components/display/MetricCard.svelte +100 -83
  51. package/dist/components/display/MetricCard.svelte.d.ts +6 -0
  52. package/dist/components/display/Table.svelte +106 -104
  53. package/dist/components/display/Table.svelte.d.ts +7 -0
  54. package/dist/components/feedback/Alert.svelte +95 -76
  55. package/dist/components/feedback/Alert.svelte.d.ts +6 -0
  56. package/dist/components/feedback/EmptyState.svelte +75 -68
  57. package/dist/components/feedback/EmptyState.svelte.d.ts +7 -0
  58. package/dist/components/feedback/ErrorState.svelte +78 -73
  59. package/dist/components/feedback/ErrorState.svelte.d.ts +5 -0
  60. package/dist/components/feedback/Skeleton.svelte +58 -52
  61. package/dist/components/feedback/Skeleton.svelte.d.ts +6 -0
  62. package/dist/components/feedback/StatusDot.svelte +84 -54
  63. package/dist/components/feedback/StatusDot.svelte.d.ts +6 -0
  64. package/dist/components/feedback/StatusLine.svelte +128 -122
  65. package/dist/components/feedback/StatusLine.svelte.d.ts +6 -0
  66. package/dist/components/feedback/Toast.svelte +144 -136
  67. package/dist/components/feedback/Toast.svelte.d.ts +10 -0
  68. package/dist/components/inputs/Button.svelte +310 -237
  69. package/dist/components/inputs/Button.svelte.d.ts +8 -0
  70. package/dist/components/inputs/Checkbox.svelte +109 -105
  71. package/dist/components/inputs/Checkbox.svelte.d.ts +5 -0
  72. package/dist/components/inputs/FileUpload.svelte +170 -163
  73. package/dist/components/inputs/FileUpload.svelte.d.ts +5 -0
  74. package/dist/components/inputs/Input.svelte +153 -147
  75. package/dist/components/inputs/Input.svelte.d.ts +7 -0
  76. package/dist/components/inputs/Select.svelte +164 -150
  77. package/dist/components/inputs/Select.svelte.d.ts +8 -0
  78. package/dist/components/inputs/Textarea.svelte +160 -154
  79. package/dist/components/inputs/Textarea.svelte.d.ts +6 -0
  80. package/dist/components/inputs/Toggle.svelte +125 -120
  81. package/dist/components/inputs/Toggle.svelte.d.ts +5 -0
  82. package/dist/components/layout/Card.svelte +81 -76
  83. package/dist/components/layout/Card.svelte.d.ts +11 -0
  84. package/dist/components/layout/Drawer.svelte +140 -109
  85. package/dist/components/layout/Drawer.svelte.d.ts +6 -0
  86. package/dist/components/layout/Grid.svelte +128 -43
  87. package/dist/components/layout/Grid.svelte.d.ts +18 -2
  88. package/dist/components/layout/Modal.svelte +191 -159
  89. package/dist/components/layout/Modal.svelte.d.ts +10 -0
  90. package/dist/components/layout/Panel.svelte +58 -54
  91. package/dist/components/layout/Panel.svelte.d.ts +9 -0
  92. package/dist/components/layout/Popover.svelte +188 -67
  93. package/dist/components/layout/Popover.svelte.d.ts +19 -1
  94. package/dist/components/layout/Stack.svelte +65 -53
  95. package/dist/components/layout/Stack.svelte.d.ts +12 -0
  96. package/dist/components/navigation/Breadcrumb.svelte +78 -73
  97. package/dist/components/navigation/Breadcrumb.svelte.d.ts +8 -0
  98. package/dist/components/navigation/DropdownMenu.svelte +179 -124
  99. package/dist/components/navigation/DropdownMenu.svelte.d.ts +24 -2
  100. package/dist/components/navigation/SidebarNav.svelte +96 -90
  101. package/dist/components/navigation/SidebarNav.svelte.d.ts +9 -0
  102. package/dist/components/navigation/Tabs.svelte +106 -86
  103. package/dist/components/navigation/Tabs.svelte.d.ts +8 -0
  104. package/dist/components/navigation/Topbar.svelte +94 -85
  105. package/dist/components/navigation/Topbar.svelte.d.ts +9 -0
  106. package/dist/components/patterns/ActionBar.svelte +82 -76
  107. package/dist/components/patterns/ActionBar.svelte.d.ts +10 -0
  108. package/dist/components/patterns/ChapterMark.svelte +152 -0
  109. package/dist/components/patterns/ChapterMark.svelte.d.ts +19 -0
  110. package/dist/components/patterns/ConfirmDialog.svelte +75 -64
  111. package/dist/components/patterns/ConfirmDialog.svelte.d.ts +12 -0
  112. package/dist/components/patterns/DepthPortal.svelte +123 -0
  113. package/dist/components/patterns/DepthPortal.svelte.d.ts +24 -0
  114. package/dist/components/patterns/Manifesto.svelte +171 -0
  115. package/dist/components/patterns/Manifesto.svelte.d.ts +25 -0
  116. package/dist/components/patterns/PageHeader.svelte +117 -114
  117. package/dist/components/patterns/PageHeader.svelte.d.ts +8 -0
  118. package/dist/components/patterns/PullQuote.svelte +145 -0
  119. package/dist/components/patterns/PullQuote.svelte.d.ts +23 -0
  120. package/dist/components/patterns/RegisterSwitcher.svelte +132 -0
  121. package/dist/components/patterns/RegisterSwitcher.svelte.d.ts +21 -0
  122. package/dist/components/patterns/SearchBar.svelte +59 -59
  123. package/dist/components/patterns/SearchBar.svelte.d.ts +5 -0
  124. package/dist/components/patterns/ShowcaseFrame.svelte +117 -0
  125. package/dist/components/patterns/ShowcaseFrame.svelte.d.ts +28 -0
  126. package/dist/components/patterns/TerminalBoot.svelte +118 -104
  127. package/dist/components/patterns/TerminalBoot.svelte.d.ts +12 -0
  128. package/dist/components/primitives/Divider.svelte +56 -29
  129. package/dist/components/primitives/Divider.svelte.d.ts +5 -0
  130. package/dist/components/primitives/Icon.svelte +53 -49
  131. package/dist/components/primitives/Icon.svelte.d.ts +9 -0
  132. package/dist/components/primitives/Label.svelte +45 -44
  133. package/dist/components/primitives/Label.svelte.d.ts +6 -0
  134. package/dist/components/primitives/Surface.svelte +154 -87
  135. package/dist/components/primitives/Surface.svelte.d.ts +7 -0
  136. package/dist/components/primitives/Text.svelte +130 -98
  137. package/dist/components/primitives/Text.svelte.d.ts +7 -0
  138. package/dist/components/scenes/ArchiveScene.svelte +102 -95
  139. package/dist/components/scenes/ArchiveScene.svelte.d.ts +17 -1
  140. package/dist/components/scenes/DepthScene.svelte +128 -0
  141. package/dist/components/scenes/DepthScene.svelte.d.ts +36 -0
  142. package/dist/components/scenes/LogScene.svelte +86 -77
  143. package/dist/components/scenes/LogScene.svelte.d.ts +14 -0
  144. package/dist/components/scenes/NarrativeScene.svelte +100 -92
  145. package/dist/components/scenes/NarrativeScene.svelte.d.ts +9 -0
  146. package/dist/components/scenes/ReadoutScene.svelte +131 -107
  147. package/dist/components/scenes/ReadoutScene.svelte.d.ts +14 -1
  148. package/dist/components/scenes/StageScene.svelte +111 -104
  149. package/dist/components/scenes/StageScene.svelte.d.ts +14 -0
  150. package/dist/components/system/AppShell.svelte +62 -0
  151. package/dist/components/system/AppShell.svelte.d.ts +32 -0
  152. package/dist/examples/ArcaneShard.svelte +364 -0
  153. package/dist/examples/ArcaneShard.svelte.d.ts +3 -0
  154. package/dist/examples/FieldReport.svelte +226 -223
  155. package/dist/examples/HextechForge.svelte +324 -0
  156. package/dist/examples/HextechForge.svelte.d.ts +3 -0
  157. package/dist/examples/ObservationDeck.svelte +333 -317
  158. package/dist/examples/SignalLost.svelte +191 -191
  159. package/dist/index.d.ts +15 -1
  160. package/dist/index.js +16 -1
  161. package/dist/styles.css +115 -0
  162. package/dist/system/actions/echo.js +21 -12
  163. package/dist/system/actions/resolve.js +28 -14
  164. package/dist/system/actions/reveal.js +2 -2
  165. package/dist/system/actions/surface.js +12 -2
  166. package/dist/system/depth/depth.css +49 -49
  167. package/dist/system/depth/depth.js +1 -1
  168. package/dist/system/expressions.css +80 -80
  169. package/dist/system/override-template.css +72 -72
  170. package/dist/system/register.css +74 -74
  171. package/dist/system/register.d.ts +1 -1
  172. package/dist/system/register.js +5 -1
  173. package/dist/system/scroll-lock.d.ts +6 -0
  174. package/dist/system/scroll-lock.js +23 -0
  175. package/dist/tokens/arcane.css +96 -0
  176. package/dist/tokens/hextech.css +96 -0
  177. package/dist/tokens/tokens.css +102 -86
  178. package/dist/tokens/tokens.d.ts +41 -0
  179. package/dist/tokens/tokens.js +44 -3
  180. package/dist/utils/motion.js +1 -1
  181. package/package.json +71 -60
@@ -1,114 +1,117 @@
1
- <script lang="ts">
2
- import { cn } from '../../utils/cn.js';
3
- import type { Snippet } from 'svelte';
4
-
5
- interface Props {
6
- /** Page title. */
7
- title?: string;
8
- /** Page subtitle. */
9
- subtitle?: string;
10
- /** Additional CSS classes. */
11
- class?: string;
12
- /** Breadcrumb slot. */
13
- breadcrumb?: Snippet;
14
- /** Actions slot (right-aligned). */
15
- actions?: Snippet;
16
- }
17
-
18
- let {
19
- title = '',
20
- subtitle = '',
21
- class: className = '',
22
- breadcrumb,
23
- actions,
24
- }: Props = $props();
25
- </script>
26
-
27
- <div class={cn('hyvui-page-header', className)}>
28
- {#if breadcrumb}
29
- <div class="hyvui-page-header-breadcrumb">
30
- {@render breadcrumb()}
31
- </div>
32
- {/if}
33
- <div class="hyvui-page-header-row">
34
- <div class="hyvui-page-header-text">
35
- <h1 class="hyvui-page-header-title">{title}</h1>
36
- {#if subtitle}
37
- <p class="hyvui-page-header-subtitle">{subtitle}</p>
38
- {/if}
39
- </div>
40
- {#if actions}
41
- <div class="hyvui-page-header-actions">
42
- {@render actions()}
43
- </div>
44
- {/if}
45
- </div>
46
- </div>
47
-
48
- <style>
49
- .hyvui-page-header {
50
- display: flex;
51
- flex-direction: column;
52
- gap: var(--space-md);
53
- padding-bottom: var(--space-lg);
54
- border-bottom: 1px solid var(--line);
55
- }
56
-
57
- .hyvui-page-header-breadcrumb {
58
- min-width: 0;
59
- }
60
-
61
- .hyvui-page-header-row {
62
- display: flex;
63
- align-items: flex-start;
64
- justify-content: space-between;
65
- gap: var(--space-xl);
66
- }
67
-
68
- .hyvui-page-header-text {
69
- display: flex;
70
- flex-direction: column;
71
- gap: var(--space-sm);
72
- min-width: 0;
73
- }
74
-
75
- .hyvui-page-header-title {
76
- font-family: var(--font-body);
77
- font-size: clamp(2rem, 4vw, 3.25rem);
78
- font-weight: 400;
79
- line-height: 0.95;
80
- letter-spacing: -0.05em;
81
- color: var(--text);
82
- margin: 0;
83
- text-wrap: balance;
84
- }
85
-
86
- .hyvui-page-header-subtitle {
87
- font-family: var(--font-body);
88
- font-size: 1.04rem;
89
- color: var(--muted);
90
- line-height: 1.62;
91
- margin: 0;
92
- max-width: 32rem;
93
- text-wrap: pretty;
94
- }
95
-
96
- .hyvui-page-header-actions {
97
- display: flex;
98
- align-items: center;
99
- flex-wrap: wrap;
100
- justify-content: flex-end;
101
- gap: var(--space-sm);
102
- flex-shrink: 0;
103
- }
104
-
105
- @media (max-width: 720px) {
106
- .hyvui-page-header-row {
107
- flex-direction: column;
108
- }
109
-
110
- .hyvui-page-header-actions {
111
- justify-content: flex-start;
112
- }
113
- }
114
- </style>
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ /**
6
+ * @remarks Use at the top of any content page: dashboards, settings, detail views.
7
+ * @see surface — add `use:surface` for an entrance animation on mount.
8
+ * @example
9
+ * <PageHeader title="field reports" subtitle="recent observations from the network">
10
+ * {#snippet actions()}<Button variant="primary">new report</Button>{/snippet}
11
+ * </PageHeader>
12
+ */
13
+ interface Props {
14
+ /** Page title. */
15
+ title?: string;
16
+ /** Page subtitle. */
17
+ subtitle?: string;
18
+ /** Additional CSS classes. */
19
+ class?: string;
20
+ /** Breadcrumb slot. */
21
+ breadcrumb?: Snippet;
22
+ /** Actions slot (right-aligned). */
23
+ actions?: Snippet;
24
+ }
25
+
26
+ let { title = '', subtitle = '', class: className = '', breadcrumb, actions }: Props = $props();
27
+ </script>
28
+
29
+ <div class={cn('hyvui-page-header', className)}>
30
+ {#if breadcrumb}
31
+ <div class="hyvui-page-header-breadcrumb">
32
+ {@render breadcrumb()}
33
+ </div>
34
+ {/if}
35
+ <div class="hyvui-page-header-row">
36
+ <div class="hyvui-page-header-text">
37
+ <h1 class="hyvui-page-header-title">{title}</h1>
38
+ {#if subtitle}
39
+ <p class="hyvui-page-header-subtitle">{subtitle}</p>
40
+ {/if}
41
+ </div>
42
+ {#if actions}
43
+ <div class="hyvui-page-header-actions">
44
+ {@render actions()}
45
+ </div>
46
+ {/if}
47
+ </div>
48
+ </div>
49
+
50
+ <style>
51
+ .hyvui-page-header {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: var(--space-md);
55
+ padding-bottom: var(--space-lg);
56
+ border-bottom: 1px solid var(--line);
57
+ container-type: inline-size;
58
+ }
59
+
60
+ .hyvui-page-header-breadcrumb {
61
+ min-width: 0;
62
+ }
63
+
64
+ .hyvui-page-header-row {
65
+ display: flex;
66
+ align-items: flex-start;
67
+ justify-content: space-between;
68
+ gap: var(--space-xl);
69
+ }
70
+
71
+ .hyvui-page-header-text {
72
+ display: flex;
73
+ flex-direction: column;
74
+ gap: var(--space-sm);
75
+ min-width: 0;
76
+ }
77
+
78
+ .hyvui-page-header-title {
79
+ font-family: var(--font-body);
80
+ font-size: clamp(2rem, 4vw, 3.25rem);
81
+ font-weight: 400;
82
+ line-height: 0.95;
83
+ letter-spacing: -0.05em;
84
+ color: var(--text);
85
+ margin: 0;
86
+ text-wrap: balance;
87
+ }
88
+
89
+ .hyvui-page-header-subtitle {
90
+ font-family: var(--font-body);
91
+ font-size: 1.04rem;
92
+ color: var(--muted);
93
+ line-height: 1.62;
94
+ margin: 0;
95
+ max-width: 32rem;
96
+ text-wrap: pretty;
97
+ }
98
+
99
+ .hyvui-page-header-actions {
100
+ display: flex;
101
+ align-items: center;
102
+ flex-wrap: wrap;
103
+ justify-content: flex-end;
104
+ gap: var(--space-sm);
105
+ flex-shrink: 0;
106
+ }
107
+
108
+ @container (max-width: var(--cq-sm)) {
109
+ .hyvui-page-header-row {
110
+ flex-direction: column;
111
+ }
112
+
113
+ .hyvui-page-header-actions {
114
+ justify-content: flex-start;
115
+ }
116
+ }
117
+ </style>
@@ -1,4 +1,12 @@
1
1
  import type { Snippet } from 'svelte';
2
+ /**
3
+ * @remarks Use at the top of any content page: dashboards, settings, detail views.
4
+ * @see surface — add `use:surface` for an entrance animation on mount.
5
+ * @example
6
+ * <PageHeader title="field reports" subtitle="recent observations from the network">
7
+ * {#snippet actions()}<Button variant="primary">new report</Button>{/snippet}
8
+ * </PageHeader>
9
+ */
2
10
  interface Props {
3
11
  /** Page title. */
4
12
  title?: string;
@@ -0,0 +1,145 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ /**
5
+ * @remarks Breakout quotation — larger than Blockquote, a page-level element.
6
+ * Use for testimonials, design maxims, and editorial pull-quotes.
7
+ * @example
8
+ * <PullQuote
9
+ * quote="every detail should look placed, not merely present."
10
+ * attribution="design constraints"
11
+ * source="hyvui"
12
+ * />
13
+ */
14
+ interface Props {
15
+ /** The quotation text. */
16
+ quote: string;
17
+ /** Who said it. */
18
+ attribution?: string;
19
+ /** Where it came from. */
20
+ source?: string;
21
+ /** Additional CSS classes. */
22
+ class?: string;
23
+ }
24
+
25
+ let { quote, attribution, source, class: className = '' }: Props = $props();
26
+ </script>
27
+
28
+ <figure class={cn('hyvui-pull-quote', className)}>
29
+ <div class="hyvui-pull-quote-bracket" aria-hidden="true">[</div>
30
+ <blockquote class="hyvui-pull-quote-body">
31
+ <p class="hyvui-pull-quote-text">{quote}</p>
32
+ </blockquote>
33
+ {#if attribution || source}
34
+ <figcaption class="hyvui-pull-quote-caption">
35
+ {#if attribution}
36
+ <cite class="hyvui-pull-quote-attribution">{attribution}</cite>
37
+ {/if}
38
+ {#if attribution && source}
39
+ <span class="hyvui-pull-quote-sep" aria-hidden="true">·</span>
40
+ {/if}
41
+ {#if source}
42
+ <span class="hyvui-pull-quote-source">{source}</span>
43
+ {/if}
44
+ </figcaption>
45
+ {/if}
46
+ </figure>
47
+
48
+ <style>
49
+ .hyvui-pull-quote {
50
+ margin: 0;
51
+ padding: 0;
52
+ position: relative;
53
+ display: grid;
54
+ grid-template-columns: auto 1fr;
55
+ gap: 1rem;
56
+ padding-left: 1.5rem;
57
+ }
58
+
59
+ .hyvui-pull-quote::before {
60
+ content: '';
61
+ position: absolute;
62
+ left: 0;
63
+ top: 0;
64
+ width: 2px;
65
+ height: 100%;
66
+ background: rgba(199, 156, 87, 0.45);
67
+ transform-origin: top;
68
+ animation: pullquote-border-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
69
+ }
70
+
71
+ @keyframes pullquote-border-in {
72
+ from {
73
+ transform: scaleY(0);
74
+ }
75
+ to {
76
+ transform: scaleY(1);
77
+ }
78
+ }
79
+
80
+ @media (prefers-reduced-motion: reduce) {
81
+ .hyvui-pull-quote::before {
82
+ animation: none;
83
+ }
84
+ }
85
+
86
+ .hyvui-pull-quote-bracket {
87
+ font-family: var(--font-body);
88
+ font-size: clamp(1.1rem, 2.5vw, 1.6rem);
89
+ line-height: 1.45;
90
+ color: rgba(199, 156, 87, 0.4);
91
+ pointer-events: none;
92
+ user-select: none;
93
+ align-self: start;
94
+ margin-top: 0.05em;
95
+ }
96
+
97
+ .hyvui-pull-quote-body {
98
+ margin: 0;
99
+ padding: 0;
100
+ border: none;
101
+ display: flex;
102
+ flex-direction: column;
103
+ gap: calc(0.9rem * var(--reg-spacing-scale, 1));
104
+ }
105
+
106
+ .hyvui-pull-quote-text {
107
+ margin: 0;
108
+ font-family: var(--font-body);
109
+ font-style: italic;
110
+ font-size: clamp(1.1rem, 2.5vw, 1.6rem);
111
+ line-height: 1.45;
112
+ color: var(--text-soft);
113
+ text-wrap: pretty;
114
+ }
115
+
116
+ .hyvui-pull-quote-caption {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 0.5rem;
120
+ flex-wrap: wrap;
121
+ }
122
+
123
+ .hyvui-pull-quote-attribution {
124
+ font-style: italic;
125
+ font-family: var(--font-body);
126
+ font-size: 0.88rem;
127
+ color: var(--muted-strong);
128
+ line-height: 1.5;
129
+ }
130
+
131
+ .hyvui-pull-quote-sep {
132
+ color: var(--muted);
133
+ opacity: 0.75;
134
+ font-family: var(--font-mono);
135
+ font-size: 0.75rem;
136
+ }
137
+
138
+ .hyvui-pull-quote-source {
139
+ font-family: var(--font-mono);
140
+ font-size: 0.82rem;
141
+ letter-spacing: 0.06em;
142
+ color: var(--muted);
143
+ line-height: 1.6;
144
+ }
145
+ </style>
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @remarks Breakout quotation — larger than Blockquote, a page-level element.
3
+ * Use for testimonials, design maxims, and editorial pull-quotes.
4
+ * @example
5
+ * <PullQuote
6
+ * quote="every detail should look placed, not merely present."
7
+ * attribution="design constraints"
8
+ * source="hyvui"
9
+ * />
10
+ */
11
+ interface Props {
12
+ /** The quotation text. */
13
+ quote: string;
14
+ /** Who said it. */
15
+ attribution?: string;
16
+ /** Where it came from. */
17
+ source?: string;
18
+ /** Additional CSS classes. */
19
+ class?: string;
20
+ }
21
+ declare const PullQuote: import("svelte").Component<Props, {}, "">;
22
+ type PullQuote = ReturnType<typeof PullQuote>;
23
+ export default PullQuote;
@@ -0,0 +1,132 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import { applyRegister, registers } from '../../system/register.js';
4
+ import type { Register } from '../../system/register.js';
5
+
6
+ /**
7
+ * A compact three-state toggle for switching between aesthetic registers.
8
+ * Persists choice to localStorage. Mounts invisibly until hovered.
9
+ *
10
+ * @example
11
+ * <RegisterSwitcher />
12
+ * <RegisterSwitcher defaultRegister="hextech" />
13
+ * <RegisterSwitcher choices={['field-notebook', 'hextech', 'arcane']} />
14
+ */
15
+ interface Props {
16
+ /** Which register to apply on first load (if no localStorage entry). */
17
+ defaultRegister?: Register;
18
+ /** Subset of registers to expose. Defaults to field-notebook, hextech, arcane. */
19
+ choices?: Register[];
20
+ /** Additional CSS classes. */
21
+ class?: string;
22
+ }
23
+
24
+ let {
25
+ defaultRegister = 'field-notebook',
26
+ choices = ['field-notebook', 'hextech', 'arcane'],
27
+ class: className = ''
28
+ }: Props = $props();
29
+
30
+ const STORAGE_KEY = 'hyvui-register';
31
+
32
+ const labels: Record<Register, string> = {
33
+ 'field-notebook': 'FN',
34
+ 'mission-control': 'MC',
35
+ archive: 'AV',
36
+ hextech: 'HX',
37
+ arcane: 'ARC'
38
+ };
39
+
40
+ const titles: Record<Register, string> = {
41
+ 'field-notebook': 'Field Notebook',
42
+ 'mission-control': 'Mission Control',
43
+ archive: 'Archive',
44
+ hextech: 'Hextech',
45
+ arcane: 'Arcane'
46
+ };
47
+
48
+ let current: Register = $state(defaultRegister);
49
+
50
+ function init() {
51
+ if (typeof localStorage === 'undefined') return;
52
+ const saved = localStorage.getItem(STORAGE_KEY) as Register | null;
53
+ if (saved && (registers as string[]).includes(saved)) {
54
+ current = saved;
55
+ }
56
+ applyRegister(current);
57
+ }
58
+
59
+ function select(reg: Register) {
60
+ current = reg;
61
+ applyRegister(reg);
62
+ if (typeof localStorage !== 'undefined') {
63
+ localStorage.setItem(STORAGE_KEY, reg);
64
+ }
65
+ }
66
+
67
+ $effect(() => {
68
+ init();
69
+ });
70
+ </script>
71
+
72
+ <div class={cn('hyvui-reg-switcher', className)} role="group" aria-label="Theme register">
73
+ {#each choices as reg}
74
+ <button
75
+ class={cn('hyvui-reg-btn', current === reg && 'hyvui-reg-btn--active')}
76
+ onclick={() => select(reg)}
77
+ title={titles[reg]}
78
+ aria-pressed={current === reg}
79
+ >
80
+ {labels[reg]}
81
+ </button>
82
+ {/each}
83
+ </div>
84
+
85
+ <style>
86
+ .hyvui-reg-switcher {
87
+ display: inline-flex;
88
+ gap: 1px;
89
+ background: rgba(255, 255, 255, 0.04);
90
+ border: 1px solid var(--line);
91
+ padding: 2px;
92
+ opacity: 0.4;
93
+ transition: opacity var(--transition-smooth);
94
+ }
95
+
96
+ .hyvui-reg-switcher:hover,
97
+ .hyvui-reg-switcher:focus-within {
98
+ opacity: 1;
99
+ }
100
+
101
+ .hyvui-reg-btn {
102
+ font-family: var(--font-mono);
103
+ font-size: 0.58rem;
104
+ letter-spacing: 0.1em;
105
+ text-transform: uppercase;
106
+ color: var(--muted);
107
+ background: transparent;
108
+ border: none;
109
+ padding: 0.25rem 0.4rem;
110
+ cursor: pointer;
111
+ transition:
112
+ color var(--transition-fast),
113
+ background var(--transition-fast);
114
+ line-height: 1;
115
+ }
116
+
117
+ .hyvui-reg-btn:hover {
118
+ color: var(--text-soft);
119
+ background: rgba(255, 255, 255, 0.06);
120
+ }
121
+
122
+ .hyvui-reg-btn--active {
123
+ color: var(--accent);
124
+ background: rgba(255, 255, 255, 0.05);
125
+ }
126
+
127
+ /* switcher itself stays visually neutral — never adopts register ornaments */
128
+ .hyvui-reg-btn:focus-visible {
129
+ outline: none;
130
+ box-shadow: var(--focus-ring);
131
+ }
132
+ </style>
@@ -0,0 +1,21 @@
1
+ import type { Register } from '../../system/register.js';
2
+ /**
3
+ * A compact three-state toggle for switching between aesthetic registers.
4
+ * Persists choice to localStorage. Mounts invisibly until hovered.
5
+ *
6
+ * @example
7
+ * <RegisterSwitcher />
8
+ * <RegisterSwitcher defaultRegister="hextech" />
9
+ * <RegisterSwitcher choices={['field-notebook', 'hextech', 'arcane']} />
10
+ */
11
+ interface Props {
12
+ /** Which register to apply on first load (if no localStorage entry). */
13
+ defaultRegister?: Register;
14
+ /** Subset of registers to expose. Defaults to field-notebook, hextech, arcane. */
15
+ choices?: Register[];
16
+ /** Additional CSS classes. */
17
+ class?: string;
18
+ }
19
+ declare const RegisterSwitcher: import("svelte").Component<Props, {}, "">;
20
+ type RegisterSwitcher = ReturnType<typeof RegisterSwitcher>;
21
+ export default RegisterSwitcher;