Replace PseudoClassInvalidator's subtree scan with targeted
invalidation for elements whose pseudo-class state changes. This scopes
state changes to affected selectors instead of rechecking a whole
common-ancestor subtree.
Use the ancestor chain that matches each pseudo-class. Hover walks the
shadow-including chain. :focus-within walks the flat-tree chain, so
slotted content invalidates its assigned slot and relevant shadow-tree
descendants. Focus, FocusVisible, and Target invalidate just the state
node.
Route each affected element through Element::invalidate_style with the
pseudo-class property. This uses the same invalidation-plan machinery as
Disabled, Checked, and other pseudo-class state changes.
Interaction state pseudo classes are not tracked in :has() metadata, so
schedule :has() ancestor invalidation explicitly when the state flips.
The callers no longer need cross-scope branching. The chain walk handles
shadow boundaries, and property invalidation already visits every
observer style scope.