diff --git a/components/primitives/HiloConductor.tsx b/components/primitives/HiloConductor.tsx index 64799e0..99b3574 100644 --- a/components/primitives/HiloConductor.tsx +++ b/components/primitives/HiloConductor.tsx @@ -38,10 +38,11 @@ const TRAZO = Array.from({ length: TRAMOS }, (_, i) => { return `C ${x} ${y + PASO * 0.25}, ${salida} ${y + PASO * 0.75}, 50 ${y + PASO}`; }).reduce((d, tramo) => `${d} ${tramo}`, 'M50 0'); -// The draw finishes at 85% of the document instead of at the very bottom: -// scrollYProgress only reaches 1 past the footer, so tying the thread to it -// left the tip trailing in mid-screen and the ending never seen. -const FIN = 0.85; +// The draw finishes halfway down the document. Tied to raw scrollYProgress the +// leading tip sat in mid-viewport for most of the page, reading as an amputated +// stub — the "unfinished" complaint. Finishing early lets the tip outrun the +// reader within the hero and leaves a complete spine for everything after. +const FIN = 0.5; export function HiloConductor({ className = '' }: { className?: string }) { const reduced = usePrefersReducedMotion(); @@ -87,8 +88,12 @@ export function HiloConductor({ className = '' }: { className?: string }) { {/* Mirrors Container's own centring (`mx-auto max-w-content`) so the thread is measured from the real column edge and stays centred in it. */}
+ {/* Explicit height, never a top+bottom pair: an carrying a viewBox + is a replaced element with an intrinsic 100:1200 ratio, so `height: + auto` resolves from the width (1152 → 13824px) and silently wins + over `bottom`, adding ~6000px of blank scroll below the footer. */} ', () => { expect(container.querySelector('path')).toHaveAttribute('vector-effect', 'non-scaling-stroke'); }); + it('sizes the band with an explicit height, never a top+bottom pair', () => { + const { container } = render(); + const cls = container.querySelector('svg')?.getAttribute('class') ?? ''; + // An carrying a viewBox is a replaced element with an intrinsic + // ratio, so `height: auto` resolves from the width and silently beats + // `bottom` — which stretched this one to 13824px and hung ~6000px of blank + // scroll below the footer. jsdom has no layout, so the class is the guard. + expect(cls).toMatch(/\bh-\[/); + expect(cls).not.toMatch(/\bbottom-/); + }); + it('reads as a band, not as a hairline', () => { const { container } = render(); const grosor = Number(container.querySelector('path')?.getAttribute('stroke-width'));