diff --git a/src/content-scripts/interventions/blur-disable.ts b/src/content-scripts/interventions/blur-disable.ts index 208f038..aa80a90 100644 --- a/src/content-scripts/interventions/blur-disable.ts +++ b/src/content-scripts/interventions/blur-disable.ts @@ -20,19 +20,38 @@ const INTERCEPTED_EVENT_TYPES = ['pointerdown', 'mousedown', 'mouseup', 'click'] const LOCK_ICON_SVG = ''; +// `backdrop-filter` (not `filter`) is deliberate: `filter` on the container +// would recomposite the container's entire subtree — including the lock +// icon overlay appended below as its child — as one filtered unit, blurring +// the icon along with the button (filter/opacity are compositing +// properties, so a child's own `filter:none` can't opt back out once an +// ancestor sets one). `backdrop-filter` on the overlay instead only blurs +// what's painted *behind* the overlay; the overlay's own children (the +// icon) paint on top of that blurred backdrop unaffected, no DOM +// restructuring of the site's own (React-owned) nodes required. const OVERLAY_STYLE = [ 'position:absolute', - 'inset:0', + // 4px on every side instead of a flush `inset:0`, so the overlay reads as + // slightly larger than the pill it's covering rather than exactly + // clipped to it. + 'top:-4px', + 'bottom:-4px', + 'left:-4px', + 'right:-4px', 'display:flex', 'align-items:center', 'justify-content:center', 'pointer-events:auto', 'cursor:not-allowed', 'z-index:2147483000', - 'filter:none', - 'opacity:1', + // A light blur (vs. the earlier 3px) avoids the pixelated look on small + // pill-sized targets; darkening + desaturating the backdrop is what + // actually communicates "disabled" here, the blur alone was carrying too + // much of that job. + 'backdrop-filter:blur(1px) grayscale(0.6) brightness(0.55)', + '-webkit-backdrop-filter:blur(1px) grayscale(0.6) brightness(0.55)', + 'background:rgba(0,0,0,0.25)', 'color:#fff', - 'background:transparent', ].join(';'); /** @@ -50,8 +69,6 @@ export const blurDisable: Intervention = { const originalStyleAttr = container.getAttribute('style'); const computedPosition = getComputedStyle(container).position; - container.style.filter = 'blur(3px)'; - container.style.opacity = '0.5'; container.style.cursor = 'not-allowed'; container.style.pointerEvents = 'none'; if (computedPosition === 'static') {