Hero Component Archetypes in Hallmark: The Single-Line Typing Effect Explained

Hallmark currently provides exactly one Hero archetype—a single-line typing animation that executes once when the element enters the viewport and remains static thereafter—implemented in the Cobalt example of the Nutlope/hallmark repository.

The Hallmark repository demonstrates a minimalist approach to Hero components through its Cobalt example. This implementation showcases a single Hero component archetype that creates an elegant typing reveal effect using vanilla JavaScript. Understanding this archetype requires examining the interplay between the HTML markup in index.html and the animation logic defined in script.js.

The Single Hero Archetype in Hallmark

Unlike component libraries that offer multiple variations, Hallmark defines only one Hero archetype: a type-once-then-static effect for single-line text. As documented in the source code comments, this archetype handles "ONE response line" that types in upon viewport entry and remains permanently static after completion.

The archetype resides specifically within the Cobalt example (site/examples/cobalt-01/), serving as a demonstration of lightweight, intersection-observer-driven animations without external dependencies.

Implementation Files and Architecture

HTML Markup Structure

The Hero component markup in site/examples/cobalt-01/index.html consists of two essential elements: a text container and an optional cursor indicator.

<span class="type"
      data-type="\n\n## 1. Chunk on headings, not bytes\n\nSplit">

</span><span class="c-cursor" aria-hidden="true"></span>

The data-type attribute stores the complete string to be revealed, while the c-cursor element provides the blinking cursor visual during the animation sequence.

JavaScript Animation Controller

The animation logic lives in site/examples/cobalt-01/script.js, where the runType() function orchestrates the character-by-character reveal. The implementation uses setInterval for timing control and IntersectionObserver for scroll-based activation.

/* ─── Hero: type ONE response line in once, then static ─── */
var typed = document.querySelector('.type');
var cursor = document.querySelector('.c-cursor');
if (typed && typed.dataset.type) {
  var full = typed.dataset.type;
  var heroDemo = document.querySelector('.demo');

  function runType() {
    if (cursor) cursor.classList.add('is-blinking');
    var i = 0;
    var total = 600;                      // ~600 ms total
    var stepMs = Math.max(12, Math.round(total / full.length));
    var timer = setInterval(function () {
      i += 1;
      typed.textContent = full.slice(0, i);
      if (i >= full.length) { clearInterval(timer); }
    }, stepMs);
  }

  var startObs = new IntersectionObserver(function (entries, obs) {
    entries.forEach(function (e) {
      if (!e.isIntersecting) return;
      setTimeout(runType, 380);          // begin after the reveal settles
      obs.disconnect();
    });
  }, { threshold: 0.4 });

  if (heroDemo) startObs.observe(heroDemo); else runType();
}

Animation Execution Flow

The Hero archetype follows a precise four-step execution sequence:

  1. Viewport Detection: An IntersectionObserver with a threshold of 0.4 monitors the .demo container, ensuring the animation triggers only when 40% of the element is visible.

  2. Timing Calculation: The script calculates a per-character interval (stepMs) by dividing the target duration of 600 milliseconds by the string length, with a minimum floor of 12ms per character to maintain readability.

  3. Progressive Reveal: The setInterval timer updates the textContent of the .type element character-by-character, while the cursor element receives the is-blinking class for visual feedback.

  4. Static Completion: Once the counter reaches the full string length, clearInterval(timer) terminates the animation, leaving the text in its final static state without further motion or blinking.

Summary

  • Hallmark implements exactly one Hero archetype: a single-line typing effect that runs once per page load.
  • The implementation relies on native browser APIs including IntersectionObserver and setInterval, requiring no external animation libraries.
  • Source files are located in site/examples/cobalt-01/ with logic in script.js and markup in index.html.
  • The animation targets a 600ms total duration with dynamic per-character timing calculated via Math.max(12, Math.round(600 / full.length)).
  • No multi-line, looping, or image-based Hero variations exist in the current codebase.

Frequently Asked Questions

How many Hero component archetypes exist in Hallmark?

Hallmark contains exactly one Hero archetype. The codebase explicitly documents this as a "type ONE response line in once, then static" implementation, with no alternative variations for multi-line text, static-only displays, or image-based heroes present in the repository.

Where is the Hero component code located in the Hallmark repository?

The Hero archetype resides in the Cobalt example at site/examples/cobalt-01/. The JavaScript logic controlling the typing animation is found in script.js at lines 61-71, while the corresponding HTML markup appears in index.html around line 95.

What triggers the Hero typing animation?

An IntersectionObserver instance triggers the animation when the Hero's container element (.demo) enters the viewport with at least 40% visibility (threshold: 0.4). Upon intersection, a 380ms delay executes before calling runType(), allowing any reveal transitions to settle before typing begins.

Can the Hero archetype handle multi-line text?

No, the current implementation supports only single-line text entries. The archetype is specifically designed for "ONE response line" as noted in the source comments, and the timing calculations (stepMs) assume a continuous string without line-break rendering logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →