AI CSS Animations

Agent Session Sidebar

A sidebar of agent sessions whose status icons and subtitles change as you watch: one run finishes with a check, another stops for input in amber, and a waiting one picks back up and spins.

Also known as: agent sessions list, chat history sidebar status, parallel agent sessions.

Sessions
  • Fix flaky checkout testRunning for 4mNeeds your inputDone, +38 -64m
  • Migrate users tableRunning for 12mNeeds your inputDone12m
  • Draft Q3 changelogRunning for 1mNeeds your inputDone, 1 file31m
  • Bump eslint to v9RunningNeeds your inputDone, 3 files1h

HTML

<div class="aia-agent-session-sidebar" role="status" aria-label="Agent sessions updating">
  <div class="aia-agent-session-sidebar-head">
    <b>Sessions</b>
    <span class="aia-agent-session-sidebar-wait" aria-hidden="true"></span>
    <span class="aia-agent-session-sidebar-new" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5.5v13M5.5 12h13"/></svg></span>
  </div>
  <ul class="aia-agent-session-sidebar-list">
    <li class="aia-agent-session-sidebar-on"><span class="aia-agent-session-sidebar-st" aria-hidden="true"><i class="aia-agent-session-sidebar-spin"></i><i class="aia-agent-session-sidebar-ask"></i><svg class="aia-agent-session-sidebar-ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5.5 12.5 4 4 9-9.5"/></svg></span><span class="aia-agent-session-sidebar-text"><b>Fix flaky checkout test</b><span class="aia-agent-session-sidebar-sub"><span>Running for 4m</span><span>Needs your input</span><span>Done, +38 -6</span></span></span><i class="aia-agent-session-sidebar-time">4m</i></li>
    <li><span class="aia-agent-session-sidebar-st" aria-hidden="true"><i class="aia-agent-session-sidebar-spin"></i><i class="aia-agent-session-sidebar-ask"></i><svg class="aia-agent-session-sidebar-ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5.5 12.5 4 4 9-9.5"/></svg></span><span class="aia-agent-session-sidebar-text"><b>Migrate users table</b><span class="aia-agent-session-sidebar-sub"><span>Running for 12m</span><span>Needs your input</span><span>Done</span></span></span><i class="aia-agent-session-sidebar-time">12m</i></li>
    <li><span class="aia-agent-session-sidebar-st" aria-hidden="true"><i class="aia-agent-session-sidebar-spin"></i><i class="aia-agent-session-sidebar-ask"></i><svg class="aia-agent-session-sidebar-ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5.5 12.5 4 4 9-9.5"/></svg></span><span class="aia-agent-session-sidebar-text"><b>Draft Q3 changelog</b><span class="aia-agent-session-sidebar-sub"><span>Running for 1m</span><span>Needs your input</span><span>Done, 1 file</span></span></span><i class="aia-agent-session-sidebar-time">31m</i></li>
    <li><span class="aia-agent-session-sidebar-st" aria-hidden="true"><i class="aia-agent-session-sidebar-spin"></i><i class="aia-agent-session-sidebar-ask"></i><svg class="aia-agent-session-sidebar-ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5.5 12.5 4 4 9-9.5"/></svg></span><span class="aia-agent-session-sidebar-text"><b>Bump eslint to v9</b><span class="aia-agent-session-sidebar-sub"><span>Running</span><span>Needs your input</span><span>Done, 3 files</span></span></span><i class="aia-agent-session-sidebar-time">1h</i></li>
  </ul>
</div>

CSS

