Back to the library

Pulse beacon, sharp

Variant: Sharp

The same beacon tuned to alarm. The ring covers half the distance in a fifth of the time and the core ticks up with it, so the pulse lands as a knock instead of a breath. Use it for failures and states that need someone to look now; the colour shift to rust does half the work.

statusloopalertdot

The source

A complete HTML document. Paste it into an empty .html file and it plays — no stylesheet, script, font, or image to fetch.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Pulse beacon — sharp</title>
    <style>
      :root {
        --ivory: #faf9f5;
        --slate: #141413;
        --rust: #b04a3f;
        --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
      }

      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }

      body {
        min-height: 100vh;
        display: grid;
        place-items: center;
        background: var(--ivory);
        font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
        color: var(--slate);
      }

      .status {
        display: flex;
        align-items: center;
        gap: 12px;
        font-size: 14px;
        letter-spacing: -0.01em;
      }

      .beacon {
        position: relative;
        width: 12px;
        height: 12px;
        flex: none;
      }

      .beacon span {
        position: absolute;
        inset: 0;
        border-radius: 50%;
      }

      /* Same beacon, urgent register: the ring travels a shorter distance in
         240ms and the core ticks with it, so the pulse reads as an alert
         rather than a heartbeat. The long tail of the cycle is dead air. */
      .beacon .core {
        background: var(--rust);
        animation: beacon-core 1.5s var(--ease-out) infinite;
      }

      .beacon .ring {
        border: 2px solid var(--rust);
        opacity: 0;
        animation: beacon-sharp 1.5s var(--ease-out) infinite;
      }

      @keyframes beacon-sharp {
        0% {
          transform: scale(1);
          opacity: 0.75;
        }
        16%,
        100% {
          transform: scale(2);
          opacity: 0;
        }
      }

      @keyframes beacon-core {
        0% {
          transform: scale(1);
        }
        8% {
          transform: scale(1.25);
        }
        20%,
        100% {
          transform: scale(1);
        }
      }

      @media (prefers-reduced-motion: reduce) {
        .beacon .core {
          animation: none;
        }

        .beacon .ring {
          animation: beacon-sharp-fade 1.5s ease infinite;
          transform: scale(1.8);
        }

        @keyframes beacon-sharp-fade {
          0%,
          100% {
            opacity: 0;
          }
          20% {
            opacity: 0.6;
          }
        }
      }
    </style>
  </head>
  <body>
    <p class="status">
      <span class="beacon">
        <span class="ring"></span>
        <span class="core"></span>
      </span>
      Build failed on main
    </p>
  </body>
</html>

The variant family

Same idea, one axis moved. Compare them side by side before you commit.