The css you pass is applied in two places, so both light-DOM and shadow-DOM selectors work in the same block:
On the page — where the documented [swish-placement-element="<id>"] selector matches the placement’s wrapper element, and parent selectors like .product-card:hover [swish-placement-element="<id>"] can reach across ancestors. This is the selector to reach for, and it is inherently scoped to the one placement.
Inside the button’s shadow DOM — where :host and the component’s own internal selectors reach the button itself, which page-level CSS cannot cross into.
Internal selectors such as .button are not scoped to the placement when
they match at the page level. Prefer [swish-placement-element="<id>"] for
anything the page can target, and reserve :host / internal selectors for
styling the component itself. Internal class names and structure may change
between Swish versions.