@hyvnt/hyvui 0.3.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 (170) hide show
  1. package/README.md +37 -7
  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 +8 -0
  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 +7 -1
  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 +6 -0
  15. package/dist/components/ambient/GlyphMark.svelte.d.ts +6 -0
  16. package/dist/components/ambient/GridOverlay.svelte +8 -0
  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 +9 -1
  21. package/dist/components/ambient/ParallaxLayer.svelte.d.ts +7 -0
  22. package/dist/components/ambient/ScanBand.svelte +8 -0
  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 +7 -1
  27. package/dist/components/ambient/SignalRing.svelte.d.ts +6 -0
  28. package/dist/components/ambient/ThreadLine.svelte +7 -0
  29. package/dist/components/ambient/ThreadLine.svelte.d.ts +7 -0
  30. package/dist/components/ambient/Vignette.svelte +6 -0
  31. package/dist/components/ambient/Vignette.svelte.d.ts +6 -0
  32. package/dist/components/depth/DepthLayer.svelte +8 -0
  33. package/dist/components/depth/DepthLayer.svelte.d.ts +8 -0
  34. package/dist/components/depth/DepthStage.svelte +8 -4
  35. package/dist/components/depth/DepthStage.svelte.d.ts +8 -0
  36. package/dist/components/depth/FloatCard.svelte +17 -1
  37. package/dist/components/depth/FloatCard.svelte.d.ts +8 -0
  38. package/dist/components/depth/HorizonGrid.svelte +25 -0
  39. package/dist/components/depth/HorizonGrid.svelte.d.ts +9 -0
  40. package/dist/components/depth/Plinth.svelte +10 -0
  41. package/dist/components/depth/Plinth.svelte.d.ts +10 -0
  42. package/dist/components/display/Avatar.svelte +5 -0
  43. package/dist/components/display/Avatar.svelte.d.ts +5 -0
  44. package/dist/components/display/Badge.svelte +16 -0
  45. package/dist/components/display/Badge.svelte.d.ts +6 -0
  46. package/dist/components/display/Blockquote.svelte +4 -0
  47. package/dist/components/display/Blockquote.svelte.d.ts +4 -0
  48. package/dist/components/display/CodeBlock.svelte +5 -0
  49. package/dist/components/display/CodeBlock.svelte.d.ts +5 -0
  50. package/dist/components/display/MetricCard.svelte +23 -0
  51. package/dist/components/display/MetricCard.svelte.d.ts +6 -0
  52. package/dist/components/display/Table.svelte +7 -0
  53. package/dist/components/display/Table.svelte.d.ts +7 -0
  54. package/dist/components/feedback/Alert.svelte +24 -0
  55. package/dist/components/feedback/Alert.svelte.d.ts +6 -0
  56. package/dist/components/feedback/EmptyState.svelte +7 -0
  57. package/dist/components/feedback/EmptyState.svelte.d.ts +7 -0
  58. package/dist/components/feedback/ErrorState.svelte +5 -0
  59. package/dist/components/feedback/ErrorState.svelte.d.ts +5 -0
  60. package/dist/components/feedback/Skeleton.svelte +6 -0
  61. package/dist/components/feedback/Skeleton.svelte.d.ts +6 -0
  62. package/dist/components/feedback/StatusDot.svelte +36 -1
  63. package/dist/components/feedback/StatusDot.svelte.d.ts +6 -0
  64. package/dist/components/feedback/StatusLine.svelte +8 -2
  65. package/dist/components/feedback/StatusLine.svelte.d.ts +6 -0
  66. package/dist/components/feedback/Toast.svelte +16 -2
  67. package/dist/components/feedback/Toast.svelte.d.ts +10 -0
  68. package/dist/components/inputs/Button.svelte +74 -4
  69. package/dist/components/inputs/Button.svelte.d.ts +8 -0
  70. package/dist/components/inputs/Checkbox.svelte +5 -0
  71. package/dist/components/inputs/Checkbox.svelte.d.ts +5 -0
  72. package/dist/components/inputs/FileUpload.svelte +5 -0
  73. package/dist/components/inputs/FileUpload.svelte.d.ts +5 -0
  74. package/dist/components/inputs/Input.svelte +10 -2
  75. package/dist/components/inputs/Input.svelte.d.ts +7 -0
  76. package/dist/components/inputs/Select.svelte +8 -0
  77. package/dist/components/inputs/Select.svelte.d.ts +8 -0
  78. package/dist/components/inputs/Textarea.svelte +9 -2
  79. package/dist/components/inputs/Textarea.svelte.d.ts +6 -0
  80. package/dist/components/inputs/Toggle.svelte +6 -1
  81. package/dist/components/inputs/Toggle.svelte.d.ts +5 -0
  82. package/dist/components/layout/Card.svelte +11 -0
  83. package/dist/components/layout/Card.svelte.d.ts +11 -0
  84. package/dist/components/layout/Drawer.svelte +7 -0
  85. package/dist/components/layout/Drawer.svelte.d.ts +6 -0
  86. package/dist/components/layout/Grid.svelte +10 -0
  87. package/dist/components/layout/Grid.svelte.d.ts +10 -0
  88. package/dist/components/layout/Modal.svelte +15 -0
  89. package/dist/components/layout/Modal.svelte.d.ts +10 -0
  90. package/dist/components/layout/Panel.svelte +9 -0
  91. package/dist/components/layout/Panel.svelte.d.ts +9 -0
  92. package/dist/components/layout/Popover.svelte +10 -0
  93. package/dist/components/layout/Popover.svelte.d.ts +9 -0
  94. package/dist/components/layout/Stack.svelte +12 -0
  95. package/dist/components/layout/Stack.svelte.d.ts +12 -0
  96. package/dist/components/navigation/Breadcrumb.svelte +8 -0
  97. package/dist/components/navigation/Breadcrumb.svelte.d.ts +8 -0
  98. package/dist/components/navigation/DropdownMenu.svelte +12 -0
  99. package/dist/components/navigation/DropdownMenu.svelte.d.ts +12 -0
  100. package/dist/components/navigation/SidebarNav.svelte +10 -0
  101. package/dist/components/navigation/SidebarNav.svelte.d.ts +9 -0
  102. package/dist/components/navigation/Tabs.svelte +26 -1
  103. package/dist/components/navigation/Tabs.svelte.d.ts +8 -0
  104. package/dist/components/navigation/Topbar.svelte +9 -0
  105. package/dist/components/navigation/Topbar.svelte.d.ts +9 -0
  106. package/dist/components/patterns/ActionBar.svelte +11 -0
  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 +12 -0
  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 +8 -0
  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 +5 -0
  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 +15 -1
  127. package/dist/components/patterns/TerminalBoot.svelte.d.ts +12 -0
  128. package/dist/components/primitives/Divider.svelte +30 -0
  129. package/dist/components/primitives/Divider.svelte.d.ts +5 -0
  130. package/dist/components/primitives/Icon.svelte +9 -0
  131. package/dist/components/primitives/Icon.svelte.d.ts +9 -0
  132. package/dist/components/primitives/Label.svelte +6 -0
  133. package/dist/components/primitives/Label.svelte.d.ts +6 -0
  134. package/dist/components/primitives/Surface.svelte +67 -2
  135. package/dist/components/primitives/Surface.svelte.d.ts +7 -0
  136. package/dist/components/primitives/Text.svelte +32 -0
  137. package/dist/components/primitives/Text.svelte.d.ts +7 -0
  138. package/dist/components/scenes/ArchiveScene.svelte +10 -0
  139. package/dist/components/scenes/ArchiveScene.svelte.d.ts +10 -0
  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 +14 -0
  143. package/dist/components/scenes/LogScene.svelte.d.ts +14 -0
  144. package/dist/components/scenes/NarrativeScene.svelte +9 -0
  145. package/dist/components/scenes/NarrativeScene.svelte.d.ts +9 -0
  146. package/dist/components/scenes/ReadoutScene.svelte +11 -0
  147. package/dist/components/scenes/ReadoutScene.svelte.d.ts +11 -0
  148. package/dist/components/scenes/StageScene.svelte +14 -0
  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/HextechForge.svelte +324 -0
  155. package/dist/examples/HextechForge.svelte.d.ts +3 -0
  156. package/dist/index.d.ts +15 -1
  157. package/dist/index.js +16 -1
  158. package/dist/styles.css +2 -0
  159. package/dist/system/actions/echo.js +13 -4
  160. package/dist/system/actions/resolve.js +20 -6
  161. package/dist/system/actions/reveal.js +1 -1
  162. package/dist/system/actions/surface.js +1 -3
  163. package/dist/system/register.d.ts +1 -1
  164. package/dist/system/register.js +5 -1
  165. package/dist/tokens/arcane.css +96 -0
  166. package/dist/tokens/hextech.css +96 -0
  167. package/dist/tokens/tokens.css +6 -4
  168. package/dist/tokens/tokens.d.ts +41 -0
  169. package/dist/tokens/tokens.js +41 -0
  170. package/package.json +6 -2