@property --aia-agent-session-sidebar-t {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@property --aia-agent-session-sidebar-n {
  syntax: "<integer>";
  inherits: false;
  initial-value: 0;
}
.aia-agent-session-sidebar {
  --c: var(--aia-color, #7c5cff);
  font-size: var(--aia-size, 16px);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.4;
  position: relative;
  box-sizing: border-box;
  padding: 0.9em 1em;
  border-radius: 0.9em;
  background: color-mix(in srgb, currentColor 3%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 11%, transparent), 0 0.1em 0.2em color-mix(in srgb, currentColor 4%, transparent), 0 0.9em 2em -1.1em rgb(0 0 0 / 0.3);
  --d: 9s;
  --t: var(--aia-agent-session-sidebar-t);
  --ok: color-mix(in srgb, #16a34a 78%, currentColor);
  --warn: color-mix(in srgb, #d97706 84%, currentColor);
  width: 17.5em;
  padding: 0.6em 0.5em 0.5em;
  animation: aia-agent-session-sidebar-clock var(--d) linear infinite;
}
.aia-agent-session-sidebar-head {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0 0.45em 0.5em 0.6em;
}
.aia-agent-session-sidebar-head b {
  margin-right: auto;
  font-size: 0.82em;
}
.aia-agent-session-sidebar-wait {
  --aia-agent-session-sidebar-n: calc(1 - clamp(0, (var(--t) - 0.17) * 50, 1) + clamp(0, (var(--t) - 0.52) * 50, 1));
  counter-reset: n var(--aia-agent-session-sidebar-n);
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.15em 0.55em;
  border-radius: 999em;
  background: color-mix(in srgb, #d97706 14%, transparent);
  color: var(--warn);
  font-size: 0.66em;
  font-weight: 700;
  opacity: var(--aia-agent-session-sidebar-n);
}
.aia-agent-session-sidebar-wait::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--warn);
}
.aia-agent-session-sidebar-wait::after { content: counter(n) " waiting"; }
.aia-agent-session-sidebar-new {
  display: grid;
  place-items: center;
  width: 1.5em;
  height: 1.5em;
  border-radius: 0.4em;
  background: color-mix(in srgb, currentColor 6%, transparent);
}
.aia-agent-session-sidebar-new svg {
  width: 0.9em;
  height: 0.9em;
}
.aia-agent-session-sidebar-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.aia-agent-session-sidebar-list li {
  --run: 0;
  --ask: 0;
  --ok-p: 0;
  position: relative;
  display: grid;
  grid-template-columns: 1em 1fr auto;
  align-items: center;
  gap: 0.6em;
  box-sizing: border-box;
  height: 2.35em;
  padding: 0 0.6em;
  border-radius: 0.55em;
}
.aia-agent-session-sidebar-list li:nth-child(1) {
  --run: calc(1 - clamp(0, (var(--t) - 0.29) * 50, 1));
  --ok-p: clamp(0, (var(--t) - 0.3) * 33.3333, 1);
}
.aia-agent-session-sidebar-list li:nth-child(2) {
  --run: calc(1 - clamp(0, (var(--t) - 0.51) * 50, 1));
  --ask: clamp(0, (var(--t) - 0.52) * 50, 1);
}
.aia-agent-session-sidebar-list li:nth-child(3) {
  --ask: calc(1 - clamp(0, (var(--t) - 0.17) * 50, 1));
  --run: calc(clamp(0, (var(--t) - 0.18) * 50, 1) * (1 - clamp(0, (var(--t) - 0.73) * 50, 1)));
  --ok-p: clamp(0, (var(--t) - 0.74) * 33.3333, 1);
}
.aia-agent-session-sidebar-list li:nth-child(4) { --ok-p: 1; }
.aia-agent-session-sidebar-list .aia-agent-session-sidebar-on {
  background: color-mix(in srgb, currentColor 6%, transparent);
}
.aia-agent-session-sidebar-on::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  bottom: 0.55em;
  width: 0.16em;
  border-radius: 1em;
  background: var(--c);
}
.aia-agent-session-sidebar-st {
  display: grid;
  place-items: center;
  width: 1em;
  height: 1em;
  animation: aia-agent-session-sidebar-fade var(--d) linear infinite;
}
.aia-agent-session-sidebar-st > * { grid-area: 1 / 1; }
.aia-agent-session-sidebar-spin {
  width: 0.85em;
  height: 0.85em;
  box-sizing: border-box;
  border-radius: 50%;
  border: 0.13em solid color-mix(in srgb, var(--c) 25%, transparent);
  border-top-color: var(--c);
  opacity: var(--run);
  animation: aia-agent-session-sidebar-spin 0.8s linear infinite;
}
.aia-agent-session-sidebar-ask {
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--warn);
  opacity: var(--ask);
  box-shadow: 0 0 0 calc(var(--ask) * 0.18em) color-mix(in srgb, #d97706 25%, transparent);
  animation: aia-agent-session-sidebar-pulse 1.6s ease-in-out infinite;
}
.aia-agent-session-sidebar-ok {
  width: 1em;
  height: 1em;
  color: var(--ok);
  stroke-width: 3;
  opacity: var(--ok-p);
  transform: scale(calc(0.4 + var(--ok-p) * 0.6));
}
.aia-agent-session-sidebar-text {
  display: grid;
  min-width: 0;
  line-height: 1.3;
}
.aia-agent-session-sidebar-text b {
  overflow: hidden;
  font-size: 0.78em;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.aia-agent-session-sidebar-sub {
  display: grid;
  font-size: 0.66em;
  animation: aia-agent-session-sidebar-fade var(--d) linear infinite;
}
.aia-agent-session-sidebar-sub > * {
  grid-area: 1 / 1;
  white-space: nowrap;
}
.aia-agent-session-sidebar-sub > :nth-child(1) { color: color-mix(in srgb, currentColor 55%, transparent); opacity: var(--run); }
.aia-agent-session-sidebar-sub > :nth-child(2) { color: var(--warn); font-weight: 600; opacity: var(--ask); }
.aia-agent-session-sidebar-sub > :nth-child(3) { color: color-mix(in srgb, currentColor 55%, transparent); opacity: var(--ok-p); }
.aia-agent-session-sidebar-time {
  align-self: start;
  margin-top: 0.75em;
  color: color-mix(in srgb, currentColor 40%, transparent);
  font: normal 0.62em ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}
@keyframes aia-agent-session-sidebar-clock {
  from { --aia-agent-session-sidebar-t: 0; }
  to { --aia-agent-session-sidebar-t: 1; }
}
@keyframes aia-agent-session-sidebar-fade {
  0% { opacity: 0; }
  3%, 93% { opacity: 1; }
  97.5%, 100% { opacity: 0; }
}
@keyframes aia-agent-session-sidebar-spin {
  to { transform: rotate(360deg); }
}
@keyframes aia-agent-session-sidebar-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(0.75); }
}
@media (prefers-reduced-motion: reduce) {
  .aia-agent-session-sidebar,
  .aia-agent-session-sidebar-st,
  .aia-agent-session-sidebar-sub,
  .aia-agent-session-sidebar-ask {
    animation: none;
    --aia-agent-session-sidebar-t: 0.6;
  }
  .aia-agent-session-sidebar-spin { animation-duration: 2.4s; }
}

@media (prefers-reduced-motion: reduce) {
  .aia-agent-session-sidebar, .aia-agent-session-sidebar *, .aia-agent-session-sidebar::before, .aia-agent-session-sidebar::after, .aia-agent-session-sidebar *::before, .aia-agent-session-sidebar *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --aia-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --aia-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar ai animations