Nebula network
CSSA constellation of nodes joined by links that travel the network in sequence, over a soft nebula cloud.
- Tier
- CSS
- Dependencies
- None
- Duration
- 4 s, loops
- Categories
- Decorative and illustrative
- Use cases
- Hero and marketing, Ambient background
- Industries
- SaaS and software, Cross-industry
- Style
- Duotone · none stroke
- Set
- nebula
- Tags
- loopnebulaspaceglowbrand
Companion assets
The same artwork, not animated. Derived from the entry’s own resting state, so it matches exactly.
Code
animation.svg
<svg xmlns="http://www.w3.org/2000/svg" aria-labelledby="nebula-network-title" class="pulsar pulsar-nebula-network" data-pulsar="nebula-network" role="img" viewBox="0 0 100 100"><title id="nebula-network-title">Nebula network</title><defs><radialGradient id="nebula-network-cloud" cx="50%" cy="50%" r="60%"><stop offset="0%" stop-color="var(--pulsar-accent, currentColor)" stop-opacity=".3"></stop><stop offset="40%" stop-color="var(--pulsar-accent, currentColor)" stop-opacity=".16"></stop><stop offset="100%" stop-color="var(--pulsar-accent, currentColor)" stop-opacity="0"></stop></radialGradient><linearGradient id="nebula-network-link-grad" x1="0" x2="100" y1="0" y2="100" gradientUnits="userSpaceOnUse"><stop offset="0%" stop-color="var(--pulsar-accent, currentColor)" stop-opacity=".55"></stop><stop offset="45%" stop-color="var(--pulsar-accent, currentColor)"></stop><stop offset="100%" stop-color="var(--pulsar-accent, currentColor)" stop-opacity=".7"></stop></linearGradient><filter id="nebula-network-glow" width="200%" height="200%" x="-50%" y="-50%"><feGaussianBlur result="b" stdDeviation="2"></feGaussianBlur><feMerge><feMergeNode in="b"></feMergeNode><feMergeNode in="SourceGraphic"></feMergeNode></feMerge></filter></defs><ellipse id="nebula-network-cloud-shape" cx="50" cy="52" rx="28" ry="20"></ellipse><path id="nebula-network-skeleton" d="m30 35 18-7 20 8 4 18-18 14-20-4z"></path><path id="nebula-network-link-1" d="m30 35 18-7 20 8" class="nebula-network-link"></path><path id="nebula-network-link-2" d="m68 36 4 18-18 14" class="nebula-network-link"></path><path id="nebula-network-link-3" d="m54 68-20-4-4-29" class="nebula-network-link"></path><path id="nebula-network-link-4" d="m48 28 24 26" class="nebula-network-link"></path><g id="nebula-network-node-1" class="nebula-network-node"><circle cx="30" cy="35" r="3.4" class="nebula-network-node-outer"></circle><circle cx="30" cy="35" r="1.6" class="nebula-network-node-inner"></circle></g><g id="nebula-network-node-2" class="nebula-network-node"><circle cx="48" cy="28" r="3.8" class="nebula-network-node-outer"></circle><circle cx="48" cy="28" r="1.9" class="nebula-network-node-inner"></circle></g><g id="nebula-network-node-3" class="nebula-network-node"><circle cx="68" cy="36" r="3.6" class="nebula-network-node-outer"></circle><circle cx="68" cy="36" r="1.8" class="nebula-network-node-inner"></circle></g><g id="nebula-network-node-4" class="nebula-network-node"><circle cx="72" cy="54" r="4.1" class="nebula-network-node-outer"></circle><circle cx="72" cy="54" r="2.1" class="nebula-network-node-inner"></circle></g><g id="nebula-network-node-5" class="nebula-network-node"><circle cx="54" cy="68" r="3.9" class="nebula-network-node-outer"></circle><circle cx="54" cy="68" r="1.9" class="nebula-network-node-inner"></circle></g><g id="nebula-network-node-6" class="nebula-network-node"><circle cx="34" cy="64" r="3.2" class="nebula-network-node-outer"></circle><circle cx="34" cy="64" r="1.5" class="nebula-network-node-inner"></circle></g></svg>
animation.css
/*
Ported from the Business Nebula site mark. Three things had to change to
meet this catalogue's contract, and none of them is cosmetic:
- The source carried its stylesheet inside the SVG, which is not allowed
here, so all of it lives in this file under the entry's own prefix.
- Its gradients were the brand purple ramp written as literals. They are
the same ramp expressed through var(--pulsar-accent), so the mark now
follows the colour control instead of ignoring it.
- Its layers ran at 4s and 3.2s with positive delays up to 2s, which never
share a cycle: the loop seam moved every repeat. Everything is on one
4000ms period now with negative delays, which keeps the stagger and
makes 0% and 100% the same picture.
*/
.pulsar-nebula-network #nebula-network-cloud-shape {
fill: url(#nebula-network-cloud);
opacity: 0.85;
}
.pulsar-nebula-network #nebula-network-skeleton {
fill: none;
stroke: currentColor;
stroke-dasharray: 3 6;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.1;
opacity: 0.22;
}
.pulsar-nebula-network .nebula-network-link {
fill: none;
stroke: url(#nebula-network-link-grad);
stroke-dasharray: 40;
stroke-dashoffset: 40;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5;
filter: url(#nebula-network-glow);
animation: nebula-network-link 4000ms ease-in-out infinite;
}
.pulsar-nebula-network #nebula-network-link-2 {
animation-delay: -500ms;
}
.pulsar-nebula-network #nebula-network-link-3 {
animation-delay: -1000ms;
}
.pulsar-nebula-network #nebula-network-link-4 {
animation-delay: -1500ms;
}
.pulsar-nebula-network .nebula-network-node {
filter: url(#nebula-network-glow);
animation: nebula-network-node 4000ms ease-in-out infinite;
}
.pulsar-nebula-network #nebula-network-node-2 {
animation-delay: -400ms;
}
.pulsar-nebula-network #nebula-network-node-3 {
animation-delay: -800ms;
}
.pulsar-nebula-network #nebula-network-node-4 {
animation-delay: -1200ms;
}
.pulsar-nebula-network #nebula-network-node-5 {
animation-delay: -1600ms;
}
.pulsar-nebula-network #nebula-network-node-6 {
animation-delay: -2000ms;
}
.pulsar-nebula-network .nebula-network-node-outer {
fill: var(--pulsar-accent, currentColor);
}
.pulsar-nebula-network .nebula-network-node-inner {
fill: currentColor;
opacity: 0.85;
}
/*
Dashoffset 40 and -40 differ by one full 80-unit dash period, so the last
frame draws exactly what the first one does. That is what lets the line
keep travelling through the seam instead of snapping back at it.
*/
@keyframes nebula-network-link {
0% {
stroke-dashoffset: 40;
opacity: 0.2;
}
30% {
stroke-dashoffset: 20;
opacity: 0.8;
}
60% {
stroke-dashoffset: 0;
opacity: 1;
}
80% {
stroke-dashoffset: -20;
opacity: 0.5;
}
100% {
stroke-dashoffset: -40;
opacity: 0.2;
}
}
@keyframes nebula-network-node {
0%,
20%,
100% {
opacity: 0.45;
}
45% {
opacity: 1;
}
70% {
opacity: 0.75;
}
}
@media (prefers-reduced-motion: reduce) {
.pulsar-nebula-network .nebula-network-link {
animation: none;
stroke-dashoffset: 0;
opacity: 0.9;
}
.pulsar-nebula-network .nebula-network-node {
animation: none;
opacity: 1;
}
}

