diff --git a/openspec/changes/animate-bullet-thread/.openspec.yaml b/openspec/changes/archive/2026-07-16-animate-bullet-thread/.openspec.yaml similarity index 100% rename from openspec/changes/animate-bullet-thread/.openspec.yaml rename to openspec/changes/archive/2026-07-16-animate-bullet-thread/.openspec.yaml diff --git a/openspec/changes/animate-bullet-thread/design.md b/openspec/changes/archive/2026-07-16-animate-bullet-thread/design.md similarity index 100% rename from openspec/changes/animate-bullet-thread/design.md rename to openspec/changes/archive/2026-07-16-animate-bullet-thread/design.md diff --git a/openspec/changes/animate-bullet-thread/proposal.md b/openspec/changes/archive/2026-07-16-animate-bullet-thread/proposal.md similarity index 100% rename from openspec/changes/animate-bullet-thread/proposal.md rename to openspec/changes/archive/2026-07-16-animate-bullet-thread/proposal.md diff --git a/openspec/changes/animate-bullet-thread/specs/outline-editor/spec.md b/openspec/changes/archive/2026-07-16-animate-bullet-thread/specs/outline-editor/spec.md similarity index 100% rename from openspec/changes/animate-bullet-thread/specs/outline-editor/spec.md rename to openspec/changes/archive/2026-07-16-animate-bullet-thread/specs/outline-editor/spec.md diff --git a/openspec/changes/animate-bullet-thread/tasks.md b/openspec/changes/archive/2026-07-16-animate-bullet-thread/tasks.md similarity index 100% rename from openspec/changes/animate-bullet-thread/tasks.md rename to openspec/changes/archive/2026-07-16-animate-bullet-thread/tasks.md diff --git a/openspec/specs/outline-editor/spec.md b/openspec/specs/outline-editor/spec.md index bdfe561..e2bea11 100644 --- a/openspec/specs/outline-editor/spec.md +++ b/openspec/specs/outline-editor/spec.md @@ -80,6 +80,25 @@ on a terminating guide, the gray tail is suppressed in favor of the bend. Both layers MUST render correctly under virtualization (computed per visible row, no whole-tree pass) and respect the outline's named layout knobs. +**Animated re-threading**: when focus moves between nodes whose visible +ancestor paths share at least one node (the same thread tree — including +creating a node, indenting/outdenting, or selecting another node under the +same thread root), the thread SHALL animate: its tip retracts to the fork +point and extends along the new path to the new bullet, with path bullets +tinting as the tip passes. **Sibling moves are the exception**: when the +old and new paths are identical except for the final node, the +already-extended horizontal elbow SHALL translate vertically between the +two rows instead of retracting and replaying from the parent — replaying +strobed under rapid sibling navigation — with the sibling bullets handing +the tint off through the traveling bend. When focus moves to a node +unrelated to the current thread tree (no shared path nodes), the thread +SHALL appear immediately without animation. When the thread's top anchor +rises to a higher visible ancestor, the top of the thread SHALL animate +upward — in reverse — to the new thread root (and shrink symmetrically +when the anchor falls). Setting the thread animation duration knob to +zero SHALL disable the animation entirely (reduced motion, and the +deterministic mode used by UI tests). + #### Scenario: Deep block is visually anchored - **WHEN** a block nested four levels deep is visible - **THEN** each of its four indent columns shows a guide segment exactly when @@ -92,6 +111,32 @@ row, no whole-tree pass) and respect the outline's named layout knobs. block's bullet, with every bullet on that path tinted the thread color — and moving focus elsewhere re-threads accordingly +#### Scenario: Same-tree refocus flows +- **WHEN** the user splits a block, changes a block's indentation, or moves + focus to another node under the same thread root +- **THEN** the thread visibly retracts to the fork it shares with the new + path and flows to the new focused bullet over the configured duration, + landing exactly on the same rendering an instant re-thread would produce + +#### Scenario: Sibling walks glide the elbow +- **WHEN** the user moves focus between sibling nodes (same parent chain), + repeatedly and in either direction +- **THEN** the elbow translates vertically from the old sibling's bullet + to the new one's — the thread's ancestors stay put and nothing replays + from the parent, so rapid sibling navigation reads as one gliding bend + rather than a strobing re-extension + +#### Scenario: Unrelated refocus is instant +- **WHEN** the user focuses a node in a different subtree, page, or view + that shares no path nodes with the current thread +- **THEN** the new thread appears immediately with no animation + +#### Scenario: Rising root grows upward +- **WHEN** the thread's top anchor moves to a higher visible ancestor + (e.g. scrolling reveals more of the focused block's chain) +- **THEN** the top of the thread animates upward to the new root while the + tip stays anchored on the focused bullet + ### Requirement: Animated programmatic scrolling Programmatic scroll changes (navigation history restore, follow-reference, zoom, scroll-to-focused-block) SHALL animate to the target offset with a