Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
An unhandled error has occurred.
Sedna.UI
v0.31.0 · main

Orb

tier 3 — a surface

What an agent is doing, drawn: an orbit around a focal body, like the mark, that moves the way the work does. The app writes one span with a name and changes one attribute; the library draws the canvas inside it. Nothing around an orb is the library's — the label beside it, the pill it sits in and the button that stops the work are the app's own markup.

Nothing goes in the host page Sedna.UI.js finds every [data-orb] and imports its drawing the first time one comes within a screen of the viewport, so a page without an orb never downloads it. Every attribute, size and colour role is in docs/orb.md.

States

data-orb names what the agent is doing, and changing it is the whole API: the drawing changes with it. waiting, error and done are the three a reader acts on, and pick their own colour family — warn, danger and go — so they are not mistaken for work still running.

The name is the app's. The orb draws no words; aria-label is its text alternative, and role="img" is added for you if it is missing. Name what the reader would want to hear, not the attribute: “Waiting for your approval”, not “waiting”.

idle
thinking
searching
working
listening
speaking
waiting
error
done
<div class="sedna-row-wrap sedna-gap-3" style="row-gap: var(--space-6)">
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="idle" role="img" aria-label="Idle"></span>
        <code>idle</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="thinking" role="img" aria-label="Thinking"></span>
        <code>thinking</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="searching" role="img" aria-label="Searching"></span>
        <code>searching</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="working" role="img" aria-label="Working"></span>
        <code>working</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="listening" role="img" aria-label="Listening"></span>
        <code>listening</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="speaking" role="img" aria-label="Speaking"></span>
        <code>speaking</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="waiting" role="img" aria-label="Waiting for you"></span>
        <code>waiting</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="error" role="img" aria-label="Stopped on an error"></span>
        <code>error</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="done" role="img" aria-label="Done"></span>
        <code>done</code>
    </div>
</div>

Activities

What the agent is busy with, where the state alone would say only “working”: solving, writing, connecting, planning, shaping, reading, remembering, syncing and analyzing. The same attribute and the same three drawings by size.

solving
writing
connecting
planning
shaping
reading
remembering
syncing
analyzing
<div class="sedna-row-wrap sedna-gap-3" style="row-gap: var(--space-6)">
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="solving" role="img" aria-label="Solving"></span>
        <code>solving</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="writing" role="img" aria-label="Writing"></span>
        <code>writing</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="connecting" role="img" aria-label="Connecting sources"></span>
        <code>connecting</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="planning" role="img" aria-label="Planning"></span>
        <code>planning</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="shaping" role="img" aria-label="Shaping"></span>
        <code>shaping</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="reading" role="img" aria-label="Reading"></span>
        <code>reading</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="remembering" role="img" aria-label="Remembering"></span>
        <code>remembering</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="syncing" role="img" aria-label="Syncing"></span>
        <code>syncing</code>
    </div>
    <div class="sedna-col sedna-center sedna-gap-1" style="width:120px">
        <span class="orb orb--lg" data-orb="analyzing" role="img" aria-label="Analyzing"></span>
        <code>analyzing</code>
    </div>
</div>

Sizes

.orb--xs (16px), --sm (20px), the bare .orb (32px), --md (48px), --lg (64px), --xl (96px) and --hero (220px); --orb-size sets any other. The same scene is drawn three ways rather than scaled, like the brand mark: below 28px the orbits are solid lines, because dots that small read as noise; from 28px they are dots; from 72px finer and denser.

--xs
--sm
.orb
--md
--lg
--xl
<div class="sedna-row-wrap sedna-gap-3" style="align-items: end">
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--xs" data-orb="thinking" role="img" aria-label="Thinking"></span><code>--xs</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--sm" data-orb="thinking" role="img" aria-label="Thinking"></span><code>--sm</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb" data-orb="thinking" role="img" aria-label="Thinking"></span><code>.orb</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="thinking" role="img" aria-label="Thinking"></span><code>--md</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--lg" data-orb="thinking" role="img" aria-label="Thinking"></span><code>--lg</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--xl" data-orb="thinking" role="img" aria-label="Thinking"></span><code>--xl</code></div>
</div>

Where a page waits on the agent

.orb--hero for the one thing on screen while the agent works, a voice session or a first answer. Pair it with a line in the app's words. An orb starts drawing as it comes within a screen of the viewport; data-orb-eager starts it at once, for one that is the first thing the page shows.

Searching the runbook
<div class="sedna-col sedna-center sedna-gap-2">
    <span class="orb orb--hero" data-orb="searching" data-orb-eager role="img" aria-label="Searching the runbook"></span>
    <span class="text-muted">Searching the runbook</span>
</div>

Tones

data-orb-tone re-points the three colour roles: brand for the app's own brand colour, mono for a dense table where colour would compete, and go, warn and danger for a state the app wants to stress. Without one, an orb is in the agent colours, --agent-from and --agent-to. Every colour is read through the element in the browser, so a theme, the colour-blind palette, contrast and forced colours all reach the canvas.

default
brand
mono
go
warn
danger
<div class="sedna-row-wrap sedna-gap-3">
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" role="img" aria-label="Working"></span><code>default</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" data-orb-tone="brand" role="img" aria-label="Working"></span><code>brand</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" data-orb-tone="mono" role="img" aria-label="Working"></span><code>mono</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" data-orb-tone="go" role="img" aria-label="Working"></span><code>go</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" data-orb-tone="warn" role="img" aria-label="Working"></span><code>warn</code></div>
    <div class="sedna-col sedna-center sedna-gap-1"><span class="orb orb--md" data-orb="working" data-orb-tone="danger" role="img" aria-label="Working"></span><code>danger</code></div>
</div>

In a line of text

.orb--inline takes the size of the text around it and sits on its x-height.

Research agent is reading three sources, and will wait for you before it writes anything.

<p class="text-lg" style="margin: 0">
    Research agent is <span class="orb orb--inline" data-orb="searching" role="img" aria-label="searching"></span>
    reading three sources, and will <span class="orb orb--inline" data-orb="waiting" role="img" aria-label="waiting"></span>
    <span>wait for you before it writes anything.</span>
</p>

Following a voice

listening and speaking follow --level, from 0 to 1, read from the orb or any element above it. It is the same number the app writes for the voice bars, the mic button, an agent avatar and Mochi, so one write moves everything that shows the voice. Without one they move gently on their own.

Motion

An orb draws one still frame the moment it starts, at the point in its state where the drawing says what it is: the tick drawn, the scan part way across. After that one clock draws every orb on screen while the tab is visible. Under prefers-reduced-motion the still frame is all there is, and a change of state draws a new one. With scripting off, the span is a still focal body inside one orbit — something is there, and it is an agent.