Attention Scoreboard

A capstone interaction for explaining self-attention from first principles. The learner picks up the glowing query vector at the top of the board and drags it onto each of three token cards; on dock, a dot-product score chip pops in beneath the card. Once every token has been visited, the bars softmax into attention weights and the connecting strokes brighten in proportion to weight.

Self-contained — the component owns drag, keyboard, dock detection, the softmax animation, and the accessibility plumbing. The caller supplies the query and tokens, theme-skins via cb-* tokens, and optionally hooks onComplete to advance a lesson step.

Attention scoreboard. Drag the query vector to each token to compute attention scores."the"k = [1, 0]2"cat"k = [2, 1]5"sat"k = [1, 2]4
The query for "cat" needs to check every key. Drag it to each token to compute a dot-product score.
Customize
Example
the / cat / sat

Installation

npx shadcn@latest add https://craftbits.dev/r/attention-scoreboard.json

Usage

import { AttentionScoreboard } from "@craft-bits/viz/attention-scoreboard";
 
<AttentionScoreboard />

Override the query and tokens for a different example:

<AttentionScoreboard
  query={[2, 1]}
  queryLabel="cat"
  tokens={[
    { label: "the", key: [1, 0], score: 2 },
    { label: "cat", key: [2, 1], score: 5 },
    { label: "sat", key: [1, 2], score: 4 },
  ]}
/>

Hook the completion event to advance a lesson step:

<AttentionScoreboard onComplete={() => goToNextPhase()} />

Understanding the component

  1. Three-stage choreography. The board moves through idlescoringall-scoredsoftmaxingweighted. Each phase swaps the narration tone and unlocks a different chunk of the UI.
  2. Draggable query. The query card lives at the top of the SVG with a breathing accent ring (motion permitting). Pointer events project the cursor into SVG-local coordinates via getScreenCTM, so the query tracks 1:1 with the cursor at any zoom.
  3. Dock detection. On pointer-up the component checks whether the query is within a small radius of any token center; if so, it pops in that token's score chip and marks the token scored. Already-scored tokens get a small pulse instead of a re-dock.
  4. Softmax animation. When the third token is scored, the component waits a beat, then runs each weight bar on a staggered ease-out grow. Once the bars settle, the weight percentage labels fade in and the connecting strokes thicken in proportion to weight.
  5. Keyboard support. Arrow keys move the query in 20-unit SVG steps; Enter or Space docks at the nearest token. Tab focuses the invisible hit-target rectangle.
  6. Reduced motion. Under prefers-reduced-motion: reduce every animation collapses to instant — the query teleports home, chips appear without scaling, bars snap to their target heights, and the breathing ring disappears.

Props

PropTypeDefaultDescription
query[number, number][2, 1]Two-dim query vector rendered inside the draggable card.
queryLabelstring"q"Subscript on the query card.
tokens[Token, Token, Token]the / cat / satExactly three tokens to score against. Each carries a label, two-dim key, and pre-computed score.
onComplete() => voidFired once the weighted phase is reached.
classNamestringMerged onto the root via cn().

Accessibility

  • The outer element exposes data-cb-viz="attention-scoreboard" and data-phase (idle / scoring / all-scored / softmaxing / weighted) so consumer apps can hook custom styles or assistive tooling.
  • The SVG is role="img" with an aria-labelledby pointing at a hidden summary line — screen readers hear the live score count as the board progresses.
  • The hit target is role="slider" with an aria-label carrying the query readout and the live score count, plus aria-valuetext carrying the live position. Arrow keys move the query; Enter or Space docks.
  • The narration line is role="status" with aria-live="polite" (suppressed during drag to avoid mid-gesture chatter). Tone shifts ride the cb-accent / cb-warning / cb-success palette so colourblind users still see the change via the swap of the narration text itself.
  • Motion respects prefers-reduced-motion: reduce — the breathing ring, dock pulse, score-chip pop, softmax bar grow, and query return-home all collapse to instant.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/math/AttentionScoreboard.tsx). The viz extract accepts the query and tokens via props, swaps every project-specific color for a cb-* token, replaces the inline springs with SPRINGS.smooth / SPRINGS.bouncy, drops the bespoke SvgLabel for plain <text> elements, and adds an onComplete callback so the same component can drive lessons, demos, or one-off explainers.