# How Stories Work in the Archify Viewer: Declarative Walkthroughs for Diagrams

> Learn how Archify stories create guided SVG diagram walkthroughs. Discover declarative attributes and automatic state transitions for interactive narratives.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: internals
- Published: 2026-08-14

---

**Archify stories are guided, interactive walkthroughs defined by `data-story-beat` and `data-story-step` attributes in SVG markup that the viewer's runtime parses into an ordered timeline, managing state transitions to drive CSS animations and caption updates automatically.**

The Archify viewer (from the `tt-a1i/archify` repository) transforms static architecture diagrams into interactive experiences using a declarative story system. By embedding specific data attributes directly into your HTML or SVG elements, you create **story beats** and **steps** that the runtime automatically sequences into animated guided tours without requiring custom JavaScript. This article examines the source code implementation to show exactly how the viewer discovers, parses, and plays these stories.

## What Are Story Beats and Steps?

The Archify story system uses a two-level hierarchy to structure guided experiences.

**Story beats** act as containers that group related visualization states into a single narrative unit. A beat is defined by the `data-story-beat` attribute on an SVG or HTML element.

**Story steps** are individual elements within a beat that become active in sequence. Marked with `data-story-step`, these elements represent the specific diagram components (nodes, edges, or groups) that receive visual emphasis as the story progresses.

As the story advances, the runtime toggles the `data-story-beat-state` attribute on each step between three values: `"past"` for completed steps, `"active"` for the current step, and `"next"` for upcoming steps. CSS selectors target these states to trigger highlight animations, opacity changes, or focus effects.

## Declarative Markup in SVG

You define a story directly in your diagram markup by adding data attributes to the elements you want to highlight. The viewer requires no additional configuration files because the metadata lives with the visual elements.

```html
<svg data-story-beat id="authentication-flow">
  <!-- Step 1: Highlight the Client node -->
  <g data-story-step data-story-beat-state="next" class="client-node">
    <rect width="100" height="40" x="50" y="50" />
    <text x="100" y="75">Client</text>
  </g>

  <!-- Step 2: Highlight the authentication edge -->
  <path data-story-step 
        data-story-beat-state="next" 
        d="M150 70 L250 70" 
        class="connection-line"/>

  <!-- Step 3: Highlight the Auth Service -->
  <g data-story-step data-story-beat-state="next">
    <rect width="120" height="40" x="250" y="50" />
    <text x="310" y="75">Auth Service</text>
  </g>
</svg>

```

The `data-story-beat` attribute on the root SVG signals to the runtime that this element contains a sequence to be indexed. Each child with `data-story-step` is ordered according to its DOM position, creating the playback sequence.

## Runtime Discovery and State Management

When the viewer initializes, it scans the document to build an internal timeline of all available stories.

In [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) around line 3370, the discovery logic executes `querySelectorAll('[data-story-beat]')` to locate every story container. For each beat found, the script queries for `[data-story-step]` children and stores them in an ordered array that functions as the story's timeline.

The state machine tracks the current step index and updates the `data-story-beat-state` attributes on the DOM elements as the user navigates. When `next()` is called—either by user interaction or the auto-play timer—the runtime:
1. Sets the current step's state to `"past"`
2. Advances the pointer to the next element
3. Sets that element's state to `"active"`
4. Updates any subsequent elements to `"next"`

This attribute-based approach decouples the timing logic from the visual presentation, allowing designers to modify animations purely through CSS without touching JavaScript.

## UI Components and Caption System

The viewer provides a standardized interface for story navigation that works automatically once markup is detected.

The caption bar structure appears in [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) between lines 4500 and 4530:

```html
<div class="guided-story-caption" id="guided-story-caption" hidden>
  <span class="guided-story-caption-index" id="guided-story-caption-index">1</span>
  <strong id="guided-story-caption-route">Step Title</strong>
  <small id="guided-story-caption-detail">Description of what is happening.</small>
</div>

```

