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

Workflow

tier 2 — classes

A run through a process, drawn as a diagram: what has happened, what is happening now, what comes next, and which way each decision went. Every node is markup the app writes, so a node can carry anything else in the library — an orb, a confidence, a progress bar, the caller's words. The wires between them are drawn from the structure and take their state from the step they lead into, so the app writes one attribute per step and nothing at all on a wire. No script.

A run

ol.workflow is the run, each li.workflow-step one step holding a .workflow-node, and an li.workflow-fork a place where the run splits into .workflow-branches, each with its own ol.workflow-path. The structure is the diagram: the list a screen reader walks is the same list the wires are drawn from.

The trail is the story. Wires behind the step at work are solid go, the wire into it carries a moving light, and the ones ahead are quiet — so a reader sees where the run has been and where it is without reading a node. A diagram wider than its container scrolls, so it takes tabindex="0" for the keyboard, and data-follow keeps the step at work in view: the diagram scrolls to it as states change, lets go when the reader scrolls away, and takes up again when they scroll back. A data-workflow-follow button brings the step back and follows again — the diagram its aria-controls names.

T-48213 · Card terminals down at store 14 Deciding where it goes0:04
  1. Ticket created By the voice agent · 09:41 Done.
    1. Assess severity Agent · 2.1 s Done.
      P1, sure
    1. Categorise Agent · 1.4 s Done.
      Network › Store link, fairly sure
    1. Find related Search · 0.8 s Done.
    2. 2 matches
      Link the pattern Agent · 1.9 s Done.

      Stores 9 and 21 reported the same in the last 15 minutes.

  2. Decide where it goes Agent · 0:04 Running.

    Weighing the on-call rota against the outage pattern

  3. Urgent
    1. Page on call Push to the rota Next.
    Can wait
    1. Queue for the morning Network team
  4. Update the ticket Priority, category, summary
  5. Handed over
<div class="card">
    <div class="card-head">
        <strong>T-48213 &middot; Card terminals down at store 14</strong>
        <span class="agent-status"><span class="orb" data-orb="thinking" role="img" aria-label="Thinking"></span><span class="agent-status-label text-shimmer">Deciding where it goes</span><span class="agent-status-time">0:04</span></span>
        <button class="btn btn--sm btn--ghost" type="button" data-workflow-follow aria-controls="run-48213"><i class="ri-focus-3-line"></i> <span>Step at work</span></button>
    </div>
    <ol class="workflow workflow--grid" id="run-48213" tabindex="0" data-follow aria-label="Ticket T-48213, from the call to the engineer on call">
        <li class="workflow-step" data-state="done">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                    <span class="workflow-node-title">Ticket created</span>
                    <span class="workflow-node-meta">By the voice agent &middot; 09:41 <span class="visually-hidden">Done.</span></span>
                </header>
            </article>
        </li>
        <li class="workflow-fork">
            <div class="workflow-branch">
                <ol class="workflow-path">
                    <li class="workflow-step" data-state="done">
                        <article class="workflow-node workflow-node--agent">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span>
                                <span class="workflow-node-title">Assess severity</span>
                                <span class="workflow-node-meta">Agent &middot; 2.1 s <span class="visually-hidden">Done.</span></span>
                            </header>
                            <span class="confidence" data-level="3"><span class="confidence-bars"><i></i><i></i><i></i></span><span>P1, sure</span></span>
                        </article>
                    </li>
                </ol>
            </div>
            <div class="workflow-branch">
                <ol class="workflow-path">
                    <li class="workflow-step" data-state="done">
                        <article class="workflow-node workflow-node--agent">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-price-tag-3-line"></i></span>
                                <span class="workflow-node-title">Categorise</span>
                                <span class="workflow-node-meta">Agent &middot; 1.4 s <span class="visually-hidden">Done.</span></span>
                            </header>
                            <span class="confidence" data-level="2"><span class="confidence-bars"><i></i><i></i><i></i></span><span>Network &rsaquo; Store link, fairly sure</span></span>
                        </article>
                    </li>
                </ol>
            </div>
            <div class="workflow-branch">
                <ol class="workflow-path">
                    <li class="workflow-step" data-state="done">
                        <article class="workflow-node">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon series-4"><i class="ri-git-merge-line"></i></span>
                                <span class="workflow-node-title">Find related</span>
                                <span class="workflow-node-meta">Search &middot; 0.8 s <span class="visually-hidden">Done.</span></span>
                            </header>
                        </article>
                    </li>
                    <li class="workflow-step" data-state="done">
                        <span class="workflow-label">2 matches</span>
                        <article class="workflow-node workflow-node--agent">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-links-line"></i></span>
                                <span class="workflow-node-title">Link the pattern</span>
                                <span class="workflow-node-meta">Agent &middot; 1.9 s <span class="visually-hidden">Done.</span></span>
                            </header>
                            <p class="workflow-node-now">Stores 9 and 21 reported the same in the last 15 minutes.</p>
                        </article>
                    </li>
                </ol>
            </div>
        </li>
        <li class="workflow-step" data-state="running">
            <article class="workflow-node workflow-node--agent">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-route-line"></i></span>
                    <span class="workflow-node-title">Decide where it goes</span>
                    <span class="workflow-node-meta">Agent &middot; 0:04 <span class="visually-hidden">Running.</span></span>
                </header>
                <p class="workflow-node-now text-shimmer">Weighing the on-call rota against the outage pattern</p>
            </article>
        </li>
        <li class="workflow-fork workflow-fork--decision">
            <div class="workflow-branch">
                <span class="workflow-label">Urgent</span>
                <ol class="workflow-path">
                    <li class="workflow-step" data-state="next">
                        <article class="workflow-node">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon series-danger"><i class="ri-alarm-warning-line"></i></span>
                                <span class="workflow-node-title">Page on call</span>
                                <span class="workflow-node-meta">Push to the rota <span class="visually-hidden">Next.</span></span>
                            </header>
                        </article>
                    </li>
                </ol>
            </div>
            <div class="workflow-branch">
                <span class="workflow-label">Can wait</span>
                <ol class="workflow-path">
                    <li class="workflow-step">
                        <article class="workflow-node">
                            <header class="workflow-node-head">
                                <span class="workflow-node-icon series-3"><i class="ri-inbox-archive-line"></i></span>
                                <span class="workflow-node-title">Queue for the morning</span>
                                <span class="workflow-node-meta">Network team</span>
                            </header>
                        </article>
                    </li>
                </ol>
            </div>
        </li>
        <li class="workflow-step">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-2"><i class="ri-edit-box-line"></i></span>
                    <span class="workflow-node-title">Update the ticket</span>
                    <span class="workflow-node-meta">Priority, category, summary</span>
                </header>
            </article>
        </li>
        <li class="workflow-step">
            <span class="workflow-end"><i class="ri-flag-line"></i><span>Handed over</span></span>
        </li>
    </ol>
