[BUG] `prefersReducedMotion: true` freezes the working indicator's elapsed timer until the next keystroke

Status Open
Reported on v2.1.227
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Aug 12, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Version: 2.1.227 · Linux (docker) · tmux 3.7b, TERM=tmux-256color · "tui": "fullscreen"

What happens

With "prefersReducedMotion": true in ~/.claude/settings.json, the elapsed-seconds
counter in the working indicator (Thinking… (36s · thinking some more with xhigh
effort)
) stops advancing. It sits frozen at whatever second it last painted for the
rest of the turn. Pressing any key makes it jump immediately to the correct elapsed
time, so the value is computed correctly — only the repaint is missing.

Setting "prefersReducedMotion": false fixes it, and applies live without a restart.

Why this looks like a repaint-scheduling bug, not a stalled event loop

Under the same setting, in the same session, a statusLine configured with
"refreshInterval": 1 keeps re-rendering on its one-second clock for the entire turn —
including while a long tool call is in flight. Timers are firing and the UI is
repainting; the working-indicator line specifically is not being invalidated.

That points at the elapsed counter having no repaint driver of its own: it appears to
rely on the spinner's animation tick, which reduced motion disables.

Repro

  1. Set "prefersReducedMotion": true in ~/.claude/settings.json
  2. Send a prompt that takes more than ~10s
  3. Watch the (Ns) counter — it freezes; type any character and it snaps to the correct value

Expected

Elapsed time is semantic information about session state, not decoration. Reduced
motion should suppress the shimmer and flash effects while leaving the counter ticking.
Today the only way to get a live timer is to re-enable every animation the setting
exists to turn off.

Possibly related

  • #83878 — Ctrl+B not taking effect until the next keypress arrives (same "state applied only on input" shape)
  • #64020 — prefersReducedMotion: true not fully disabling animation work

View original on GitHub ↗

3 Comments

bcherny collaborator · 15 days ago

Reproduced on v2.1.233 (macOS, tmux).

Steps:

  1. In a project dir, create .claude/settings.json with {"prefersReducedMotion": true} (also reproduces with "tui": "fullscreen").
  2. Start claude, turn fast mode off, set /effort max.
  3. Send a prompt that keeps the model thinking for a while with no tool calls, e.g. "Without using any tools, think extremely deeply for as long as you can about whether P = NP, then answer in one line."
  4. Watch the (Ns · thinking …) counter without touching the keyboard, then press any key.

Observed: the counter stops advancing while the model is thinking. In one run it sat at (1s · thinking with max effort) for the full 60s of a 1m 9s turn. In another it showed (11s …) at 25s of wall clock; typing one character made it jump straight to (26s …), then it stayed at 26s for the next 8s with no further keys.

--- before keypress (25s wall clock)
● Recalibrating… (11s · thinking with max effort)
--- right after typing one character
● Recalibrating… (26s · thinking more with max effort)
--- 8s later, no keys
● Recalibrating… (26s · thinking more with max effort)

The counter does keep moving when something else on screen is changing (tokens streaming, a running Bash tool updating its own timer), which matches the report: the value is right, it just isn't repainted on its own once reduced motion is on.

Expected: the elapsed-seconds counter keeps ticking about once a second under reduced motion; only the spinner animation and shimmer should be suppressed.

Assessment: this looks like a genuine bug. The docs say prefersReducedMotion "reduces or disables spinners, shimmer, and other animations without changing the rest of the interface", but the elapsed timer is status information, not an animation, and it goes stale because the working indicator only repaints on the animation clock that reduced motion turns off. This is longstanding behavior rather than a recent regression. The fix is to keep a slow (about once per second) repaint for the elapsed counter even when reduced motion is on.

🤖 Generated with Claude Code

bcherny collaborator · 5 days ago

Reproduced on the current release (2.1.233), with one narrowing observation.

With "prefersReducedMotion": true and "tui": "fullscreen" (as in your config), the elapsed counter in the working indicator freezes during thinking pauses — I watched it sit at (0s · thinking) for 15+ seconds of real time with no input, then snap to the correct value on the next keystroke, exactly the "value is computed, repaint is missing" shape you described. Toggling prefersReducedMotion back to false live made the same phase tick again.

Two things look better than in 2.1.227, so a partial fix seems to have landed: the counter now ticks during long tool executions even with reduced motion on, and in the default (non-fullscreen) TUI I couldn't reproduce a freeze in any phase. The remaining gap is the fullscreen working indicator during thinking/quiet periods, which matches the frozen Thinking… (36s · …) state in your report.

Agreed on the expectation: elapsed time is state, not decoration, and reduced motion shouldn't stop it updating. Keeping this open for the fullscreen thinking-phase case — in the meantime the default TUI mode keeps a live counter with reduced motion enabled, if that's an acceptable workaround for you.

🤖 Generated with Claude Code

rohitbanga-db · 5 days ago

Is it possible to hide the timer entirely when prefersReducedMotion is set to true or through some related setting? I would personally find it useful to not look at the ticker at all.