package/README.md CHANGED
@@ -143,7 +143,10 @@ GridOverlay CornerBrackets
143
143
  ScanBand Vignette
144
144
  ParallaxLayer SignalRing
145
145
  GlyphMark DataStream
146
- ThreadLine
146
+ ThreadLine HexGrid
147
+ BrassFiligree CrystalShard
148
+ ArcaneVein EnergyArc
149
+ ShimmerCloud
147
150
  ```
148
151
 
149
152
  **depth**
@@ -174,7 +177,7 @@ LogScene
174
177
  the library is organized in three additive layers. each one works without the next.
175
178
 
176
179
  <pre lang="txt">
177
- [ base ] 42 components. tokens. css custom properties throughout.
180
+ [ base ] 75 components. tokens. css custom properties throughout.
178
181
  nothing hardcoded. nothing fighting your cascade.
179
182
 
180
183
  [ expressive ] registers shift the ambient mood of a section.
@@ -198,11 +201,38 @@ registers are named aesthetic states. apply one and the ambient properties shift
198
201
  </script>
199
202
  ```
200
203
 
201
- | register | character |
202
- | ----------------- | ---------------------------- |
203
- | `field-notebook` | warm, worn, analog |
204
- | `mission-control` | cold, precise, dense |
205
- | `archive` | flat, institutional, drained |
204
+ | register | character |
205
+ | ----------------- | -------------------------------------------- |
206
+ | `field-notebook` | warm, worn, analog |
207
+ | `mission-control` | cold, precise, dense |
208
+ | `archive` | flat, institutional, drained |
209
+ | `hextech` | piltover-refined. brass, crystal, mechanical |
210
+ | `arcane` | zaun-unstable. shimmer, shards, organic glow |
211
+
212
+ the hextech and arcane registers ship their own palette and motif token files. import the ones you use:
213
+
214
+ ```ts
215
+ import '@hyvnt/hyvui/styles.css'; // base tokens + all 5 register weights
216
+ import '@hyvnt/hyvui/tokens/hextech.css'; // --htx-* palette + motif tokens
217
+ import '@hyvnt/hyvui/tokens/arcane.css'; // --arc-* palette + motif tokens
218
+ ```
219
+
220
+ **motif tokens** (hextech + arcane only):
221
+
222
+ ```css
223
+ --orn-hex-density /* hex grid tile density */
224
+ --orn-vein-intensity /* arcane crack-vein strength, 0–1 */
225
+ --orn-shimmer-rate /* particle drift / shimmer speed */
226
+ ```
227
+
228
+ use `RegisterSwitcher` from the patterns layer to let users toggle at runtime:
229
+
230
+ ```svelte
231
+ <script>
232
+ import { RegisterSwitcher } from '@hyvnt/hyvui';
233
+ </script>
234
+ <RegisterSwitcher />
235
+ ```
206
236
 