Navigation controls include:
- **Play/Pause**: The button with class `guided-view-play` (ID `guided-view-play`) toggles automatic advancement using `setInterval`
- **Step Navigation**: Buttons with `data-story-link="forward"` or `data-story-link="backward"` trigger the state machine's `next()` and `prev()` methods
- **Stop**: The `guided-view-stop` button halts playback and resets the story to the initial state

The runtime updates the caption text content dynamically based on the active step's context, though you can customize the caption content by modifying the markup or overriding the update handlers.

## CSS Animations and Visual Feedback

Visual feedback relies entirely on CSS selectors targeting the state attributes. The keyframe definitions reside in the template's stylesheet section around line 4298 of [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html).

```css
[data-story-beat-state="active"] {
  animation: archify-story-flow 1.5s ease-in-out infinite alternate;
  stroke-width: 3px;
  filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.8));
}

[data-story-beat-state="past"] {
  opacity: 0.5;
  filter: grayscale(0.6);
}

[data-story-beat-state="next"] {
  opacity: 0.8;
}

@keyframes archify-story-flow {
  from { stroke: #3b82f6; }
  to { stroke: #60a5fa; }
}

```

Because the runtime only manipulates data attributes, designers have complete control over the visual language of stories. You can replace the default pulse animation with fades, slides, or 3D transforms by modifying the CSS without changing the core viewer logic.

## Programmatic Story Control

While the viewer creates story objects automatically, you can access them via the DOM to build custom controls or integrate with external UI frameworks.

```javascript
// Access the story object attached to the SVG element
const storyElement = document.querySelector('[data-story-beat]');
const story = storyElement.story; // Attached by the runtime

// Manual control
story.play();      // Start auto-advancement
story.pause();     // Pause auto-advancement
story.next();      // Advance one step
story.prev();      // Go back one step
story.stop();      // Reset to beginning and clear active states

// Check current state
console.log(story.currentIndex); // Current step number
console.log(story.totalSteps);   // Total number of steps

```

This API allows integration with routing libraries or presentation frameworks, letting you synchronize the diagram story with documentation scroll position or tutorial checklists.

## Summary

- **Stories** in Archify are created using declarative `data-story-beat` and `data-story-step` attributes embedded directly in SVG or HTML markup.
- The **runtime** discovers stories using `querySelectorAll` and builds an ordered timeline from DOM elements, storing the logic in [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) around line 3370.
- A **state machine** manages progression by cycling `data-story-beat-state` attributes through `"past"`, `"active"`, and `"next"` values.
- **Visual effects** are handled entirely by CSS keyframes (defined near line 4298) that respond to state attribute changes, enabling custom animations without JavaScript modifications.
- **UI controls** including play buttons, navigation arrows, and caption bars are pre-defined in the template (lines 4500-4530) and wire automatically to the story state machine.
- The system supports **programmatic control** through story objects exposed on DOM elements, enabling integration with external applications or custom interaction patterns.

## Frequently Asked Questions

### How do I create a basic story in an Archify diagram?

Add the `data-story-beat` attribute to your root SVG element, then place `data-story-step` on each element you want to highlight in sequence. The viewer automatically detects these attributes and initializes the story timeline when the page loads. No JavaScript initialization is required for basic playback.

### What triggers the visual animations during story playback?

The runtime modifies the `data-story-beat-state` attribute on active elements to `"active"`, which triggers CSS rules defined in the viewer template. The default stylesheet includes pulse animations and glow effects, but you can customize these by targeting `[data-story-beat-state="active"]` in your own CSS.

### Can I control story playback programmatically?

Yes. Once initialized, the viewer attaches a story object to the DOM element bearing `data-story-beat`. Access it via `element.story` to call methods like `play()`, `pause()`, `next()`, and `stop()`. This allows you to synchronize diagram walkthroughs with external documentation or user interactions outside the diagram itself.

### Where is the story logic implemented in the Archify source code?

The core story parsing and state management logic resides in [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html) around line 3370. The caption UI markup appears between lines 4500-4530, and the associated CSS animations are defined near line 4298. Additional examples demonstrating gallery and guide implementations appear in [`scripts/gallery-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/gallery-template.html) and [`scripts/guide-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/guide-template.html).