Fix overflow in normal browser tab (fit after responsive layout)

Symptoms

In Replit preview: logo fits.

In a normal Chrome tab: logo overflows the preview box.

Cause (likely)

We compute fitToPreview() before the full page layout settles (sidebar/header widths, container max-widths, or fonts). The preview rect grows after our fit, so the logo ends up scaled/translated wrong in the larger tab.

Do this (all 5):

Measure the true inner preview element

Only ever read getBoundingClientRect() from the exact inner preview node (previewRef.current) — not the card/container.

Defer first fit until layout is stable

Run fitToPreview() after:

requestAnimationFrame and a micro-delay (e.g., one more rAF) and window.onload fallback.

If rect.width === 0 || rect.height === 0, retry next rAF until non-zero (cap ~10 frames).

Respond to responsive changes

Add a ResizeObserver on the preview element and on the page’s main layout container (the one that changes at breakpoints).

On resize, recompute only if the user hasn’t manually moved/scaled (or provide a “Refit” button to do it on demand).

Lock SVG sizing + aspect

<svg> must have:

preserveAspectRatio="xMidYMid meet"

no width/height attributes (strip them)

CSS: svg { display:block; width:100%; height:100%; }

Preview box: fixed height (e.g., 520px) and overflow: hidden;

Ensure no ancestor applies transform: scale() (browser zoom styles) to the preview; it breaks bbox math.

Guard the fit math

Compute initialScale from untransformed #logo-root.getBBox() vs current preview rect with 8–10% padding.

Apply exactly: transform="translate(tx, ty) scale(initialScale)".

If any value is NaN or rect is 0, abort and retry on next rAF.

Acceptance

Open “Scales of Justice” in a normal tab → auto-fits with padding, no overflow.

Resize the window (trigger breakpoints) → still fits (or “Refit” resets it).

Replit preview remains fine.

(Optional UX)

Add a “Refit to Screen” button in the Logo panel → calls fitToPreview().

If it still overflows, log these and paste back:

previewRect (w,h) when fit runs,

<svg>.getAttribute('viewBox'),

#logo-root.getBBox() before transform,

the transform applied to #logo-root.

Those four numbers will pinpoint whether it’s a rect timing issue, a bad viewBox, or an off-node transform.