> ## Documentation Index
> Fetch the complete documentation index at: /llms.txt
> Use this file to discover all available pages before exploring further.

# Word-Sweep Highlight

> A sentence whose word-by-word emphasis is driven by a single scalar — tween it to sync the highlight with a voiceover

# Word-Sweep Highlight

A sentence whose word-by-word emphasis is driven by a single scalar — tween it to sync the highlight with a voiceover

**Word-Sweep Highlight**

```html mk-callout-highlight.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
    <style>
      *,
      *::before,
      *::after {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        background: transparent;
        overflow: hidden;
      }
      #mk-ch-root {
        /* ---- mk tokens: override in the host to re-skin the family ---- */
        --mk-font: "Inter", -apple-system, sans-serif;
        --mk-ink: #1d1d1f;
        /* faint = transient pre-sweep tier (tweens up to full ink) — distinct from the family --mk-ink-dim */
        --mk-ink-faint: #bcbcc2;
        --mk-ink-dark: #f5f5f7;
        --mk-ink-faint-dark: rgba(245, 245, 247, 0.32);

        position: relative;
        width: 1920px;
        height: 1080px;
        overflow: hidden;
        background: transparent; /* overlays footage or mk-background */
      }
      #mk-ch-box {
        position: absolute;
        font-family: var(--mk-font);
        font-weight: 500;
        letter-spacing: -0.015em;
      }
      .mk-ch-word {
        display: inline;
      }
    </style>
  </head>
  <body>
    <div
      id="mk-ch-root"
      data-composition-id="mk-callout-highlight"
      data-start="0"
      data-duration="8"
      data-width="1920"
      data-height="1080"
    >
      <div id="mk-ch-box" data-layout-allow-occlusion></div>
      <div
        id="mk-ch-drv"
        class="clip"
        data-start="0"
        data-duration="8"
        data-track-index="0"
        style="position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none"
      ></div>
    </div>
    <script>
      (function () {
        window.__timelines = window.__timelines || {};

        /* ---- published parameters (inspector-style CONFIG) ----
           The mechanic: one scalar (highlight progress 0..1) sweeps word-by-word
           emphasis across the sentence — a "highlight amount"
           slider. Tween the scalar over the speaker's sentence to follow speech. */
        var CONFIG = {
          scheme: "light", // "light" (ink on light bg) | "dark" (white on footage)
          text: "Functionality was our goal from the very beginning",
          fontSize: 60,
          lineHeight: 1.3,
          maxWidth: 700, // px; sentence wraps inside this
          x: 1030, // box left edge; null = centered horizontally
          y: null, // box top edge; null = centered vertically
          align: "left",
          sweep: { start: 1.2, end: 6.2 }, // block-local seconds, linear
          animationIn: true, // fade/rise entrance before the sweep
          animationOut: true,
        };

        var DUR = 8;
        var root = document.getElementById("mk-ch-root");
        var box = document.getElementById("mk-ch-box");

        var FULL = CONFIG.scheme === "dark" ? "#f5f5f7" : "#1d1d1f";
        var FAINT = CONFIG.scheme === "dark" ? "rgba(245,245,247,0.32)" : "#bcbcc2";

        box.style.fontSize = CONFIG.fontSize + "px";
        box.style.lineHeight = String(CONFIG.lineHeight);
        box.style.maxWidth = CONFIG.maxWidth + "px";
        box.style.textAlign = CONFIG.align;

        /* build word spans */
        var wordEls = [];
        CONFIG.text.split(/\s+/).forEach(function (w, i) {
          if (i > 0) box.appendChild(document.createTextNode(" "));
          var span = document.createElement("span");
          span.id = "mk-ch-w-" + i;
          span.className = "mk-ch-word";
          span.textContent = w;
          span.style.color = FAINT;
          box.appendChild(span);
          wordEls.push(span);
        });

        /* position (measure after building) */
        var rect = box.getBoundingClientRect();
        box.style.left =
          (CONFIG.x === null ? Math.round((1920 - rect.width) / 2) : CONFIG.x) + "px";
        box.style.top =
          (CONFIG.y === null ? Math.round((1080 - rect.height) / 2) : CONFIG.y) + "px";

        /* state proxy: GSAP animates st.p, render derives every word color from it */
        var st = { p: 0 };
        var mix = gsap.utils.interpolate(FAINT, FULL);
        function render() {
          var k = st.p * wordEls.length;
          for (var i = 0; i < wordEls.length; i++) {
            var f = Math.max(0, Math.min(1, k - i));
            wordEls[i].style.color = mix(f);
          }
        }

        var tl = gsap.timeline({ paused: true });

        if (CONFIG.animationIn) {
          gsap.set(box, { opacity: 0, y: 24 });
          tl.to(box, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, 0.3);
        }

        /* the highlight sweep — one scalar, linear so it tracks speech evenly.
           To follow a real voiceover, replace with several tweens between
           per-phrase progress values (keyframes on the slider). */
        tl.to(
          st,
          { p: 1, duration: CONFIG.sweep.end - CONFIG.sweep.start, ease: "none" },
          CONFIG.sweep.start,
        );

        if (CONFIG.animationOut) {
          tl.to(box, { opacity: 0, y: -16, duration: 0.4, ease: "power2.in" }, DUR - 0.5);
        }
        tl.set(root, { visibility: "hidden" }, DUR - 0.02);

        tl.eventCallback("onUpdate", render);
        render();

        window.__timelines["mk-callout-highlight"] = tl;
      })();
    </script>
  </body>
</html>
```

Copy npx hyperframes add mk-callout-highlight to the clipboard

That writes one file: `compositions/mk-callout-highlight.html`.

## Add it to your video

It runs for 8 seconds at 1920×1080. Paste this into your composition:

```html index.html
<div
  data-composition-id="mk-callout-highlight"
  data-composition-src="compositions/mk-callout-highlight.html"
  data-start="0"
  data-duration="8"
  data-track-index="1"
  data-width="1920"
  data-height="1080"
></div>
```

Move it in time with `data-start`. Put it on a different timeline row with
`data-track-index`. See [data attributes](/concepts/data-attributes.md) for the rest.

{/* hf:generated-footer */}

Tagged `typography` `karaoke` `captions` `minimal`.

## Related topics

* [Browse the complete Catalog](/catalog.md)
* [Add assets and Catalog items in the browser editor](/studio/assets-and-blocks.md)
* [Put blocks together into one video](/concepts/compositions.md)
