feat(stammbaum): render generation gutter on the family tree (#689)

The gutter sits 100 px to the left of the tree canvas on md+ viewports
(hidden entirely below md to preserve scrollable area on phones — see
spec's deliberate dual-audience trade-off). Per occupied generation
row it draws:

- A full-width decorative stripe rect alternating transparent and
  var(--c-gutter-stripe). aria-hidden because it carries no meaning.
- The label `G{n}` at the left edge, sourced from the un-shifted
  node.generation value (never the post-normalise rank), wrapped in
  `<g role="text" aria-label="Generation N">` so screen readers
  announce the full word instead of "G three".

CSS adds --c-gutter-stripe in both the light root and the dark mode
blocks (8% / 14% mint over canvas — decorative contrast carve-out).

Browser tests cover label rendering, the ARIA wrapper, and the
viewport-below-md absent-gutter path via a matchMedia stub. Existing
StammbaumTree structural-invariant tests still pass since none of
them assert anything inside the gutter region.

Refs #689

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-28 15:49:23 +02:00
parent cb8c85a742
commit c0b500b692
3 changed files with 168 additions and 3 deletions

View File

@@ -160,6 +160,12 @@
with axe (tracked in #480) before tweaking the palette. */
--timeline-bar-idle: rgba(161, 220, 216, 0.35);
--timeline-bar-outside: var(--c-line);
/* Stammbaum gutter stripe (issue #689) — decorative full-row underlay
alternating with transparent. Mint-tinted on canvas to mark generation
rows without competing with node fills. 8% on light surface ≈ #ECF6F4
(~1.04:1 vs canvas — decorative carve-out). */
--c-gutter-stripe: rgba(161, 220, 216, 0.08);
}
/* ─── 5. Dark mode ─────────────────────────────────────────────────────────── */
@@ -236,6 +242,10 @@
clears WCAG 1.4.11 non-text contrast for large UI elements. */
--timeline-bar-idle: #3a6e8c;
--timeline-bar-outside: #1a2735;
/* Stammbaum gutter stripe (issue #689) — 14% mint on dark canvas for
visibility parity with the 8% light-mode token. Decorative carve-out. */
--c-gutter-stripe: rgba(161, 220, 216, 0.14);
}
}
@@ -308,6 +318,9 @@
clears WCAG 1.4.11 non-text contrast for large UI elements. */
--timeline-bar-idle: #3a6e8c;
--timeline-bar-outside: #1a2735;
/* Stammbaum gutter stripe (issue #689) — KEEP IN SYNC with the @media block. */
--c-gutter-stripe: rgba(161, 220, 216, 0.14);
}
/* ─── 6. Icon inversion — De Gruyter icons are black SVGs loaded as <img> ──── */