Skip to content

Give the year slider something to aim at - #2358

Merged
mholzi merged 1 commit into
mainfrom
fix/2344-decade-labels-on-the-slider
Aug 23, 2026
Merged

Give the year slider something to aim at#2358
mholzi merged 1 commit into
mainfrom
fix/2344-decade-labels-on-the-slider

Conversation

@mholzi

@mholzi mholzi commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Closes #2344.

The issue's own number was wrong

It said roughly four years per thumb-pixel. Measured against the real range: 1950–2026 is 76 years, and on a ~300px track that is 0.25 years per pixel — an 8px thumb movement covers about two years. Out by a factor of sixteen, and corrected in a comment on the issue.

The problem is orientation, not precision. The track carried no landmarks at all, so there was no way to see where 1985 sits. The interaction was drag, read the number, drag again — with twelve seconds on the clock, in a dim room, one-handed. A mark to aim at puts the first movement close and leaves the ±1/±5 buttons doing what they were designed for.

Derived, not pinned

#2337 made the bounds move: applyYearRange() sets min/max from the playlist in play. Marks nailed to fixed percentages would drift the moment a playlist reaches past the default — and the markup shipping an empty container is the point, not an omission.

The scale is rebuilt inside applyYearRange() itself, so the bounds and the marks cannot come from two sources and disagree.

Three details that took the extra lines

The thumb never reaches the edge. A range thumb's centre travels from thumbWidth/2 to width - thumbWidth/2, so marks are laid out inside that inset. One at a true 100% would sit past the highest year the slider can actually select.

The step widens rather than letting labels collide. Past eight marks the interval grows. Measured across the spans that actually occur:

span step marks spacing on a 300px track
1950–2026 (default) 10 8 ~35px
1975–2026 10 5 ~53px
1980–1995 10 2 ~179px
1927–2026 20 5 ~54px

Two digits, until they stop being unambiguous. '80 is language-neutral — no translation needed — and narrow enough that eight fit. But a span crossing a century renders '00 twice, so the short form is used only while every label is distinct; four digits take over otherwise.

Tests

tests/unit/test_year_scale_marks_2344.py, 7 cases. Four fail against the unfixed code:

FAILED test_positions_are_inset_by_half_the_thumb
FAILED test_a_century_crossing_falls_back_to_four_digits
FAILED test_applyyearrange_rebuilds_the_scale
FAILED test_the_markup_ships_an_empty_container
4 failed, 3 passed

The three that pass are the step rule reproduced independently of the source, so a change to the constants shows up as a behavioural diff rather than a silently different picture.

Bundle and CSS rebuilt, all 18 artifacts match. 2058 unit tests green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LYnmkDxHC2drccP1XFpJN4

Closes #2344.

The track carried no landmarks — 76 years of blank rail. Decade marks
now sit under it, derived from the live span.

The issue's own framing was wrong and is corrected in a comment there.
It said roughly four years per thumb-pixel; measured against the real
range, 1950-2026 on a ~300px track is 0.25 years per pixel, so an 8px
thumb movement covers about two years. Out by a factor of sixteen.

The problem is orientation, not precision. There was no way to see where
1985 sits, so the interaction was drag, read the number, drag again —
with twelve seconds on the clock, in a dim room, one-handed. A mark to
aim at puts the first movement close and leaves the +-1/+-5 buttons doing
what they were designed for.

Derived rather than pinned. #2337 made the bounds move: applyYearRange()
sets min/max from the playlist in play, so marks nailed to fixed
percentages would drift the moment a playlist reaches past the default.
The scale is rebuilt from the same span, in the same function, so the
bounds and the marks cannot disagree.

Three details worth the extra lines:

A range thumb's centre travels from thumbWidth/2 to width - thumbWidth/2
and never reaches the edge, so marks are laid out inside that inset. One
at a true 100% would sit past the highest year the slider can select.

The step widens past eight marks rather than letting labels collide. The
default span lands on eight decades, about 35px apart at 10px type.

Labels are two digits with an apostrophe — language-neutral, so no
translation is needed, and narrow enough that eight fit. A span crossing
a century would render '00 twice, so the short form is used only while it
stays unambiguous and four digits take over otherwise.

7 tests, four of which fail against the unfixed code.

Bundle and CSS rebuilt, 18 artifacts match. 2058 unit tests green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LYnmkDxHC2drccP1XFpJN4
@mholzi
mholzi merged commit 7a1242c into main Aug 23, 2026
11 checks passed
@mholzi
mholzi deleted the fix/2344-decade-labels-on-the-slider branch August 23, 2026 13:24
mholzi added a commit that referenced this pull request Aug 23, 2026
manifest 4.3.0 -> 4.3.1-rc1.

Contents since the 4.3.0 stable cut:
- feat(player): decade marks under the year slider (#2358)
- feat(player): the slider ends where the selected playlist ends (#2347)
- feat(errors): the reason a game refuses to start reaches the host, and the
  Mix tab keeps the server's reason (#2295, #2309, #2302)
- fix(player): only a genuinely lost session sends a player back to the join
  screen (#2353)
- fix(player): the submit button re-enables when an answer does not get through
  (#2354), and a reload believes the server about its own submission (#2355)
- fix(game): the round deadline applies to steal and sabotage (#2352)
- fix(api): the current answer is no longer readable from the status endpoint
  before the reveal (#2348)
- fix(playback): confirmation waits for the speaker to actually change tracks
  (#2349)

Catalog and backfill work since 4.3.0 is deliberately absent from the
user-facing notes.

User-facing notes in docs/release-notes-v4.3.1-rc1.md. docs/ is gitignored, so
the notes file is force-added.


Claude-Session: https://claude.ai/code/session_016FybsxoKwCGDToatP3h5u9

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

Give the year slider a scale — 75 years on an unmarked track

1 participant