Live demo, running in your browser

Obsidian panther

A violet hero with a giant cream FOCUS wordmark while a black panther with gold veins prowls across it, passing in front of the lower letters, with drifting golden motes and a wavy shimmer on the animation.

Assets

Code: MIT license. Imagery generated with Google Gemini · Video generated with Google Veo

<!doctype html>
<html lang="en">
  <head
    ><script>
      /* 6to9 pattern harness */ (function () {
        var parentPaused = false,
          hidden = document.hidden,
          p = (window.__pattern = { paused: false, reducedMotion: false, maxDpr: 2 });
        function sync() {
          p.paused = parentPaused || hidden;
        }
        sync();
        try {
          p.reducedMotion = matchMedia("(prefers-reduced-motion: reduce)").matches;
        } catch (e) {}
        document.addEventListener("visibilitychange", function () {
          hidden = document.hidden;
          sync();
        });
        addEventListener("message", function (e) {
          var d = e.data || {};
          if (d.pattern === "pause") {
            parentPaused = true;
            sync();
          }
          if (d.pattern === "play") {
            parentPaused = false;
            sync();
          }
        });
      })();
    </script>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Veinwork - Obsidian Panther</title>
    <style>
      html,
      body {
        margin: 0;
        height: 100%;
        background: #6b2cf5;
        overflow: hidden;
      }
      .hero {
        position: relative;
        width: 100vw;
        height: 100vh;
        height: 100svh;
        overflow: hidden;
        background: #6b2cf5;
        color: #f7edd8;
        font-family:
          system-ui,
          -apple-system,
          Segoe UI,
          Helvetica Neue,
          Arial,
          sans-serif;
      }
      canvas {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        display: block;
      }
      h1 {
        position: absolute;
        margin: 0;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
      }
      .nofx h1 {
        width: auto;
        height: auto;
        clip-path: none;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 27vw;
        font-weight: 900;
        letter-spacing: -0.045em;
        padding-bottom: 12vh;
        background: radial-gradient(
          60% 40% at 50% 62%,
          rgba(255, 190, 70, 0.35),
          rgba(255, 190, 70, 0) 70%
        );
      }
      .top {
        position: absolute;
        top: 28px;
        left: 32px;
        right: 32px;
        display: flex;
        justify-content: space-between;
        font-size: 13px;
        font-weight: 700;
        letter-spacing: 0.22em;
        text-transform: uppercase;
        opacity: 0.85;
      }
      .foot {
        position: absolute;
        left: 32px;
        right: 32px;
        bottom: 36px;
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: 24px;
      }
      .sub {
        margin: 0;
        max-width: 420px;
        font-size: 19px;
        line-height: 1.45;
        font-weight: 500;
      }
      .sub b {
        color: #ffd36b;
        font-weight: 700;
      }
      .cta {
        appearance: none;
        border: 0;
        cursor: pointer;
        padding: 18px 30px;
        border-radius: 999px;
        background: #14081f;
        color: #f7edd8;
        font: inherit;
        font-size: 16px;
        font-weight: 700;
        letter-spacing: 0.04em;
        box-shadow: inset 0 0 0 1.5px #e6b450;
        transition:
          transform 0.25s ease,
          background 0.25s ease;
      }
      .cta:hover {
        transform: translateY(-2px);
        background: #240f3a;
      }
      @media (max-width: 640px) {
        .top {
          top: 20px;
          left: 20px;
          right: 20px;
          font-size: 11px;
        }
        .foot {
          left: 20px;
          right: 20px;
          bottom: 28px;
          flex-direction: column;
          align-items: flex-start;
          gap: 20px;
        }
        .sub {
          font-size: 17px;
        }
      }
    </style>
  </head>
  <body>
    <section class="hero" id="hero">
      <canvas id="stage"></canvas>
      <h1>FOCUS</h1>
      <div class="top">
        <span>Veinwork</span>
        <span>No. 01 / Obsidian</span>
      </div>
      <div class="foot">
        <p class="sub">Carved from black glass, veined in gold. <b>Stay on what matters.</b></p>
        <button class="cta" type="button">Start focusing</button>
      </div>
    </section>
    <script>
      (function () {
        var P = window.__pattern || { paused: false, reducedMotion: false, maxDpr: 2 };
        var hero = document.getElementById("hero");
        var canvas = document.getElementById("stage");
        var ctx = canvas.getContext("2d");
        if (!ctx) {
          hero.classList.add("nofx");
          return;
        }
        var STACK = "system-ui, -apple-system, Segoe UI, Helvetica Neue, Arial, sans-serif";
        var WORD = "FOCUS";
        var CREAM = "#f7edd8";
        var BG = "#6b2cf5";
        var CELL_W = 480;
        var CELL_H = 192;
        var FRAMES = 48;
        var FPS = 24;
        var PERIOD = 20;
        var STEP = 3;
        var atlas = new Image();
        var atlasReady = false;
        atlas.crossOrigin = "anonymous";
        atlas.onload = function () {
          atlasReady = true;
          dirty = true;
        };
        atlas.onerror = function () {
          atlasReady = false;
        };
        atlas.src = "https://agents-dev.6to9.ai/visuals/ef4f298f84011a6689bad696ff39d003.webp";
        var vw = 0;
        var vh = 0;
        var L = null;
        var dirty = true;
        var clock = 0;
        var last = 0;
        var motes = [];
        for (var k = 0; k < 38; k++) {
          motes.push({
            x: Math.random(),
            y: Math.random(),
            r: 0.8 + Math.random() * 2.2,
            v: 0.01 + Math.random() * 0.025,
            s: 0.3 + Math.random() * 0.8,
            t: 1 + Math.random() * 2.5,
            p: Math.random() * 6.28,
          });
        }
        function clamp01(v) {
          return Math.max(0, Math.min(1, v));
        }
        function smooth(v) {
          v = clamp01(v);
          return v * v * (3 - 2 * v);
        }
        function layout() {
          vw = hero.clientWidth || window.innerWidth;
          vh = hero.clientHeight || window.innerHeight;
          var dpr = Math.max(1, Math.min(window.devicePixelRatio || 1, P.maxDpr || 2));
          canvas.width = Math.round(vw * dpr);
          canvas.height = Math.round(vh * dpr);
          ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
          ctx.font = "900 200px " + STACK;
          var track = -0.045;
          var widths = [];
          var total200 = 0;
          for (var i = 0; i < WORD.length; i++) {
            var w = ctx.measureText(WORD[i]).width;
            widths.push(w);
            total200 += w;
          }
          total200 += track * 200 * (WORD.length - 1);
          var capRatio = ctx.measureText("H").actualBoundingBoxAscent / 200;
          if (!capRatio) {
            capRatio = 0.72;
          }
          var fs = (200 * (vw * 0.92)) / total200;
          fs = Math.min(fs, (vh * 0.44) / capRatio);
          var scale = fs / 200;
          var total = total200 * scale;
          var x = (vw - total) / 2;
          var xs = [];
          for (var j = 0; j < WORD.length; j++) {
            xs.push(x);
            x += widths[j] * scale + track * fs;
          }
          var capH = capRatio * fs;
          var small = vw < 640;
          var baseline = vh * (small ? 0.42 : 0.47) + capH / 2;
          var H = capH * 1.4;
          var W = H * (CELL_W / CELL_H);
          L = {
            fs: fs,
            xs: xs,
            capH: capH,
            baseline: baseline,
            H: H,
            W: W,
            bottom: baseline + H * 0.04,
            pawLine: baseline - capH * 0.2,
          };
          dirty = true;
        }
        function drawWord(clipY) {
          ctx.save();
          if (clipY) {
            ctx.beginPath();
            ctx.rect(0, 0, vw, clipY);
            ctx.clip();
          }
          ctx.fillStyle = CREAM;
          ctx.font = "900 " + L.fs + "px " + STACK;
          ctx.textAlign = "left";
          ctx.textBaseline = "alphabetic";
          for (var i = 0; i < WORD.length; i++) {
            ctx.fillText(WORD[i], L.xs[i], L.baseline);
          }
          ctx.restore();
        }
        function drawStrips(index, alpha, dx, dy, time) {
          if (alpha <= 0.002) {
            return;
          }
          var sx = (index % 4) * CELL_W;
          var sy = Math.floor(index / 4) * CELL_H;
          var s = L.W / CELL_W;
          var amp = L.W * 0.009;
          ctx.globalAlpha = alpha;
          for (var srcY = 0; srcY < CELL_H; srcY += STEP) {
            var h = Math.min(STEP + 1, CELL_H - srcY);
            var off =
              amp * Math.sin(srcY * 0.055 - time * 2.4) +
              amp * 0.5 * Math.sin(srcY * 0.021 + time * 1.3);
            ctx.drawImage(
              atlas,
              sx,
              sy + srcY,
              CELL_W,
              h,
              dx + off,
              dy + srcY * s,
              L.W,
              h * s + 0.6,
            );
          }
          ctx.globalAlpha = 1;
        }
        function drawPanther(time, p) {
          var fade = smooth(p / 0.07) * smooth((1 - p) / 0.07);
          var startX = -0.45 * L.W;
          var endX = vw - 0.55 * L.W;
          var dx = startX + (endX - startX) * p;
          var bob = Math.sin(time * 0.9) * L.H * 0.018;
          var dy = L.bottom - L.H + bob;
          ctx.save();
          var cx = dx + L.W * 0.5;
          var cy = L.bottom - L.H * 0.03;
          var rx = L.W * 0.4;
          var ry = L.H * 0.06;
          ctx.translate(cx, cy);
          ctx.scale(1, ry / rx);
          var g = ctx.createRadialGradient(0, 0, 0, 0, 0, rx);
          g.addColorStop(0, "rgba(25, 0, 70, 0.5)");
          g.addColorStop(1, "rgba(25, 0, 70, 0)");
          ctx.globalAlpha = fade;
          ctx.fillStyle = g;
          ctx.beginPath();
          ctx.arc(0, 0, rx, 0, Math.PI * 2);
          ctx.fill();
          ctx.restore();
          if (!atlasReady) {
            return;
          }
          var f = (time * FPS) % FRAMES;
          var i = Math.floor(f);
          var frac = f - i;
          var next = (i + 1) % FRAMES;
          drawStrips(i, fade, dx, dy, time);
          drawStrips(next, fade * frac, dx, dy, time);
        }
        function drawMotes(time) {
          ctx.save();
          ctx.fillStyle = "#ffd06a";
          for (var i = 0; i < motes.length; i++) {
            var m = motes[i];
            var yy = (((m.y - time * m.v) % 1) + 1) % 1;
            var xx = m.x * vw + Math.sin(time * m.s + m.p) * 18;
            var tw = Math.sin(time * m.t + m.p);
            ctx.globalAlpha = 0.15 + 0.5 * tw * tw;
            ctx.beginPath();
            ctx.arc(xx, yy * vh, m.r, 0, Math.PI * 2);
            ctx.fill();
          }
          ctx.restore();
        }
        function render(time, p) {
          if (!L) {
            return;
          }
          ctx.globalAlpha = 1;
          ctx.fillStyle = BG;
          ctx.fillRect(0, 0, vw, vh);
          drawWord(0);
          drawPanther(time, p);
          drawMotes(time);
          drawWord(L.pawLine);
        }
        function frame(now) {
          requestAnimationFrame(frame);
          var dt = Math.min(0.05, Math.max(0, (now - last) / 1000));
          last = now;
          if (P.reducedMotion) {
            if (dirty) {
              render(8.2, 0.42);
              dirty = false;
            }
            return;
          }
          if (P.paused) {
            if (dirty) {
              render(clock, (clock / PERIOD) % 1);
              dirty = false;
            }
            return;
          }
          clock += dt;
          render(clock, (clock / PERIOD) % 1);
          dirty = false;
        }
        window.addEventListener("resize", layout);
        layout();
        requestAnimationFrame(frame);
      })();
    </script>
  </body>
</html>

Made by 6to9. Back to all motion patterns.