refactor(timeline): single-source the spine X position via --spine-x
All checks were successful
CI / fail2ban Regex (pull_request) Successful in 46s
CI / Semgrep Security Scan (pull_request) Successful in 22s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m9s
SDD Gate / RTM Check (pull_request) Successful in 18s
SDD Gate / Contract Validate (pull_request) Successful in 25s
SDD Gate / Constitution Impact (pull_request) Successful in 19s
CI / Unit & Component Tests (push) Successful in 4m33s
CI / OCR Service Tests (push) Successful in 24s
CI / Backend Unit Tests (push) Successful in 5m19s
CI / fail2ban Regex (push) Successful in 46s
CI / Semgrep Security Scan (push) Successful in 26s
CI / Compose Bucket Idempotency (push) Successful in 1m8s
CI / Unit & Component Tests (pull_request) Successful in 4m24s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Successful in 5m21s

The spine offset (0.5rem phone / 50% desktop) was hard-coded in both
TimelineView's .timeline-axis::before and YearBand's .year-node/.letter-dot,
kept in sync only by a comment. Declare --spine-x once on .timeline-axis
and have the markers consume it by inheritance, so a change to the spine
position moves the markers with it. Add a test that the year-node tracks
the token.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #836.
This commit is contained in:
Marcel
2026-06-14 13:51:46 +02:00
parent 0a235dc911
commit 239565ea20
3 changed files with 36 additions and 11 deletions

View File

@@ -85,9 +85,10 @@ const rows = $derived.by<Row[]>(() => {
z-index: 1;
}
/* Spine geometry below mirrors TimelineView's .timeline-axis::before
(left: 0.5rem phone / left: 50% desktop) — keep the two in sync so the
markers never desync from the spine. #833 REQ-003/004/005. */
/* Markers ride on the spine's single source of truth: --spine-x, declared
once on TimelineView's .timeline-axis and inherited here (0.5rem phone /
50% desktop). The 0.5rem fallback only applies when a YearBand is rendered
outside the axis (e.g. component tests). #833 REQ-003/004/005. */
/* Phone (< 1024px): badge sits at the left spine, clearing the node marker.
The badge sits above the node (z-index) so on desktop, where the centered
@@ -105,7 +106,7 @@ const rows = $derived.by<Row[]>(() => {
.year-node {
position: absolute;
top: 50%;
left: 0.5rem;
left: var(--spine-x, 0.5rem);
width: 11px;
height: 11px;
border-radius: 9999px;
@@ -121,7 +122,7 @@ const rows = $derived.by<Row[]>(() => {
.letter-dot {
position: absolute;
top: 0.9rem;
left: 0.5rem;
left: var(--spine-x, 0.5rem);
width: 13px;
height: 13px;
border-radius: 9999px;
@@ -140,9 +141,8 @@ const rows = $derived.by<Row[]>(() => {
margin-left: auto;
margin-right: auto;
}
.year-node {
left: 50%;
}
/* .year-node needs no desktop override — it inherits --spine-x: 50% from
the axis. */
.letter-row {
width: 50%;
padding-left: 0;