diff --git a/web/src/components/Companion/useCardOverlap.ts b/web/src/components/Companion/useCardOverlap.ts index 6d5c363..686a593 100644 --- a/web/src/components/Companion/useCardOverlap.ts +++ b/web/src/components/Companion/useCardOverlap.ts @@ -24,6 +24,21 @@ export interface CardOverlap { modal: boolean } +// The mascot shrinks a step when it yields (.petal-companion-faded), and +// getBoundingClientRect reports the *scaled* box. Measuring that lets the +// mascot shrink out of its own overlap test: it yields, stops overlapping, +// wakes back up, overlaps again — pulsing forever against a card that sits just +// at its edge. The layout box doesn't move when it yields, so measure that. The +// transform origin is the centre, so it's the visual centre ± the layout size. +function layoutRect(el: HTMLElement) { + const r = el.getBoundingClientRect() + const halfW = el.offsetWidth / 2 + const halfH = el.offsetHeight / 2 + const cx = (r.left + r.right) / 2 + const cy = (r.top + r.bottom) / 2 + return { left: cx - halfW, right: cx + halfW, top: cy - halfH, bottom: cy + halfH } +} + // Reports what, if anything, the mascot should yield to at the given element. // Used to fade the corner mascot out of the way when a card or panel reaches // into its corner, so nothing is ever hidden (or made unclickable) by the @@ -37,7 +52,7 @@ export function useCardOverlap(ref: RefObject): CardOverlap const check = () => { const el = ref.current if (!el) return - const r = el.getBoundingClientRect() + const r = layoutRect(el) const hits = (selector: string) => { for (const other of document.querySelectorAll(selector)) { const b = other.getBoundingClientRect()