Pulsar
Canary deployment track metering test traffic before merging into primary production stream

Canary

CSS

A secondary canary progress bar fills alongside the main production stream before successfully verifying and merging.

Tier
CSS
Dependencies
None
Duration
3.6 s, loops
Categories
Icons and micro-interactions, Data and progress
Use cases
Determinate progress, Workflow and approvals
Industries
SaaS and software, Cross-industry
Style
Technical · light stroke
Set
deploy
Tags
loopprogresslineui

Companion assets

The same artwork, not animated. Derived from the entry’s own resting state, so it matches exactly.

Animated
Canary deployment track metering test traffic before merging into primary production stream
CSS tier
Static vector
Canary, not animated
Download SVG

Code

animation.svg

<svg xmlns="http://www.w3.org/2000/svg" aria-labelledby="deploy-canary-title" class="pulsar pulsar-deploy-canary" data-pulsar="deploy-canary" role="img" viewBox="0 0 160 96"><title id="deploy-canary-title">Canary deployment track metering test traffic before merging into primary production stream</title><g fill="none" stroke="currentColor" stroke-linecap="square" stroke-width=".75" opacity=".3"><path id="deploy-canary-datum" d="M20 20h8m-8 0v8m120-8h-8m8 0v8M20 76h8m-8 0v-8m120 8h-8m8 0v-8"></path><line id="deploy-canary-axis" x1="24" x2="136" y1="48" y2="48" stroke-dasharray="2 4"></line></g><g fill="none" stroke="currentColor" stroke-linecap="square" stroke-width="1.25"><line id="deploy-canary-main-rail" x1="28" x2="112" y1="40" y2="40" opacity=".4"></line><path id="deploy-canary-sub-rail" stroke-dasharray="2 3" d="m40 40 14 18h42l14-18" opacity=".5"></path><line id="deploy-canary-out-rail" x1="112" x2="132" y1="40" y2="40" opacity=".4"></line></g><g fill="none" stroke="currentColor" stroke-linecap="square" stroke-width="1.2"><line x1="54" x2="54" y1="55" y2="61" opacity=".6"></line><line x1="96" x2="96" y1="55" y2="61" opacity=".6"></line></g><line id="deploy-canary-main-flow" x1="28" x2="112" y1="40" y2="40" fill="none" stroke="currentColor" stroke-dasharray="12 18" stroke-width="1.5"></line><path id="deploy-canary-sub-fill" fill="none" stroke="currentColor" stroke-dasharray="78" stroke-dashoffset="78" stroke-width="1.75" d="m40 40 14 18h42l14-18"></path><circle id="deploy-canary-sensor-node" cx="75" cy="58" r="2.5" fill="currentColor"></circle><circle id="deploy-canary-sensor-ring" cx="75" cy="58" r="6" fill="none" stroke="currentColor" stroke-width="1" opacity="0"></circle><polygon id="deploy-canary-merge-pip" fill="currentColor" points="112,37 116,40 112,43 108,40"></polygon><line id="deploy-canary-out-flow" x1="112" x2="132" y1="40" y2="40" fill="none" stroke="currentColor" stroke-dasharray="20" stroke-dashoffset="20" stroke-width="2"></line></svg>

animation.css

.pulsar-deploy-canary {
  --pulsar-accent: currentColor;
}

.pulsar-deploy-canary #deploy-canary-sub-fill,
.pulsar-deploy-canary #deploy-canary-sensor-ring,
.pulsar-deploy-canary #deploy-canary-out-flow {
  stroke: var(--pulsar-accent, currentColor);
}

.pulsar-deploy-canary #deploy-canary-sensor-node,
.pulsar-deploy-canary #deploy-canary-merge-pip {
  fill: var(--pulsar-accent, currentColor);
}

.pulsar-deploy-canary #deploy-canary-main-flow {
  animation: deploy-canary-flow-main 3600ms linear infinite;
}

.pulsar-deploy-canary #deploy-canary-sub-fill {
  animation: deploy-canary-fill-sub 3600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

.pulsar-deploy-canary #deploy-canary-sensor-node {
  animation: deploy-canary-sensor-pop 3600ms cubic-bezier(0.16, 1, 0.3, 1) infinite;
  transform-origin: 75px 58px;
}

.pulsar-deploy-canary #deploy-canary-sensor-ring {
  animation: deploy-canary-sensor-wave 3600ms cubic-bezier(0.16, 1, 0.3, 1) infinite;
  transform-origin: 75px 58px;
}

.pulsar-deploy-canary #deploy-canary-merge-pip {
  animation: deploy-canary-merge-flash 3600ms cubic-bezier(0.16, 1, 0.3, 1) infinite;
  transform-origin: 112px 40px;
}

.pulsar-deploy-canary #deploy-canary-out-flow {
  animation: deploy-canary-release 3600ms cubic-bezier(0.16, 1, 0.3, 1) infinite;
}

@keyframes deploy-canary-flow-main {
  0% {
    stroke-dashoffset: 0;
  }
  100% {
    stroke-dashoffset: -60;
  }
}

@keyframes deploy-canary-fill-sub {
  0%,
  10% {
    stroke-dashoffset: 78;
    opacity: 0.3;
  }
  45% {
    stroke-dashoffset: 35;
    opacity: 1;
  }
  65%,
  88% {
    stroke-dashoffset: 0;
    opacity: 1;
  }
  96%,
  100% {
    stroke-dashoffset: 0;
    opacity: 0.2;
  }
}

@keyframes deploy-canary-sensor-pop {
  0%,
  35% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  48%,
  85% {
    transform: scale(1.3);
    opacity: 1;
  }
  95%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
}

@keyframes deploy-canary-sensor-wave {
  0%,
  42% {
    opacity: 0;
    transform: scale(0.5);
  }
  48% {
    opacity: 0.9;
  }
  62% {
    opacity: 0;
    transform: scale(2.2);
  }
  100% {
    opacity: 0;
    transform: scale(2.2);
  }
}

@keyframes deploy-canary-merge-flash {
  0%,
  60% {
    transform: scale(0.8);
    opacity: 0.4;
  }
  68%,
  88% {
    transform: scale(1.4);
    opacity: 1;
  }
  96%,
  100% {
    transform: scale(0.8);
    opacity: 0.4;
  }
}

@keyframes deploy-canary-release {
  0%,
  64% {
    stroke-dashoffset: 20;
    opacity: 0;
  }
  72%,
  88% {
    stroke-dashoffset: 0;
    opacity: 1;
  }
  98%,
  100% {
    stroke-dashoffset: -20;
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pulsar-deploy-canary * {
    animation: none !important;
    transform: none;
  }
  .pulsar-deploy-canary #deploy-canary-sub-fill,
  .pulsar-deploy-canary #deploy-canary-out-flow {
    stroke-dashoffset: 0;
    opacity: 1;
  }
  .pulsar-deploy-canary #deploy-canary-sensor-node,
  .pulsar-deploy-canary #deploy-canary-merge-pip {
    opacity: 1;
  }
}

From this family15 in Deploy

See the family