</div>

The state of a step

data-state on the <li> — done, waiting, running, failed, next or skipped, and nothing at all for a step not reached yet. Put it on the step, never the node: the wire into the step reads it too. waiting is a step that has been reached and is held up by someone outside the run — a caller answering, a person approving — which is a different thing to tell a reader from a step still working.

The paint is not the words. A screen reader hears the list, not the tick, so say the state in the meta line or in a .visually-hidden span, as the first example does.

  1. Done done
  2. Waiting waiting
  3. Running running
  4. Failed failed
  1. Next next
  2. Not reached no data-state
  3. Skipped skipped
<div class="sedna-col sedna-gap-3">
    <ol class="workflow workflow--sm" tabindex="0" aria-label="States of a step that has been reached">
        <li class="workflow-step" data-state="done">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-go"><i class="ri-check-line"></i></span>
                    <span class="workflow-node-title">Done</span>
                    <span class="workflow-node-meta">done</span>
                </header>
            </article>
        </li>
        <li class="workflow-step" data-state="waiting">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-warn"><i class="ri-user-voice-line"></i></span>
                    <span class="workflow-node-title">Waiting</span>
                    <span class="workflow-node-meta">waiting</span>
                </header>
            </article>
        </li>
        <li class="workflow-step" data-state="running">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-2"><i class="ri-loader-4-line"></i></span>
                    <span class="workflow-node-title">Running</span>
                    <span class="workflow-node-meta">running</span>
                </header>
            </article>
        </li>
        <li class="workflow-step" data-state="failed">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon series-danger"><i class="ri-error-warning-line"></i></span>
                    <span class="workflow-node-title">Failed</span>
                    <span class="workflow-node-meta">failed</span>
                </header>
            </article>
        </li>
    </ol>
    <ol class="workflow workflow--sm" tabindex="0" aria-label="States of a step that has not been reached">
        <li class="workflow-step" data-state="next">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon"><i class="ri-arrow-right-line"></i></span>
                    <span class="workflow-node-title">Next</span>
                    <span class="workflow-node-meta">next</span>
                </header>
            </article>
        </li>
        <li class="workflow-step">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon"><i class="ri-time-line"></i></span>
                    <span class="workflow-node-title">Not reached</span>
                    <span class="workflow-node-meta">no data-state</span>
                </header>
            </article>
        </li>
        <li class="workflow-step" data-state="skipped">
            <article class="workflow-node">
                <header class="workflow-node-head">
                    <span class="workflow-node-icon"><i class="ri-skip-forward-line"></i></span>
                    <span class="workflow-node-title">Skipped</span>
                    <span class="workflow-node-meta">skipped</span>
                </header>
            </article>
        </li>
    </ol>
</div>

The step at work

