fix(hilo): la banda alargaba el documento 5.800px de vacío
Un <svg> con viewBox es un elemento reemplazado con proporción intrínseca (100:1200). Al dimensionarlo con top-0 + bottom-20 y dejar la altura en auto, el navegador la resolvía desde el ancho — 1152 × 12 = 13.824px — y esa altura ganaba silenciosamente a `bottom`. Consecuencias, todas visibles en el navegador y ninguna en los tests: - 5.840px de blanco vacío scrolleable por debajo del footer. - scrollYProgress repartido sobre 13.901px en vez de 8.061, así que el trazo nunca terminaba sobre contenido real. - la onda estirada 1,8x de más, otra vez casi recta. Altura explícita con h-[calc(100%-5rem)], y test que lo fija: jsdom no hace layout, así que el guardián es la clase. El trazo pasa a completarse a mitad de scroll (FIN 0.85 → 0.5). Con 0.85 la punta se quedaba a media pantalla durante el 42% de la página, que es justo lo que se leía como "sin terminar". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d3d5b2f9a
commit
174fcb855a
2 files changed
+21
-5
No files matched your search
@@ -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. */}
|
||||
<div className="relative mx-auto h-full w-full max-w-content">
|
||||
{/* Explicit height, never a top+bottom pair: an <svg> 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. */}
|
||||
<svg
|
||||
className="absolute top-0 bottom-20 left-1/2 w-full -translate-x-1/2 text-dorado/25"
|
||||
className="absolute top-0 left-1/2 h-[calc(100%-5rem)] w-full -translate-x-1/2 text-dorado/25"
|
||||
viewBox={`0 0 100 ${ALTO}`}
|
||||
preserveAspectRatio="none"
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -95,6 +95,17 @@ describe('<HiloConductor />', () => {
|
||||
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(<HiloConductor />);
|
||||
const cls = container.querySelector('svg')?.getAttribute('class') ?? '';
|
||||
// An <svg> 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(<HiloConductor />);
|
||||
const grosor = Number(container.querySelector('path')?.getAttribute('stroke-width'));
|
||||
|
||||
Reference in new issue
Block a user