diff --git a/docs/pr-screenshots/dispatch-milestone/after-10-dispatches-mobile.png b/docs/pr-screenshots/dispatch-milestone/after-10-dispatches-mobile.png new file mode 100644 index 0000000..76fbcf7 Binary files /dev/null and b/docs/pr-screenshots/dispatch-milestone/after-10-dispatches-mobile.png differ diff --git a/docs/pr-screenshots/dispatch-milestone/after-10-dispatches.png b/docs/pr-screenshots/dispatch-milestone/after-10-dispatches.png new file mode 100644 index 0000000..04d2e65 Binary files /dev/null and b/docs/pr-screenshots/dispatch-milestone/after-10-dispatches.png differ diff --git a/docs/pr-screenshots/dispatch-milestone/before-10-dispatches.png b/docs/pr-screenshots/dispatch-milestone/before-10-dispatches.png new file mode 100644 index 0000000..50cae1d Binary files /dev/null and b/docs/pr-screenshots/dispatch-milestone/before-10-dispatches.png differ diff --git a/index.html b/index.html index ca20e5e..c7f00b5 100644 --- a/index.html +++ b/index.html @@ -180,6 +180,54 @@ pointer-events: none; } + .milestone { + position: fixed; + inset: 0; + z-index: 8; + display: grid; + place-items: center; + pointer-events: none; + opacity: 0; + } + + .milestone.show { + animation: milestone-pop 1800ms ease-out both; + } + + .milestone-message { + display: grid; + gap: 10px; + place-items: center; + color: var(--ink); + font-size: clamp(30px, 6vw, 72px); + font-weight: 760; + line-height: 1; + text-align: center; + text-shadow: + 0 1px 0 #fff, + 0 12px 34px rgba(0, 0, 0, 0.14); + } + + .milestone-message small { + color: var(--muted); + font-size: clamp(13px, 2.3vw, 18px); + font-weight: 650; + } + + .confetti { + position: fixed; + left: 50%; + top: 50%; + z-index: 7; + width: 10px; + height: 16px; + border-radius: 2px; + background: var(--confetti-color); + pointer-events: none; + transform: translate(-50%, -50%); + animation: confetti-burst 1100ms ease-out forwards; + } + @keyframes wiggle { 0%, 100% { @@ -227,17 +275,58 @@ } } + @keyframes milestone-pop { + 0% { + opacity: 0; + transform: scale(0.86) rotate(-2deg); + } + + 16%, + 72% { + opacity: 1; + transform: scale(1) rotate(0); + } + + 100% { + opacity: 0; + transform: scale(1.05) rotate(1deg); + } + } + + @keyframes confetti-burst { + 0% { + opacity: 1; + transform: translate(-50%, -50%) rotate(0deg) scale(1); + } + + 100% { + opacity: 0; + transform: translate( + calc(-50% + var(--confetti-x)), + calc(-50% + var(--confetti-y)) + ) + rotate(var(--confetti-rotate)) scale(0.8); + } + } + @media (prefers-reduced-motion: reduce) { .hero, - .train-emoji:hover { + .train-emoji:hover, + .milestone.show, + .confetti { animation: none; transition: none; } - .steam { + .steam, + .confetti { display: none; } + .milestone.show { + opacity: 1; + } + .train.ltr, .train.rtl { left: 50%; @@ -284,14 +373,18 @@