A step at work wears one of three looks, chosen on its node: its edge in the light’s colour with a ring, by default; .workflow-node--glow, the same edge with a glow; or .workflow-node--agent, the agent’s two colours and glow, for a step an agent is doing. Put the class on the node whatever its state — the look shows only while the step is at work, so an app writes it once, from what the step is, and never from where the run is.

The wires never wear the agent’s colours. What runs along them is data, whichever kind of step sent it.

  1. Look up the store Asset database · running
  1. Notify the store Mail · running
  1. Decide where it goes Agent · running
<ol class="workflow workflow--sm" tabindex="0" aria-label="Three steps at work, one in each look">
    <li class="workflow-step" data-state="running">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-database-2-line"></i></span>
                <span class="workflow-node-title">Look up the store</span>
                <span class="workflow-node-meta">Asset database &middot; running</span>
            </header>
        </article>
    </li>
</ol>

<ol class="workflow workflow--sm" tabindex="0" aria-label="A step at work with a glow">
    <li class="workflow-step" data-state="running">
        <article class="workflow-node workflow-node--glow">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-4"><i class="ri-mail-send-line"></i></span>
                <span class="workflow-node-title">Notify the store</span>
                <span class="workflow-node-meta">Mail &middot; running</span>
            </header>
        </article>
    </li>
</ol>

<ol class="workflow workflow--sm" tabindex="0" aria-label="An agent's step at work">
    <li class="workflow-step" data-state="running">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-sparkling-2-line"></i></span>
                <span class="workflow-node-title">Decide where it goes</span>
                <span class="workflow-node-meta">Agent &middot; running</span>
            </header>
        </article>
    </li>
</ol>

What a node carries

.workflow-node-head is the one fixed part: whatever leads it — a .workflow-node-icon tile, an .orb, an .avatar — then .workflow-node-title and .workflow-node-meta. A .series-* class on the tile colours it, and .workflow-node-icon--agent paints it in the agent's colours, so the steps an agent takes stand apart from the ones a tool does.

Everything after the head is the node's body, spaced for you: .workflow-node-now for what it is doing in a line or two — with .text-shimmer while the words are still a guess — a .progress, chips, a .confidence, and .workflow-node-foot for the small print. Every wire meets the head's centre line, so nodes of any height still join in a straight line.

  1. Create a ticket
  2. Check the runbook Knowledge base · 0.6 s

    No fix on record for “host unreachable” at a single store.

  3. Read the store's link Agent · 0:09

    Comparing packet loss with the other stores in the region

    12 of 20 stores orders-console-01
  4. Write the summary Agent
    Ticket Call transcript
<ol class="workflow" tabindex="0" aria-label="Four nodes, from the least to the most a node can carry">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                <span class="workflow-node-title">Create a ticket</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-4"><i class="ri-book-2-line"></i></span>
                <span class="workflow-node-title">Check the runbook</span>
                <span class="workflow-node-meta">Knowledge base &middot; 0.6 s</span>
            </header>
            <p class="workflow-node-now">No fix on record for &ldquo;host unreachable&rdquo; at a single store.</p>
        </article>
    </li>
    <li class="workflow-step" data-state="running">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="orb" data-orb="analyzing" role="img" aria-label="Analysing"></span>
                <span class="workflow-node-title">Read the store's link</span>
                <span class="workflow-node-meta">Agent &middot; 0:09</span>
            </header>
            <p class="workflow-node-now text-shimmer">Comparing packet loss with the other stores in the region</p>
            <div class="progress" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" aria-label="Stores compared"><div class="progress-bar" style="width: 60%"></div></div>
            <div class="workflow-node-foot">
                <span>12 of 20 stores</span>
                <span class="sedna-push">orders-console-01</span>
            </div>
        </article>
    </li>
    <li class="workflow-step">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-quill-pen-line"></i></span>
                <span class="workflow-node-title">Write the summary</span>
                <span class="workflow-node-meta">Agent</span>
            </header>
            <div class="chip-set">
                <span class="chip"><span class="chip-label">Ticket</span></span>
                <span class="chip"><span class="chip-label">Call transcript</span></span>
            </div>
        </article>
    </li>
</ol>

Steps that run side by side

A .workflow-fork followed by a step joins again: the bracket on the right gathers its branches into the next step, and a short branch's wire runs on to meet it. Nothing is written on a bracket. The piece down to each branch lights once that branch has been reached, and the piece back up once its last step is done, so a reader can see which branch the join is still waiting for.

  1. Ticket created T-48213
    1. Assess severity P1 · done
    1. Find related 2 matches · done
    2. Link the pattern Agent · running
    1. Categorise Store link · done
  2. Update the ticket Waits for all three
