Pulsar
1×

Floor

Medium

A perspective floor receding to a horizon, with the horizon itself glowing and breathing.

“Copy the hero” is the styles and the SVG, carrying the colours and speed you set above. “Copy as a section” adds the wrapper a hero actually needs: the SVG absolute behind the copy, inert to the pointer, and a scrim so the heading holds. The Free licence asks for one visible credit per page: Animation by Pulsar, linked to Pulsar. Licence

Tech
CSS, no JavaScript
Longest band
27 s, mirrored, loops
Canvas
1600 by 900, crops to fill
Default tone
Dark ground: ground #0b0a16, ink #ffffff
Series
lattice
Tags
gridperspectiveglow

The four variables

Set any of these on the section, or on any ancestor, and the hero follows. Nothing else in the file needs editing.

--pulsar-hero-bg
the ground, default #0b0a16
--pulsar-hero-ink
the strokes, default #ffffff
--pulsar-accent
the accented strokes
--pulsar-hero-speed
a rate: 2 is twice as fast, 0.5 half speed

Files

Animated SVG
One file, styles inside it, animates in an img tag or on its own.Download animated SVG
Still
Floor, not animated
Download SVG

The code

As a section

<!-- Pulsar by Business Nebula · "hero-lattice-floor" · https://pulsaricons.com | Licence: https://pulsaricons.com/legal/licence | Free-licence credit: Animation by Pulsar, linked to https://pulsaricons.com | Business Nebula: https://businessnebula.com.au -->
<style>
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 70vh;
  display: flex;
  align-items: center;
  padding: 5rem 5%;
  color: #ffffff;
  background: #0b0a16;
}
.hero > .pulsar-hero {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* A scrim under the copy, heavier on the side the text sits on. */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(100deg, #0b0a16 0%, color-mix(in oklab, #0b0a16 78%, transparent) 40%, transparent 68%);
}
.hero-copy {
  position: relative;
  z-index: 2;
  max-width: 40rem;
}
.hero-eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.8;
}
/* Generated by scripts/hero-lattice.mjs from heroes/hero-lattice-floor/params.json.
   Consumers set four custom properties on any ancestor:
     --pulsar-hero-bg     the ground          (default #0b0a16)
     --pulsar-hero-ink    the grid            (default #ffffff)
     --pulsar-accent      the glows and nodes (default #8a7df7)
     --pulsar-hero-speed  a rate; 2 is twice as fast, 0.5 half speed */
