Skip to content

Hang the margin action's hover lift on the press spelling, not the class - #117

Merged
max-sixty merged 3 commits into
mainfrom
fix/ci-33278297208
Aug 30, 2026
Merged

Hang the margin action's hover lift on the press spelling, not the class#117
max-sixty merged 3 commits into
mainfrom
fix/ci-33278297208

Conversation

@leaf-agent

@leaf-agent leaf-agent commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Problem

985d242 landed the fix this PR opened with — the hand off the class, role="img" on the copy's mark, the CLAUDE.md paragraph — so the branch is now rebased down to the half that commit left behind. .lf-margin-action's hover lift still keys on the class alone, so an exported copy's standing reaction mark still rises to --chip under the pointer, which is the same promise the hand was making, in the other property.

The three tone hovers have the same shape, and :not([aria-disabled="true"]) is no guard in a file: BAKE strips the aria state along with the role, so a decided suggestion's record — which survives a copy on data-lf-said — lights its accept or reject tint under a pointer that can decide nothing. No shipped example carries a decided suggestion, so the corpus never asks.

Solution

Spell all four hovers the way the hand is now spelled: :is(button, [role="button"]). Every margin action is a <button> or an offer("button", …) span, so a live page is unchanged; a copy, whose roles BAKE removed, stops lifting.

The copy's offering reading takes the cursor and nothing else, so no gate could see this half — which is why the class-hung hand went red and the class-hung lift did not. test_a_copy_keeps_a_standing_reaction_as_a_mark_and_drops_the_press now hovers the mark in the exported file and holds its background still.

Testing

  • Bug-back: with the scoping reverted, the new assertion fails on rgb(238, 234, 222) against rgb(255, 254, 251) — the copy lifting to --chip.
  • uv run pytest tests/test_render_reactions.py tests/test_render_export.py tests/test_render_margin.py tests/test_render_drafts.py --run-nightly — 112 passed.
  • uv run pytest tests — 721 passed, 6 skipped.
  • pre-commit run --files … on both changed files — clean.

What is still red on main

Two of the seven, both at 81653d3 + this branch, from this runner:

  • test_render_gate.py::test_a_page_hands_its_note_strip_back_when_the_panel_takes_the_room<lf-option id=nx-revoke> and three siblings drawn 14px outside <lf-options id=next-jobs>;
  • test_render_pages.py::test_a_drawing_stands_on_the_columns_axis_until_it_needs_the_free_margin — a scrollbar where both margins hold the drawing whole.

985d242 closed the other four (the aim press, both conversation cases, and the decided-note timeout). Neither remaining one is this PR's concern and I have not touched them.

The drawing case, measured here

At 1500×900 on DIAGRAM_AND_RAIL_PAGE, DRAWING_PLACEMENT reads: column 257.5 → 977.5, rail at 1023.5, the wide drawing 1216.66 wide, and its box 24 → 1211. So the box takes the left margin whole and stops 289px short of the window on the right, which leaves the drawing about 30px over its box — hence the scrollbar the assert refuses, and the 14.8px it sits off the column's axis. Both drawings are below the row that claims the rail, so by the test's premise the right margin is theirs to take too.

@leaf-agent leaf-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role="img" swap and the cursor scoping both read correctly, and every marginAction call site is a <button> or an offer("button", …) span, so nothing on a live page loses its hand.

One thing the fix leaves behind: the hand was not the only paint hung on .lf-margin-action. The line directly under the new rule — .lf-margin-action:hover:not([aria-disabled="true"]) { background: var(--chip); } — still keys on the class alone, so a copy's standing reaction mark still lifts to --chip under the pointer. That is the promise the new CLAUDE.md paragraph rules out ("Paint that promises a gesture … hangs on how a press is spelled … never on a control class alone"), and the pill this PR takes as its model scopes both halves: .lf-pill:is(button, [role="button"]) for the hand and .lf-pill:is(button, [role="button"]):hover for the lift. The export gate won't see it either — offering reads getComputedStyle(el).cursor and nothing else, which is why the class-hung hand was the only half that turned red.