<ol class="workflow workflow--sm" tabindex="0" aria-label="Triage: three checks run side by side, then the ticket is updated">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                <span class="workflow-node-title">Ticket created</span>
                <span class="workflow-node-meta">T-48213</span>
            </header>
        </article>
    </li>
    <li class="workflow-fork">
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span>
                            <span class="workflow-node-title">Assess severity</span>
                            <span class="workflow-node-meta">P1 &middot; done</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon series-4"><i class="ri-git-merge-line"></i></span>
                            <span class="workflow-node-title">Find related</span>
                            <span class="workflow-node-meta">2 matches &middot; done</span>
                        </header>
                    </article>
                </li>
                <li class="workflow-step" data-state="running">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-links-line"></i></span>
                            <span class="workflow-node-title">Link the pattern</span>
                            <span class="workflow-node-meta">Agent &middot; running</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-price-tag-3-line"></i></span>
                            <span class="workflow-node-title">Categorise</span>
                            <span class="workflow-node-meta">Store link &middot; done</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-edit-box-line"></i></span>
                <span class="workflow-node-title">Update the ticket</span>
                <span class="workflow-node-meta">Waits for all three</span>
            </header>
        </article>
    </li>
</ol>

A decision

.workflow-fork--decision is a fork where one branch is chosen. Mark it data-state="taken" and the others data-state="skipped": a skipped branch goes quiet, dashed and grey, with no state written on any step inside it. A .workflow-label first in a branch is the case it is for, on its wire.

A fork that ends its path does not join; each branch ends where its last step does. Before the choice is made, leave both branches unmarked.

  1. Fixed on the call? No · still down
  2. Yes
    1. Confirm and close Not taken
    No
    1. Open a ticket T-48213 · done
    2. Read it back Voice agent · speaking
<ol class="workflow workflow--sm" tabindex="0" aria-label="The agent could not fix it on the call, so it opened a ticket">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-question-line"></i></span>
                <span class="workflow-node-title">Fixed on the call?</span>
                <span class="workflow-node-meta">No &middot; still down</span>
            </header>
        </article>
    </li>
    <li class="workflow-fork workflow-fork--decision">
        <div class="workflow-branch" data-state="skipped">
            <span class="workflow-label">Yes</span>
            <ol class="workflow-path">
                <li class="workflow-step">
                    <article class="workflow-node">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon series-go"><i class="ri-chat-check-line"></i></span>
                            <span class="workflow-node-title">Confirm and close</span>
                            <span class="workflow-node-meta">Not taken</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch" data-state="taken">
            <span class="workflow-label">No</span>
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                            <span class="workflow-node-title">Open a ticket</span>
                            <span class="workflow-node-meta">T-48213 &middot; done</span>
                        </header>
                    </article>
                </li>
                <li class="workflow-step" data-state="running">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-voiceprint-line"></i></span>
                            <span class="workflow-node-title">Read it back</span>
                            <span class="workflow-node-meta">Voice agent &middot; speaking</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
    </li>
</ol>

Steps that repeat

li.workflow-loop holds the path that repeats — a turn of a conversation, a retry — and draws the way back under it. .workflow-loop-count on the way back says how many times, in your words. data-state on the loop colours the way back, and the steps inside take their own: show the turn in progress, not every turn so far.

  1. Call in
    1. Ask “Is the router lit?”
    2. Listen Waiting for the caller
    3. Check the runbook Knowledge base
    Turn 2
  2. Fixed, or a ticket
<ol class="workflow workflow--sm" tabindex="0" aria-label="Troubleshooting with the caller, one question at a time">
    <li class="workflow-step" data-state="done">
        <span class="workflow-end"><i class="ri-phone-line"></i><span>Call in</span></span>
    </li>
    <li class="workflow-loop" data-state="running">
        <ol class="workflow-path">
            <li class="workflow-step" data-state="done">
                <article class="workflow-node workflow-node--agent">
                    <header class="workflow-node-head">
                        <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-question-answer-line"></i></span>
                        <span class="workflow-node-title">Ask</span>
                        <span class="workflow-node-meta">&ldquo;Is the router lit?&rdquo;</span>
                    </header>
                </article>
            </li>
            <li class="workflow-step" data-state="waiting">
                <article class="workflow-node">
                    <header class="workflow-node-head">
                        <span class="workflow-node-icon series-warn"><i class="ri-user-voice-line"></i></span>
                        <span class="workflow-node-title">Listen</span>
                        <span class="workflow-node-meta">Waiting for the caller</span>
                    </header>
                </article>
            </li>
            <li class="workflow-step">
                <article class="workflow-node">
                    <header class="workflow-node-head">
                        <span class="workflow-node-icon series-4"><i class="ri-book-2-line"></i></span>
                        <span class="workflow-node-title">Check the runbook</span>
                        <span class="workflow-node-meta">Knowledge base</span>
                    </header>
                </article>
            </li>
        </ol>
        <span class="workflow-loop-count"><i class="ri-repeat-line"></i><span>Turn 2</span></span>
    </li>
    <li class="workflow-step">
        <span class="workflow-end"><i class="ri-flag-line"></i><span>Fixed, or a ticket</span></span>
    </li>
</ol>

Starts, ends and what was handed on

