mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
fix(ui): make session lineage lines read as arcs, not straight threads
The lines that join a tab to the workers its codeman skill spawned were drawn with numbers tuned against two tabs sitting side by side, and they degraded in exactly the two situations the feature is actually used in. 1. A spawned worker is appended to the END of the strip, so the real span between a lead and its worker is 800-1500px. With the dip clamped at 44px that is a 33px sag: the arc reads as a straight line drawn across the terminal instead of a bracket hanging under the strip. The dip now grows at 0.085/px and clamps at 104. 2. When the desktop strip wraps (tabs-two-rows / tabs-auto-wrap), a parent on row 1 and its child on row 2 are ~14px apart, and the cross-row branch drew parent-bottom to child-TOP: a flat line hidden inside the row gap, with siblings overprinting each other. Both ends now anchor on the tab BOTTOM with the control points below the LOWER row, so a wrapped pair gets the same bracket a flat strip gets. That deletes the branch: one shape covers both. Visibility, at 1:1 rather than in a zoomed mockup: 2 -> 2.5px stroke, 4 4 -> 5 5 dashes (lineage-flow moves with them, -16 -> -20), opacity .55 -> .72, and a second wider glow so the contrast comes from the halo rather than from more weight, keeping the line under the subagent lines' 3px. A working child is bright (.95) outside the reduced-motion block, so turning motion off no longer also dims every worker's arc. Sibling nesting 6 -> 8px and the direction dot 3 -> 3.5px to match the heavier stroke. Verified at 1:1 in a harness driving the real styles.css and the real computeLineagePath over three layouts (adjacent workers, workers at the far end of a full strip, wrapped two-row strip) on a dark and a light skin. test/session-lineage-lines.test.ts pins both regressions. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,17 +93,37 @@ The path math itself lives in `constants.js` as a pure
|
||||
### 4.2 Geometry
|
||||
|
||||
Both endpoints are tabs in one horizontal strip, so the subagent shape (tab-bottom →
|
||||
window-top) does not apply. Two cases:
|
||||
window-top) does not apply. **One case**, a **U-bridge hanging below the strip** that
|
||||
touches both tabs on their bottom edge:
|
||||
|
||||
- **Same row** (the normal case): a shallow **U-bridge hanging below the strip**.
|
||||
`y0 = max(parent.bottom, child.bottom)`, dip
|
||||
`d = clamp(14 + |x2 - x1| * 0.06, 16, 44) + depth * 6`, path
|
||||
`M x1 y0 C x1 y0+d, x2 y0+d, x2 y0`. `depth` is the child's index among its
|
||||
siblings, so several children of one parent **nest** instead of overprinting.
|
||||
- **Different rows** (`tabs-two-rows` / `tabs-auto-wrap` on desktop): the existing
|
||||
vertical bezier from parent-bottom-center to child-top-center.
|
||||
```
|
||||
y0 = max(parent.bottom, child.bottom)
|
||||
d = clamp(14 + |x2 - x1| * 0.085, 22, 104) + depth * 8 + |child.bottom - parent.bottom|
|
||||
path: M x1 parent.bottom C x1 y0+d, x2 y0+d, x2 child.bottom
|
||||
```
|
||||
|
||||
A small `<circle r="3">` at the child end marks direction (an SVG `marker` would need a
|
||||
`depth` is the child's index among its siblings, so several children of one parent
|
||||
**nest** instead of overprinting.
|
||||
|
||||
> **Superseded (2026-08-14): the two shapes this section used to specify.** The dip was
|
||||
> `clamp(14 + span * 0.06, 16, 44) + depth * 6`, and a wrapped strip
|
||||
> (`tabs-two-rows` / `tabs-auto-wrap`) got its own parent-bottom → child-**top** bezier.
|
||||
> Both were tuned against two tabs side by side and failed at the distances the feature
|
||||
> is used at:
|
||||
>
|
||||
> - a skill worker is appended to the **end** of the strip, so the real span is
|
||||
> 800-1500px, where a 44px cap is a 33px sag, i.e. a line that reads as straight and
|
||||
> crosses the terminal instead of bracketing under the strip;
|
||||
> - and when the strip wraps, parent-bottom (34) to child-top (48) leaves **14px** to
|
||||
> bend in, so the arc was a flat line hidden in the row gap, with siblings drawn on
|
||||
> top of each other. Reported as *"they connect already, but the lines are straight
|
||||
> and not easy visible"*.
|
||||
>
|
||||
> Anchoring both ends at the tab bottoms and hanging the control points below the
|
||||
> **lower** row gives the wrapped case the same bracket as the flat one, and removes the
|
||||
> branch. Pinned by `test/session-lineage-lines.test.ts`.
|
||||
|
||||
A small `<circle r="3.5">` at the child end marks direction (it breathes to 4.5 while that worker is busy) (an SVG `marker` would need a
|
||||
`<defs>` block and fights `stroke-dasharray`).
|
||||
|
||||
Each path gets `class="connection-line lineage-line"`, `data-parent-tab`,
|
||||
@@ -139,8 +159,12 @@ callers are cheap. Needed:
|
||||
### 4.5 Styling
|
||||
|
||||
`.connection-line.lineage-line`: violet stroke from a `--lineage-line` token,
|
||||
`stroke-width: 2`, `dasharray 4 4`, `opacity: .55`, softer glow than the subagent lines
|
||||
so the two layers read as different things. Trap to respect: the skin block nests under
|
||||
`stroke-width: 2.5`, `dasharray 5 5`, `opacity: .72` (`.95` while the child works),
|
||||
softer than the subagent lines so the two layers read as different things, but the
|
||||
contrast comes from a **second, wider glow** rather than more weight, because the first
|
||||
cut (2px / `4 4` / `.55` / one 5px glow) disappeared into terminal text on a real 1080p
|
||||
desktop. `lineage-flow` marches by two dash cycles, so it moves with the dash array
|
||||
(`5 5` → `-20`). Trap to respect: the skin block nests under
|
||||
`html:not([data-skin="og"])`, so a bare `.lineage-line` rule inside it would outrank the
|
||||
base rule at higher specificity. **Define the color as a token per skin, keep exactly
|
||||
one `.lineage-line` rule.** Light skins get a darker stroke.
|
||||
|
||||
Reference in New Issue
Block a user