@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
@@ -0,0 +1,3 @@
1
+ declare const ArcaneShard: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ArcaneShard = ReturnType<typeof ArcaneShard>;
3
+ export default ArcaneShard;
@@ -1,223 +1,226 @@
1
- <!--
2
- EXAMPLE: Field Report
3
- REGISTER: field-notebook
4
- CONCEPT: a case study page that reads like a recovered classified document
5
- DEMONSTRATES: NarrativeScene, FloatCard, Plinth, MetricCard, Table, Blockquote, CodeBlock, Badge, Text expressions, DepthStage, DepthLayer, GlyphMark, surface action
6
- INSPIRED BY: a handwritten field notebook digitized and presented across a table
7
- -->
8
- <script lang="ts">
9
- import {
10
- Text,
11
- Label,
12
- Badge,
13
- Divider,
14
- Stack,
15
- Grid,
16
- MetricCard,
17
- Table,
18
- Blockquote,
19
- CodeBlock,
20
- NarrativeScene,
21
- FloatCard,
22
- Plinth,
23
- DepthStage,
24
- DepthLayer,
25
- GlyphMark,
26
- CornerBrackets,
27
- surface,
28
- applyRegister,
29
- } from '../index.js';
30
- import { onMount } from 'svelte';
31
-
32
- const metrics = [
33
- { label: 'first paint', value: '0.8s', trend: 'down' as const, trendValue: '-34%' },
34
- { label: 'bundle weight', value: '12kb', trend: 'down' as const, trendValue: '-61%' },
35
- { label: 'field duration', value: '9 weeks', trend: 'neutral' as const, trendValue: '' },
36
- ];
37
-
38
- const phases = [
39
- { phase: '01', designation: 'survey', date: '2025.09.12', status: 'complete' },
40
- { phase: '02', designation: 'excavation', date: '2025.09.28', status: 'complete' },
41
- { phase: '03', designation: 'assembly', date: '2025.10.14', status: 'complete' },
42
- { phase: '04', designation: 'calibration', date: '2025.10.30', status: 'complete' },
43
- { phase: '05', designation: 'field test', date: '2025.11.08', status: 'complete' },
44
- { phase: '06', designation: 'deployment', date: '2025.11.15', status: 'active' },
45
- ];
46
-
47
- const phaseColumns = [
48
- { key: 'phase', label: 'phase' },
49
- { key: 'designation', label: 'designation' },
50
- { key: 'date', label: 'date' },
51
- { key: 'status', label: 'status' },
52
- ];
53
-
54
- const codeSnippet = `const signal = await listen({
55
- frequency: 47.2,
56
- threshold: 0.003,
57
- timeout: Infinity,
58
- });
59
-
60
- if (signal.strength > baseline) {
61
- log('contact', signal.origin);
62
- }`;
63
-
64
- const technologies = ['svelte', 'typescript', 'css custom properties', 'canvas 2d', 'webgl'];
65
-
66
- onMount(() => {
67
- applyRegister('field-notebook');
68
- return () => {
69
- document.body.removeAttribute('data-register');
70
- };
71
- });
72
- </script>
73
-
74
- <NarrativeScene chapter="field report 03 — signal architecture">
75
- {#snippet heading()}
76
- <DepthStage perspective="far">
77
- <DepthLayer level="foreground">
78
- <Text variant="heading" expression="title-card" as="h1" color="primary">
79
- building the listening station
80
- </Text>
81
- </DepthLayer>
82
- </DepthStage>
83
- {/snippet}
84
-
85
- {#snippet copy()}
86
- <div class="field-report-copy">
87
- <div use:surface={{ delay: 200 }}>
88
- <Text variant="body">
89
- the project started as a question. not the kind you find in a brief.
90
- the kind that stays after the meeting ends. what does it feel like
91
- when a system is paying attention.
92
- </Text>
93
- </div>
94
-
95
- <div use:surface={{ delay: 350 }}>
96
- <Text variant="body">
97
- we built the component library first. not because it was the most
98
- important part, but because naming things forces clarity. every
99
- token, every variant, every slot had to earn its name.
100
- </Text>
101
- </div>
102
-
103
- <div use:surface={{ delay: 500 }}>
104
- <Blockquote>
105
- the real constraint was not technical. it was tonal. how do you
106
- build an interface that feels serious without feeling cold. that
107
- feels precise without feeling sterile.
108
- </Blockquote>
109
- </div>
110
-
111
- <div class="field-report-metrics" use:surface={{ delay: 650 }}>
112
- <DepthStage perspective="far">
113
- <DepthLayer level="raised">
114
- <Grid cols={3} gap="0.75rem">
115
- {#each metrics as m}
116
- <FloatCard tiltMax={5}>
117
- <div class="field-report-metric-inner">
118
- <Label color="muted">{m.label}</Label>
119
- <Text variant="heading" as="span" color="primary">{m.value}</Text>
120
- {#if m.trendValue}
121
- <Text variant="caption" as="span" color={m.trend === 'down' ? 'signal' : 'muted'}>
122
- {m.trend === 'down' ? '\u2193' : '\u2014'} {m.trendValue}
123
- </Text>
124
- {/if}
125
- </div>
126
- </FloatCard>
127
- {/each}
128
- </Grid>
129
- </DepthLayer>
130
- </DepthStage>
131
- <Plinth width="90%" depth="24px" />
132
- </div>
133
-
134
- <div use:surface={{ delay: 800 }}>
135
- <Text expression="chapter" as="span">mission log</Text>
136
- </div>
137
-
138
- <div use:surface={{ delay: 900 }}>
139
- <Table columns={phaseColumns} rows={phases} />
140
- </div>
141
-
142
- <div use:surface={{ delay: 1000 }}>
143
- <Text expression="chapter" as="span">from the field notebook</Text>
144
- </div>
145
-
146
- <div use:surface={{ delay: 1100 }}>
147
- <CodeBlock code={codeSnippet} />
148
- </div>
149
-
150
- <div class="field-report-tags" use:surface={{ delay: 1200 }}>
151
- {#each technologies as tech}
152
- <Badge variant="default">{tech}</Badge>
153
- {/each}
154
- </div>
155
- </div>
156
- {/snippet}
157
-
158
- {#snippet canvas()}
159
- <div class="field-report-canvas" use:surface={{ delay: 400 }}>
160
- <div class="field-report-canvas-inner" style:position="relative">
161
- <CornerBrackets size={40} color="rgba(199, 156, 87, 0.12)" />
162
- <div class="field-report-canvas-marks">
163
- <GlyphMark variant="reticle" size={48} color="var(--muted-strong)" />
164
- <div class="field-report-canvas-label">
165
- <Label color="muted">artifact scan</Label>
166
- <Label color="accent">47.2 mhz</Label>
167
- </div>
168
- </div>
169
- </div>
170
- </div>
171
- {/snippet}
172
- </NarrativeScene>
173
-
174
- <style>
175
- .field-report-copy {
176
- display: flex;
177
- flex-direction: column;
178
- gap: 1.75rem;
179
- }
180
-
181
- .field-report-metrics {
182
- display: flex;
183
- flex-direction: column;
184
- gap: 0.5rem;
185
- }
186
-
187
- .field-report-metric-inner {
188
- display: flex;
189
- flex-direction: column;
190
- gap: 0.25rem;
191
- }
192
-
193
- .field-report-tags {
194
- display: flex;
195
- flex-wrap: wrap;
196
- gap: 0.375rem;
197
- }
198
-
199
- .field-report-canvas {
200
- display: flex;
201
- align-items: center;
202
- justify-content: center;
203
- min-height: 50vh;
204
- }
205
-
206
- .field-report-canvas-inner {
207
- padding: 3rem;
208
- }
209
-
210
- .field-report-canvas-marks {
211
- display: flex;
212
- flex-direction: column;
213
- align-items: center;
214
- gap: 1.5rem;
215
- }
216
-
217
- .field-report-canvas-label {
218
- display: flex;
219
- flex-direction: column;
220
- align-items: center;
221
- gap: 0.25rem;
222
- }
223
- </style>
1
+ <!--
2
+ EXAMPLE: Field Report
3
+ REGISTER: field-notebook
4
+ CONCEPT: a case study page that reads like a recovered classified document
5
+ DEMONSTRATES: NarrativeScene, FloatCard, Plinth, MetricCard, Table, Blockquote, CodeBlock, Badge, Text expressions, DepthStage, DepthLayer, GlyphMark, surface action
6
+ INSPIRED BY: a handwritten field notebook digitized and presented across a table
7
+ -->
8
+ <script lang="ts">
9
+ import {
10
+ Text,
11
+ Label,
12
+ Badge,
13
+ Divider,
14
+ Stack,
15
+ Grid,
16
+ MetricCard,
17
+ Table,
18
+ Blockquote,
19
+ CodeBlock,
20
+ NarrativeScene,
21
+ FloatCard,
22
+ Plinth,
23
+ DepthStage,
24
+ DepthLayer,
25
+ GlyphMark,
26
+ CornerBrackets,
27
+ surface,
28
+ applyRegister
29
+ } from '../index.js';
30
+ import { onMount } from 'svelte';
31
+
32
+ const metrics = [
33
+ { label: 'first paint', value: '0.8s', trend: 'down' as const, trendValue: '-34%' },
34
+ { label: 'bundle weight', value: '12kb', trend: 'down' as const, trendValue: '-61%' },
35
+ { label: 'field duration', value: '9 weeks', trend: 'neutral' as const, trendValue: '' }
36
+ ];
37
+
38
+ const phases = [
39
+ { phase: '01', designation: 'survey', date: '2025.09.12', status: 'complete' },
40
+ { phase: '02', designation: 'excavation', date: '2025.09.28', status: 'complete' },
41
+ { phase: '03', designation: 'assembly', date: '2025.10.14', status: 'complete' },
42
+ { phase: '04', designation: 'calibration', date: '2025.10.30', status: 'complete' },
43
+ { phase: '05', designation: 'field test', date: '2025.11.08', status: 'complete' },
44
+ { phase: '06', designation: 'deployment', date: '2025.11.15', status: 'active' }
45
+ ];
46
+
47
+ const phaseColumns = [
48
+ { key: 'phase', label: 'phase' },
49
+ { key: 'designation', label: 'designation' },
50
+ { key: 'date', label: 'date' },
51
+ { key: 'status', label: 'status' }
52
+ ];
53
+
54
+ const codeSnippet = `const signal = await listen({
55
+ frequency: 47.2,
56
+ threshold: 0.003,
57
+ timeout: Infinity,
58
+ });
59
+
60
+ if (signal.strength > baseline) {
61
+ log('contact', signal.origin);
62
+ }`;
63
+
64
+ const technologies = ['svelte', 'typescript', 'css custom properties', 'canvas 2d', 'webgl'];
65
+
66
+ onMount(() => {
67
+ applyRegister('field-notebook');
68
+ return () => {
69
+ document.body.removeAttribute('data-register');
70
+ };
71
+ });
72
+ </script>
73
+
74
+ <NarrativeScene chapter="field report 03 — signal architecture">
75
+ {#snippet heading()}
76
+ <DepthStage perspective="far">
77
+ <DepthLayer level="foreground">
78
+ <Text variant="heading" expression="title-card" as="h1" color="primary">
79
+ building the listening station
80
+ </Text>
81
+ </DepthLayer>
82
+ </DepthStage>
83
+ {/snippet}
84
+
85
+ {#snippet copy()}
86
+ <div class="field-report-copy">
87
+ <div use:surface={{ delay: 200 }}>
88
+ <Text variant="body">
89
+ the project started as a question. not the kind you find in a brief. the kind that stays
90
+ after the meeting ends. what does it feel like when a system is paying attention.
91
+ </Text>
92
+ </div>
93
+
94
+ <div use:surface={{ delay: 350 }}>
95
+ <Text variant="body">
96
+ we built the component library first. not because it was the most important part, but
97
+ because naming things forces clarity. every token, every variant, every slot had to earn
98
+ its name.
99
+ </Text>
100
+ </div>
101
+
102
+ <div use:surface={{ delay: 500 }}>
103
+ <Blockquote>
104
+ the real constraint was not technical. it was tonal. how do you build an interface that
105
+ feels serious without feeling cold. that feels precise without feeling sterile.
106
+ </Blockquote>
107
+ </div>
108
+
109
+ <div class="field-report-metrics" use:surface={{ delay: 650 }}>
110
+ <DepthStage perspective="far">
111
+ <DepthLayer level="raised">
112
+ <Grid cols={3} gap="0.75rem">
113
+ {#each metrics as m}
114
+ <FloatCard tiltMax={5}>
115
+ <div class="field-report-metric-inner">
116
+ <Label color="muted">{m.label}</Label>
117
+ <Text variant="heading" as="span" color="primary">{m.value}</Text>
118
+ {#if m.trendValue}
119
+ <Text
120
+ variant="caption"
121
+ as="span"
122
+ color={m.trend === 'down' ? 'signal' : 'muted'}
123
+ >
124
+ {m.trend === 'down' ? '\u2193' : '\u2014'}
125
+ {m.trendValue}
126
+ </Text>
127
+ {/if}
128
+ </div>
129
+ </FloatCard>
130
+ {/each}
131
+ </Grid>
132
+ </DepthLayer>
133
+ </DepthStage>
134
+ <Plinth width="90%" depth="24px" />
135
+ </div>
136
+
137
+ <div use:surface={{ delay: 800 }}>
138
+ <Text expression="chapter" as="span">mission log</Text>
139
+ </div>
140
+
141
+ <div use:surface={{ delay: 900 }}>
142
+ <Table columns={phaseColumns} rows={phases} />
143
+ </div>
144
+
145
+ <div use:surface={{ delay: 1000 }}>
146
+ <Text expression="chapter" as="span">from the field notebook</Text>
147
+ </div>
148
+
149
+ <div use:surface={{ delay: 1100 }}>
150
+ <CodeBlock code={codeSnippet} />
151
+ </div>
152
+
153
+ <div class="field-report-tags" use:surface={{ delay: 1200 }}>
154
+ {#each technologies as tech}
155
+ <Badge variant="default">{tech}</Badge>
156
+ {/each}
157
+ </div>
158
+ </div>
159
+ {/snippet}
160
+
161
+ {#snippet canvas()}
162
+ <div class="field-report-canvas" use:surface={{ delay: 400 }}>
163
+ <div class="field-report-canvas-inner" style:position="relative">
164
+ <CornerBrackets size={40} color="rgba(199, 156, 87, 0.12)" />
165
+ <div class="field-report-canvas-marks">
166
+ <GlyphMark variant="reticle" size={48} color="var(--muted-strong)" />
167
+ <div class="field-report-canvas-label">
168
+ <Label color="muted">artifact scan</Label>
169
+ <Label color="accent">47.2 mhz</Label>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ </div>
174
+ {/snippet}
175
+ </NarrativeScene>
176
+
177
+ <style>
178
+ .field-report-copy {
179
+ display: flex;
180
+ flex-direction: column;
181
+ gap: 1.75rem;
182
+ }
183
+
184
+ .field-report-metrics {
185
+ display: flex;
186
+ flex-direction: column;
187
+ gap: 0.5rem;
188
+ }
189
+
190
+ .field-report-metric-inner {
191
+ display: flex;
192
+ flex-direction: column;
193
+ gap: 0.25rem;
194
+ }
195
+
196
+ .field-report-tags {
197
+ display: flex;
198
+ flex-wrap: wrap;
199
+ gap: 0.375rem;
200
+ }
201
+
202
+ .field-report-canvas {
203
+ display: flex;
204
+ align-items: center;
205
+ justify-content: center;
206
+ min-height: 50vh;
207
+ }
208
+
209
+ .field-report-canvas-inner {
210
+ padding: 3rem;
211
+ }
212
+
213
+ .field-report-canvas-marks {
214
+ display: flex;
215
+ flex-direction: column;
216
+ align-items: center;
217
+ gap: 1.5rem;
218
+ }
219
+
220
+ .field-report-canvas-label {
221
+ display: flex;
222
+ flex-direction: column;
223
+ align-items: center;
224
+ gap: 0.25rem;
225
+ }
226
+ </style>