.workflow-end stands in for a node where a run starts or stops; done, it turns go. A .workflow-label first in a step is what was passed along the wire into it — a transcript, a ticket number, three articles — which is often the one thing a reader wants to know about a hand-off.

  1. Call ended
  2. Transcript
    Summarise the call Agent · 3.0 s
  3. T-48213
    Attach articles Knowledge base
  4. 3 articles Ticket ready
<ol class="workflow workflow--sm" tabindex="0" aria-label="What each step handed to the next">
    <li class="workflow-step" data-state="done">
        <span class="workflow-end"><i class="ri-phone-line"></i><span>Call ended</span></span>
    </li>
    <li class="workflow-step" data-state="done">
        <span class="workflow-label"><i class="ri-chat-voice-line"></i><span>Transcript</span></span>
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-quill-pen-line"></i></span>
                <span class="workflow-node-title">Summarise the call</span>
                <span class="workflow-node-meta">Agent &middot; 3.0 s</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="done">
        <span class="workflow-label">T-48213</span>
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-4"><i class="ri-book-2-line"></i></span>
                <span class="workflow-node-title">Attach articles</span>
                <span class="workflow-node-meta">Knowledge base</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="done">
        <span class="workflow-label">3 articles</span>
        <span class="workflow-end"><i class="ri-checkbox-circle-line"></i><span>Ticket ready</span></span>
    </li>
</ol>

Top to bottom

.workflow--down runs the diagram down the page for a phone, a tablet held upright or a side panel. Nodes take the width they are given, and the wire runs down a rail through their icons. A fork hangs its branches off the rail, indented like a tree, and the rail runs on past them to the next step; a loop draws its way back up its right-hand side. The markup is the same as across — only the class differs.

.workflow--auto is across on a wide screen and down below 640px, so one diagram serves a desk and a phone; the live run’s detail uses it. With data-follow in a box of fixed height, a diagram run down keeps the step at work in view by scrolling down instead of across.

  1. Call in
  2. Identify the callerAlex Fischer, store 14
    1. AskVoice agent
    2. Look it upRunbook
    2
  3. Fixed
    1. Confirm and close
    Not fixed
    1. Create a ticketT-48213
    1. Assess severityP1
    1. CategoriseAgent
  4. 3 checks
    Decide where it goesAgent
  5. Handed over
<div style="max-width: 380px; margin-inline: auto">
    <ol class="workflow workflow--down workflow--sm" tabindex="0" aria-label="Card terminals down at store 14, on a phone">
      <li class="workflow-step" data-state="done"><span class="workflow-end"><i class="ri-phone-line"></i><span>Call in</span></span></li>
      <li class="workflow-step" data-state="done">
        <article class="workflow-node workflow-node--agent"><header class="workflow-node-head"><span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-user-search-line"></i></span><span class="workflow-node-title">Identify the caller</span><span class="workflow-node-meta">Alex Fischer, store 14</span></header></article>
      </li>
      <li class="workflow-loop" data-state="done">
        <ol class="workflow-path">
          <li class="workflow-step" data-state="done"><article class="workflow-node workflow-node--agent"><header class="workflow-node-head"><span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-question-answer-line"></i></span><span class="workflow-node-title">Ask</span><span class="workflow-node-meta">Voice agent</span></header></article></li>
          <li class="workflow-step" data-state="done"><article class="workflow-node"><header class="workflow-node-head"><span class="workflow-node-icon series-4"><i class="ri-book-2-line"></i></span><span class="workflow-node-title">Look it up</span><span class="workflow-node-meta">Runbook</span></header></article></li>
        </ol>
        <span class="workflow-loop-count"><i class="ri-repeat-line"></i><span>2</span></span>
      </li>
      <li class="workflow-fork workflow-fork--decision">
        <div class="workflow-branch" data-state="skipped"><span class="workflow-label">Fixed</span><ol class="workflow-path"><li class="workflow-step"><span class="workflow-end"><i class="ri-chat-check-line"></i><span>Confirm and close</span></span></li></ol></div>
        <div class="workflow-branch" data-state="taken"><span class="workflow-label">Not fixed</span><ol class="workflow-path">
          <li class="workflow-step" data-state="done"><article class="workflow-node"><header class="workflow-node-head"><span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span><span class="workflow-node-title">Create a ticket</span><span class="workflow-node-meta">T-48213</span></header></article></li>
        </ol></div>
      </li>
      <li class="workflow-fork">
        <div class="workflow-branch"><ol class="workflow-path"><li class="workflow-step" data-state="done"><article class="workflow-node workflow-node--agent"><header class="workflow-node-head"><span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span><span class="workflow-node-title">Assess severity</span><span class="workflow-node-meta">P1</span></header></article></li></ol></div>
        <div class="workflow-branch"><ol class="workflow-path"><li class="workflow-step" data-state="running"><article class="workflow-node workflow-node--agent"><header class="workflow-node-head"><span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-price-tag-3-line"></i></span><span class="workflow-node-title">Categorise</span><span class="workflow-node-meta">Agent</span></header></article></li></ol></div>
      </li>
      <li class="workflow-step" data-state="next">
        <span class="workflow-label">3 checks</span>
        <article class="workflow-node workflow-node--agent"><header class="workflow-node-head"><span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-route-line"></i></span><span class="workflow-node-title">Decide where it goes</span><span class="workflow-node-meta">Agent</span></header></article>
      </li>
      <li class="workflow-step"><span class="workflow-end"><i class="ri-flag-line"></i><span>Handed over</span></span></li>
    </ol>
