The dim + hole. One fixed div positioned over the target whose oversized
box-shadow paints the scrim — rounded corners come free, and moving the div
animates the hole gliding between steps. By default it carries
pointer-events so the spotlit target is NOT clickable (narrative steps; a
click could unmount the target mid-tour), and a full-viewport shield beneath
swallows clicks on the dimmed page. An interactive step (advanceOn:
"click") instead builds the shield from four rects AROUND the hole and lets
clicks through the cutout, so the target is genuinely clickable. Dismissal
is explicit (X / Escape) — clicking the scrim does nothing, since
accidentally killing a once-per-user tour is worse than one deliberate
click.
The dim + hole. One fixed div positioned over the target whose oversized box-shadow paints the scrim — rounded corners come free, and moving the div animates the hole gliding between steps. By default it carries pointer-events so the spotlit target is NOT clickable (narrative steps; a click could unmount the target mid-tour), and a full-viewport shield beneath swallows clicks on the dimmed page. An
interactivestep (advanceOn: "click") instead builds the shield from four rects AROUND the hole and lets clicks through the cutout, so the target is genuinely clickable. Dismissal is explicit (X / Escape) — clicking the scrim does nothing, since accidentally killing a once-per-user tour is worse than one deliberate click.