@viraui/react 2026.10.0 → 2026.11.0-next.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 (127) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +8 -0
  2. package/dist/catalog.json +12 -0
  3. package/dist/components/avatar/avatar.d.ts +6 -0
  4. package/dist/components/avatar/avatar.js +2 -2
  5. package/dist/components/badge/badge.css +1 -1
  6. package/dist/components/button/button.css +1 -1
  7. package/dist/components/dialog/dialog-sheet.d.ts +1 -1
  8. package/dist/components/gauge/arcs.d.ts +134 -0
  9. package/dist/components/gauge/arcs.js +145 -0
  10. package/dist/components/gauge/context.d.ts +134 -0
  11. package/dist/components/gauge/context.js +83 -0
  12. package/dist/components/gauge/control.d.ts +107 -0
  13. package/dist/components/gauge/control.js +223 -0
  14. package/dist/components/gauge/demos/_shared.d.ts +28 -0
  15. package/dist/components/gauge/demos/activity-ring.d.ts +9 -0
  16. package/dist/components/gauge/demos/air-quality.d.ts +9 -0
  17. package/dist/components/gauge/demos/analog-dial.d.ts +9 -0
  18. package/dist/components/gauge/demos/battery.d.ts +9 -0
  19. package/dist/components/gauge/demos/chronograph.d.ts +9 -0
  20. package/dist/components/gauge/demos/clock.d.ts +9 -0
  21. package/dist/components/gauge/demos/compass.d.ts +9 -0
  22. package/dist/components/gauge/demos/data-usage.d.ts +9 -0
  23. package/dist/components/gauge/demos/dimmer.d.ts +9 -0
  24. package/dist/components/gauge/demos/fuel.d.ts +9 -0
  25. package/dist/components/gauge/demos/heart-rate.d.ts +9 -0
  26. package/dist/components/gauge/demos/internet-speed.d.ts +9 -0
  27. package/dist/components/gauge/demos/nested-rings.d.ts +11 -0
  28. package/dist/components/gauge/demos/orrery.d.ts +12 -0
  29. package/dist/components/gauge/demos/power-meter.d.ts +9 -0
  30. package/dist/components/gauge/demos/progress-ring.d.ts +9 -0
  31. package/dist/components/gauge/demos/range.d.ts +10 -0
  32. package/dist/components/gauge/demos/saas-metric.d.ts +9 -0
  33. package/dist/components/gauge/demos/segments.d.ts +9 -0
  34. package/dist/components/gauge/demos/simple.d.ts +9 -0
  35. package/dist/components/gauge/demos/speed-fuel.d.ts +10 -0
  36. package/dist/components/gauge/demos/speedometer.d.ts +9 -0
  37. package/dist/components/gauge/demos/sprint.d.ts +9 -0
  38. package/dist/components/gauge/demos/sun-path.d.ts +9 -0
  39. package/dist/components/gauge/demos/system.d.ts +11 -0
  40. package/dist/components/gauge/demos/tachometer.d.ts +9 -0
  41. package/dist/components/gauge/demos/temperature.d.ts +9 -0
  42. package/dist/components/gauge/demos/thermostat.d.ts +9 -0
  43. package/dist/components/gauge/demos/timer.d.ts +9 -0
  44. package/dist/components/gauge/demos/volume.d.ts +10 -0
  45. package/dist/components/gauge/demos/wind.d.ts +9 -0
  46. package/dist/components/gauge/dot.d.ts +55 -0
  47. package/dist/components/gauge/dot.js +34 -0
  48. package/dist/components/gauge/gauge.css +1 -0
  49. package/dist/components/gauge/gauge.d.ts +84 -0
  50. package/dist/components/gauge/gauge.js +62 -0
  51. package/dist/components/gauge/gauge.module.js +24 -0
  52. package/dist/components/gauge/index.d.ts +15 -0
  53. package/dist/components/gauge/inset.d.ts +30 -0
  54. package/dist/components/gauge/inset.js +39 -0
  55. package/dist/components/gauge/math.d.ts +69 -0
  56. package/dist/components/gauge/math.js +135 -0
  57. package/dist/components/gauge/needle.d.ts +81 -0
  58. package/dist/components/gauge/needle.js +162 -0
  59. package/dist/components/gauge/scale.d.ts +44 -0
  60. package/dist/components/gauge/scale.js +21 -0
  61. package/dist/components/gauge/text.d.ts +79 -0
  62. package/dist/components/gauge/text.js +42 -0
  63. package/dist/components/gauge/ticks.d.ts +169 -0
  64. package/dist/components/gauge/ticks.js +124 -0
  65. package/dist/components/gauge/tooltip.d.ts +117 -0
  66. package/dist/components/gauge/tooltip.js +337 -0
  67. package/dist/components/gauge/transition.d.ts +60 -0
  68. package/dist/components/gauge/transition.js +129 -0
  69. package/dist/components/gauge/use-animated-value.d.ts +14 -0
  70. package/dist/components/gauge/use-animated-value.js +111 -0
  71. package/dist/components/gauge/utils.d.ts +51 -0
  72. package/dist/components/gauge/utils.js +80 -0
  73. package/dist/components/icon-meter/icon-meter.css +1 -0
  74. package/dist/components/icon-meter/icon-meter.d.ts +62 -0
  75. package/dist/components/icon-meter/icon-meter.js +105 -0
  76. package/dist/components/icon-meter/icon-meter.module.js +11 -0
  77. package/dist/components/icon-meter/index.d.ts +2 -0
  78. package/dist/components/icon-meter/utils.d.ts +22 -0
  79. package/dist/components/icon-meter/utils.js +40 -0
  80. package/dist/components/index.d.ts +2 -0
  81. package/dist/components/popover/popover-sheet.d.ts +1 -2
  82. package/dist/components/stack/stack.d.ts +9 -2
  83. package/dist/components/tabs/tabs.d.ts +1 -2
  84. package/dist/index.js +17 -1
  85. package/dist/internal/chrome-icons/chrome-icons.d.ts +4 -0
  86. package/dist/internal/chrome-icons/chrome-icons.js +12 -4
  87. package/dist/node_modules/.pnpm/react-dom@19.3.0_react@19.3.0/node_modules/react-dom/cjs/react-dom.development.js +192 -0
  88. package/dist/node_modules/.pnpm/react-dom@19.3.0_react@19.3.0/node_modules/react-dom/cjs/react-dom.production.js +156 -0
  89. package/dist/node_modules/.pnpm/react-dom@19.3.0_react@19.3.0/node_modules/react-dom/index.js +22 -0
  90. package/dist/preflight.css +1 -1
  91. package/dist/specs/components/avatar/props.xml +3 -0
  92. package/dist/specs/components/avatar/usage.xml +1 -0
  93. package/dist/specs/components/badge/a11y.xml +1 -1
  94. package/dist/specs/components/button/props.xml +2 -2
  95. package/dist/specs/components/button/usage.xml +1 -1
  96. package/dist/specs/components/gauge/a11y.xml +8 -0
  97. package/dist/specs/components/gauge/meta.xml +38 -0
  98. package/dist/specs/components/gauge/patterns.xml +1158 -0
  99. package/dist/specs/components/gauge/props.xml +452 -0
  100. package/dist/specs/components/gauge/usage.xml +21 -0
  101. package/dist/specs/components/icon-button/props.xml +2 -2
  102. package/dist/specs/components/icon-button/usage.xml +1 -1
  103. package/dist/specs/components/icon-meter/a11y.xml +9 -0
  104. package/dist/specs/components/icon-meter/meta.xml +21 -0
  105. package/dist/specs/components/icon-meter/patterns.xml +23 -0
  106. package/dist/specs/components/icon-meter/props.xml +44 -0
  107. package/dist/specs/components/icon-meter/usage.xml +13 -0
  108. package/dist/specs/components/linear-progress/usage.xml +1 -0
  109. package/dist/specs/components/meter/meta.xml +1 -0
  110. package/dist/specs/components/meter/props.xml +1 -0
  111. package/dist/specs/components/meter/usage.xml +1 -0
  112. package/dist/specs/components/stack/patterns.xml +21 -21
  113. package/dist/specs/components/stack/props.xml +6 -6
  114. package/dist/specs/components/stack/usage.xml +4 -2
  115. package/dist/specs/components/text/patterns.xml +1 -1
  116. package/dist/specs/components/text/usage.xml +1 -1
  117. package/dist/specs/components/toggle-button/props.xml +1 -1
  118. package/dist/specs/components/toggle-button/usage.xml +1 -1
  119. package/dist/specs/components/toggle-text-button/props.xml +1 -1
  120. package/dist/specs/foundation/attributes.xml +3 -3
  121. package/dist/specs/foundation/modules.xml +1 -1
  122. package/dist/specs/foundation/theme-topics.xml +7 -2
  123. package/dist/specs/index.xml +21 -1
  124. package/dist/specs/patterns/compose-layout-first.xml +1 -1
  125. package/dist/specs/patterns/settings-panel.xml +1 -1
  126. package/dist/specs/patterns/settings-row.xml +1 -1
  127. package/package.json +2 -2