</div>

How much moves

One streak of light at a time leaves the step before the one at work and runs the whole way into it — down a fork’s bracket into every branch at work, up a join’s bracket from every branch into the step after it — at one speed, round every bend, in one piece. The step at work is what the reader watches, so the light stays quiet. .workflow--flow-off stills it to a lit line.

--workflow-flow-speed makes it slower or faster (0.5 is half the pace) and --workflow-flow-packets sparser or denser at the same pace (2 is twice as many). Set them on the diagram. The live run has a control for each.

  1. Ticket created T-48213
    1. Assess severity P1 · done
    1. Categorise Agent · running
  2. Update the ticket Waits for both
  1. Ticket created T-48213
    1. Assess severity P1 · done
    1. Categorise Agent · running
  2. Update the ticket Waits for both
<ol class="workflow workflow--sm" style="--workflow-flow-speed: 0.5; --workflow-flow-packets: 2" tabindex="0" aria-label="Triage, with the light at half the pace and twice as dense">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                <span class="workflow-node-title">Ticket created</span>
                <span class="workflow-node-meta">T-48213</span>
            </header>
        </article>
    </li>
    <li class="workflow-fork">
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span>
                            <span class="workflow-node-title">Assess severity</span>
                            <span class="workflow-node-meta">P1 &middot; done</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="running">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-price-tag-3-line"></i></span>
                            <span class="workflow-node-title">Categorise</span>
                            <span class="workflow-node-meta">Agent &middot; running</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-edit-box-line"></i></span>
                <span class="workflow-node-title">Update the ticket</span>
                <span class="workflow-node-meta">Waits for both</span>
            </header>
        </article>
    </li>
</ol>

<ol class="workflow workflow--sm workflow--flow-off" tabindex="0" aria-label="Triage, with the light still">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                <span class="workflow-node-title">Ticket created</span>
                <span class="workflow-node-meta">T-48213</span>
            </header>
        </article>
    </li>
    <li class="workflow-fork">
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span>
                            <span class="workflow-node-title">Assess severity</span>
                            <span class="workflow-node-meta">P1 &middot; done</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="running">
                    <article class="workflow-node workflow-node--agent">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-price-tag-3-line"></i></span>
                            <span class="workflow-node-title">Categorise</span>
                            <span class="workflow-node-meta">Agent &middot; running</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-edit-box-line"></i></span>
                <span class="workflow-node-title">Update the ticket</span>
                <span class="workflow-node-meta">Waits for both</span>
            </header>
        </article>
    </li>
</ol>

An overview

The same classes at another height. A handful of stages, each standing for a diagram of its own, is how a run reads to someone who will never open a step: .workflow--lg sizes everything up for a room, and .workflow--fill shares the width out so the overview fits instead of scrolling. .workflow--sm is the other way, for a diagram in a panel, and .workflow--xl further still, for a wall screen. A single node can be widened with --workflow-node on its step.

.workflow--focus is for showing rather than reading: every step keeps only its head except the one at work, which opens wider with everything in it. Write the detail into every node; the diagram shows it for the step that is happening. The wall screen is the two together.

  1. Call 4:12 with the caller
  2. Ticket T-48213, P1
  3. Triage Agent · 0:12

    Three stores, one region: an outage

  4. On call Rin Nakamura
<ol class="workflow workflow--lg workflow--fill" tabindex="0" aria-label="Card terminals down at store 14: where the request is now">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-customer-service-2-line"></i></span>
                <span class="workflow-node-title">Call</span>
                <span class="workflow-node-meta">4:12 with the caller</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-coupon-3-line"></i></span>
                <span class="workflow-node-title">Ticket</span>
                <span class="workflow-node-meta">T-48213, P1</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="running">
        <article class="workflow-node workflow-node--agent">
            <header class="workflow-node-head">
                <span class="orb" data-orb="thinking" role="img" aria-label="Thinking"></span>
                <span class="workflow-node-title">Triage</span>
                <span class="workflow-node-meta">Agent &middot; 0:12</span>
            </header>
            <p class="workflow-node-now text-shimmer">Three stores, one region: an outage</p>
        </article>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-danger"><i class="ri-alarm-warning-line"></i></span>
                <span class="workflow-node-title">On call</span>
                <span class="workflow-node-meta">Rin Nakamura</span>
            </header>
        </article>
    </li>
</ol>