The tone rules a few lines below (.lf-margin-action[data-lf-tone="positive"]:hover:not([aria-disabled="true"]) and its negative twin) have the same shape, and a copy does reach them: a decided suggestion's record survives BAKE on data-lf-said, and the sweep over [data-lf-offer][tabindex] removes every aria-* but aria-label and aria-hiddenaria-disabled among them — so the record that #name set out to make refuse a press lights its accept/reject tint under the pointer in a file. No shipped example carries a decided suggestion, so the corpus never asks.

Separately, the branch no longer merges. main is three commits past this branch's parent, and the last of them (Make leaf a normal Python package and the repository its plugin) moved plugins/leaf/skills/leaf/** to skills/leaf/**; all three non-test files here want rebasing onto the new paths.

Comment thread skills/leaf/assets/runtime/chrome-style.js Outdated
@leaf-agent

Copy link
Copy Markdown
Collaborator Author

All seven failures — this one and the six listed in the body — were introduced by fdaa3ea itself, not by anything that landed after it. I ran the same seven node ids at 62560cc, its parent: 18 passed. At fdaa3ea: 7 failed, 11 passed, each with the message it still carries. All seven still fail on main at 81653d3 (--run-nightly -n 4, 7 failed, 11 passed), so the package restructure did not move any of them either.

The run that dispatched me, for the record

33276954557 on 62560cc had five failures, and none of them needs a fix now:

  • the three offline-review-policy ones, fixed by Serve the examples by path so their shipped data comes with them #116 (merged as 9973180);
  • test_render_reactions.py::test_the_reaction_list_stacks_at_a_narrow_edge_without_moving_comment[keyboard] — that test no longer exists. fdaa3ea replaced it with test_the_reaction_list_joins_a_docked_margin_item_on_a_narrow_screen, which docks the list in the margin item rather than asserting the comment glyph holds its box;
  • test_render_controls.py::test_the_responsive_action_shelf_keeps_primary_actions_in_reachversion news moved the focused banner destination: 761.03125 to {'left': 760.03125, …}, exactly one pixel against a 0.5 tolerance. It did not reproduce in 19 runs here, 12 of them under a concurrent -n 3 browser suite, so I have not written a fix against it. Instrumenting the shelf on a passing run: the focused control sits with shelf.right - box.right - outset == 0.96875 of slack, showNews's compensation loop never has to spend a scroll at all, and the shelf's scrollLeft is whole-pixel (829) while the layout under it is fractional. That makes revealFocus, which runs after that loop and spends a sub-pixel violation, a whole-pixel scroll whenever it fires — the shape of the one-pixel move — but that is a mechanism I could not make happen, not one I watched.

985d242 took `cursor: pointer` off `.lf-margin-action`'s class and hung it on
`:is(button, [role="button"])`, so an exported copy no longer draws a hand over
a gesture it cannot take. The lift under the pointer is the same promise in the
other property and still keys on the class alone: a copy's standing reaction
mark rises to `--chip` under the pointer.

The three tone hovers have the same shape, and `:not([aria-disabled="true"])`
does not guard them in a file — BAKE strips the aria state along with the role,
so a decided suggestion's record, which survives on `data-lf-said`, would light
its accept tint under a pointer that can decide nothing.

The copy's `offering` reading takes the cursor and nothing else, so no gate can
see this half. `test_a_copy_keeps_a_standing_reaction_as_a_mark_and_drops_the_press`
hovers the mark in the exported file and holds its background still; with the
scoping reverted it fails on `rgb(238, 234, 222)` against `rgb(255, 254, 251)`.

Tests: the export, reaction, margin, and draft files pass together (112), and
`uv run pytest tests` is 721 passed, 6 skipped.
@leaf-agent leaf-agent changed the title Take the pointer hand off a copy's margin actions and name the reaction mark Hang the margin action's hover lift on the press spelling, not the class Aug 29, 2026
@max-sixty
max-sixty merged commit 1ad72bc into main Aug 30, 2026
4 checks passed
@max-sixty
max-sixty deleted the fix/ci-33278297208 branch August 30, 2026 22:47
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.

2 participants