add payday anim
This commit is contained in:
@@ -248,6 +248,15 @@
|
|||||||
// ─── Payday countdown (child view) ───
|
// ─── Payday countdown (child view) ───
|
||||||
let nowMs = $state(Date.now());
|
let nowMs = $state(Date.now());
|
||||||
let eowFired = $state(false);
|
let eowFired = $state(false);
|
||||||
|
// Nyan-style payday party: rainbow banner + confetti when payday unlocks.
|
||||||
|
let paydayParty = $state(false);
|
||||||
|
let partyTimer: ReturnType<typeof setTimeout> | undefined;
|
||||||
|
function startPaydayParty() {
|
||||||
|
paydayParty = true;
|
||||||
|
fire();
|
||||||
|
if (partyTimer) clearTimeout(partyTimer);
|
||||||
|
partyTimer = setTimeout(() => (paydayParty = false), 15000);
|
||||||
|
}
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const id = setInterval(() => (nowMs = Date.now()), 1000);
|
const id = setInterval(() => (nowMs = Date.now()), 1000);
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
@@ -269,6 +278,7 @@
|
|||||||
if (!pbToken || !famId) return;
|
if (!pbToken || !famId) return;
|
||||||
eowFired = true;
|
eowFired = true;
|
||||||
memberApi.payday(famId).catch(() => {});
|
memberApi.payday(famId).catch(() => {});
|
||||||
|
startPaydayParty();
|
||||||
});
|
});
|
||||||
|
|
||||||
function paydayWeekStart(): string {
|
function paydayWeekStart(): string {
|
||||||
@@ -1273,6 +1283,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if paydayParty}
|
||||||
|
<div class="payday-party" role="status" onclick={() => (paydayParty = false)}>
|
||||||
|
<span class="party-cat">🐖</span>
|
||||||
|
<div class="party-body">
|
||||||
|
<p class="party-title">PAYDAY!!</p>
|
||||||
|
<p class="party-sub">Your cash is ready — go collect it! 🎉</p>
|
||||||
|
</div>
|
||||||
|
<span class="party-stars">🌈⭐🌈</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<!-- HERO -->
|
<!-- HERO -->
|
||||||
<header class="hero">
|
<header class="hero">
|
||||||
<svg
|
<svg
|
||||||
@@ -3107,6 +3127,91 @@
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Payday party: nyan-style colour-cycling celebration ── */
|
||||||
|
.payday-party {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding: 1rem 1.2rem;
|
||||||
|
border-radius: 14px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
#ef4444,
|
||||||
|
#f97316,
|
||||||
|
#eab308,
|
||||||
|
#22c55e,
|
||||||
|
#3b82f6,
|
||||||
|
#a855f7,
|
||||||
|
#ec4899,
|
||||||
|
#ef4444
|
||||||
|
);
|
||||||
|
background-size: 300% 100%;
|
||||||
|
animation:
|
||||||
|
nyan-slide 3s linear infinite,
|
||||||
|
party-pop 0.45s ease-out;
|
||||||
|
box-shadow: 0 8px 24px rgba(168, 85, 247, 0.45);
|
||||||
|
}
|
||||||
|
@keyframes nyan-slide {
|
||||||
|
to {
|
||||||
|
background-position: 300% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes party-pop {
|
||||||
|
from {
|
||||||
|
transform: scale(0.85);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.party-cat {
|
||||||
|
font-size: 2.6rem;
|
||||||
|
animation: party-bounce 0.55s ease-in-out infinite alternate;
|
||||||
|
}
|
||||||
|
@keyframes party-bounce {
|
||||||
|
from {
|
||||||
|
transform: translateY(-4px) rotate(-10deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(4px) rotate(10deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.party-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.1rem;
|
||||||
|
}
|
||||||
|
.party-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
animation: party-wiggle 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
@keyframes party-wiggle {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: rotate(-2deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(2deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.party-sub {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
.party-stars {
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
animation: party-bounce 0.55s ease-in-out infinite alternate-reverse;
|
||||||
|
}
|
||||||
/* Mobile: declared last so it wins over the base .goal-mini (.kanban)
|
/* Mobile: declared last so it wins over the base .goal-mini (.kanban)
|
||||||
rules (same specificity, source order decides). */
|
rules (same specificity, source order decides). */
|
||||||
@media (max-width: 639px) {
|
@media (max-width: 639px) {
|
||||||
|
|||||||
Reference in New Issue
Block a user