A run that is no agent's

Nothing in a workflow is about agents. A release, a production line, a delivery, an onboarding — any run of steps with states is drawn the same way. The trail and the light are knobs on the .workflow: --workflow-trail for the way the run went, and --workflow-flow, --workflow-flow-line, --workflow-flow-tint and --workflow-flow-glow for the data flowing into the step at work and that step’s edge. Set them from tokens, as here in the brand’s colours.

  1. Build a3f9c1e · 3:12
    1. Unit tests 1,204 passed
    1. Security scan No findings
  2. v2.14.1
    Deploy to staging 12 of 30 smoke tests
  3. Production Needs approval
<ol class="workflow workflow--sm" tabindex="0" aria-label="Release 2.14.1, stage by stage"
    style="--workflow-trail: var(--info-solid); --workflow-flow: var(--brand-soft); --workflow-flow-line: var(--brand-tint-strong); --workflow-flow-tint: var(--brand-tint); --workflow-flow-glow: var(--brand-glow)">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-1"><i class="ri-hammer-line"></i></span>
                <span class="workflow-node-title">Build</span>
                <span class="workflow-node-meta">a3f9c1e &middot; 3:12</span>
            </header>
        </article>
    </li>
    <li class="workflow-fork">
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon series-4"><i class="ri-flask-line"></i></span>
                            <span class="workflow-node-title">Unit tests</span>
                            <span class="workflow-node-meta">1,204 passed</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
        <div class="workflow-branch">
            <ol class="workflow-path">
                <li class="workflow-step" data-state="done">
                    <article class="workflow-node">
                        <header class="workflow-node-head">
                            <span class="workflow-node-icon series-4"><i class="ri-shield-check-line"></i></span>
                            <span class="workflow-node-title">Security scan</span>
                            <span class="workflow-node-meta">No findings</span>
                        </header>
                    </article>
                </li>
            </ol>
        </div>
    </li>
    <li class="workflow-step" data-state="running">
        <span class="workflow-label">v2.14.1</span>
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-3"><i class="ri-rocket-2-line"></i></span>
                <span class="workflow-node-title">Deploy to staging</span>
                <span class="workflow-node-meta">12 of 30 smoke tests</span>
            </header>
        </article>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-3"><i class="ri-earth-line"></i></span>
                <span class="workflow-node-title">Production</span>
                <span class="workflow-node-meta">Needs approval</span>
            </header>
        </article>
    </li>
</ol>

Why it chose

ol.workflow-decision is the options a step weighed, a .meter each, the score, and .workflow-decision-why under it. data-state="chosen" ticks the winner; "rejected" quiets the rest but keeps them readable, because why the others lost is half of the explanation. Pair it with the .reasoning behind it.

Where the ticket goes Decided by the agent
  1. Page the on-call engineer (chosen) 0.86 Three stores in one region within 15 minutes, out of hours: an outage, not a fault.
  2. Queue for the network team 0.31 The team starts at 07:00; the tills would be down for nine hours.
  3. Close as a known issue 0.08
Thought for 3 s

One store losing its link is a fault for the morning. Three stores in the same region within a quarter of an hour is the regional uplink, and nobody can fix that from a store.

It is 21:40 and the stores close at 22:00, but they open at 07:00 and cannot take cards until the link is back. That is worth waking someone for.

<div class="card" style="max-width: 560px">
    <div class="card-head">
        <strong>Where the ticket goes</strong>
        <span class="badge badge-ai"><i class="ri-sparkling-2-line"></i><span>Decided by the agent</span></span>
    </div>
    <div class="card-body sedna-col sedna-gap-3">
        <ol class="workflow-decision" aria-label="Options the agent weighed">
            <li data-state="chosen">
                <span class="workflow-decision-option">Page the on-call engineer <span class="visually-hidden">(chosen)</span></span>
                <span class="meter"><span class="meter-fill" style="--value: 86%"></span></span>
                <span class="workflow-decision-score">0.86</span>
                <span class="workflow-decision-why">Three stores in one region within 15 minutes, out of hours: an outage, not a fault.</span>
            </li>
            <li data-state="rejected">
                <span class="workflow-decision-option">Queue for the network team</span>
                <span class="meter"><span class="meter-fill" style="--value: 31%"></span></span>
                <span class="workflow-decision-score">0.31</span>
                <span class="workflow-decision-why">The team starts at 07:00; the tills would be down for nine hours.</span>
            </li>
            <li data-state="rejected">
                <span class="workflow-decision-option">Close as a known issue</span>
                <span class="meter"><span class="meter-fill" style="--value: 8%"></span></span>
                <span class="workflow-decision-score">0.08</span>
            </li>
        </ol>
        <details class="reasoning">
            <summary><i class="ri-arrow-right-s-line reasoning-chevron"></i><span>Thought for 3 s</span></summary>
            <div class="reasoning-body">
                <p>One store losing its link is a fault for the morning. Three stores in the same region within a quarter of an hour is the regional uplink, and nobody can fix that from a store.</p>
                <p>It is 21:40 and the stores close at 22:00, but they open at 07:00 and cannot take cards until the link is back. That is worth waking someone for.</p>
            </div>
        </details>
    </div>