207
237
  ---
208
238
 
@@ -0,0 +1,151 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ /**
5
+ * Decorative glowing crack / energy conduit rendered as SVG.
6
+ * Parent must have `position: relative`. Renders `aria-hidden`.
7
+ *
8
+ * Under `hextech`: precise etched control line, traveling cyan dot.
9
+ * Under `arcane`: pulsing violet crack, traveling particle + glow.
10
+ *
11
+ * @example
12
+ * <div style="position: relative; height: 200px;">
13
+ * <ArcaneVein x1="10%" y1="0%" x2="90%" y2="100%" />
14
+ * </div>
15
+ */
16
+ interface Props {
17
+ /** Start x (CSS %). */
18
+ x1?: string;
19
+ /** Start y (CSS %). */
20
+ y1?: string;
21
+ /** End x (CSS %). */
22
+ x2?: string;
23
+ /** End y (CSS %). */
24
+ y2?: string;
25
+ /** Duration of traveling particle. */
26
+ speed?: number;
27
+ /** Enable traveling particle animation. */
28
+ animated?: boolean;
29
+ /** Additional CSS classes. */
30
+ class?: string;
31
+ }
32
+
33
+ let {
34
+ x1 = '0%',
35
+ y1 = '0%',
36
+ x2 = '100%',
37
+ y2 = '100%',
38
+ speed = 3,
39
+ animated = true,
40
+ class: className = ''
41
+ }: Props = $props();
42
+
43
+ const prefersReduced =
44
+ typeof window !== 'undefined'
45
+ ? window.matchMedia('(prefers-reduced-motion: reduce)').matches
46
+ : false;
47
+
48
+ const dur = $derived(`${speed}s`);
49
+ const shouldAnimate = $derived(animated && !prefersReduced);
50
+
51
+ // Unique filter ID to avoid SVG filter collision when multiple veins are on a page.
52
+ const filterId = `av-glow-${Math.random().toString(36).slice(2, 8)}`;
53
+ </script>
54
+
55
+ <svg class={cn('hyvui-arcane-vein', className)} aria-hidden="true">
56
+ <defs>
57
+ <filter id={filterId} x="-50%" y="-50%" width="200%" height="200%">
58
+ <feGaussianBlur stdDeviation="2.5" result="blur" />
59
+ <feMerge>
60
+ <feMergeNode in="blur" />
61
+ <feMergeNode in="SourceGraphic" />
62
+ </feMerge>
63
+ </filter>
64
+ </defs>
65
+
66
+ <!-- glow halo (arcane only, separate pass) -->
67
+ <line
68
+ class="hyvui-av-halo"
69
+ {x1} {y1} {x2} {y2}
70
+ stroke-width="4"
71
+ filter="url(#{filterId})"
72
+ />
73
+
74
+ <!-- main vein line -->
75
+ <line
76
+ class="hyvui-av-line"
77
+ {x1} {y1} {x2} {y2}
78
+ stroke-width="1"
79
+ />
80
+
81
+ <!-- traveling particle -->
82
+ {#if shouldAnimate}
83
+ <circle class="hyvui-av-particle" r="2.5">
84
+ <animateMotion
85
+ dur={dur}
86
+ repeatCount="indefinite"
87
+ keyPoints="0;1"
88
+ keyTimes="0;1"
89
+ calcMode="linear"
90
+ >
91
+ <mpath>
92
+ <line {x1} {y1} {x2} {y2} />
93
+ </mpath>
94
+ </animateMotion>
95
+ <animate
96
+ attributeName="opacity"
97
+ values="0;0.9;0.9;0"
98
+ keyTimes="0;0.08;0.88;1"
99
+ dur={dur}
100
+ repeatCount="indefinite"
101
+ />
102
+ </circle>
103
+ {/if}
104
+ </svg>
105
+
106
+ <style>
107
+ .hyvui-arcane-vein {
108
+ position: absolute;
109
+ inset: 0;
110
+ width: 100%;
111
+ height: 100%;
112
+ pointer-events: none;
113
+ overflow: visible;
114
+ }
115
+
116
+ /* ── default (field-notebook) ─────────────────────────────────────── */
117
+ .hyvui-av-halo { stroke: transparent; }
118
+ .hyvui-av-line { stroke: rgba(199, 156, 87, 0.22); }
119
+ .hyvui-av-particle { fill: rgba(199, 156, 87, 0.7); }
120
+
121
+ /* ── hextech: etched control line, cyan particle ──────────────────── */
122
+ :global([data-register='hextech']) .hyvui-av-halo {
123
+ stroke: rgba(93, 217, 240, 0.08);
124
+ }
125
+ :global([data-register='hextech']) .hyvui-av-line {
126
+ stroke: rgba(93, 217, 240, 0.4);
127
+ stroke-dasharray: 6 3;
128
+ }
129
+ :global([data-register='hextech']) .hyvui-av-particle {
130
+ fill: rgba(184, 230, 242, 0.95);
131
+ }
132
+
133
+ /* ── arcane: glowing crack, violet bleed particle ─────────────────── */
134
+ :global([data-register='arcane']) .hyvui-av-halo {
135
+ stroke: rgba(184, 69, 201, 0.28);
136
+ }
137
+ :global([data-register='arcane']) .hyvui-av-line {
138
+ stroke: rgba(184, 69, 201, 0.7);
139
+ stroke-dasharray: none;
140
+ }
141
+ :global([data-register='arcane']) .hyvui-av-particle {
142
+ fill: rgba(233, 76, 188, 1);
143
+ r: 3.5;
144
+ }
145
+
146
+ @media (prefers-reduced-motion: reduce) {
147
+ .hyvui-av-particle {
148
+ display: none;
149
+ }
150
+ }
151
+ </style>
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Decorative glowing crack / energy conduit rendered as SVG.
3
+ * Parent must have `position: relative`. Renders `aria-hidden`.
4
+ *
5
+ * Under `hextech`: precise etched control line, traveling cyan dot.
6
+ * Under `arcane`: pulsing violet crack, traveling particle + glow.
7
+ *
8
+ * @example
9
+ * <div style="position: relative; height: 200px;">
10
+ * <ArcaneVein x1="10%" y1="0%" x2="90%" y2="100%" />
11
+ * </div>
12
+ */
13
+ interface Props {
14
+ /** Start x (CSS %). */
15
+ x1?: string;
16
+ /** Start y (CSS %). */
17
+ y1?: string;
18
+ /** End x (CSS %). */
19
+ x2?: string;
20
+ /** End y (CSS %). */
21
+ y2?: string;
22
+ /** Duration of traveling particle. */
23
+ speed?: number;
24
+ /** Enable traveling particle animation. */
25
+ animated?: boolean;
26
+ /** Additional CSS classes. */
27
+ class?: string;
28
+ }
29
+ declare const ArcaneVein: import("svelte").Component<Props, {}, "">;
30
+ type ArcaneVein = ReturnType<typeof ArcaneVein>;
31
+ export default ArcaneVein;
@@ -0,0 +1,109 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ /**
5
+ * Decorative corner brackets with an Art Deco / Hextech filigree motif.
6
+ * Renders four corners as SVG ornaments. Parent must have `position: relative`.
7
+ * Under `hextech`: bright brass. Under `arcane`: subdued violet-tinted.
8
+ * Renders `aria-hidden`.
9
+ * @example
10
+ * <div style="position: relative; padding: 2rem;">
11
+ * <BrassFiligree size={40} />
12
+ * framed content
13
+ * </div>
14
+ */
15
+ interface Props {
16
+ /** Arm length in pixels. */
17
+ size?: number;
18
+ /** Additional CSS classes. */
19
+ class?: string;
20
+ }
21
+
22
+ let { size = 40, class: className = '' }: Props = $props();
23
+
24
+ // Filigree corner SVG path:
25
+ // - Two arms (top+left or equivalent) of the given length
26
+ // - Small interior notch at 45° angle (the "filigree" detail)
27
+ // - Tiny rivet dot at the corner apex
28
+ // All paths are for a top-left oriented corner; CSS rotation handles others.
29
+ const arm = $derived(size);
30
+ const notch = $derived(Math.round(size * 0.28));
31
+ const rivet = $derived(Math.round(size * 0.09));
32
+ </script>
33
+
34
+ <div class={cn('hyvui-brass-filigree', className)} aria-hidden="true">
35
+ {#each ['tl', 'tr', 'bl', 'br'] as pos}
36
+ <svg
37
+ class="hyvui-bf-corner hyvui-bf-{pos}"
38
+ width={arm}
39
+ height={arm}
40
+ viewBox="0 0 {arm} {arm}"
41
+ fill="none"
42
+ >
43
+ <!-- main bracket arms -->
44
+ <polyline
45
+ class="hyvui-bf-arm"
46
+ points="{arm},1 1,1 1,{arm}"
47
+ stroke-width="1"
48
+ />
49
+ <!-- interior notch (diagonal filigree detail) -->
50
+ <line
51
+ class="hyvui-bf-notch"
52
+ x1={notch}
53
+ y1="1"
54
+ x2="1"
55
+ y2={notch}
56
+ stroke-width="0.75"
57
+ />
58
+ <!-- apex rivet dot -->
59
+ <circle class="hyvui-bf-rivet" cx="1" cy="1" r={rivet} />
60
+ </svg>
61
+ {/each}
62
+ </div>
63
+
64
+ <style>
65
+ .hyvui-brass-filigree {
66
+ position: absolute;
67
+ inset: 0;
68
+ pointer-events: none;
69
+ }
70
+
71
+ .hyvui-bf-corner {
72
+ position: absolute;
73
+ overflow: visible;
74
+ }
75
+
76
+ .hyvui-bf-tl { top: 0; left: 0; }
77
+ .hyvui-bf-tr { top: 0; right: 0; transform: scaleX(-1); }
78
+ .hyvui-bf-bl { bottom: 0; left: 0; transform: scaleY(-1); }
79
+ .hyvui-bf-br { bottom: 0; right: 0; transform: scale(-1); }
80
+
81
+ /* ── default (field-notebook) ─────────────────────────────────────── */
82
+ .hyvui-bf-arm { stroke: rgba(199, 156, 87, 0.3); }
83
+ .hyvui-bf-notch { stroke: rgba(199, 156, 87, 0.15); }
84
+ .hyvui-bf-rivet { fill: rgba(199, 156, 87, 0.35); }
85
+
86
+ /* ── hextech: bright brass precision ──────────────────────────────── */
87
+ :global([data-register='hextech']) .hyvui-bf-arm {
88
+ stroke: rgba(212, 165, 116, 0.65);
89
+ stroke-width: 1.2px;
90
+ }
91
+ :global([data-register='hextech']) .hyvui-bf-notch {
92
+ stroke: rgba(93, 217, 240, 0.35);
93
+ }
94
+ :global([data-register='hextech']) .hyvui-bf-rivet {
95
+ fill: rgba(212, 165, 116, 0.8);
96
+ }
97
+
98
+ /* ── arcane: dim violet-tinted, thinner ───────────────────────────── */
99
+ :global([data-register='arcane']) .hyvui-bf-arm {
100
+ stroke: rgba(184, 69, 201, 0.28);
101
+ stroke-width: 0.8px;
102
+ }
103
+ :global([data-register='arcane']) .hyvui-bf-notch {
104
+ stroke: rgba(233, 76, 188, 0.18);
105
+ }
106
+ :global([data-register='arcane']) .hyvui-bf-rivet {
107
+ fill: rgba(233, 76, 188, 0.3);
108
+ }
109
+ </style>
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Decorative corner brackets with an Art Deco / Hextech filigree motif.
3
+ * Renders four corners as SVG ornaments. Parent must have `position: relative`.
4
+ * Under `hextech`: bright brass. Under `arcane`: subdued violet-tinted.
5
+ * Renders `aria-hidden`.
6
+ * @example
7
+ * <div style="position: relative; padding: 2rem;">
8
+ * <BrassFiligree size={40} />
9
+ * framed content
10
+ * </div>
11
+ */
12
+ interface Props {
13
+ /** Arm length in pixels. */
14
+ size?: number;
15
+ /** Additional CSS classes. */
16
+ class?: string;
17
+ }
18
+ declare const BrassFiligree: import("svelte").Component<Props, {}, "">;
19
+ type BrassFiligree = ReturnType<typeof BrassFiligree>;
20
+ export default BrassFiligree;
@@ -1,6 +1,14 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../../utils/cn.js';
3
3
 
4
+ /**
5
+ * Decorative. Parent must have `position: relative`. Renders `aria-hidden`.
6
+ * @example
7
+ * <div style="position: relative; padding: 2rem;">
8
+ * <CornerBrackets size={24} />
9
+ * content framed by brackets
10
+ * </div>
11
+ */
4
12
  interface Props {
5
13
  /** Bracket arm length in pixels. */
6
14
  size?: number;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Decorative. Parent must have `position: relative`. Renders `aria-hidden`.
3
+ * @example
4
+ * <div style="position: relative; padding: 2rem;">
5
+ * <CornerBrackets size={24} />
6
+ * content framed by brackets
7
+ * </div>
8
+ */
1
9
  interface Props {
2
10
  /** Bracket arm length in pixels. */
3
11
  size?: number;
@@ -0,0 +1,151 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ /**
5
+ * Decorative faceted crystal accent. Adapts per register:
6
+ * hextech → flat cyan prism; arcane → jagged violet shard with glow.
7
+ * Renders `aria-hidden`.
8
+ * @example
9
+ * <CrystalShard size={48} />
10
+ * <CrystalShard size={32} animated={false} />
11
+ */
12
+ interface Props {
13
+ /** Bounding size in pixels (width = size, height ~= size * 1.4). */
14
+ size?: number;
15
+ /** Enable breathing pulse. */
16
+ animated?: boolean;
17
+ /** Additional CSS classes. */
18
+ class?: string;
19
+ }
20
+
21
+ let { size = 48, animated = true, class: className = '' }: Props = $props();
22
+
23
+ const prefersReduced =
24
+ typeof window !== 'undefined'
25
+ ? window.matchMedia('(prefers-reduced-motion: reduce)').matches
26
+ : false;
27
+
28
+ const shouldAnimate = $derived(animated && !prefersReduced);
29
+
30
+ // Pointy-top crystal: two overlapping polygons for faceted look.
31
+ // Outer shard — tall diamond with offset peak
32
+ // Inner face — smaller highlight face giving depth
33
+ const w = $derived(size);
34
+ const h = $derived(Math.round(size * 1.4));
35
+ const cx = $derived(Math.round(w / 2));
36
+
37
+ // Outer polygon: asymmetric diamond (peak offset left for natural shard look)
38
+ const outerPoints = $derived(
39
+ `${Math.round(cx * 0.7)},2 ${w - 4},${Math.round(h * 0.32)} ${w - 8},${h - 4} ${Math.round(cx * 0.4)},${h - 2} 4,${Math.round(h * 0.72)}`
40
+ );
41
+
42
+ // Inner face: smaller, offset for "facet" depth
43
+ const innerPoints = $derived(
44
+ `${Math.round(cx * 0.7)},2 ${w - 4},${Math.round(h * 0.32)} ${Math.round(w * 0.6)},${Math.round(h * 0.55)}`
45
+ );
46
+ </script>
47
+
48
+ <svg
49
+ class={cn(
50
+ 'hyvui-crystal-shard',
51
+ shouldAnimate && 'hyvui-crystal-shard--animated',
52
+ className
53
+ )}
54
+ width={w}
55
+ height={h}
56
+ viewBox="0 0 {w} {h}"
57
+ fill="none"
58
+ aria-hidden="true"
59
+ >
60
+ <defs>
61
+ <filter id="cs-glow" x="-40%" y="-40%" width="180%" height="180%">
62
+ <feGaussianBlur stdDeviation="3" result="blur" />
63
+ <feMerge>
64
+ <feMergeNode in="blur" />
65
+ <feMergeNode in="SourceGraphic" />
66
+ </feMerge>
67
+ </filter>
68
+ </defs>
69
+
70
+ <!-- outer shard body -->
71
+ <polygon class="hyvui-cs-body" points={outerPoints} />
72
+ <!-- inner facet face -->
73
+ <polygon class="hyvui-cs-face" points={innerPoints} />
74
+ <!-- edge highlight line -->
75
+ <polyline
76
+ class="hyvui-cs-edge"
77
+ points="{Math.round(cx * 0.7)},2 {w - 4},{Math.round(h * 0.32)}"
78
+ />
79
+ </svg>
80
+
81
+ <style>
82
+ .hyvui-crystal-shard {
83
+ display: block;
84
+ pointer-events: none;
85
+ overflow: visible;
86
+ }
87
+
88
+ /* ── default (field-notebook) ─────────────────────────────────────── */
89
+ .hyvui-cs-body {
90
+ fill: rgba(199, 156, 87, 0.06);
91
+ stroke: rgba(199, 156, 87, 0.3);
92
+ stroke-width: 1;
93
+ }
94
+ .hyvui-cs-face {
95
+ fill: rgba(199, 156, 87, 0.12);
96
+ stroke: none;
97
+ }
98
+ .hyvui-cs-edge {
99
+ stroke: rgba(199, 156, 87, 0.5);
100
+ stroke-width: 0.75;
101
+ }
102
+
103
+ /* ── hextech: flat cyan prism, clean geometry ─────────────────────── */
104
+ :global([data-register='hextech']) .hyvui-cs-body {
105
+ fill: rgba(93, 217, 240, 0.08);
106
+ stroke: rgba(93, 217, 240, 0.55);
107
+ stroke-width: 1;
108
+ }
109
+ :global([data-register='hextech']) .hyvui-cs-face {
110
+ fill: rgba(93, 217, 240, 0.18);
111
+ }
112
+ :global([data-register='hextech']) .hyvui-cs-edge {
113
+ stroke: rgba(184, 230, 242, 0.8);
114
+ stroke-width: 1;
115
+ }
116
+
117
+ /* ── arcane: violet shard with glow filter ────────────────────────── */
118
+ :global([data-register='arcane']) .hyvui-cs-body {
119
+ fill: rgba(184, 69, 201, 0.12);
120
+ stroke: rgba(184, 69, 201, 0.65);
121
+ stroke-width: 1;
122
+ filter: url(#cs-glow);
123
+ }
124
+ :global([data-register='arcane']) .hyvui-cs-face {
125
+ fill: rgba(233, 76, 188, 0.22);
126
+ }
127
+ :global([data-register='arcane']) .hyvui-cs-edge {
128
+ stroke: rgba(233, 76, 188, 0.9);
129
+ stroke-width: 1.2;
130
+ }
131
+
132
+ /* ── pulse animation ─────────────────────────────────────────────── */
133
+ .hyvui-crystal-shard--animated .hyvui-cs-body {
134
+ animation: cs-breathe var(--orn-shimmer-rate, 4s) var(--orn-pulse-rhythm, ease-in-out) infinite;
135
+ }
136
+
137
+ :global([data-register='arcane']) .hyvui-crystal-shard--animated .hyvui-cs-body {
138
+ animation: cs-breathe var(--orn-shimmer-rate, 2.4s) var(--orn-pulse-rhythm, ease-in-out) infinite;
139
+ }
140
+
141
+ @keyframes cs-breathe {
142
+ 0%, 100% { opacity: 1; }
143
+ 50% { opacity: 0.55; }
144
+ }
145
+
146
+ @media (prefers-reduced-motion: reduce) {
147
+ .hyvui-crystal-shard--animated .hyvui-cs-body {
148
+ animation: none;
149
+ }
150
+ }
151
+ </style>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Decorative faceted crystal accent. Adapts per register:
3
+ * hextech → flat cyan prism; arcane → jagged violet shard with glow.
4
+ * Renders `aria-hidden`.
5
+ * @example
6
+ * <CrystalShard size={48} />
7
+ * <CrystalShard size={32} animated={false} />
8
+ */
9
+ interface Props {
10
+ /** Bounding size in pixels (width = size, height ~= size * 1.4). */
11
+ size?: number;
12
+ /** Enable breathing pulse. */
13
+ animated?: boolean;
14
+ /** Additional CSS classes. */
15
+ class?: string;
16
+ }
17
+ declare const CrystalShard: import("svelte").Component<Props, {}, "">;
18
+ type CrystalShard = ReturnType<typeof CrystalShard>;
19
+ export default CrystalShard;
@@ -2,6 +2,12 @@
2
2
  import { cn } from '../../utils/cn.js';
3
3
  import { onMount } from 'svelte';
4
4
 
5
+ /**
6
+ * Decorative scrolling hex character column. Renders `aria-hidden`.
7
+ * @example
8
+ * <DataStream width="1.4rem" speed="slow" />
9
+ * <DataStream active={isConnected} />
10
+ */
5
11
  interface Props {
6
12
  /** Enable the scrolling animation. */
7
13
  active?: boolean;
@@ -100,7 +106,7 @@
100
106
 
101
107
  .hyvui-data-stream-char {
102
108
  display: block;
103
- transition: opacity 0.3s ease-out;
109
+ transition: opacity 0.3s var(--ease-fast);
104
110
  }
105
111
 
106
112
  @media (prefers-reduced-motion: reduce) {
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Decorative scrolling hex character column. Renders `aria-hidden`.
3
+ * @example
4
+ * <DataStream width="1.4rem" speed="slow" />
5
+ * <DataStream active={isConnected} />
6
+ */
1
7
  interface Props {
2
8
  /** Enable the scrolling animation. */
3
9
  active?: boolean;