@zumer/orbit 1.5.0 → 2.0.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.
package/README.md CHANGED
@@ -1,233 +1,323 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="orbit-logo-blanco.svg">
4
+ <img src="orbit-logo-negro.svg" alt="Orbit" width="120">
5
+ </picture>
6
+ </p>
7
+
1
8
  # Orbit
2
9
 
3
- **Orbit** builds radial UIs — gauges, donuts, knobs, pie menus, dashboards — with **CSS geometry and a small JavaScript runtime**. CSS controls presentation; JavaScript keeps ring indices, spacing and SVG paths in sync as the interface changes. Use it with plain HTML or frameworks such as React, Vue and Svelte.
10
+ Orbit puts HTML on circles. Gauges, dials, knobs, radial menus, donut charts, watch faces, sci-fi panels: anything that grows around a center instead of down a page.
4
11
 
5
- <p align="center">
6
- <a href="https://zumerlab.github.io/orbit-docs" target="_blank"><strong>🚀 Live showcase &amp; docs</strong></a>
12
+ You write plain HTML with a few classes. CSS does the geometry and the look; a small runtime keeps numbering, spacing and SVG arcs right as things change. It works the same in plain HTML, React, Vue, Svelte or anything else that renders the DOM.
7
13
 
8
- </p>
14
+ [Documentation and examples](https://zumerlab.com/orbit/) · [npm](https://www.npmjs.com/package/@zumer/orbit) · [Orbit 1.x docs](https://zumerlab.com/orbit-docs/)
9
15
 
10
- <p align="center">
11
- <a href="https://www.npmjs.com/package/@zumer/orbit"><img src="https://img.shields.io/npm/v/@zumer/orbit" alt="npm"></a>
12
- <a href="https://github.com/zumerlab/orbit/stargazers"><img src="https://img.shields.io/github/stars/zumerlab/orbit" alt="Stars"></a>
13
- </p>
16
+ ## Install
14
17
 
15
- ---
18
+ ```sh
19
+ npm install @zumer/orbit
20
+ ```
16
21
 
17
- ## Why Orbit?
22
+ ```js
23
+ import '@zumer/orbit/style'
24
+ import '@zumer/orbit'
25
+ ```
18
26
 
19
- Orbit provides reusable radial layout primitives, CSS custom properties and Web Components for arcs and progress rings. Load the stylesheet and script, then compose an interface with HTML classes. The runtime updates added, removed and reordered elements, ancestor style changes and container resizes.
27
+ Or, in a plain page:
20
28
 
21
- > **Want ready-made components?** [**orbit-kit**](https://zumerlab.com/orbit-kit) wraps the common Orbit patterns into one-line custom elements — gauges, charts, activity rings, knobs, pie menus, cockpit instruments, analog clocks, compasses and radars.
29
+ ```html
30
+ <link rel="stylesheet" href="https://unpkg.com/@zumer/orbit/dist/orbit.min.css">
31
+ <script defer src="https://unpkg.com/@zumer/orbit/dist/orbit.min.js"></script>
32
+ ```
22
33
 
23
- ## Installation
34
+ ## Your first universe
24
35
 
25
- **CDN (fastest):**
36
+ Save this as `index.html` and open it. It draws a progress ring with a label in the middle, and the whole thing is as big as its 240px box.
26
37
 
27
38
  ```html
28
- <link rel="stylesheet" href="https://unpkg.com/@zumer/orbit@latest/dist/orbit.css">
29
- <script src="https://unpkg.com/@zumer/orbit@latest/dist/orbit.js"></script>
39
+ <!doctype html>
40
+ <html lang="en">
41
+ <head>
42
+ <meta charset="utf-8">
43
+ <meta name="viewport" content="width=device-width, initial-scale=1">
44
+ <title>A first Orbit</title>
45
+ <link rel="stylesheet" href="https://unpkg.com/@zumer/orbit/dist/orbit.min.css">
46
+ <script defer src="https://unpkg.com/@zumer/orbit/dist/orbit.min.js"></script>
47
+ <style>
48
+ body { margin: 0; min-height: 100vh; display: grid; place-items: center; font-family: system-ui, sans-serif; }
49
+ .gauge { width: 240px; }
50
+ .gauge o-progress { --o-fill: #3da9fc; --o-back-fill: #1d3749; --o-stroke: none; }
51
+ .gauge .value { font-size: 40px; font-weight: 600; }
52
+ </style>
53
+ </head>
54
+ <body>
55
+ <div class="gauge bigbang">
56
+ <div class="gravity-spot">
57
+ <div class="orbit-10" style="--o-size-ratio: 2">
58
+ <o-progress value="72" shape="rounded" role="progressbar"
59
+ aria-label="Upload" aria-valuenow="72" aria-valuemin="0" aria-valuemax="100"></o-progress>
60
+ </div>
61
+ <div class="orbit-0" style="--o-size-ratio: 12">
62
+ <div class="satellite at-center"><div class="capsule value">72%</div></div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </body>
67
+ </html>
30
68
  ```
31
69
 
32
- **npm:**
70
+ Change `width` on `.gauge` and everything follows: the ring, its thickness, the space for the label. Change `value` and the ring redraws.
33
71
 
34
- ```bash
35
- npm install @zumer/orbit
36
- ```
72
+ ## How Orbit thinks
37
73
 
38
- ```js
39
- import '@zumer/orbit/style'
40
- import '@zumer/orbit'
41
- ```
74
+ Orbit borrows its words from a solar system. It sounds like a gimmick for about a minute; after that it is the easiest way to remember what each piece does.
42
75
 
43
- The npm import resolves to an ES module. Importing it during server rendering is safe; registration and layout observation start when the module runs in a browser. Render the markup on the server and include the JavaScript in your client entrypoint to activate it.
76
+ **First there is a big bang.** A `.bigbang` creates the universe: the space your layout lives in. Its box is the only size you ever set. It is square by default, as wide as its parent, and a parent with a height keeps it from growing taller.
44
77
 
45
- The module also exports `Orbit`, `OrbitArc`, `OrbitProgress` and `registerOrbit`:
78
+ **Then gravity.** Inside it, a `.gravity-spot` is the center of mass. Its gravity reaches as far as the shorter side of the universe; that reach is `--o-force`, and it is the diameter of the outermost orbit, `orbit-12`.
46
79
 
47
- ```js
48
- import { Orbit } from '@zumer/orbit'
80
+ **Gravity draws orbits.** From the center to that edge there are 12 lanes. `orbit-1` is the first lane, `orbit-6` is halfway out, `orbit-12` touches the edge. `orbit-0` is the center itself, and `orbit-13` to `orbit-24` exist too, past the edge, for things that should stick out.
49
81
 
50
- // Run after the container mounts. Dispose the observer when it unmounts.
51
- const stopResizing = Orbit.resize('#instrument-panel')
52
- // Later: stopResizing()
82
+ **Satellites travel the orbits.** A `.satellite` sits on a ring, and Orbit spreads all the satellites of a ring around it on its own. Each one carries a `.capsule`, where your content goes, kept upright however far around the ring it is.
53
83
 
54
- // After changing stylesheet rules through CSSOM, refresh the affected subtree.
55
- Orbit.refresh(document.querySelector('#instrument-panel'))
84
+ **And there is more up there.** A `.vector` is a ray pointing out from the center: ticks, needles. A `.side` is a chord between neighbors: polygons. `<o-arc>` draws a piece of a lane, with text along it if you want. `<o-progress>` fills a lane up to a value.
85
+
86
+ ```
87
+ .bigbang the universe: its box sets the size
88
+ └── .gravity-spot the center; reaches the shorter side
89
+ ├── .orbit-N a lane, N twelfths of the way out
90
+ │ ├── .satellite > .capsule ← your content
91
+ │ ├── .vector · .side rays and chords
92
+ │ └── <o-arc> · <o-progress>
93
+ └── .orbit-M …
56
94
  ```
57
95
 
58
- `Orbit.resize` accepts a selector or an element. `Orbit.refresh(root)` accepts a document, element or shadow root, defaults to the document and updates layout synchronously. DOM, attribute and resize changes within a layout or its ancestors are observed automatically and batched for the next animation frame; use `refresh` when immediate results are needed. Repeated calls to `registerOrbit()` are safe. The classic CDN script exposes the same `Orbit` API as `window.Orbit`.
96
+ That is all the structure there is. A few rules keep it working:
97
+
98
+ - Rings are direct children of a `.gravity-spot`, never of another ring.
99
+ - A ring holds only `.satellite`, `.vector`, `.side`, `<o-arc>` and `<o-progress>`.
100
+ - Content goes in a `.capsule` inside a `.satellite`. Centered content goes in `.orbit-0 > .satellite.at-center > .capsule`.
101
+
102
+ Add `dev-orbit` to the `.bigbang` while you build. It draws the lanes, outlines anything in the wrong place and explains it in the console.
59
103
 
60
- Arcs and progress elements also register layouts inside open or closed shadow roots. Include the Orbit stylesheet inside each shadow root; host and ancestor style changes then refresh its SVGs. For a shadow tree containing only CSS elements, call `Orbit.refresh(shadowRoot)` to register it explicitly. Removing a shadow host releases its observers; reconnecting its components restores them.
104
+ ### Size is a fraction of the universe
105
+
106
+ Every element on a ring is one lane thick: a twelfth of the radius. A satellite on `orbit-8` is a circle one lane across; a band of `<o-progress>` is one lane wide. To make things thicker or thinner, set `--o-size-ratio`, in lanes, on the element, on its ring, or on the whole `.gravity-spot`:
107
+
108
+ ```html
109
+ <div class="orbit-8" style="--o-size-ratio: 2">
110
+ <div class="satellite"><div class="capsule">A</div></div>
111
+ <div class="satellite"><div class="capsule">B</div></div>
112
+ <div class="satellite"><div class="capsule">C</div></div>
113
+ </div>
114
+ ```
61
115
 
62
- Changes made through CSSOM, or selectors driven by external siblings and control states (such as `:checked`), may affect a chart without mutating the layout or an ancestor. Call `Orbit.refresh(chart)` after those changes. Orbit does not infer arbitrary CSS dependencies across unrelated elements.
116
+ An element on `orbit-N` reaches half its thickness past lane N. So a band two lanes thick on `orbit-11` ends exactly at the edge of the universe.
63
117
 
64
- ---
118
+ Because everything is a fraction of one box, an Orbit layout is responsive without any code. Put it in a sidebar, a card or a full screen and it scales as one piece. If you need a fixed size instead, give the reach a length: `.gravity-spot { --o-force: 400px }`.
65
119
 
66
- ## Quick start
120
+ ### Universes inside universes
67
121
 
68
- Minimal gauge in 10 lines:
122
+ A satellite is a universe too. Put a `.gravity-spot` inside one and its reach is the satellite's edge, like a moon system around a planet:
69
123
 
70
124
  ```html
71
- <div class="bigbang">
72
- <div class="gravity-spot">
73
- <div class="orbit-4">
74
- <o-progress value="72"></o-progress>
125
+ <div class="orbit-9" style="--o-size-ratio: 4">
126
+ <div class="satellite">
127
+ <div class="gravity-spot">
128
+ <div class="orbit-12"><o-progress value="40"></o-progress></div>
75
129
  </div>
76
130
  </div>
77
131
  </div>
78
132
  ```
79
133
 
80
- **Structure:** `bigbang` (container) → `gravity-spot` (center) → `orbit-N` (ring level) → `o-progress` or `o-arc` (the visual element).
134
+ Every `.gravity-spot` starts from the defaults, so a nested system does not inherit the sizes or angles of the one around it.
81
135
 
82
- ---
136
+ ### Angles
83
137
 
84
- ## Core elements
138
+ Angles start at the top and grow clockwise. `--o-range` is how much of the circle a ring uses, and `--o-from` where it starts:
85
139
 
86
- | Element | Role |
87
- |---------|------|
88
- | `.bigbang` | Root container, sets viewport |
89
- | `.gravity-spot` | Center of the radial layout; holds rings |
90
- | `.orbit` / `.orbit-N` | Automatically numbered rings, or an explicit nonnegative integer ring level (1 = innermost) |
91
- | `.satellite` | Item placed on a ring (dot, label, icon) |
92
- | `<o-arc>` | Arc segment (donut slice, gauge needle, menu sector); `value` 0–100, `shape` e.g. `arrow`, `circle-a` |
93
- | `<o-progress>` | Simple progress ring |
94
- | `.vector` | Tick/marker on a ring |
95
- | `.side` | Stretch content along arc |
96
- | `.capsule` | Wrapper for content inside satellite; required when satellite holds more than plain text |
140
+ ```html
141
+ <div class="orbit-10" style="--o-range: 240deg; --o-from: 240deg">…</div>
142
+ ```
97
143
 
98
- **Structure rules:**
144
+ Classes cover the common values: `range-180`, `from-270`, `ccw` to go counterclockwise, and `fit-range` to put the first and last satellite or tick on the two ends of a partial range.
99
145
 
100
- - `.bigbang` → direct children: `.gravity-spot` only
101
- - `.gravity-spot` → direct children: `.orbit`, `.orbit-N`, or `.gravity-spot` only
102
- - `.satellite` → direct children: `.capsule` or `.gravity-spot` (for nesting) only
103
- - `.orbit` / `.orbit-N` → do not nest other orbits; orbits live inside gravity-spot
104
- - `o-arc` and `o-progress` → only work in circular orbits; they are hidden in elliptical shapes
146
+ | Property | Default | Set it on | What it does |
147
+ | --- | --- | --- | --- |
148
+ | `--o-force` | `100cqmin` | `.gravity-spot` | Reach: the diameter of `orbit-12`. |
149
+ | `--o-size-ratio` | `1` | system, ring or element | Thickness, in lanes. |
150
+ | `--o-range` | `360deg` | system or ring | How much of the circle the ring uses. |
151
+ | `--o-from` | `0deg` | system or ring | Where the range starts. |
152
+ | `--o-gap` | `1` | system, ring or arc | Space between sibling arcs. |
153
+ | `--o-alignment` | `0px` | element | Moves an element in (positive) or out (negative) from its lane. Also set by `.inner-orbit` and `.outer-orbit`. |
105
154
 
106
- **Useful classes:** `range-180`, `range-270`, `range-360` (arc span); `from-180` (start angle); `fit-range` (distribute items); `shrink-50`, `gap-4` (spacing); `at-center` (place satellite in middle).
155
+ Values cascade, so set them once on the `.gravity-spot` for the whole system or on a ring for its elements.
107
156
 
108
- The runtime supports ring levels and child counts beyond the static CSS fallback's 24 levels and 60 children per type. Without JavaScript, that fallback can position simple CSS elements in browsers supporting `:has()` and `:nth-child(... of ...)`; `<o-arc>` and `<o-progress>` require JavaScript. Ring classes are matched as complete tokens, so application classes such as `orbit-card` do not become rings.
157
+ ### Which way is out
109
158
 
110
- Use public custom properties such as `--o-range`, `--o-from`, `--o-orbit-number` and `--o-orbit-child-number` for overrides. The runtime owns `data-orbit-ring`, `--o-layout-*` and `--o-arc-start`; leave these internal values to Orbit.
159
+ Each satellite tells its content where it sits: `--o-dir-x` and `--o-dir-y` are the direction from the center, from `-1` to `1` (`y` grows down, and both are `0` on the center satellite). It is handy for labels that should hang outward, above the satellites of the upper half and below the rest:
111
160
 
112
- ---
161
+ ```css
162
+ .label {
163
+ /* -1 in the upper half, 1 in the lower half */
164
+ --side: clamp(-1, var(--o-dir-y) * 1000, 1);
165
+ position: absolute; left: 50%;
166
+ top: calc(50% + var(--side) * (50% + 4px));
167
+ translate: -50% calc((var(--side) - 1) * 50%);
168
+ }
169
+ ```
113
170
 
114
- ## Themes
171
+ ## Arcs and progress
115
172
 
116
- Orbit includes built-in themes. Add the theme class to `.bigbang`:
173
+ `<o-arc>` and `<o-progress>` go straight into a ring. Both take a `value` out of `max` (100 by default) and an ending: `shape="rounded"`, `circle`, `arrow`, `slash`, `zigzag` and a few more, all scaled to the band.
117
174
 
118
- | Theme | Class | Description |
119
- |-------|-------|-------------|
120
- | **Default** | *(none)* | Transparent borders, gray fills, satellites use `currentColor` |
121
- | **Cyan** | `theme-cyan` | Cyan satellite borders, cyan vectors/sides, light cyan fills for `o-arc` and `o-progress` |
122
- | **Developer** | `dev-orbit` | Dashed red borders on orbits and satellites to visualize structure while debugging |
175
+ Without `value`, sibling arcs split the ring between them: that is a segmented ring or a pie. With `value`, they stack one after another: that is a donut chart.
123
176
 
124
177
  ```html
125
- <!-- Default (no class) -->
126
- <div class="bigbang">...</div>
178
+ <div class="orbit-10" style="--o-size-ratio: 3">
179
+ <o-arc value="45" style="--o-fill: #3da9fc"></o-arc>
180
+ <o-arc value="30" style="--o-fill: #ef4565"></o-arc>
181
+ <o-arc value="25" style="--o-fill: #90b4ce"></o-arc>
182
+ </div>
183
+ ```
127
184
 
128
- <!-- Cyan theme -->
129
- <div class="bigbang theme-cyan">...</div>
185
+ Text inside an arc is drawn along it. With `range="auto"` the arc is as long as its text, and consecutive auto arcs follow each other, which makes curved menus easy. `text-anchor="middle"` centers an auto arc on its angle:
130
186
 
131
- <!-- Developer mode for layout debugging -->
132
- <div class="bigbang dev-orbit">...</div>
187
+ ```html
188
+ <div class="orbit-11 from-300">
189
+ <o-arc range="auto">Home</o-arc><o-arc range="auto">Projects</o-arc><o-arc range="auto">About</o-arc>
190
+ </div>
133
191
  ```
134
192
 
135
- You can combine themes, e.g. `class="bigbang theme-cyan dev-orbit"`.
193
+ Progress rings draw filled bands. For a thin gauge line, use `variant="stroke"`: a 2px line over a gray track, colored with `--o-stroke` and `--o-back-stroke`.
136
194
 
137
- ---
195
+ Arcs and progress are decorative until you say otherwise. `interactive` makes the whole band clickable, transparent or not, and `hit-width="12"` adds 12px of touch area on each side:
138
196
 
139
- ## Visual aids & development
197
+ ```html
198
+ <div class="orbit-10" style="--o-size-ratio: 2">
199
+ <o-arc interactive hit-width="8" style="--o-fill: transparent" aria-label="Volume"></o-arc>
200
+ </div>
201
+ ```
140
202
 
141
- Orbit provides **opt-in CSS visual warnings** to catch invalid structure. Inside a `dev-orbit` container, invalid children show a dotted border, dimmed content and a ⚠️ icon. These diagnostics require `:has()` and respect reduced-motion preferences.
203
+ You bring the keyboard behavior and the accessible names for any control you build. Arcs are placed with the `rotate` property, so a `transform` or `scale` of yours adds to it instead of replacing it.
142
204
 
143
- Add **`class="dev-orbit"`** to your root container to enable **developer mode**: dashed red borders on `gravity-spot`, `orbit`, and `satellite` to visualize the layout structure. Useful for debugging.
205
+ ## Depth
206
+
207
+ A system can stack its rings in 3D. Add `depth` to the `.gravity-spot` and each ring becomes a layer: `data-depth="1"` sends it one step back, `.layer-front` marks the one in front. Layers keep their apparent size, because the scale makes up for the perspective, and they animate when their depth changes.
144
208
 
145
209
  ```html
146
- <div class="bigbang dev-orbit">
147
- <div class="gravity-spot">
148
- ...
149
- </div>
210
+ <div class="gravity-spot depth" style="--o-depth-grow: .42">
211
+ <div class="orbit-4 layer-front"><o-progress value="82"></o-progress></div>
212
+ <div class="orbit-4" data-depth="1"><o-progress value="40"></o-progress></div>
213
+ <div class="orbit-4" data-depth="2"><o-progress value="65"></o-progress></div>
150
214
  </div>
151
215
  ```
152
216
 
153
- CSS trigonometric functions (`cos`, `sin`) are required for geometry; unsupported browsers show an upgrade message. Missing `:has()` support does not block the JavaScript layout runtime. See [CSS visual aids](https://zumerlab.github.io/orbit-docs/tools/support) in the full docs.
217
+ | Property | Default | What it does |
218
+ | --- | --- | --- |
219
+ | `--o-z` | `depth × step` | Position on the z axis in unitless pixels; negative is farther. Overrides `data-depth`. |
220
+ | `--o-depth-step` | `-110` | Distance between steps. |
221
+ | `--o-perspective` | `900` | Perspective, in unitless pixels. |
222
+ | `--o-depth-grow` | `0` | Extra size per step back: `.42` gives 1×, 1.42×, 1.84×. |
223
+ | `--o-depth-compensate` | `1` | `0` lets farther layers look smaller. |
224
+ | `--o-back-opacity` | `1` | Opacity of the layers behind the front one. |
225
+ | `--o-depth-duration` / `--o-depth-easing` | `.8s` / `cubic-bezier(.2,.8,.2,1)` | The depth transition. Off with `prefers-reduced-motion`. |
154
226
 
155
- ## Building and testing
227
+ A layer can be a whole system, ring, label and face together: make it a nested `.gravity-spot` with `data-depth`. To tilt the whole object from outside (with the pointer, say), add `outer-perspective` next to `depth` and set `--o-perspective` to the perspective of the ancestor that owns it. The [depth demo](https://zumerlab.com/orbit/demos/11-depth-layers.html) shows both.
156
228
 
157
- ```sh
158
- npm ci
159
- npx playwright install chromium
160
- npm test
161
- npm run build
229
+ ## In an app
230
+
231
+ Orbit watches the DOM for you: added, removed and reordered elements, attribute and style changes, and resized containers. Updates are batched into the next animation frame.
232
+
233
+ The package is safe to import during server rendering; import it in the browser entry too, so it can register the elements and watch the page. It exports `Orbit`, `OrbitArc`, `OrbitProgress` and `registerOrbit`; registration happens on import and calling `registerOrbit()` again is harmless.
234
+
235
+ A few things for when you need them:
236
+
237
+ ```js
238
+ import { Orbit } from '@zumer/orbit'
239
+
240
+ await Orbit.ready() // every pending arc is drawn
241
+ gauge.addEventListener('o-rendered', () => measure(gauge)) // one arc redrew
242
+ Orbit.refresh(panel) // update now, e.g. after editing a stylesheet through CSSOM
162
243
  ```
163
244
 
164
- `npm test` compiles the package, tests its published file list and server imports, then runs browser and shadow-root regressions in Chromium. Set `BROWSERS=chromium,firefox,webkit` to run all three engines after installing them with Playwright; CI runs this matrix. Use `npm run test:package`, `npm run test:browser` or `npm run test:shadow` for an individual suite. The shadow suite builds in memory so it can also check source changes independently of `dist`.
245
+ `Orbit.resize(target)` only matters for systems with a fixed px `--o-force`: it scales them with the target's width, taking 500px as 1×, and returns a function that stops it.
165
246
 
166
- `npm run build` compiles CSS, classic browser scripts and the ES module, then creates an npm tarball. It does not commit, tag, push or publish; release operations are separate.
247
+ For shadow DOM, include the stylesheet inside each shadow root. Arcs and progress register their shadow root on their own; for a shadow tree with only CSS elements, call `Orbit.refresh(shadowRoot)` once.
167
248
 
168
- ---
249
+ Override Orbit through the documented custom properties. The runtime manages `data-orbit-ring`, `--o-layout-*` and `--o-arc-start` itself.
169
250
 
170
- ## Examples
251
+ ### TypeScript and editors
171
252
 
172
- Run the core playground against your local checkout:
253
+ The package ships types for the API and for `document.querySelector('o-progress')`. For JSX, load the element types once, for example in a `.d.ts` file:
173
254
 
174
- ```sh
175
- npm run demo
255
+ ```ts
256
+ import type {} from '@zumer/orbit/react'
257
+ ```
258
+
259
+ `@zumer/orbit/custom-elements.json` is a [Custom Elements Manifest](https://custom-elements-manifest.open-wc.org/). For attribute completion in VS Code:
260
+
261
+ ```json
262
+ { "html.customData": ["./node_modules/@zumer/orbit/dist/vscode.html-custom-data.json"] }
176
263
  ```
177
264
 
178
- Open **http://127.0.0.1:5174**. The command compiles the current source and serves the interactive playground and existing examples using that local build. Use `PORT=5175 npm run demo` to choose another port; stop the server with Ctrl+C.
265
+ ## When something looks wrong
179
266
 
180
- Browse examples on the [Orbit docs site](https://zumerlab.github.io/orbit-docs):
267
+ Orbit explains common mistakes in the browser console, starting with `[orbit]`:
181
268
 
182
- | Example | Link |
183
- |---------|------|
184
- | Circular timer | [circular_time](https://zumerlab.github.io/orbit-docs/examples/circular_time/) |
185
- | Progress bars | [progress](https://zumerlab.github.io/orbit-docs/examples/progress/) |
186
- | Charts (donut, pie, sunburst) | [charts](https://zumerlab.github.io/orbit-docs/examples/charts/) |
187
- | Gauges (180°, 240°, fuel) | [gauges](https://zumerlab.github.io/orbit-docs/examples/gauges/) |
188
- | Knobs | [knobs](https://zumerlab.github.io/orbit-docs/examples/knobs/) |
189
- | Pie menus | [piemenu](https://zumerlab.github.io/orbit-docs/examples/piemenu/) |
190
- | Watch faces | [watches](https://zumerlab.github.io/orbit-docs/examples/watches/) |
191
- | Chemical structures | [chemical_structures](https://zumerlab.github.io/orbit-docs/examples/chemical_structures/) |
192
- | Calendars & time planners | [calendar](https://zumerlab.github.io/orbit-docs/examples/calendar/) |
193
- | Mandalas | [mandalas](https://zumerlab.github.io/orbit-docs/examples/mandalas/) |
194
- | Dashboard | [dashboard](https://zumerlab.github.io/orbit-docs/examples/dashboard/) |
195
- | Abstract orbital map | [abstract_map](https://zumerlab.github.io/orbit-docs/examples/abstract_map/) |
269
+ | You see | Because | Fix |
270
+ | --- | --- | --- |
271
+ | Nothing, and the console says *has no size* | The `.bigbang` is 0px wide or tall, usually in a parent that shrinks to fit. | Give the `.bigbang` or its parent a width. |
272
+ | A layout as big as the window | The `.gravity-spot` is not inside a `.bigbang`, so it measures the viewport. | Wrap it in a `.bigbang`. |
273
+ | An empty arc or ring | `value` is not a number, or `max` is not positive. | Fix the attribute; the console names it. |
274
+ | Content overlapping or off the ring | It sits directly in a ring instead of a `.satellite`. | Add `dev-orbit` to see where, then wrap it. |
275
+ | Curved text cut off | The text is longer than its arc. | Shorten it, widen `--o-range`, use `range="auto"`, or `fit-range`. |
276
+ | Everything thin | Elements are one lane thick. | Raise `--o-size-ratio` on the ring or the system. |
277
+ | An arc that ignores clicks | Arcs are decorative by default. | Add `interactive`, and `hit-width` for a bigger target. |
196
278
 
197
- ---
279
+ The reset and the default theme have zero specificity, so a single class of yours always wins, also inside a `.capsule`. `theme-cyan` gives a ready-made cyan look and combines with `dev-orbit`.
198
280
 
199
- ## Use cases
281
+ Orbit needs CSS `sin()`, `cos()` and container query units. Without JavaScript, a CSS fallback still places simple layouts (up to 24 rings and 60 children per type; it also needs `:has()` and `:nth-child(… of …)`); `<o-arc>` and `<o-progress>` always need the runtime.
200
282
 
201
- - **Dashboards:** gauges, status rings, KPIs
202
- - **Automotive / HUD:** speedometers, tachometers, battery, temp
203
- - **IoT / Smart home:** thermostats, energy rings, scenes
204
- - **Ops / monitoring:** status rings, uptime gauges
205
- - **Fitness / health:** activity rings (Move, Exercise, Stand)
206
- - **Controls:** knobs, radial menus, compass
283
+ ## Coming from 1.x
207
284
 
208
- ---
285
+ Version 2 changes where size comes from. In 1.x every system was 500px across, whatever the size of its `.bigbang`, and you needed `Orbit.resize()` to make it responsive. Now `orbit-12` reaches the edge of the `.bigbang`.
286
+
287
+ - **To keep the 1.x size**, set `.gravity-spot { --o-force: 500px }`. `Orbit.resize()` still scales those systems.
288
+ - **To move to the new model**, remove `--o-force` and `Orbit.resize()` and pick rings by their share of the space. A 1.x `orbit-N` in a box `W` px wide lands near `orbit-(N × 500 / W)`, and its thickness near `--o-size-ratio: 500 / W`.
289
+ - A `.bigbang` is a size container, so it is the containing block of `position: fixed` descendants. Directly in `<body>` it is capped at the viewport height instead of forced to it.
290
+ - `.satellite` no longer resets `--o-size-ratio`, so a value on its ring reaches it. `shrink-N` on a ring only changes how close it sits to the previous lane.
291
+ - `--o-gap` cascades from the ring and the system. `--o-aligment` still works; `--o-alignment` is the right spelling.
292
+ - `fit-range` on a ring of arcs no longer overflows the range.
293
+ - Satellites have no border by default. The reset, the default theme and `theme-cyan` have zero specificity apart from their own class, so your styles apply without `!important`.
294
+ - `<o-arc>` and `<o-progress>` are placed with `rotate` instead of `transform`, and endings scale with the band. `interactive` makes the whole band clickable.
295
+ - `variant="stroke"` on `<o-progress>` draws a 2px line over a gray track by default.
296
+
297
+ The [1.x documentation](https://zumerlab.com/orbit-docs/) stays online.
298
+
299
+ ## Demos
300
+
301
+ From a checkout:
302
+
303
+ ```sh
304
+ npm ci
305
+ npm run docs
306
+ ```
209
307
 
210
- ## Using Orbit with AI / LLMs
308
+ Then open <http://127.0.0.1:5174> (`PORT=5175 npm run docs` for another port). That is this repo's documentation site, from `docs/`, running on your local build. Start with [the universe model](docs/demos/00-universe.html): drag the corner of the box and watch the system follow. All the examples are in the gallery, from full pages to small pieces with their code open.
211
309
 
212
- Orbit's radial model is unlike the box-flow layouts most models were trained on,
213
- so an assistant generating Orbit markup from scratch will struggle. Give it the
214
- reference first — these files are written for that purpose:
310
+ The [documentation site](https://zumerlab.com/orbit/) has many more: [gauges](https://zumerlab.com/orbit/examples/gauges/), [charts](https://zumerlab.com/orbit/examples/charts/), [radial menus](https://zumerlab.com/orbit/examples/piemenu.html), [knobs](https://zumerlab.com/orbit/examples/knobs/), [watch faces](https://zumerlab.com/orbit/examples/watches/). [Orbit Kit](https://zumerlab.com/orbit/kit/) has ready-made components built on Orbit.
215
311
 
216
- - **[llms.txt](https://zumerlab.github.io/orbit-docs/llms.txt)** — concise overview, structure rules, quick recipes.
217
- - **[llms-full.txt](https://zumerlab.github.io/orbit-docs/llms-full.txt)** — complete reference: every class, custom property, web component, and copy-paste pattern.
312
+ ## Help and contributing
218
313
 
219
- Paste the relevant one into your prompt (or your tool's context/rules) before
220
- asking the model to build a radial UI.
314
+ Report bugs in [Issues](https://github.com/zumerlab/orbit/issues), share what you made or ask in [Discussions](https://github.com/zumerlab/orbit/discussions), or say hi in the [Telegram group](https://t.me/ZumlyCommunity). To work on Orbit itself, see [CONTRIBUTING.md](CONTRIBUTING.md).
221
315
 
222
- ## Resources
316
+ For coding assistants, [llms.txt](https://zumerlab.com/orbit/llms.txt) is a short reference and [llms-full.txt](https://zumerlab.com/orbit/llms-full.txt) the complete one.
223
317
 
224
- - [orbit-kit](https://zumerlab.com/orbit-kit) — ready-made radial components built on Orbit
225
- - [Full documentation](https://zumerlab.github.io/orbit-docs) — elements, tools, advanced examples
226
- - [Contributing](CONTRIBUTING.md)
227
- - [GitHub Discussions](https://github.com/zumerlab/orbit/discussions)
228
- - [Telegram](https://t.me/ZumlyCommunity)
318
+ ## Sponsor
229
319
 
230
- ---
320
+ Orbit is free and made in spare time. If it saves you time, you can [sponsor it on GitHub](https://github.com/sponsors/tinchox5).
231
321
 
232
322
  ## License
233
323