</div>

A short flow, centred

.workflow--center centres a diagram narrower than its container, and still starts it at the edge once it is wider, so nothing is cut off.

  1. Requested Alex Fischer
  2. Approval Finance
  3. Paid out
<ol class="workflow workflow--center" tabindex="0" aria-label="Refund for ORD-4211: where it is now">
    <li class="workflow-step" data-state="done">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-2"><i class="ri-refund-2-line"></i></span>
                <span class="workflow-node-title">Requested</span>
                <span class="workflow-node-meta">Alex Fischer</span>
            </header>
        </article>
    </li>
    <li class="workflow-step" data-state="running">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-3"><i class="ri-scales-3-line"></i></span>
                <span class="workflow-node-title">Approval</span>
                <span class="workflow-node-meta">Finance</span>
            </header>
        </article>
    </li>
    <li class="workflow-step">
        <article class="workflow-node">
            <header class="workflow-node-head">
                <span class="workflow-node-icon series-4"><i class="ri-bank-card-line"></i></span>
                <span class="workflow-node-title">Paid out</span>
            </header>
        </article>
    </li>
</ol>

A step and what it did

A node that opens its detail is a <button class="workflow-node"> with spans inside, and aria-pressed="true" on the one on show. The detail is your own panel beside the diagram — a .sedna-split stacks it underneath when the room runs out — holding whatever explains the step: what it read, what it weighed, the tools it ran.

.workflow--grid dots the canvas. For a graph too large to write by hand — a flow generated from an automation's own definition — the graph draws the same states on a canvas.

<div class="sedna-split sedna-split--lg">
    <ol class="workflow workflow--sm workflow--grid" tabindex="0" aria-label="The ticket's steps; choose one to see what it did">
        <li class="workflow-step" data-state="done">
            <button class="workflow-node" type="button" aria-pressed="false">
                <span class="workflow-node-head">
                    <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-scales-3-line"></i></span>
                    <span class="workflow-node-title">Assess severity</span>
                    <span class="workflow-node-meta">P1 &middot; 2.1 s</span>
                </span>
            </button>
        </li>
        <li class="workflow-step" data-state="done">
            <button class="workflow-node" type="button" aria-pressed="true">
                <span class="workflow-node-head">
                    <span class="workflow-node-icon workflow-node-icon--agent"><i class="ri-route-line"></i></span>
                    <span class="workflow-node-title">Decide where it goes</span>
                    <span class="workflow-node-meta">Page on call &middot; 3.0 s</span>
                </span>
            </button>
        </li>
        <li class="workflow-step" data-state="waiting">
            <button class="workflow-node" type="button" aria-pressed="false">
                <span class="workflow-node-head">
                    <span class="workflow-node-icon series-danger"><i class="ri-alarm-warning-line"></i></span>
                    <span class="workflow-node-title">Page on call</span>
                    <span class="workflow-node-meta">Waiting for Rin</span>
                </span>
            </button>
        </li>
    </ol>
    <aside class="card sedna-split-aside">
        <div class="card-head">
            <strong>Decide where it goes</strong>
            <span class="badge badge--go">Done</span>
        </div>
        <div class="card-body sedna-col sedna-gap-3">
            <div>
                <div class="kv"><span class="k">Started</span><span class="v">21:40:12</span></div>
                <div class="kv"><span class="k">Took</span><span class="v">3.0 s</span></div>
                <div class="kv"><span class="k">Read</span><span class="v">T-48213, 2 related</span></div>
            </div>
            <ol class="workflow-decision" aria-label="Options it weighed">
                <li data-state="chosen">
                    <span class="workflow-decision-option">Page on call <span class="visually-hidden">(chosen)</span></span>
                    <span class="meter"><span class="meter-fill" style="--value: 86%"></span></span>
                    <span class="workflow-decision-score">0.86</span>
                </li>
                <li data-state="rejected">
                    <span class="workflow-decision-option">Queue for the morning</span>
                    <span class="meter"><span class="meter-fill" style="--value: 31%"></span></span>
                    <span class="workflow-decision-score">0.31</span>
                </li>
            </ol>
            <ol class="agent-steps">
                <li data-state="done">
                    <span class="agent-step-icon"><i class="ri-check-line"></i></span>
                    <details class="agent-step">
                        <summary><span class="agent-step-label"><i class="ri-calendar-schedule-line"></i><span>Read the on-call rota</span></span><span class="agent-step-meta">0.4 s</span></summary>
                        <pre class="code-block"><code>rota.current(team: "network") &rarr; Rin Nakamura, until 07:00</code></pre>
                    </details>
                </li>
            </ol>
        </div>
    </aside>
</div>