Pulsar
Blueprint frame drawing itself with registration ticks

Blueprint Frame

CSS

A sheet border draws itself clockwise from the top-left corner and four registration ticks click into place behind it.

Tier
CSS
Dependencies
None
Duration
1.2 s, plays once
Categories
Transitions and reveals
Use cases
Empty states, Transitions and reveals
Industries
SaaS and software, Cross-industry
Style
Technical · hairline stroke
Set
blueprint
Tags
strokeone-shotgeometriclineminimal
Themeable
Yes. Inherits currentColor and reads --pulsar-accent.
Version
1.0.0, added 2026-09-09
Licence
To be confirmed. See the repository LICENSE.

Code

animation.svg

<svg xmlns="http://www.w3.org/2000/svg" aria-labelledby="blueprint-frame-title" class="pulsar pulsar-blueprint-frame" data-pulsar="blueprint-frame" role="img" viewBox="0 0 160 96"><title id="blueprint-frame-title">Blueprint frame drawing itself with registration ticks</title><g id="blueprint-frame-ticks" fill="none" stroke="currentColor" stroke-linecap="square" stroke-linejoin="miter" stroke-width=".75"><path id="blueprint-frame-tick-tl" d="M20 12h-8v8" class="blueprint-frame-tick"></path><path id="blueprint-frame-tick-tr" d="M140 12h8v8" class="blueprint-frame-tick"></path><path id="blueprint-frame-tick-br" d="M140 84h8v-8" class="blueprint-frame-tick"></path><path id="blueprint-frame-tick-bl" d="M20 84h-8v-8" class="blueprint-frame-tick"></path></g><path id="blueprint-frame-outline" fill="none" stroke="currentColor" stroke-linecap="square" stroke-linejoin="miter" stroke-width="1.5" d="M8 8h144v80H8Z"></path></svg>

animation.css

.pulsar-blueprint-frame #blueprint-frame-outline {
  fill: none;
  stroke: var(--pulsar-accent, currentColor);
  stroke-dasharray: 448;
  stroke-dashoffset: 448;
  animation: blueprint-frame-draw 1200ms cubic-bezier(0.65, 0, 0.35, 1) both;
}

.pulsar-blueprint-frame .blueprint-frame-tick {
  fill: none;
  stroke: currentColor;
  opacity: 0;
  transform: scale(0.7);
  transform-box: fill-box;
}

.pulsar-blueprint-frame #blueprint-frame-tick-tl {
  transform-origin: 0% 0%;
  animation: blueprint-frame-tick-tl 1200ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.pulsar-blueprint-frame #blueprint-frame-tick-tr {
  transform-origin: 100% 0%;
  animation: blueprint-frame-tick-tr 1200ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.pulsar-blueprint-frame #blueprint-frame-tick-br {
  transform-origin: 100% 100%;
  animation: blueprint-frame-tick-br 1200ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.pulsar-blueprint-frame #blueprint-frame-tick-bl {
  transform-origin: 0% 100%;
  animation: blueprint-frame-tick-bl 1200ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes blueprint-frame-draw {
  0% {
    stroke-dashoffset: 448;
  }
  75% {
    stroke-dashoffset: 0;
  }
  100% {
    stroke-dashoffset: 0;
  }
}

@keyframes blueprint-frame-tick-tl {
  0%,
  75% {
    opacity: 0;
    transform: scale(0.7);
  }
  85%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes blueprint-frame-tick-tr {
  0%,
  80% {
    opacity: 0;
    transform: scale(0.7);
  }
  90%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes blueprint-frame-tick-br {
  0%,
  85% {
    opacity: 0;
    transform: scale(0.7);
  }
  95%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes blueprint-frame-tick-bl {
  0%,
  90% {
    opacity: 0;
    transform: scale(0.7);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pulsar-blueprint-frame #blueprint-frame-outline {
    animation: none;
    stroke-dashoffset: 0;
  }

  .pulsar-blueprint-frame #blueprint-frame-tick-tl,
  .pulsar-blueprint-frame #blueprint-frame-tick-tr,
  .pulsar-blueprint-frame #blueprint-frame-tick-br,
  .pulsar-blueprint-frame #blueprint-frame-tick-bl {
    animation: none;
    opacity: 1;
    transform: scale(1);
  }
}