let cardEl: HTMLElement | null = null;
let cardInnerEl: HTMLElement | null = null;
let resizeAnim: Animation | null = null;
let trackedHeight = 0;
let measuredOnce = false;
let cardResizeReady = false;
const RESIZE_DURATION_MS = 200;
const RESIZE_EASING = "cubic-bezier(0.16, 1, 0.3, 1)";
function prefersReducedMotion(): boolean {
try {
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
} catch (_) {
return false;
}
}
function cardHeightCap(): number {
const compact = window.matchMedia("(max-width: 560px), (max-height: 680px)").matches;
const margin = compact ? 20 : 32;
return Math.max(160, window.innerHeight - margin);
}
function naturalHeight(): number {
if (!cardInnerEl) return 0;
return Math.min(cardInnerEl.offsetHeight, cardHeightCap());
}
function applyHeight(px: number): void {
if (cardEl) cardEl.style.height = Math.round(px) + "px";
}
function settleToContent(): void {
if (!cardEl || !cardInnerEl) return;
const target = naturalHeight();
if (!measuredOnce) {
measuredOnce = true;
trackedHeight = target;
applyHeight(target);
return;
}
if (Math.abs(target - trackedHeight) < 1) return;
const from = cardEl.getBoundingClientRect().height || trackedHeight;
trackedHeight = target;
animateHeight(from, target);
}
function animateHeight(from: number, to: number): void {
const el = cardEl;
if (!el) return;
if (resizeAnim) {
try { resizeAnim.cancel(); } catch (_) {}
resizeAnim = null;
}
applyHeight(to);
if (typeof el.animate !== "function" || prefersReducedMotion() || Math.abs(to - from) < 1) return;
const anim = el.animate(
[{ height: Math.round(from) + "px" }, { height: Math.round(to) + "px" }],
{ duration: RESIZE_DURATION_MS, easing: RESIZE_EASING }
);
resizeAnim = anim;
const clear = (): void => { if (resizeAnim === anim) resizeAnim = null; };
anim.onfinish = clear;
anim.oncancel = clear;
}
export function setupCardResize(): void {
if (cardResizeReady) return;
cardEl = document.getElementById("card");
cardInnerEl = document.getElementById("card-inner");
if (!cardEl || !cardInnerEl || typeof ResizeObserver === "undefined") return;
cardResizeReady = true;
settleToContent();
let scheduled = false;
const observer = new ResizeObserver(() => {
if (scheduled) return;
scheduled = true;
requestAnimationFrame(() => {
scheduled = false;
settleToContent();
});
});
observer.observe(cardInnerEl);
window.addEventListener("resize", () => settleToContent());
}