@@ -0,0 +1,1158 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <patterns surface="gauge">
3
+ <!-- Round dial templates only (bars omitted). Demos are source; examples mirror them. -->
4
+
5
+ <example title="activity-ring">
6
+ <tsx><![CDATA[
7
+ <Gauge
8
+ value={value}
9
+ min={min}
10
+ max={max}
11
+ startAngle={180}
12
+ endAngle={540}
13
+ label={label}
14
+ >
15
+ <GaugeTrack width={44} color={TOKEN.foreground} opacity={0.12} />
16
+ <GaugeArc width={44} color={TOKEN.foreground} />
17
+ <GaugeValue fontSize={80} font="rounded" weight="bold" {...pos(0, 0.06)} />
18
+ <GaugeText fontSize={24} font="rounded" {...pos(0, -0.3)}>
19
+ kcal
20
+ </GaugeText>
21
+ <GaugeText
22
+ fontSize={22}
23
+ font="rounded"
24
+ weight="semibold"
25
+ color={TOKEN.foreground}
26
+ {...pos(0, 0.4)}
27
+ >
28
+ Move
29
+ </GaugeText>
30
+ </Gauge>
31
+ ]]></tsx>
32
+ <notes>Round template `activity-ring` from demos/activity-ring.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
33
+ </example>
34
+
35
+ <example title="air-quality">
36
+ <tsx><![CDATA[
37
+ const zones: Zone[] = [
38
+ { to: 50, color: TOKEN.muted },
39
+ { to: 100, color: TOKEN.contrast },
40
+ { to: 500, color: TOKEN.foreground },
41
+ ];
42
+
43
+ <Gauge
44
+ value={value}
45
+ min={min}
46
+ max={max}
47
+ startAngle={90}
48
+ endAngle={270}
49
+ fit="content"
50
+ label={label}
51
+ >
52
+ <GaugeTrack width={20} />
53
+ <GaugeArc width={20} color={TOKEN.foreground} />
54
+ <GaugeZones
55
+ zones={zones}
56
+ width={6}
57
+ offset={-22}
58
+ gap={2}
59
+ cap="butt"
60
+ endCap="round"
61
+ />
62
+ <GaugeMarks values={zoneCutoffs(zones)} length={10} width={2} offset={-22} />
63
+ <GaugeValue fontSize={84} font="rounded" weight="bold" {...pos(0, 0.22)} />
64
+ <GaugeText fontSize={24} {...pos(0, -0.08)}>
65
+ AQI
66
+ </GaugeText>
67
+ <GaugeText fontSize={20} {...pos(0, 0.62)}>
68
+ Air quality
69
+ </GaugeText>
70
+ </Gauge>
71
+ ]]></tsx>
72
+ <notes>Round template `air-quality` from demos/air-quality.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
73
+ </example>
74
+
75
+ <example title="analog-dial">
76
+ <tsx><![CDATA[
77
+ <Gauge
78
+ value={value}
79
+ min={min}
80
+ max={max}
81
+ startAngle={45}
82
+ endAngle={315}
83
+ label={label}
84
+ >
85
+ <GaugeTicks
86
+ count={10}
87
+ length={20}
88
+ width={2.5}
89
+ offset={-10}
90
+ cap="butt"
91
+ color={TOKEN.foreground}
92
+ />
93
+ <GaugeTicks count={50} length={10} width={1.5} offset={-5} cap="butt" opacity={0.6} />
94
+ <GaugeTickLabels count={10} offset={-46} fontSize={18} font="mono" weight="regular" />
95
+ <GaugeNeedle kind="line" length={0.86} width={4} tail={40} />
96
+ <GaugeHub radius={10} />
97
+ <GaugeValue fontSize={40} font="mono" weight="regular" {...pos(0, -0.48)} />
98
+ <GaugeText fontSize={18} font="mono" {...pos(0, -0.66)}>
99
+ psi
100
+ </GaugeText>
101
+ </Gauge>
102
+ ]]></tsx>
103
+ <notes>Round template `analog-dial` from demos/analog-dial.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
104
+ </example>
105
+
106
+ <example title="battery">
107
+ <tsx><![CDATA[
108
+ const zones: Zone[] = [
109
+ { to: 80, color: TOKEN.muted },
110
+ { to: 100, color: TOKEN.muted },
111
+ ];
112
+
113
+ <Gauge
114
+ value={value}
115
+ min={min}
116
+ max={max}
117
+ startAngle={180}
118
+ endAngle={540}
119
+ label={label}
120
+ >
121
+ <GaugeTrack width={30} cap="butt" />
122
+ <GaugeArc width={30} color={TOKEN.foreground} cap="butt" />
123
+ <GaugeZones
124
+ zones={zones}
125
+ width={30}
126
+ offset={0}
127
+ gap={0}
128
+ cap="butt"
129
+ endCap="butt"
130
+ opacity={0}
131
+ />
132
+ <GaugeMarks
133
+ values={zoneCutoffs(zones)}
134
+ length={46}
135
+ width={5}
136
+ offset={0}
137
+ cap="butt"
138
+ color={TOKEN.foreground}
139
+ />
140
+ <GaugeValue
141
+ fontSize={92}
142
+ font="rounded"
143
+ weight="bold"
144
+ {...pos(-0.06, 0.02)}
145
+ />
146
+ <GaugeText fontSize={30} anchor="start" {...pos(0.24, 0.06)}>
147
+ %
148
+ </GaugeText>
149
+ <GaugeText fontSize={22} {...pos(0, -0.36)}>
150
+ 307 km
151
+ </GaugeText>
152
+ </Gauge>
153
+ ]]></tsx>
154
+ <notes>Round template `battery` from demos/battery.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
155
+ </example>
156
+
157
+ <example title="chronograph">
158
+ <tsx><![CDATA[
159
+ <Gauge
160
+ value={value}
161
+ min={min}
162
+ max={max}
163
+ startAngle={180}
164
+ endAngle={540}
165
+ label={label}
166
+ >
167
+ <GaugeTicks
168
+ count={12}
169
+ length={22}
170
+ width={4}
171
+ offset={-11}
172
+ cap="butt"
173
+ color={TOKEN.foreground}
174
+ />
175
+ <GaugeTicks count={60} length={14} width={2.5} offset={-7} cap="butt" opacity={0.6} />
176
+ <GaugeTickLabels
177
+ count={12}
178
+ offset={-50}
179
+ fontSize={26}
180
+ weight="semibold"
181
+ color={TOKEN.foreground}
182
+ />
183
+ <GaugeNeedle kind="line" length={0.92} width={4} tail={44} tailDot={10} />
184
+ <GaugeHub radius={11} />
185
+ <GaugeText fontSize={30} font="mono" {...pos(0, 0.36)}>
186
+ 05:42.1
187
+ </GaugeText>
188
+ <GaugeInset
189
+ value={5.7}
190
+ min={0}
191
+ max={30}
192
+ startAngle={180}
193
+ endAngle={540}
194
+ scale={0.28}
195
+ {...pos(0, -0.36)}
196
+ >
197
+ <GaugeTrack width={6} cap="butt" opacity={0.25} offset={-3} />
198
+ <GaugeTicks
199
+ count={6}
200
+ length={34}
201
+ width={9}
202
+ offset={-26}
203
+ cap="butt"
204
+ color={TOKEN.foreground}
205
+ />
206
+ <GaugeTicks count={30} length={18} width={5} offset={-18} cap="butt" opacity={0.5} />
207
+ <GaugeNeedle kind="pointer" length={0.78} width={30} tail={0} />
208
+ <GaugeHub radius={22} />
209
+ </GaugeInset>
210
+ </Gauge>
211
+ ]]></tsx>
212
+ <notes>Round template `chronograph` from demos/chronograph.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
213
+ </example>
214
+
215
+ <example title="clock">
216
+ <tsx><![CDATA[
217
+ <Gauge
218
+ value={value}
219
+ min={min}
220
+ max={max}
221
+ startAngle={180}
222
+ endAngle={540}
223
+ label={label}
224
+ >
225
+ <GaugeTicks
226
+ count={12}
227
+ length={16}
228
+ width={3}
229
+ offset={-8}
230
+ cap="butt"
231
+ color={TOKEN.foreground}
232
+ />
233
+ <GaugeTicks count={60} length={6} width={1.5} offset={-3} cap="butt" opacity={0.6} />
234
+ <GaugeTickLabels
235
+ count={12}
236
+ offset={-48}
237
+ fontSize={26}
238
+ weight="semibold"
239
+ color={TOKEN.foreground}
240
+ format={clockLabel}
241
+ />
242
+ <GaugeNeedle kind="pointer" length={0.5} width={12} tail={0} />
243
+ <GaugeNeedle kind="pointer" length={0.74} width={8} tail={0} turns={12} />
244
+ <GaugeHub radius={7} />
245
+ </Gauge>
246
+ ]]></tsx>
247
+ <notes>Round template `clock` from demos/clock.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
248
+ </example>
249
+
250
+ <example title="compass">
251
+ <tsx><![CDATA[
252
+ <Gauge
253
+ value={value}
254
+ min={min}
255
+ max={max}
256
+ startAngle={180}
257
+ endAngle={540}
258
+ label={label}
259
+ >
260
+ <GaugeTrack width={2} color={TOKEN.muted} opacity={0.4} />
261
+ <GaugeTicks
262
+ count={8}
263
+ length={18}
264
+ width={3}
265
+ offset={-9}
266
+ cap="butt"
267
+ color={TOKEN.foreground}
268
+ />
269
+ <GaugeTicks count={36} length={8} width={1.5} offset={-4} cap="butt" opacity={0.8} />
270
+ <GaugeTickLabels
271
+ count={8}
272
+ offset={-46}
273
+ fontSize={22}
274
+ weight="bold"
275
+ color={TOKEN.foreground}
276
+ format={compassLabel}
277
+ />
278
+ <GaugeNeedle
279
+ kind="compass"
280
+ length={0.62}
281
+ width={22}
282
+ tail={124}
283
+ color={TOKEN.foreground}
284
+ tailColor={TOKEN.muted}
285
+ />
286
+ <GaugeHub radius={5} color={TOKEN.background} />
287
+ </Gauge>
288
+ ]]></tsx>
289
+ <notes>Round template `compass` from demos/compass.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
290
+ </example>
291
+
292
+ <example title="data-usage">
293
+ <tsx><![CDATA[
294
+ <Gauge
295
+ value={value}
296
+ min={min}
297
+ max={max}
298
+ startAngle={60}
299
+ endAngle={300}
300
+ label={label}
301
+ >
302
+ <GaugeTrack width={28} />
303
+ <GaugeArc width={28} />
304
+ <GaugeDot radius={7} color={TOKEN.background} />
305
+ <GaugeTooltip label="Used" unit="GB" decimals={1} position="value" />
306
+ <GaugeValue
307
+ fontSize={96}
308
+ font="rounded"
309
+ weight="bold"
310
+ {...pos(-0.08, 0.06)}
311
+ />
312
+ <GaugeText fontSize={32} font="rounded" weight="bold" anchor="start" {...pos(0.2, 0.02)}>
313
+ GB
314
+ </GaugeText>
315
+ <GaugeText fontSize={26} {...pos(0, -0.26)}>
316
+ of 50 GB
317
+ </GaugeText>
318
+ </Gauge>
319
+ ]]></tsx>
320
+ <notes>Round template `data-usage` from demos/data-usage.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
321
+ </example>
322
+
323
+ <example title="dimmer">
324
+ <tsx><![CDATA[
325
+ <Gauge
326
+ value={value}
327
+ min={min}
328
+ max={max}
329
+ startAngle={40}
330
+ endAngle={320}
331
+ label={label}
332
+ >
333
+ <GaugeTrack width={40} opacity={0.1} />
334
+ <GaugeArc width={40} />
335
+ <GaugeDot radius={9} color={TOKEN.background} />
336
+ <GaugeValue fontSize={84} font="rounded" weight="bold" {...pos(-0.07, 0)} />
337
+ <GaugeText
338
+ fontSize={30}
339
+ font="rounded"
340
+ weight="bold"
341
+ anchor="start"
342
+ {...pos(0.22, 0.04)}
343
+ >
344
+ %
345
+ </GaugeText>
346
+ </Gauge>
347
+ ]]></tsx>
348
+ <notes>Round template `dimmer` from demos/dimmer.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
349
+ </example>
350
+
351
+ <example title="fuel">
352
+ <tsx><![CDATA[
353
+ const zones: Zone[] = [
354
+ { to: 12, color: TOKEN.foreground },
355
+ { to: 100, color: TOKEN.muted },
356
+ ];
357
+
358
+ <Gauge
359
+ value={value}
360
+ min={min}
361
+ max={max}
362
+ startAngle={90}
363
+ endAngle={270}
364
+ label={label}
365
+ >
366
+ <GaugeZones zones={zones} width={10} gap={0} cap="butt" endCap="butt" />
367
+ <GaugeTicks
368
+ count={4}
369
+ length={18}
370
+ width={3}
371
+ offset={-20}
372
+ cap="butt"
373
+ color={TOKEN.foreground}
374
+ />
375
+ <GaugeTicks count={16} length={8} width={1.5} offset={-15} cap="butt" opacity={0.5} />
376
+ <GaugeNeedle kind="pointer" length={0.85} width={9} tail={24} />
377
+ <GaugeHub radius={10} />
378
+ <GaugeValue fontSize={36} font="mono" weight="semibold" {...pos(0, -0.42)} />
379
+ <GaugeText fontSize={28} weight="bold" color={TOKEN.foreground} {...pos(0.8, -0.16)}>
380
+ F
381
+ </GaugeText>
382
+ <GaugeText fontSize={28} weight="bold" color={TOKEN.foreground} {...pos(-0.8, -0.16)}>
383
+ E
384
+ </GaugeText>
385
+ </Gauge>
386
+ ]]></tsx>
387
+ <notes>Round template `fuel` from demos/fuel.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
388
+ </example>
389
+
390
+ <example title="heart-rate">
391
+ <tsx><![CDATA[
392
+ const zones: Zone[] = [
393
+ { to: 100, color: TOKEN.muted },
394
+ { to: 160, color: TOKEN.primary },
395
+ { to: 200, color: TOKEN.foreground },
396
+ ];
397
+
398
+ <Gauge
399
+ value={value}
400
+ min={min}
401
+ max={max}
402
+ startAngle={60}
403
+ endAngle={300}
404
+ label={label}
405
+ >
406
+ <GaugeTrack width={14} />
407
+ <GaugeArc width={14} color={zoneColor(zones, value, TOKEN.foreground)} />
408
+ <GaugeZones
409
+ zones={zones}
410
+ width={4}
411
+ offset={-18}
412
+ gap={1.5}
413
+ cap="butt"
414
+ endCap="round"
415
+ />
416
+ <GaugeValue fontSize={96} font="rounded" weight="bold" />
417
+ <GaugeText fontSize={28} {...pos(0, -0.34)}>
418
+ bpm
419
+ </GaugeText>
420
+ <GaugeText fontSize={22} {...pos(0, 0.36)}>
421
+ Heart rate
422
+ </GaugeText>
423
+ </Gauge>
424
+ ]]></tsx>
425
+ <notes>Round template `heart-rate` from demos/heart-rate.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
426
+ </example>
427
+
428
+ <example title="internet-speed">
429
+ <tsx><![CDATA[
430
+ <Gauge
431
+ value={value}
432
+ min={min}
433
+ max={max}
434
+ startAngle={60}
435
+ endAngle={300}
436
+ label={label}
437
+ >
438
+ <GaugeTrack width={18} />
439
+ <GaugeArc width={18} />
440
+ <GaugeTicks count={40} length={6} width={1.5} offset={-34} opacity={0.5} />
441
+ <GaugeText fontSize={20} {...pos(0, -0.7)}>
442
+ Download
443
+ </GaugeText>
444
+ <GaugeText fontSize={24} {...pos(0, -0.28)}>
445
+ Mbps
446
+ </GaugeText>
447
+ <GaugeValue fontSize={92} font="rounded" weight="bold" {...pos(0, 0.04)} />
448
+ </Gauge>
449
+ ]]></tsx>
450
+ <notes>Round template `internet-speed` from demos/internet-speed.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
451
+ </example>
452
+
453
+ <example title="nested-rings">
454
+ <tsx><![CDATA[
455
+ const RING = {
456
+ stand: 'var(--highlight-cyan)',
457
+ exercise: 'var(--highlight-acid)',
458
+ move: 'var(--highlight-red)',
459
+ } as const;
460
+
461
+ <Gauge value={value} min={min} max={max} startAngle={180} endAngle={540} label={label}>
462
+ <GaugeTrack width={44} color={RING.move} opacity={0.18} />
463
+ <GaugeArc width={44} color={RING.move} />
464
+ <GaugeValue fontSize={52} font="rounded" weight="bold" {...pos(0, 0.08)} />
465
+ <GaugeText fontSize={20} font="rounded" weight="semibold" {...pos(0, -0.12)}>
466
+ {label}
467
+ </GaugeText>
468
+
469
+ <GaugeInset value={exercise} min={min} max={max} startAngle={180} endAngle={540} scale={0.74}>
470
+ <GaugeTrack width={60} color={RING.exercise} opacity={0.18} />
471
+ <GaugeArc width={60} color={RING.exercise} />
472
+ </GaugeInset>
473
+
474
+ <GaugeInset value={stand} min={min} max={max} startAngle={180} endAngle={540} scale={0.5}>
475
+ <GaugeTrack width={76} color={RING.stand} opacity={0.18} />
476
+ <GaugeArc width={76} color={RING.stand} />
477
+ </GaugeInset>
478
+ </Gauge>
479
+ ]]></tsx>
480
+ <notes>Concentric rings centre→rim cyan/acid/red (highlight); tracks share arc colour at low opacity.</notes>
481
+ </example>
482
+
483
+ <example title="optional-token-colors">
484
+ <tsx><![CDATA[
485
+ {/* Omit color → part defaults (Track contrast, Arc primary, text foreground). */}
486
+ <Gauge value={72} min={0} max={100} label="Charge">
487
+ <GaugeTrack width={20} />
488
+ <GaugeArc width={20} />
489
+ <GaugeValue fontSize={72} />
490
+ </Gauge>
491
+
492
+ {/* Optional: pass theme CSS vars on part `color` / zone entries. */}
493
+ const zones: Zone[] = [
494
+ { to: 20, color: 'var(--highlight-red)' },
495
+ { to: 70, color: 'var(--highlight-yellow)' },
496
+ { to: 100, color: 'var(--highlight-green)' },
497
+ ];
498
+
499
+ <Gauge value={value} min={0} max={100} label="Health">
500
+ <GaugeTrack width={16} color="var(--global-contrast)" opacity={0.35} />
501
+ <GaugeArc width={16} color={zoneColor(zones, value)} />
502
+ <GaugeZones zones={zones} width={5} offset={-18} gap={1} cap="butt" endCap="round" />
503
+ <GaugeTicks count={10} length={10} width={2} color="var(--global-foreground)" />
504
+ <GaugeNeedle
505
+ kind="pointer"
506
+ color="var(--global-primary)"
507
+ tailColor="var(--global-muted)"
508
+ />
509
+ <GaugeHub radius={10} color="var(--global-background)" />
510
+ <GaugeValue fontSize={64} color="var(--global-foreground)" />
511
+ <GaugeText fontSize={20} color="var(--global-muted)" {...pos(0, -0.34)}>
512
+ status
513
+ </GaugeText>
514
+ </Gauge>
515
+ ]]></tsx>
516
+ <notes>Optional paint only. Defaults from props.xml. Chrome/labels → `--global-*`; status bands → `--highlight-*`. No Meter/Chip `variant` — use CSS var strings. Also see `nested-rings` for multi-highlight arcs.</notes>
517
+ </example>
518
+
519
+ <example title="orrery">
520
+ <tsx><![CDATA[
521
+ <Gauge
522
+ value={value}
523
+ min={min}
524
+ max={max}
525
+ startAngle={180}
526
+ endAngle={540}
527
+ label={label}
528
+ >
529
+ <PlanetOrbit offset={0} size={7} />
530
+ <GaugeNeedle kind="line" length={0.1} width={1} tail={0} />
531
+ <GaugeHub radius={24} color={TOKEN.foreground} />
532
+
533
+ <GaugeInset
534
+ value={earth}
535
+ min={min}
536
+ max={max}
537
+ startAngle={180}
538
+ endAngle={540}
539
+ scale={1}
540
+ {...pos(0, 0)}
541
+ >
542
+ <PlanetOrbit offset={-40} size={9} />
543
+ </GaugeInset>
544
+
545
+ <GaugeInset
546
+ value={venus}
547
+ min={min}
548
+ max={max}
549
+ startAngle={180}
550
+ endAngle={540}
551
+ scale={1}
552
+ {...pos(0, 0)}
553
+ >
554
+ <PlanetOrbit offset={-80} size={8.5} />
555
+ </GaugeInset>
556
+
557
+ <GaugeInset
558
+ value={mercury}
559
+ min={min}
560
+ max={max}
561
+ startAngle={180}
562
+ endAngle={540}
563
+ scale={1}
564
+ {...pos(0, 0)}
565
+ >
566
+ <PlanetOrbit offset={-120} size={6} />
567
+ </GaugeInset>
568
+ </Gauge>
569
+ ]]></tsx>
570
+ <notes>Round template `orrery` from demos/orrery.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
571
+ </example>
572
+
573
+ <example title="power-meter">
574
+ <tsx><![CDATA[
575
+ <Gauge
576
+ value={value}
577
+ min={min}
578
+ max={max}
579
+ startAngle={90}
580
+ endAngle={270}
581
+ fit="content"
582
+ label={label}
583
+ >
584
+ <GaugeTrack width={20} cap="butt" />
585
+ <GaugeTicks
586
+ count={4}
587
+ length={14}
588
+ width={3}
589
+ offset={-24}
590
+ cap="butt"
591
+ color={TOKEN.foreground}
592
+ />
593
+ <GaugeTicks count={20} length={8} width={2} offset={-20} opacity={0.5} />
594
+ <GaugeTickLabels count={4} offset={-56} fontSize={22} weight="semibold" />
595
+ <GaugeNeedle kind="pointer" length={0.9} width={18} tail={0} />
596
+ <GaugeHub radius={16} />
597
+ <GaugeText fontSize={20} {...pos(-0.42, 0.16)}>
598
+ kW out
599
+ </GaugeText>
600
+ <GaugeText fontSize={20} {...pos(0.42, 0.16)}>
601
+ kW in
602
+ </GaugeText>
603
+ </Gauge>
604
+ ]]></tsx>
605
+ <notes>Round template `power-meter` from demos/power-meter.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
606
+ </example>
607
+
608
+ <example title="progress-ring">
609
+ <tsx><![CDATA[
610
+ <Gauge
611
+ value={value}
612
+ min={min}
613
+ max={max}
614
+ startAngle={0}
615
+ endAngle={360}
616
+ label={label}
617
+ >
618
+ <GaugeTrack width={20} />
619
+ <GaugeArc width={20} />
620
+ <GaugeValue fontSize={84} font="sans" weight="semibold" />
621
+ <GaugeText fontSize={26} {...pos(0, -0.32)}>
622
+ %
623
+ </GaugeText>
624
+ <GaugeText fontSize={20} {...pos(0, 0.34)}>
625
+ Complete
626
+ </GaugeText>
627
+ </Gauge>
628
+ ]]></tsx>
629
+ <notes>Round template `progress-ring` from demos/progress-ring.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
630
+ </example>
631
+
632
+ <example title="range">
633
+ <tsx><![CDATA[
634
+ <Gauge
635
+ value={value}
636
+ min={min}
637
+ max={max}
638
+ startAngle={40}
639
+ endAngle={320}
640
+ label={label}
641
+ >
642
+ <GaugeTrack width={28} cap="butt" />
643
+ <GaugeArc width={28} opacity={0.35} cap="butt" />
644
+ <GaugeTicks count={20} length={8} width={2} offset={-38} opacity={0.6} />
645
+ <GaugeDot end="from" radius={16} />
646
+ <GaugeDot end="to" radius={16} />
647
+ <GaugeValue fontSize={76} font="rounded" weight="bold" {...pos(0, 0.02)} />
648
+ <GaugeText fontSize={24} {...pos(0, -0.3)}>
649
+ °C
650
+ </GaugeText>
651
+ <GaugeText fontSize={20} weight="semibold" {...pos(0, 0.36)}>
652
+ Comfort
653
+ </GaugeText>
654
+ </Gauge>
655
+ ]]></tsx>
656
+ <notes>Round template `range` from demos/range.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
657
+ </example>
658
+
659
+ <example title="saas-metric">
660
+ <tsx><![CDATA[
661
+ <Gauge
662
+ value={value}
663
+ min={min}
664
+ max={max}
665
+ startAngle={90}
666
+ endAngle={270}
667
+ fit="content"
668
+ label={label}
669
+ >
670
+ <GaugeTrack width={28} />
671
+ <GaugeArc width={28} />
672
+ <GaugeValue fontSize={84} weight="semibold" {...pos(0, 0.22)} />
673
+ <GaugeText fontSize={28} anchor="start" {...pos(0.27, 0.26)}>
674
+ %
675
+ </GaugeText>
676
+ <GaugeText fontSize={20} {...pos(0, -0.04)}>
677
+ Conversion rate
678
+ </GaugeText>
679
+ </Gauge>
680
+ ]]></tsx>
681
+ <notes>Round template `saas-metric` from demos/saas-metric.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
682
+ </example>
683
+
684
+ <example title="segments">
685
+ <tsx><![CDATA[
686
+ <Gauge value={value} min={min} max={max} label={label}>
687
+ <GaugeTickFill
688
+ count={40}
689
+ length={28}
690
+ litLength={40}
691
+ width={7}
692
+ color={TOKEN.foreground}
693
+ dimColor={TOKEN.muted}
694
+ />
695
+ <GaugeValue fontSize={104} font="rounded" weight="bold" />
696
+ <GaugeText fontSize={26} {...pos(0, -0.34)}>
697
+ %
698
+ </GaugeText>
699
+ </Gauge>
700
+ ]]></tsx>
701
+ <notes>Round template `segments` from demos/segments.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
702
+ </example>
703
+
704
+ <example title="simple">
705
+ <tsx><![CDATA[
706
+ <Gauge value={value} min={min} max={max} label={label}>
707
+ <GaugeTrack />
708
+ <GaugeArc />
709
+ <GaugeValue fontSize={104} />
710
+ </Gauge>
711
+ ]]></tsx>
712
+ <notes>Round template `simple` from demos/simple.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
713
+ </example>
714
+
715
+ <example title="speed-fuel">
716
+ <tsx><![CDATA[
717
+ const zones: Zone[] = [
718
+ { to: 180, color: TOKEN.muted },
719
+ { to: 240, color: TOKEN.foreground },
720
+ ];
721
+
722
+ <Gauge
723
+ value={value}
724
+ min={min}
725
+ max={max}
726
+ startAngle={40}
727
+ endAngle={320}
728
+ label={label}
729
+ >
730
+ <GaugeZones zones={zones} width={8} gap={0} cap="butt" endCap="butt" />
731
+ <GaugeMarks values={zoneCutoffs(zones)} length={8} width={2} />
732
+ <GaugeTicks count={12} length={18} width={3} offset={-16} cap="butt" />
733
+ <GaugeTicks count={48} length={8} width={1.5} offset={-12} cap="butt" opacity={0.6} />
734
+ <GaugeTickLabels count={12} offset={-54} fontSize={20} weight="semibold" />
735
+ <GaugeInset
736
+ value={fuel}
737
+ min={0}
738
+ max={100}
739
+ startAngle={326}
740
+ endAngle={394}
741
+ scale={1}
742
+ {...pos(0, 0)}
743
+ >
744
+ <GaugeTrack width={8} color={TOKEN.muted} cap="butt" />
745
+ <GaugeArc
746
+ width={8}
747
+ color={TOKEN.muted}
748
+ cap="butt"
749
+ reverse
750
+ />
751
+ <GaugeTicks
752
+ count={4}
753
+ length={10}
754
+ width={2}
755
+ offset={-12}
756
+ cap="butt"
757
+ color={TOKEN.muted}
758
+ />
759
+ <GaugeText fontSize={20} weight="semibold" {...pos(-0.64, -0.94)}>
760
+ E
761
+ </GaugeText>
762
+ <GaugeText fontSize={20} weight="semibold" {...pos(0.64, -0.94)}>
763
+ F
764
+ </GaugeText>
765
+ </GaugeInset>
766
+ <GaugeNeedle kind="pointer" length={0.85} width={10} tail={32} />
767
+ <GaugeHub radius={12} />
768
+ <GaugeValue fontSize={40} font="mono" weight="semibold" {...pos(0, -0.28)} />
769
+ <GaugeText fontSize={16} {...pos(0, -0.44)}>
770
+ km/h
771
+ </GaugeText>
772
+ </Gauge>
773
+ ]]></tsx>
774
+ <notes>Round template `speed-fuel` from demos/speed-fuel.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
775
+ </example>
776
+
777
+ <example title="speedometer">
778
+ <tsx><![CDATA[
779
+ const zones: Zone[] = [
780
+ { to: 180, color: 'var(--global-contrast)' },
781
+ { to: 240, color: 'var(--global-foreground)' },
782
+ ];
783
+
784
+ <Gauge
785
+ value={value}
786
+ min={min}
787
+ max={max}
788
+ startAngle={40}
789
+ endAngle={320}
790
+ label={label}
791
+ >
792
+ <GaugeZones zones={zones} width={8} gap={0} cap="butt" endCap="butt" />
793
+ <GaugeMarks values={zoneCutoffs(zones)} length={8} width={2} />
794
+ <GaugeTicks count={12} length={18} width={3} offset={-16} cap="butt" />
795
+ <GaugeTicks count={48} length={8} width={1.5} offset={-12} cap="butt" opacity={0.6} />
796
+ <GaugeTickLabels count={12} offset={-54} fontSize={20} weight="semibold" />
797
+ <GaugeNeedle kind="pointer" length={0.85} width={10} tail={32} />
798
+ <GaugeHub radius={12} />
799
+ <GaugeValue fontSize={44} font="mono" weight="semibold" {...pos(0, -0.46)} />
800
+ <GaugeText fontSize={18} {...pos(0, -0.64)}>
801
+ km/h
802
+ </GaugeText>
803
+ </Gauge>
804
+ ]]></tsx>
805
+ <notes>Round template `speedometer` from demos/speedometer.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
806
+ </example>
807
+
808
+ <example title="sprint">
809
+ <tsx><![CDATA[
810
+ const RINGS: SprintRing[] = [
811
+ { x: -0.5, y: 0.5, value: 85, title: 'Design', done: 17, total: 20 },
812
+ { x: 0.5, y: 0.5, value: 12, title: 'QA', done: 3, total: 25 },
813
+ { x: -0.5, y: -0.5, value: 62, title: 'Frontend', done: 13, total: 21 },
814
+ { x: 0.5, y: -0.5, value: 38, title: 'Backend', done: 9, total: 24 },
815
+ ];
816
+
817
+ <Gauge
818
+ value={value}
819
+ min={min}
820
+ max={max}
821
+ startAngle={180}
822
+ endAngle={540}
823
+ label={label}
824
+ >
825
+ {RINGS.map((ring) => (
826
+ <GaugeInset
827
+ key={ring.title}
828
+ value={ring.value}
829
+ min={0}
830
+ max={100}
831
+ startAngle={180}
832
+ endAngle={540}
833
+ scale={0.42}
834
+ {...pos(ring.x, ring.y)}
835
+ >
836
+ <GaugeTrack width={36} />
837
+ <GaugeArc width={36} color={TOKEN.foreground} />
838
+ <GaugeText fontSize={52} weight="semibold" {...pos(0, 0)}>
839
+ {ring.title}
840
+ </GaugeText>
841
+ <GaugeTooltip
842
+ position="value"
843
+ label={`${ring.done} of ${ring.total} tasks`}
844
+ unit="%"
845
+ />
846
+ </GaugeInset>
847
+ ))}
848
+ </Gauge>
849
+ ]]></tsx>
850
+ <notes>Round template `sprint` from demos/sprint.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
851
+ </example>
852
+
853
+ <example title="sun-path">
854
+ <tsx><![CDATA[
855
+ <Gauge
856
+ value={value}
857
+ min={min}
858
+ max={max}
859
+ startAngle={90}
860
+ endAngle={270}
861
+ fit="content"
862
+ label={label}
863
+ >
864
+ <GaugeTrack width={26} opacity={0.19} />
865
+ <GaugeArc width={24} color={TOKEN.contrast} />
866
+ <GaugeTicks count={24} length={2} width={3} offset={0} color={TOKEN.foreground} opacity={0.5} />
867
+ <GaugeDot radius={17.5} />
868
+ <GaugeText fontSize={19} font="rounded" weight="semibold" {...pos(0, 0.1)}>
869
+ 06:12 – 18:04
870
+ </GaugeText>
871
+ <GaugeText
872
+ fontSize={24}
873
+ font="rounded"
874
+ weight="semibold"
875
+ color={TOKEN.foreground}
876
+ {...pos(0, 0.33)}
877
+ >
878
+ Daylight
879
+ </GaugeText>
880
+ </Gauge>
881
+ ]]></tsx>
882
+ <notes>Round template `sun-path` from demos/sun-path.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
883
+ </example>
884
+
885
+ <example title="system">
886
+ <tsx><![CDATA[
887
+ <Gauge
888
+ value={value}
889
+ min={min}
890
+ max={max}
891
+ startAngle={90}
892
+ endAngle={270}
893
+ label={label}
894
+ >
895
+ <GaugeTrack width={26} />
896
+ <GaugeArc width={26} />
897
+ <GaugeValue fontSize={76} font="rounded" weight="bold" {...pos(-0.06, 0.3)} />
898
+ <GaugeText fontSize={26} anchor="start" {...pos(0.19, 0.34)}>
899
+ %
900
+ </GaugeText>
901
+ <GaugeText fontSize={22} {...pos(0, 0.62)}>
902
+ {label}
903
+ </GaugeText>
904
+ <HalfDialInset x={-0.5} value={mem} title="MEM" color={TOKEN.foreground} min={min} max={max} />
905
+ <HalfDialInset x={0.5} value={disk} title="DISK" color={TOKEN.muted} min={min} max={max} />
906
+ </Gauge>
907
+ ]]></tsx>
908
+ <notes>Round template `system` from demos/system.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
909
+ </example>
910
+
911
+ <example title="tachometer">
912
+ <tsx><![CDATA[
913
+ const zones: Zone[] = [
914
+ { to: 6.5, color: TOKEN.muted },
915
+ { to: 8, color: TOKEN.foreground },
916
+ ];
917
+
918
+ <Gauge
919
+ value={value}
920
+ min={min}
921
+ max={max}
922
+ startAngle={40}
923
+ endAngle={320}
924
+ label={label}
925
+ >
926
+ <GaugeZones
927
+ zones={zones}
928
+ width={10}
929
+ offset={4}
930
+ gap={0}
931
+ cap="butt"
932
+ endCap="butt"
933
+ />
934
+ <GaugeMarks values={zoneCutoffs(zones)} length={8} width={2} />
935
+ <GaugeTicks count={8} length={18} width={3} offset={-16} cap="butt" />
936
+ <GaugeTicks count={40} length={8} width={1.5} offset={-12} cap="butt" opacity={0.6} />
937
+ <GaugeTickLabels count={8} offset={-52} fontSize={24} weight="bold" />
938
+ <GaugeNeedle kind="pointer" length={0.88} width={10} tail={30} />
939
+ <GaugeHub radius={12} />
940
+ <GaugeValue fontSize={44} font="mono" weight="semibold" decimals={1} {...pos(0, -0.46)} />
941
+ <GaugeText fontSize={16} {...pos(0, -0.64)}>
942
+ x1000 rpm
943
+ </GaugeText>
944
+ </Gauge>
945
+ ]]></tsx>
946
+ <notes>Round template `tachometer` from demos/tachometer.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
947
+ </example>
948
+
949
+ <example title="temperature">
950
+ <tsx><![CDATA[
951
+ const zones: Zone[] = [
952
+ { to: 10, color: TOKEN.contrast },
953
+ { to: 26, color: TOKEN.primary },
954
+ { to: 40, color: TOKEN.foreground },
955
+ ];
956
+
957
+ <Gauge
958
+ value={value}
959
+ min={min}
960
+ max={max}
961
+ startAngle={40}
962
+ endAngle={320}
963
+ label={label}
964
+ >
965
+ <GaugeTrack width={16} />
966
+ <GaugeArc width={16} color={zoneColor(zones, value, TOKEN.foreground)} />
967
+ <GaugeZones
968
+ zones={zones}
969
+ width={6}
970
+ offset={-20}
971
+ gap={1}
972
+ cap="butt"
973
+ endCap="butt"
974
+ opacity={0.9}
975
+ />
976
+ <GaugeMarks values={zoneCutoffs(zones)} length={6} width={2} offset={-20} />
977
+ <GaugeTicks count={60} length={6} width={1.5} offset={-34} opacity={0.5} />
978
+ <GaugeDot radius={5} offset={-54} color={TOKEN.foreground} />
979
+ <GaugeValue fontSize={84} decimals={1} />
980
+ <GaugeText fontSize={28} {...pos(0, -0.34)}>
981
+ °C
982
+ </GaugeText>
983
+ <GaugeText fontSize={22} {...pos(0, 0.36)}>
984
+ Cabin
985
+ </GaugeText>
986
+ </Gauge>
987
+ ]]></tsx>
988
+ <notes>Round template `temperature` from demos/temperature.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
989
+ </example>
990
+
991
+ <example title="thermostat">
992
+ <tsx><![CDATA[
993
+ <Gauge
994
+ value={value}
995
+ min={min}
996
+ max={max}
997
+ startAngle={40}
998
+ endAngle={320}
999
+ label={label}
1000
+ >
1001
+ <GaugeTrack width={26} cap="butt" />
1002
+ <GaugeArc width={26} opacity={0.4} cap="butt" />
1003
+ <GaugeTicks
1004
+ count={80}
1005
+ length={30}
1006
+ width={2.5}
1007
+ offset={0}
1008
+ cap="butt"
1009
+ color={TOKEN.background}
1010
+ opacity={1}
1011
+ />
1012
+ <GaugeDot radius={13} />
1013
+ <GaugeValue fontSize={88} font="rounded" weight="bold" decimals={1} {...pos(0, 0.02)} />
1014
+ <GaugeText fontSize={24} {...pos(0, -0.32)}>
1015
+ °C
1016
+ </GaugeText>
1017
+ <GaugeText fontSize={20} weight="semibold" {...pos(0, 0.4)}>
1018
+ Heating
1019
+ </GaugeText>
1020
+ </Gauge>
1021
+ ]]></tsx>
1022
+ <notes>Round template `thermostat` from demos/thermostat.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
1023
+ </example>
1024
+
1025
+ <example title="timer">
1026
+ <tsx><![CDATA[
1027
+ <Gauge
1028
+ value={value}
1029
+ min={min}
1030
+ max={max}
1031
+ startAngle={180}
1032
+ endAngle={540}
1033
+ label={label}
1034
+ >
1035
+ <GaugeTrack width={8} cap="butt" />
1036
+ <GaugeArc width={8} color={TOKEN.foreground} cap="butt" />
1037
+ <GaugeTicks
1038
+ count={12}
1039
+ length={10}
1040
+ width={2.5}
1041
+ offset={18}
1042
+ color={TOKEN.foreground}
1043
+ />
1044
+ <GaugeTicks
1045
+ count={60}
1046
+ length={5}
1047
+ width={1.5}
1048
+ offset={16}
1049
+ opacity={0.5}
1050
+ />
1051
+ <GaugeValue
1052
+ fontSize={110}
1053
+ font="mono"
1054
+ weight="regular"
1055
+ {...pos(0, 0.04)}
1056
+ />
1057
+ <GaugeText fontSize={24} font="mono" {...pos(0, -0.3)}>
1058
+ sec
1059
+ </GaugeText>
1060
+ </Gauge>
1061
+ ]]></tsx>
1062
+ <notes>Round template `timer` from demos/timer.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
1063
+ </example>
1064
+
1065
+ <example title="volume">
1066
+ <tsx><![CDATA[
1067
+ <GaugeControl
1068
+ value={value}
1069
+ onChange={setValue}
1070
+ min={min}
1071
+ max={max}
1072
+ startAngle={40}
1073
+ endAngle={320}
1074
+ label={label}
1075
+ knob
1076
+ >
1077
+ <Gauge
1078
+ value={value}
1079
+ min={min}
1080
+ max={max}
1081
+ startAngle={40}
1082
+ endAngle={320}
1083
+ padding={56}
1084
+ transition={{ type: 'spring', visualDuration: 0.3, bounce: 0 }}
1085
+ aria-hidden
1086
+ >
1087
+ <GaugeHub radius={156} color={TOKEN.muted} />
1088
+ <GaugeTrack width={6} color={TOKEN.foreground} opacity={0.12} offset={-18} />
1089
+ <GaugeArc width={6} color={TOKEN.foreground} offset={-18} />
1090
+ <GaugeTicks
1091
+ count={20}
1092
+ length={12}
1093
+ width={3}
1094
+ offset={6}
1095
+ cap="round"
1096
+ color={TOKEN.contrast}
1097
+ opacity={0.45}
1098
+ />
1099
+ <GaugeDot radius={11} offset={-76} color={TOKEN.foreground} />
1100
+ <GaugeValue fontSize={64} font="rounded" weight="bold" />
1101
+ </Gauge>
1102
+ </GaugeControl>
1103
+ ]]></tsx>
1104
+ <notes>Round template `volume` from demos/volume.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
1105
+ </example>
1106
+
1107
+ <example title="wind">
1108
+ <tsx><![CDATA[
1109
+ <Gauge
1110
+ value={value}
1111
+ min={min}
1112
+ max={max}
1113
+ startAngle={180}
1114
+ endAngle={540}
1115
+ label={label}
1116
+ >
1117
+ <GaugeTrack cap="butt" />
1118
+ <GaugeTicks count={4} length={8} offset={0} />
1119
+ <GaugeTicks count={36} length={4} width={3} offset={0} />
1120
+ <GaugeTickLabels
1121
+ count={4}
1122
+ offset={-44}
1123
+ fontSize={32}
1124
+ font="rounded"
1125
+ weight="bold"
1126
+ format={compassLabel}
1127
+ />
1128
+ <GaugeNeedle
1129
+ kind="arrow"
1130
+ length={1.05}
1131
+ width={7}
1132
+ tail={200}
1133
+ tailDot={12}
1134
+ gap={84}
1135
+ />
1136
+ <GaugeText
1137
+ fontSize={72}
1138
+ font="rounded"
1139
+ weight="bold"
1140
+ color={TOKEN.foreground}
1141
+ {...pos(0, 0.07)}
1142
+ >
1143
+ 5
1144
+ </GaugeText>
1145
+ <GaugeText
1146
+ fontSize={26}
1147
+ font="rounded"
1148
+ weight="medium"
1149
+ color={TOKEN.muted}
1150
+ {...pos(0, -0.16)}
1151
+ >
1152
+ m/s
1153
+ </GaugeText>
1154
+ </Gauge>
1155
+ ]]></tsx>
1156
+ <notes>Round template `wind` from demos/wind.tsx. Text/inset via pos() (y-up). Tokens: contrast not muted.</notes>
1157
+ </example>
1158
+ </patterns>