diff --git a/app.jsx b/app.jsx index 92b8f90..e2dbb5a 100644 --- a/app.jsx +++ b/app.jsx @@ -68,11 +68,46 @@ const GLYPHS = { ], }; -function PixelLogo({ word = "FACERE", scale = 11, gap = 0 }) { +function useResponsiveLogoScale(word = "FACERE") { + const [scale, setScale] = useState(() => computeLogoScale(word)); + useEffect(() => { + let raf = 0; + const onResize = () => { + cancelAnimationFrame(raf); + raf = requestAnimationFrame(() => setScale(computeLogoScale(word))); + }; + window.addEventListener("resize", onResize); + window.addEventListener("orientationchange", onResize); + return () => { + cancelAnimationFrame(raf); + window.removeEventListener("resize", onResize); + window.removeEventListener("orientationchange", onResize); + }; + }, [word]); + return scale; +} + +function computeLogoScale(word) { + // Total logo width = letters * GLYPH_W * scale + (letters-1) * scale * 1.6 + // Solve for scale that fits the viewport with side margins. + if (typeof window === "undefined") return 11; + const vw = window.innerWidth; + const letters = word.length; + const sideMargin = vw < 480 ? 0.10 : vw < 760 ? 0.12 : 0.16; // each side + const usable = vw * (1 - 2 * sideMargin); + const denom = letters * GLYPH_W + (letters - 1) * 1.6; + const fit = Math.floor(usable / denom); + // Clamp so it doesn't get too small or absurdly large on ultrawide. + return Math.max(4, Math.min(11, fit)); +} + +function PixelLogo({ word = "FACERE", scale, gap = 0 }) { + const responsiveScale = useResponsiveLogoScale(word); + const px = scale ?? responsiveScale; const letters = word.split(""); return (