Orbit Timeline
Overview
Nodes orbit slowly along a track while staying upright; click one to pause and open that stage’s description.
Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Orbit Timeline to your project in your colors.
Where to use it
Dashboards, data tables, chart cards, comparison tables and status panels.
Install
With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.
$ npm i -g @8pt-dev/cli && 8pt add orbit-timeline
mcp › Use 8pt MCP to call get_component("orbit-timeline")
Code
Source for Orbit Timeline. Motion uses only transform and opacity and respects the Reduce motion setting.
<div class="x-orb">
<div class="x-orb__ring">
<button style="--i:0" type="button"><span>Research</span></button>
<button style="--i:1" type="button"><span>Sketch</span></button>
<button style="--i:2" type="button"><span>Components</span></button>
<button style="--i:3" type="button"><span>Test</span></button>
<button style="--i:4" type="button"><span>Launch</span></button>
</div>
<div class="x-orb__core" aria-hidden="true"><svg viewBox="0 0 60 60" width="30" height="30"><path fill="currentColor" fill-rule="evenodd" d="M10.31,60c-5.7,0 -10.31,-4.62 -10.31,-10.31v-20.63c0,-5.7 4.62,-10.31 10.31,-10.31h8.52c-0.06,0.62 -0.08,1.24 -0.08,1.88c0,11.39 9.23,20.63 20.63,20.63c0.63,0 1.26,-0.03 1.88,-0.08v8.52c0,5.7 -4.62,10.31 -10.31,10.31zM30.94,18.75h-12.1c0.95,-10.51 9.78,-18.75 20.54,-18.75c11.39,0 20.63,9.23 20.63,20.63c0,10.76 -8.24,19.59 -18.75,20.54v-12.1c0,-5.7 -4.62,-10.31 -10.31,-10.31z"/></svg></div>
<div class="x-orb__info" aria-live="polite"></div>
</div>.x-orb{position:relative;width:240px;height:240px;color:var(--d-fg,#fff)}
.x-orb::before{content:"";position:absolute;inset:20px;border-radius:50%;border:1px dashed var(--d-line,rgba(255,255,255,.18))}
.x-orb__ring{position:absolute;inset:0;animation:x-orb 30s linear infinite}
.x-orb.paused .x-orb__ring,.x-orb.paused .x-orb__ring span{animation-play-state:paused}
.x-orb__ring button{position:absolute;left:50%;top:50%;width:46px;height:46px;margin:-23px;padding:0;border:0;background:none;cursor:pointer;transform:rotate(calc(var(--i)*72deg)) translateY(-100px) rotate(calc(var(--i)*-72deg))}
.x-orb__ring span{display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--d-card,#101016);border:1px solid var(--d-line,rgba(255,255,255,.14));color:var(--d-fg,#fff);font:600 12px/1 var(--d-font,system-ui,sans-serif);animation:x-orb 30s linear infinite reverse;transition:box-shadow .3s,border-color .3s}
.x-orb__ring button.on span{border-color:var(--d-accent,#4D74FF);box-shadow:0 0 0 4px color-mix(in srgb,var(--d-accent,#4D74FF) 25%,transparent)}
.x-orb__core{position:absolute;left:50%;top:50%;width:64px;height:64px;margin:-32px;display:grid;place-items:center;border-radius:18px;background:var(--d-card,#101016);border:1px solid var(--d-line,rgba(255,255,255,.14));color:var(--d-fg,#fff)}
.x-orb__info{position:absolute;left:50%;bottom:-6px;width:200px;margin-left:-100px;text-align:center;font:13px/1.4 var(--d-font,system-ui,sans-serif);color:var(--d-muted,#a0a0ab);opacity:0;transform:translateY(6px);transition:opacity .3s,transform .3s}
.x-orb__info.on{opacity:1;transform:none}
@keyframes x-orb{to{transform:rotate(1turn)}}const init = (root) => {
const orb = root.querySelector('.x-orb'), info = orb.querySelector('.x-orb__info'), btns = orb.querySelectorAll('.x-orb__ring button');
const notes = ['Understand users and competitors', 'Low-fi, fast iteration', 'Build up reusable parts', 'Walk through the flow on a real device', 'Ship and collect feedback'];
btns.forEach((b, i) => b.addEventListener('click', () => {
const on = !b.classList.contains('on');
btns.forEach(x => x.classList.remove('on')); orb.classList.toggle('paused', on);
if (on) { b.classList.add('on'); info.textContent = notes[i]; }
info.classList.toggle('on', on);
}));
};Subscribe to Builder to see the full source.See pricing