From a0d71388c419bf5c43f45e93baec035c67abc1ab Mon Sep 17 00:00:00 2001 From: odysseus Date: Mon, 13 Jul 2026 15:32:09 +1000 Subject: [PATCH] =?UTF-8?q?constellation:=20seamless=20animation=20loops?= =?UTF-8?q?=20=E2=80=94=20dash=20offset=20aligned=20to=20the=20136px=20pat?= =?UTF-8?q?tern=20period=20(dots=20no=20longer=20jump=20at=20the=20seam),?= =?UTF-8?q?=20radar=20ring=20fades=20in=20instead=20of=20popping?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Constellation.astro | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/Constellation.astro b/src/components/Constellation.astro index 57b8c12..e8ac0b8 100644 --- a/src/components/Constellation.astro +++ b/src/components/Constellation.astro @@ -246,11 +246,15 @@ animation: bzRing 3.6s ease-out infinite; } - @keyframes bzDash { to { stroke-dashoffset: -260; } } - @keyframes bzDashRev { to { stroke-dashoffset: 260; } } + /* dash pattern is 9+127 = a 136px period — the loop offset MUST be an exact multiple of it + (2×136 = 272) or every packet dot visibly teleports at the loop seam. */ + @keyframes bzDash { to { stroke-dashoffset: -272; } } + @keyframes bzDashRev { to { stroke-dashoffset: 272; } } @keyframes bzPulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } } @keyframes bzRing { - 0% { transform: scale(0.5); opacity: 0.9; } + /* start AND end at opacity 0 so the 3.6s restart never pops */ + 0% { transform: scale(0.5); opacity: 0; } + 10% { opacity: 0.9; } 100% { transform: scale(1.7); opacity: 0; } }