.pulsar-hero-lattice-floor {
  display: block;
  width: 100%;
  height: 100%;
  color: var(--pulsar-hero-ink, #ffffff);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-ground {
  fill: var(--pulsar-hero-bg, #0b0a16);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-accent-stop {
  stop-color: var(--pulsar-accent, #8a7df7);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-ground-stop {
  stop-color: var(--pulsar-hero-bg, #0b0a16);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-band {
  transform-box: view-box;
  will-change: transform;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
.pulsar-hero-lattice-floor .hero-lattice-floor-glow-1 {
  transform-origin: 800px 330px;
  animation-name: hero-lattice-floor-glow-1;
  animation-duration: calc(21s / var(--pulsar-hero-speed, 1));
}
.pulsar-hero-lattice-floor .hero-lattice-floor-glow-2 {
  transform-origin: 800px 330px;
  animation-name: hero-lattice-floor-glow-2;
  animation-duration: calc(27s / var(--pulsar-hero-speed, 1));
}
@keyframes hero-lattice-floor-glow-1 {
  from {
    transform: translate(-40px, -6px) scale(0.9);
  }
  to {
    transform: translate(40px, 6px) scale(1.1);
  }
}
@keyframes hero-lattice-floor-glow-2 {
  from {
    transform: translate(20px, 4px) scale(0.94);
  }
  to {
    transform: translate(-20px, -4px) scale(1.06);
  }
}
@media (prefers-reduced-motion: reduce) {
  .pulsar-hero-lattice-floor .hero-lattice-floor-glow-1,
  .pulsar-hero-lattice-floor .hero-lattice-floor-glow-2 {
    animation: none;
  }
}
</style>
<section class="hero">
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="pulsar pulsar-hero pulsar-hero-lattice-floor" data-pulsar="hero-lattice-floor" preserveAspectRatio="xMidYMid slice" viewBox="0 0 1600 900"><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description><dc:title>hero-lattice-floor</dc:title><dc:creator>Pulsar by Business Nebula</dc:creator><dc:publisher>Business Nebula</dc:publisher><dc:source>https://pulsaricons.com/icons</dc:source><dc:relation>https://businessnebula.com.au</dc:relation><dc:rights>Pulsar licence, https://pulsaricons.com/legal/licence</dc:rights></rdf:Description></rdf:RDF></metadata><defs><radialGradient id="hero-lattice-floor-glow-1"><stop class="hero-lattice-floor-accent-stop" offset="0" stop-opacity=".6"></stop><stop class="hero-lattice-floor-accent-stop" offset=".5" stop-opacity=".25"></stop><stop class="hero-lattice-floor-accent-stop" offset="1" stop-opacity="0"></stop></radialGradient><radialGradient id="hero-lattice-floor-glow-2"><stop offset="0" stop-color="currentColor" stop-opacity=".18"></stop><stop offset=".5" stop-color="currentColor" stop-opacity=".08"></stop><stop offset="1" stop-color="currentColor" stop-opacity="0"></stop></radialGradient><linearGradient id="hero-lattice-floor-veil" x1="0" x2="1600" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop class="hero-lattice-floor-ground-stop" offset="0" stop-opacity=".92"></stop><stop class="hero-lattice-floor-ground-stop" offset=".3" stop-opacity=".6"></stop><stop class="hero-lattice-floor-ground-stop" offset=".62" stop-opacity=".15"></stop><stop class="hero-lattice-floor-ground-stop" offset="1" stop-opacity="0"></stop></linearGradient></defs><rect width="1600" height="900" class="hero-lattice-floor-ground"></rect><g class="hero-lattice-floor-band hero-lattice-floor-glow hero-lattice-floor-glow-1"><ellipse cx="800" cy="330" fill="url(#hero-lattice-floor-glow-1)" rx="700" ry="160"></ellipse></g><g class="hero-lattice-floor-band hero-lattice-floor-glow hero-lattice-floor-glow-2"><ellipse cx="800" cy="330" fill="url(#hero-lattice-floor-glow-2)" rx="1100" ry="260"></ellipse></g><g class="hero-lattice-floor-field" opacity=".35"><path fill="none" stroke="currentColor" d="M800 330-480 900M800 330-381.5 900M800 330-283.1 900M800 330l-984.6 570M800 330-86.2 900M800 330 12.3 900M800 330 110.8 900M800 330 209.2 900M800 330 307.7 900M800 330 406.2 900M800 330 504.6 900M800 330 603.1 900M800 330l-98.5 570M800 330v570m0-570 98.5 570M800 330l196.9 570M800 330l295.4 570M800 330l393.8 570M800 330l492.3 570M800 330l590.8 570M800 330l689.2 570M800 330l787.7 570M800 330l886.2 570M800 330l984.6 570M800 330l1083.1 570M800 330l1181.5 570M800 330l1280 570" class="hero-lattice-floor-grid"></path><path fill="none" stroke="currentColor" d="M0 331.7h1600M0 337.9h1600M0 349.2h1600M0 366.2h1600M0 389.2h1600M0 418.4h1600M0 454.1h1600M0 496.4h1600M0 545.6h1600M0 601.9h1600M0 665.3h1600M0 736.1h1600M0 814.2h1600M0 900h1600" class="hero-lattice-floor-grid"></path></g><rect width="1600" height="900" fill="url(#hero-lattice-floor-veil)" class="hero-lattice-floor-veil"></rect></svg>
  <div class="hero-scrim" aria-hidden="true"></div>
  <div class="hero-copy">
    <h1>Your heading</h1>
    <p>Your supporting sentence.</p>
    <a href="#">Your call to action</a>
  </div>
</section>

animation.css

/* Generated by scripts/hero-lattice.mjs from heroes/hero-lattice-floor/params.json.
   Consumers set four custom properties on any ancestor:
     --pulsar-hero-bg     the ground          (default #0b0a16)
     --pulsar-hero-ink    the grid            (default #ffffff)
     --pulsar-accent      the glows and nodes (default #8a7df7)
     --pulsar-hero-speed  a rate; 2 is twice as fast, 0.5 half speed */
.pulsar-hero-lattice-floor {
  display: block;
  width: 100%;
  height: 100%;
  color: var(--pulsar-hero-ink, #ffffff);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-ground {
  fill: var(--pulsar-hero-bg, #0b0a16);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-accent-stop {
  stop-color: var(--pulsar-accent, #8a7df7);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-ground-stop {
  stop-color: var(--pulsar-hero-bg, #0b0a16);
}
.pulsar-hero-lattice-floor .hero-lattice-floor-band {
  transform-box: view-box;
  will-change: transform;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
.pulsar-hero-lattice-floor .hero-lattice-floor-glow-1 {
  transform-origin: 800px 330px;
  animation-name: hero-lattice-floor-glow-1;
  animation-duration: calc(21s / var(--pulsar-hero-speed, 1));
}
.pulsar-hero-lattice-floor .hero-lattice-floor-glow-2 {
  transform-origin: 800px 330px;
  animation-name: hero-lattice-floor-glow-2;
  animation-duration: calc(27s / var(--pulsar-hero-speed, 1));
}
@keyframes hero-lattice-floor-glow-1 {
  from {
    transform: translate(-40px, -6px) scale(0.9);
  }
  to {
    transform: translate(40px, 6px) scale(1.1);
  }
}
@keyframes hero-lattice-floor-glow-2 {
  from {
    transform: translate(20px, 4px) scale(0.94);
  }
  to {
    transform: translate(-20px, -4px) scale(1.06);
  }
}
@media (prefers-reduced-motion: reduce) {
  .pulsar-hero-lattice-floor .hero-lattice-floor-glow-1,
  .pulsar-hero-lattice-floor .hero-lattice-floor-glow-2 {
    animation: none;
  }
}

More in this series10 in lattice

All heroes