@5voltfx/design-system 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Whether a label riding the rim at this absolute angle would read upside
3
+ * down, and so must flip about its own radial centre.
4
+ *
5
+ * @param {number} absDeg
6
+ * @returns {boolean}
7
+ */
8
+ export function uprightFlip(absDeg: number): boolean;
9
+ /**
10
+ * Shortest signed difference between two angles, in degrees.
11
+ *
12
+ * Dragging a disc crosses the ±180° seam constantly; without normalising, a
13
+ * pointer moving a few degrees past the seam reads as a 350° jump.
14
+ *
15
+ * @param {number} to
16
+ * @param {number} from
17
+ * @returns {number} Degrees in (-180, 180].
18
+ */
19
+ export function angleDelta(to: number, from: number): number;
20
+ /**
21
+ * Ticks for a log10 decade around the hub, at slide-rule gradations.
22
+ *
23
+ * Each band is walked with an integer counter rather than by accumulating a
24
+ * float step: accumulating drifts off the gradations, and because the band
25
+ * boundaries are themselves tested against the drifting value, the 5–10 band
26
+ * starts half a step late and never lands on 6, 7, 8 or 9.
27
+ */
28
+ export function logRingTicks(): {
29
+ v: number;
30
+ angle: number;
31
+ major: boolean;
32
+ }[];
33
+ /**
34
+ * The fan's backing plate: an annular sector, not a pie slice. Its inner
35
+ * radius stops at the hub so the rest-state hint survives underneath it.
36
+ *
37
+ * @param {object} spec
38
+ * @returns {string} SVG path data.
39
+ */
40
+ export function wedgePath(spec: object): string;
41
+ export const DIAL: Readonly<{
42
+ /** C-I — a disc that swings out of the edge and spins to an index. */
43
+ volvelle: Readonly<{
44
+ viewBox: readonly number[];
45
+ cx: 210;
46
+ cy: 210;
47
+ /** Disc face, and the hairline circle just inside it. */
48
+ r: 200;
49
+ rInner: 193;
50
+ /** Decorative rim ticks run inward from rInner. */
51
+ rRing: 179;
52
+ /** Station band: quarter-detent ticks run inward from rBand. */
53
+ rBand: 177;
54
+ /** Radial centre of a station label — the pivot its flip turns about. */
55
+ labelR: 129;
56
+ /** Logarithmic ring at the hub, for the same reason the original had one. */
57
+ rLogInner: 62;
58
+ rLogOuter: 76;
59
+ rLogPlate: 78;
60
+ rLogNumeral: 52;
61
+ rHub: 34;
62
+ /** Total sweep the stations are spread across. */
63
+ arc: 216;
64
+ /** Fixed cursor arm, due east. */
65
+ arm: Readonly<{
66
+ x: 38;
67
+ w: 166;
68
+ h: 38;
69
+ hairline: 208;
70
+ index: 218;
71
+ }>;
72
+ /**
73
+ * Half the width of the widest station label, including its padding.
74
+ * Labels are HTML, so this cannot be derived from the SVG — it is
75
+ * measured, and it is what the extraction distance has to clear.
76
+ */
77
+ labelClearance: 60;
78
+ rest: -376;
79
+ out: -10;
80
+ settleMs: 520;
81
+ }>;
82
+ /** C-II — two concentric rings and a swept arm, after the E6B. */
83
+ concentric: Readonly<{
84
+ viewBox: readonly number[];
85
+ cx: 220;
86
+ cy: 220;
87
+ r: 208;
88
+ /** Outer ring: sections, spread over a full turn. */
89
+ rOuter: 200;
90
+ rOuterInner: 146;
91
+ labelR: 164;
92
+ labelClearance: 44;
93
+ /** Inner ring: the pages of whichever section is indexed. */
94
+ rInnerPlate: 132;
95
+ rHubPlate: 58;
96
+ innerLabelR: 122;
97
+ innerArc: 135;
98
+ innerCount: 4;
99
+ arm: Readonly<{
100
+ x: 50;
101
+ w: 106;
102
+ h: 30;
103
+ tip: 156;
104
+ point: 172;
105
+ }>;
106
+ index: Readonly<{
107
+ from: 198;
108
+ to: 226;
109
+ chevron: 232;
110
+ back: 214;
111
+ }>;
112
+ rest: -396;
113
+ out: -6;
114
+ settleMs: 480;
115
+ innerSettleMs: 380;
116
+ }>;
117
+ /** C-III — a quadrant that blooms out of the edge on a ratchet. */
118
+ fan: Readonly<{
119
+ viewBox: readonly number[];
120
+ /** The pivot sits hard against the left edge. */
121
+ cx: 46;
122
+ cy: 210;
123
+ /** Spoke length. With halfAngle 80°, ro·sin(80°) ≈ 193 — the most a
124
+ 420-tall viewBox will take. Do not raise without re-measuring. */
125
+ r: 192;
126
+ labelR: 130;
127
+ labelClearance: 60;
128
+ arc: 150;
129
+ wedge: Readonly<{
130
+ halfAngle: 80;
131
+ ri: 64;
132
+ ro: 196;
133
+ }>;
134
+ hub: Readonly<{
135
+ outer: 64;
136
+ inner: 52;
137
+ }>;
138
+ /** Ratchet teeth ride just outside the spoke ends. */
139
+ tooth: Readonly<{
140
+ from: 3;
141
+ to: 10;
142
+ lead: 3.4;
143
+ }>;
144
+ /** How far the clip is held closed at rest, hiding all but the hub. */
145
+ restClip: 328;
146
+ bloomStaggerMs: 34;
147
+ settleMs: 440;
148
+ }>;
149
+ }>;
150
+ export function polar(cx: any, cy: any, r: any, deg: any): any[];
151
+ export function pitchFor(spec: any, count: any): number;
152
+ export function startAngle(spec: any): number;
153
+ export function stationAngle(spec: any, count: any, pos: any): number;
154
+ export function rotationFor(spec: object, count: number, pos: number): number;
155
+ export function innerPitchFor(spec: any, count: any): number;
156
+ export function innerStartAngle(spec: any): number;
157
+ export function innerAngle(spec: any, count: any, pos: any): number;
158
+ export function toothLead(spec: object, detent: number): number;
159
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../../src/components/DialNav/geometry.js"],"names":[],"mappings":"AA8GA;;;;;;GAMG;AACH,oCAHW,MAAM,GACJ,OAAO,CAKnB;AAuBD;;;;;;;;;GASG;AACH,+BAJW,MAAM,QACN,MAAM,GACJ,MAAM,CAOlB;AAED;;;;;;;GAOG;AACH;;;;IAmBC;AA2BD;;;;;;GAMG;AACH,gCAHW,MAAM,GACJ,MAAM,CAelB;AAjOD;IACE,sEAAsE;;;;;QAKpE,yDAAyD;;;QAGzD,mDAAmD;;QAEnD,gEAAgE;;QAEhE,yEAAyE;;QAEzE,6EAA6E;;;;;;QAM7E,kDAAkD;;QAElD,kCAAkC;;;;;;;;QAElC;;;;WAIG;;;;;;IAaL,kEAAkE;;;;;;QAOhE,qDAAqD;;;;;QAOrD,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;IAgB/D,mEAAmE;;;QAGjE,iDAAiD;;;QAGjD;6EACqE;;;;;;;;;;;;;;QAOrE,sDAAsD;;;;;;QAEtD,uEAAuE;;;;;GAKxE;AAGI,iEAGN;AAeM,wDAAmE;AAGnE,8CAA0C;AAG1C,sEACyC;AAUzC,kCALI,MAAM,SACN,MAAM,OACN,MAAM,GACJ,MAAM,CAGc;AAoD1B,6DACiC;AAEjC,mDAAoD;AAEpD,oEACmD;AAYnD,gCAJI,MAAM,UACN,MAAM,GACJ,MAAM,CAGuB"}
@@ -0,0 +1,321 @@
1
+ /* src/components/DialNav/DialNav.css */
2
+ .ds-dial {
3
+ position: relative;
4
+ }
5
+ .ds-dial__stage {
6
+ position: relative;
7
+ height: var(--ds-dial-stage-height, 460px);
8
+ min-height: var(--dial-h);
9
+ overflow: hidden;
10
+ }
11
+ .ds-dial__frame {
12
+ position: absolute;
13
+ inset: 0;
14
+ transform: scale(var(--dial-scale, 1));
15
+ transform-origin: 0 50%;
16
+ pointer-events: none;
17
+ z-index: var(--ds-z-dropdown);
18
+ }
19
+ .ds-dial__dock {
20
+ position: absolute;
21
+ top: 50%;
22
+ left: 0;
23
+ width: var(--dial-w);
24
+ height: var(--dial-h);
25
+ margin-top: calc(var(--dial-h) / -2);
26
+ transition: transform 0.55s cubic-bezier(0.2, 0.9, 0.25, 1);
27
+ }
28
+ .ds-dial__chrome {
29
+ display: block;
30
+ width: 100%;
31
+ height: auto;
32
+ overflow: visible;
33
+ touch-action: none;
34
+ user-select: none;
35
+ -webkit-user-select: none;
36
+ pointer-events: auto;
37
+ filter: drop-shadow(3px 2px 9px var(--ds-rule-shadow));
38
+ }
39
+ .ds-dial__face {
40
+ fill: var(--ds-rule-plate);
41
+ stroke: var(--ds-rule-edge);
42
+ stroke-width: 1.5;
43
+ }
44
+ .ds-dial__grab {
45
+ fill: transparent;
46
+ cursor: grab;
47
+ }
48
+ .ds-dial__disc:active .ds-dial__grab {
49
+ cursor: grabbing;
50
+ }
51
+ .ds-dial__hairline-ring,
52
+ .ds-dial__log-plate {
53
+ fill: none;
54
+ stroke: var(--ds-rule-edge);
55
+ stroke-width: 0.5;
56
+ }
57
+ .ds-dial__log-plate {
58
+ fill: var(--ds-rule-plate-2);
59
+ }
60
+ .ds-dial__tick {
61
+ stroke: var(--ds-rule-tick);
62
+ stroke-width: 1;
63
+ }
64
+ .ds-dial__tick--faint {
65
+ opacity: 0.5;
66
+ }
67
+ .ds-dial__tick--station {
68
+ stroke: var(--ds-rule-hair);
69
+ stroke-width: 1.6;
70
+ }
71
+ .ds-dial__numeral,
72
+ .ds-dial__caption {
73
+ font-family: var(--ds-font-body);
74
+ font-size: 8px;
75
+ fill: var(--ds-rule-ink-soft);
76
+ }
77
+ .ds-dial__numeral {
78
+ font-variant-numeric: tabular-nums;
79
+ fill: var(--ds-rule-hair);
80
+ }
81
+ .ds-dial__caption {
82
+ letter-spacing: 0.16em;
83
+ fill: var(--ds-rule-hair);
84
+ }
85
+ .ds-dial__hub {
86
+ fill: var(--ds-rule-plate);
87
+ stroke: var(--ds-rule-edge);
88
+ stroke-width: 0.5;
89
+ }
90
+ .ds-dial__rivet {
91
+ fill: var(--ds-rule-brass);
92
+ }
93
+ .ds-dial__rivet-hi {
94
+ fill: var(--ds-rule-brass);
95
+ opacity: 0.6;
96
+ }
97
+ .ds-dial__arm {
98
+ pointer-events: none;
99
+ }
100
+ .ds-dial__arm,
101
+ .ds-dial__stations {
102
+ opacity: 1;
103
+ transition: opacity 0.3s ease 0.12s;
104
+ }
105
+ .ds-dial:not(.is-out) .ds-dial__arm,
106
+ .ds-dial:not(.is-out) .ds-dial__stations {
107
+ opacity: 0;
108
+ transition-delay: 0s;
109
+ }
110
+ .ds-dial:not(.is-out) .ds-dial__station {
111
+ pointer-events: none;
112
+ }
113
+ .ds-dial__glass {
114
+ fill: var(--ds-rule-glass);
115
+ stroke: var(--ds-rule-glass-edge);
116
+ stroke-width: 0.75;
117
+ }
118
+ .ds-dial__frame-line {
119
+ fill: none;
120
+ stroke: var(--ds-rule-glass-edge);
121
+ stroke-width: 2.4;
122
+ stroke-linejoin: round;
123
+ opacity: 0.7;
124
+ }
125
+ .ds-dial__hairline {
126
+ stroke: var(--ds-rule-hair);
127
+ stroke-width: 1.1;
128
+ }
129
+ .ds-dial__index {
130
+ fill: var(--ds-rule-hair);
131
+ }
132
+ .ds-dial__stations {
133
+ position: absolute;
134
+ inset: 0;
135
+ margin: 0;
136
+ padding: 0;
137
+ list-style: none;
138
+ pointer-events: none;
139
+ transform-origin: var(--dial-cx) var(--dial-cy);
140
+ }
141
+ .ds-dial__station {
142
+ position: absolute;
143
+ left: var(--dial-cx);
144
+ top: var(--dial-cy);
145
+ transform: translate(-50%, -50%) rotate(var(--a)) translateX(var(--r)) rotate(var(--flip));
146
+ pointer-events: auto;
147
+ }
148
+ .ds-dial__link {
149
+ display: inline-block;
150
+ padding: var(--ds-space-1) var(--ds-space-2);
151
+ border: none;
152
+ border-bottom: 2px solid transparent;
153
+ border-radius: var(--ds-radius-sm);
154
+ background: transparent;
155
+ font-family: var(--ds-font-body);
156
+ font-size: var(--ds-font-size-100);
157
+ font-weight: var(--ds-font-weight-semibold);
158
+ letter-spacing: 0.13em;
159
+ text-transform: uppercase;
160
+ text-decoration: none;
161
+ white-space: nowrap;
162
+ color: var(--ds-rule-ink-soft);
163
+ cursor: pointer;
164
+ transition: color var(--ds-motion-duration-base) var(--ds-motion-ease-standard);
165
+ }
166
+ .ds-dial__link:hover {
167
+ color: var(--ds-rule-ink);
168
+ }
169
+ .ds-dial__link:focus-visible {
170
+ outline: 2px solid var(--ds-color-focus-ring);
171
+ outline-offset: 2px;
172
+ }
173
+ .ds-dial__link--active {
174
+ color: var(--ds-rule-ink);
175
+ border-bottom-color: var(--ds-rule-hair);
176
+ }
177
+ .ds-dial__peek {
178
+ position: absolute;
179
+ left: 10px;
180
+ top: 50%;
181
+ transform: translateY(-50%) rotate(180deg);
182
+ writing-mode: vertical-rl;
183
+ font-family: var(--ds-font-body);
184
+ font-size: var(--ds-font-size-100);
185
+ letter-spacing: 0.28em;
186
+ text-transform: uppercase;
187
+ color: var(--ds-rule-ink-soft);
188
+ pointer-events: none;
189
+ transition: opacity 0.25s;
190
+ z-index: calc(var(--ds-z-dropdown) + 1);
191
+ }
192
+ .ds-dial.is-out .ds-dial__peek {
193
+ opacity: 0;
194
+ }
195
+ .ds-dial__hotzone {
196
+ position: absolute;
197
+ top: 0;
198
+ bottom: 0;
199
+ left: 0;
200
+ width: 92px;
201
+ padding: 0;
202
+ border: none;
203
+ background: transparent;
204
+ cursor: e-resize;
205
+ z-index: calc(var(--ds-z-dropdown) + 2);
206
+ }
207
+ .ds-dial__hotzone:focus-visible {
208
+ outline: 2px solid var(--ds-color-focus-ring);
209
+ outline-offset: -4px;
210
+ }
211
+ .ds-dial.is-out .ds-dial__hotzone {
212
+ pointer-events: none;
213
+ }
214
+ @media (max-width: 760px) {
215
+ .ds-dial__stage {
216
+ height: var(--ds-dial-stage-height, 340px);
217
+ min-height: 0;
218
+ }
219
+ .ds-dial__frame {
220
+ --dial-scale: 0.72;
221
+ }
222
+ .ds-dial__link {
223
+ font-size: calc(var(--ds-font-size-100) / 0.72);
224
+ }
225
+ }
226
+ @media (prefers-reduced-motion: reduce) {
227
+ .ds-dial__dock {
228
+ transition-duration: 0.01ms;
229
+ }
230
+ .ds-dial__link {
231
+ transition-duration: 0.01ms;
232
+ }
233
+ }
234
+ .ds-dial--concentric {
235
+ --dial-cx: 220px;
236
+ --dial-cy: 220px;
237
+ }
238
+ .ds-dial__grab-hole {
239
+ fill: transparent;
240
+ pointer-events: none;
241
+ }
242
+ .ds-dial__arm-sweep {
243
+ cursor: grab;
244
+ }
245
+ .ds-dial__arm-sweep:active {
246
+ cursor: grabbing;
247
+ }
248
+ .ds-dial__brass-rail {
249
+ stroke: var(--ds-rule-brass);
250
+ stroke-width: 1.6;
251
+ }
252
+ .ds-dial__brass-point {
253
+ fill: var(--ds-rule-brass);
254
+ }
255
+ .ds-dial__stations--inner {
256
+ transform: none;
257
+ }
258
+ .ds-dial--concentric .ds-dial__link {
259
+ font-size: calc(var(--ds-font-size-100) * 0.8);
260
+ letter-spacing: 0.1em;
261
+ padding: var(--ds-space-1);
262
+ }
263
+ .ds-dial__link--page {
264
+ letter-spacing: 0.08em;
265
+ }
266
+ .ds-dial--fan {
267
+ --dial-cx: 46px;
268
+ --dial-cy: 210px;
269
+ }
270
+ .ds-dial--fan .ds-dial__dock {
271
+ transition: clip-path 0.5s cubic-bezier(0.2, 0.9, 0.25, 1);
272
+ }
273
+ .ds-dial__wedge {
274
+ fill: var(--ds-rule-plate);
275
+ stroke: var(--ds-rule-edge);
276
+ stroke-width: 1;
277
+ }
278
+ .ds-dial__ratchet {
279
+ fill: none;
280
+ stroke: var(--ds-rule-brass);
281
+ stroke-width: 1.4;
282
+ opacity: 0.85;
283
+ }
284
+ .ds-dial__pawl {
285
+ cursor: grab;
286
+ }
287
+ .ds-dial__pawl:active {
288
+ cursor: grabbing;
289
+ }
290
+ .ds-dial__fanchrome {
291
+ opacity: 1;
292
+ transition: opacity 0.4s ease 0.18s;
293
+ }
294
+ .ds-dial:not(.is-out) .ds-dial__fanchrome,
295
+ .ds-dial:not(.is-out) .ds-dial__pawl {
296
+ opacity: 0;
297
+ transition: opacity 0.25s;
298
+ }
299
+ .ds-dial__spoke {
300
+ transition: transform 0.5s cubic-bezier(0.18, 1.05, 0.3, 1), opacity 0.3s;
301
+ }
302
+ .ds-dial:not(.is-out) .ds-dial__spoke {
303
+ transform: scaleX(0.04);
304
+ opacity: 0;
305
+ }
306
+ .ds-dial--fan .ds-dial__station {
307
+ opacity: 1;
308
+ transition: opacity 0.3s ease var(--bloom-delay, 0ms);
309
+ }
310
+ .ds-dial--fan:not(.is-out) .ds-dial__station {
311
+ opacity: 0;
312
+ }
313
+ @media (prefers-reduced-motion: reduce) {
314
+ .ds-dial__spoke,
315
+ .ds-dial__fanchrome,
316
+ .ds-dial--fan .ds-dial__station {
317
+ transition-duration: 0.01ms;
318
+ transition-delay: 0ms;
319
+ }
320
+ }
321
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/DialNav/DialNav.css"],"sourcesContent":["/*\n Circular slide-rule navigation. As with SlideRuleNav, the engraved chrome is\n an aria-hidden SVG and the navigation is the HTML list positioned over it.\n\n The station rail lives *inside* the dock so it carries the same translation\n the disc does, and rotates by the same angle. Scale and translation sit on\n two different elements (frame and dock) so they never have to compose in one\n declaration.\n\n Component tokens (--ds-rule-*) live in src/tokens/rule.css.\n*/\n\n.ds-dial {\n position: relative;\n}\n\n/*\n The dock is as tall as the disc's viewBox, so the stage has to exceed that\n or the face sits flush against both edges and its shadow is cut off. Sized\n as a variable: a real sidebar usually wants 100vh or the height of its\n layout column.\n*/\n.ds-dial__stage {\n position: relative;\n height: var(--ds-dial-stage-height, 460px);\n min-height: var(--dial-h);\n overflow: hidden;\n}\n\n.ds-dial__frame {\n position: absolute;\n inset: 0;\n transform: scale(var(--dial-scale, 1));\n transform-origin: 0 50%;\n /* Only the painted instrument takes pointer events, not its bounding box. */\n pointer-events: none;\n z-index: var(--ds-z-dropdown);\n}\n\n.ds-dial__dock {\n position: absolute;\n top: 50%;\n left: 0;\n width: var(--dial-w);\n height: var(--dial-h);\n margin-top: calc(var(--dial-h) / -2);\n /* the travel itself is written inline from geometry.js — see DialNav.jsx */\n transition: transform 0.55s cubic-bezier(0.2, 0.9, 0.25, 1);\n}\n\n.ds-dial__chrome {\n display: block;\n width: 100%;\n height: auto;\n overflow: visible;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n pointer-events: auto;\n filter: drop-shadow(3px 2px 9px var(--ds-rule-shadow));\n}\n\n/* ── engraved chrome ─────────────────────────────────────────────────── */\n\n.ds-dial__face {\n fill: var(--ds-rule-plate);\n stroke: var(--ds-rule-edge);\n stroke-width: 1.5;\n}\n\n.ds-dial__grab {\n fill: transparent;\n cursor: grab;\n}\n.ds-dial__disc:active .ds-dial__grab {\n cursor: grabbing;\n}\n\n.ds-dial__hairline-ring,\n.ds-dial__log-plate {\n fill: none;\n stroke: var(--ds-rule-edge);\n stroke-width: 0.5;\n}\n\n.ds-dial__log-plate {\n fill: var(--ds-rule-plate-2);\n}\n\n.ds-dial__tick {\n stroke: var(--ds-rule-tick);\n stroke-width: 1;\n}\n.ds-dial__tick--faint {\n opacity: 0.5;\n}\n\n/* Station marks have to read as a different scale from the decorative rim,\n or the two tick bands merge into one texture. */\n.ds-dial__tick--station {\n stroke: var(--ds-rule-hair);\n stroke-width: 1.6;\n}\n\n.ds-dial__numeral,\n.ds-dial__caption {\n font-family: var(--ds-font-body);\n font-size: 8px;\n fill: var(--ds-rule-ink-soft);\n}\n.ds-dial__numeral {\n font-variant-numeric: tabular-nums;\n fill: var(--ds-rule-hair);\n}\n.ds-dial__caption {\n letter-spacing: 0.16em;\n fill: var(--ds-rule-hair);\n}\n\n.ds-dial__hub {\n fill: var(--ds-rule-plate);\n stroke: var(--ds-rule-edge);\n stroke-width: 0.5;\n}\n.ds-dial__rivet {\n fill: var(--ds-rule-brass);\n}\n.ds-dial__rivet-hi {\n fill: var(--ds-rule-brass);\n opacity: 0.6;\n}\n\n/* The arm is instrument furniture; drags belong to the disc beneath it. */\n.ds-dial__arm {\n pointer-events: none;\n}\n\n/*\n At rest, only the disc face may break the edge. The cursor arm reaches\n 218 units from the hub against the face's 200, so left alone it pokes out\n further than the instrument it belongs to — a red chevron floating in the\n margin. The station labels sit proud of the crescent for the same reason.\n Both fade in with the extraction.\n*/\n.ds-dial__arm,\n.ds-dial__stations {\n opacity: 1;\n transition: opacity 0.3s ease 0.12s;\n}\n\n.ds-dial:not(.is-out) .ds-dial__arm,\n.ds-dial:not(.is-out) .ds-dial__stations {\n opacity: 0;\n transition-delay: 0s;\n}\n\n.ds-dial:not(.is-out) .ds-dial__station {\n pointer-events: none;\n}\n\n.ds-dial__glass {\n fill: var(--ds-rule-glass);\n stroke: var(--ds-rule-glass-edge);\n stroke-width: 0.75;\n}\n\n.ds-dial__frame-line {\n fill: none;\n stroke: var(--ds-rule-glass-edge);\n stroke-width: 2.4;\n stroke-linejoin: round;\n opacity: 0.7;\n}\n\n.ds-dial__hairline {\n stroke: var(--ds-rule-hair);\n stroke-width: 1.1;\n}\n\n.ds-dial__index {\n fill: var(--ds-rule-hair);\n}\n\n/* ── stations (the actual navigation) ────────────────────────────────── */\n\n.ds-dial__stations {\n position: absolute;\n inset: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n pointer-events: none;\n transform-origin: var(--dial-cx) var(--dial-cy);\n}\n\n.ds-dial__station {\n position: absolute;\n left: var(--dial-cx);\n top: var(--dial-cy);\n /* Centre on the hub, swing out to the label radius, then flip about the\n label's own centre if it would otherwise read upside down. */\n transform: translate(-50%, -50%) rotate(var(--a)) translateX(var(--r))\n rotate(var(--flip));\n pointer-events: auto;\n}\n\n.ds-dial__link {\n display: inline-block;\n padding: var(--ds-space-1) var(--ds-space-2);\n border: none;\n border-bottom: 2px solid transparent;\n border-radius: var(--ds-radius-sm);\n background: transparent;\n font-family: var(--ds-font-body);\n font-size: var(--ds-font-size-100);\n font-weight: var(--ds-font-weight-semibold);\n letter-spacing: 0.13em;\n text-transform: uppercase;\n text-decoration: none;\n white-space: nowrap;\n color: var(--ds-rule-ink-soft);\n cursor: pointer;\n transition: color var(--ds-motion-duration-base)\n var(--ds-motion-ease-standard);\n}\n\n.ds-dial__link:hover {\n color: var(--ds-rule-ink);\n}\n\n.ds-dial__link:focus-visible {\n outline: 2px solid var(--ds-color-focus-ring);\n outline-offset: 2px;\n}\n\n.ds-dial__link--active {\n color: var(--ds-rule-ink);\n border-bottom-color: var(--ds-rule-hair);\n}\n\n/* ── rail affordances ────────────────────────────────────────────────── */\n\n.ds-dial__peek {\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%) rotate(180deg);\n writing-mode: vertical-rl;\n font-family: var(--ds-font-body);\n font-size: var(--ds-font-size-100);\n letter-spacing: 0.28em;\n text-transform: uppercase;\n color: var(--ds-rule-ink-soft);\n pointer-events: none;\n transition: opacity 0.25s;\n z-index: calc(var(--ds-z-dropdown) + 1);\n}\n\n.ds-dial.is-out .ds-dial__peek {\n opacity: 0;\n}\n\n.ds-dial__hotzone {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 92px;\n padding: 0;\n border: none;\n background: transparent;\n cursor: e-resize;\n z-index: calc(var(--ds-z-dropdown) + 2);\n}\n\n.ds-dial__hotzone:focus-visible {\n outline: 2px solid var(--ds-color-focus-ring);\n outline-offset: -4px;\n}\n\n/* Once extracted the rail must stop intercepting drags aimed at the disc. */\n.ds-dial.is-out .ds-dial__hotzone {\n pointer-events: none;\n}\n\n@media (max-width: 760px) {\n .ds-dial__stage {\n height: var(--ds-dial-stage-height, 340px);\n /* the frame is scaled, so the dock's own height no longer sets the floor */\n min-height: 0;\n }\n .ds-dial__frame {\n --dial-scale: 0.72;\n }\n /* Counteract the frame scale so labels keep their intended size while the\n instrument's geometry shrinks. */\n .ds-dial__link {\n font-size: calc(var(--ds-font-size-100) / 0.72);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-dial__dock {\n transition-duration: 0.01ms;\n }\n .ds-dial__link {\n transition-duration: 0.01ms;\n }\n}\n\n/* ── C-II Concentric ─────────────────────────────────────────────────── */\n\n.ds-dial--concentric {\n --dial-cx: 220px;\n --dial-cy: 220px;\n}\n\n/* Punch the inner plate out of the outer ring's hit area, so drags landing\n there belong to the sweeping arm rather than the ring. */\n.ds-dial__grab-hole {\n fill: transparent;\n pointer-events: none;\n}\n\n.ds-dial__arm-sweep {\n cursor: grab;\n}\n.ds-dial__arm-sweep:active {\n cursor: grabbing;\n}\n\n.ds-dial__brass-rail {\n stroke: var(--ds-rule-brass);\n stroke-width: 1.6;\n}\n\n.ds-dial__brass-point {\n fill: var(--ds-rule-brass);\n}\n\n/* The inner rail is fixed in disc space — the arm sweeps it, it does not\n turn. */\n.ds-dial__stations--inner {\n transform: none;\n}\n\n/* The outer ring turns a full circle, so a section label can swing due west.\n It has to stay inside labelClearance of the hub to clear the stage edge. */\n.ds-dial--concentric .ds-dial__link {\n font-size: calc(var(--ds-font-size-100) * 0.8);\n letter-spacing: 0.1em;\n padding: var(--ds-space-1);\n}\n\n.ds-dial__link--page {\n letter-spacing: 0.08em;\n}\n\n/* ── C-III Ratchet Fan ───────────────────────────────────────────────── */\n\n.ds-dial--fan {\n --dial-cx: 46px;\n --dial-cy: 210px;\n}\n\n/* The fan does not slide out; it is unveiled by opening a clip, so the hub\n band stays visible at the edge as the rest-state hint. */\n.ds-dial--fan .ds-dial__dock {\n transition: clip-path 0.5s cubic-bezier(0.2, 0.9, 0.25, 1);\n}\n\n.ds-dial__wedge {\n fill: var(--ds-rule-plate);\n stroke: var(--ds-rule-edge);\n stroke-width: 1;\n}\n\n.ds-dial__ratchet {\n fill: none;\n stroke: var(--ds-rule-brass);\n stroke-width: 1.4;\n opacity: 0.85;\n}\n\n.ds-dial__pawl {\n cursor: grab;\n}\n.ds-dial__pawl:active {\n cursor: grabbing;\n}\n\n.ds-dial__fanchrome {\n opacity: 1;\n transition: opacity 0.4s ease 0.18s;\n}\n.ds-dial:not(.is-out) .ds-dial__fanchrome,\n.ds-dial:not(.is-out) .ds-dial__pawl {\n opacity: 0;\n transition: opacity 0.25s;\n}\n\n/* Rotation lives on the parent group as an SVG attribute; the retract is a\n CSS transform here, on an element that carries no transform attribute of\n its own. Sharing one element would make transform-origin double-apply on\n top of a rotate() that already encodes its centre. */\n.ds-dial__spoke {\n transition: transform 0.5s cubic-bezier(0.18, 1.05, 0.3, 1), opacity 0.3s;\n}\n.ds-dial:not(.is-out) .ds-dial__spoke {\n transform: scaleX(0.04);\n opacity: 0;\n}\n\n/* Labels bloom outward in the same order the spokes deploy. */\n.ds-dial--fan .ds-dial__station {\n opacity: 1;\n transition: opacity 0.3s ease var(--bloom-delay, 0ms);\n}\n.ds-dial--fan:not(.is-out) .ds-dial__station {\n opacity: 0;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ds-dial__spoke,\n .ds-dial__fanchrome,\n .ds-dial--fan .ds-dial__station {\n transition-duration: 0.01ms;\n transition-delay: 0ms;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ export { DialNav } from "./DialNav.jsx";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DialNav/index.js"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import {
2
+ DialNav
3
+ } from "../../chunk-NJ2SBQYA.js";
4
+ import "../../chunk-UZW4E2UH.js";
5
+ export {
6
+ DialNav
7
+ };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * C-II — Concentric Computer.
3
+ *
4
+ * After the E6B. The outer ring carries sections and turns a full circle; the
5
+ * inner ring re-cuts itself to the pages of whichever section is indexed, and
6
+ * a brass arm sweeps between them. The only two-level plate, so it renders
7
+ * both label rails itself rather than using the shell's single rail.
8
+ */
9
+ export const Concentric: import("react").ForwardRefExoticComponent<import("react").RefAttributes<any>>;
10
+ //# sourceMappingURL=Concentric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Concentric.d.ts","sourceRoot":"","sources":["../../../../src/components/DialNav/variants/Concentric.jsx"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,uGA2SG"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * C-III — Ratchet Fan.
3
+ *
4
+ * The hint is a bare hub band at the edge. On approach the quadrant blooms and
5
+ * the spokes deploy in sequence, each carrying a station outward. A sprung
6
+ * pawl rides a real sawtooth, kicking against every quarter-detent it crosses.
7
+ *
8
+ * Decorative only — the navigation is the HTML list the parent renders over
9
+ * this, one label per spoke.
10
+ */
11
+ export const RatchetFan: import("react").ForwardRefExoticComponent<import("react").RefAttributes<any>>;
12
+ //# sourceMappingURL=RatchetFan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RatchetFan.d.ts","sourceRoot":"","sources":["../../../../src/components/DialNav/variants/RatchetFan.jsx"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AACH,uGA8LG"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * C-I — Volvelle.
3
+ *
4
+ * A disc carrying its stations on a band, read against a fixed glass cursor
5
+ * arm due east. Spinning it ratchets through quarter-pitch detents; releasing
6
+ * settles a station onto the index.
7
+ *
8
+ * Decorative only — the navigation is the HTML list the parent renders over
9
+ * this, which rotates by the same angle the disc does.
10
+ */
11
+ export const Volvelle: import("react").ForwardRefExoticComponent<import("react").RefAttributes<any>>;
12
+ //# sourceMappingURL=Volvelle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Volvelle.d.ts","sourceRoot":"","sources":["../../../../src/components/DialNav/variants/Volvelle.jsx"],"names":[],"mappings":"AAUA;;;;;;;;;GASG;AACH,qGAiOG"}
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  SlideRuleNav
3
- } from "../../chunk-SUYKOWXJ.js";
3
+ } from "../../chunk-YLUQANAI.js";
4
+ import "../../chunk-UZW4E2UH.js";
4
5
  export {
5
6
  SlideRuleNav
6
7
  };