Skip to content

Step the press line as you scroll, with a terminal that replays each unit's lines - #82

Merged
JacobStephens2 merged 3 commits into
mainfrom
issue-65
Sep 26, 2026
Merged

JacobStephens2 merged 3 commits into
mainfrom
issue-65

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

The static press line from #64 stays the source. main.js only steps it, and only when JavaScript runs and prefers-reduced-motion isn't reduce. The steps, buttons and terminal are hidden markup that the script reveals.

stepPressLine(section)                       # skipped with reduced motion; toggles off and on live
  IntersectionObserver(step markers, rootMargin -45% 0px -45% 0px)
    → render(n)                              # n = marker in the centre band, from the observer's own entries
  1–4 buttons → scroll instantly to marker n → render(n)
  render(n)                                  # sets the whole state, never a change from the last step
    lit unit (SVG + its column), aria-current on the buttons
    terminal = earlier units' lines (dimmed) + replay of unit n's lines, copied from the columns
  Pause / Play                               # stops or continues the replay and the cursor blink (WCAG 2.2.2)
 <section class="press">
   sec-head
+  .press-track               # 380vh while stepped; 4 hidden step markers
+    .press-stage             # position: sticky while stepped
       .press-frame (SVG)     # full width; the other units dim, the lit unit glows
+      .press-controls        # 1 · C … 4 · K (hidden until stepped)
       .press-cols            # stepped: only the lit unit's text, no lines
+      .press-term            # terminal + Pause (hidden until stepped)
   press-source, misprint

On wide screens, the press is full width and the lit unit's text and the terminal sit beneath it. On phones they stack. Scrolling stays native: no snap, no smooth scroll, and no scroll-linked animation, only 0.25s fades between steps.

There's one non-obvious fix. The observer callback follows the observer's own entries, not the live scroll position. A stress run of 300 random jump sequences found 3 stale steps when the callback read live positions: the observer only notifies on a change from what it last saw. After the fix, 600 of 600 sequences ended consistent.

Evidence

Chromium, 1440×900. From left to right: steps 1–4.

1 · C 2 · M 3 · Y 4 · K
step 1 step 2 step 3 step 4

Chromium, 390×844:

1 · C 2 · M 3 · Y 4 · K
step 1 step 2 step 3 step 4

The replay paused mid-unit (3 · Y): paused

  • Before: the static press line from Press line, static: the full How a Run works diagram in HTML and SVG #64 only.
    After: a Playwright script (run outside the repo, since the site has no front-end tests) passed every check in Chromium and Firefox, at 1440×900 and at 390×844:
    • Scrolling to each step lights that unit and replays exactly its lines (1, 13, 18 and 10).
    • A fast scroll that jumps 1→4→2→3→1→4→3 ends on step 3 with a consistent state. A 20-notch mouse-wheel fling does too.
    • Buttons 3, 1, 4 and 2 each jump to that step, and a nudge of the scroll wheel afterwards agrees.
    • Pause holds the terminal at 3 lines for 1.5s, and Play resumes it (3 → 6 lines).
    • With reduced motion, and with JavaScript off, the full page renders pixel-identical to main, in both engines.
    • cargo test: all suites pass after merging origin/main.
  • Not verified: Safari. Playwright's WebKit can't start on this host: it needs libjxl.so.0.8, which no Ubuntu or Debian archive ships, and there's no root access. The planned human acceptance pass should cover Safari, especially scrollTo({ behavior: "instant" }) and the sticky stage under iOS's collapsing toolbar (the stage uses 100svh).
  • The share card is unaffected. docs/share-card/render.mjs clones the SVG out of .press, and all the dimming CSS is scoped under .press.is-stepped.

Merge Danger

Door: two-way

The change touches only site/ (HTML, CSS and one JS module). Reverting it restores the #64 version.

Blast Radius: home-page

The press section becomes about 3.8 viewport heights tall while stepped, which changes the page's scroll length. Readers with reduced motion or without JavaScript see no change.

Unaddressed findings

Standards

  • Step as a bare 1-based integer, and the count of four in HTML, CSS and JS (possible Primitive Obsession / Shotgun Surgery): the press line is fixed content with four units. A fifth unit would need new SVG, a new column and a new button anyway.
  • render mixes working out the state with writing it to the DOM (testability): the spec rules out front-end tests. Checks are by screenshots and the human acceptance pass.
  • Two per-unit colour maps in CSS (--glow on SVG units, --ink on columns): these are different elements with different tokens. The glows use the "glows only" neon tokens. Sharing a key would mean adding classes to the SVG just for this.

Spec

Closes #65

🤖 Generated with Claude Code

JacobStephens2 and others added 3 commits September 26, 2026 14:32
…unit's lines

The static press line from #64 stays the source. Unless the reader prefers
reduced motion, main.js makes the section sticky over about four viewport
heights and steps it: step markers watched by an IntersectionObserver, and
1-4 step buttons, all call one render(n) that sets the lit unit, the button
state and the terminal's lines. The terminal replays copies of the lit
unit's lines from the columns, with Pause and Play.

The observer's state follows its own entries rather than the live scroll
position, so a fast scroll back to the last observed step can't leave a
stale step lit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erminal log

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps the press line's track and stage wrappers (and their re-indent) and
reapplies main's links from the unit columns' skill labels to the Prompts
and skills page. main.js keeps both main's commit label and the press
stepping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit 5091249 into main Sep 26, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-65 branch September 26, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Press line, motion: stepped, sticky, with terminal replay

1 participant