Add generationStatus and match3d/runtime fixes

Introduce persistent generationStatus to work summaries (puzzle & match3d) and propagate generation recovery rules across docs and frontend/backends so "generating" is restored from server-side work summary rather than ephemeral front-end notices. Update API server image/asset handling (improve match3d material sheet green/alpha decontamination and promote generatedItemAssets background fields) and add runtime improvements: alpha-based hotspot hit-testing, tray insertion/three-match animation behavior, and session re-read on client-side VectorEngine timeouts/lock-screen interruptions. Many docs, tests and related frontend modules updated/added to reflect these contract and behavior changes.
This commit is contained in:
2026-05-16 22:59:02 +08:00
parent bb60ca91ef
commit a45e358e83
42 changed files with 3872 additions and 443 deletions

View File

@@ -281,8 +281,124 @@ body {
will-change: transform, opacity;
}
@keyframes match3d-tray-token-shift {
0% {
transform: translate3d(
var(--match3d-tray-shift-x, 0px),
var(--match3d-tray-shift-y, 0px),
0
);
}
100% {
transform: translate3d(0, 0, 0);
}
}
.match3d-tray-token-shift {
animation: match3d-tray-token-shift 0.24s cubic-bezier(0.2, 0.8, 0.2, 1)
both;
will-change: transform;
}
@keyframes match3d-tray-token-clear {
0% {
opacity: 1;
transform: translate3d(-50%, -50%, 0) scale(1);
}
62% {
opacity: 1;
transform:
translate3d(
calc(-50% + var(--match3d-tray-clear-dx, 0px)),
calc(-50% + var(--match3d-tray-clear-dy, 0px)),
0
)
scale(0.84);
}
100% {
opacity: 0;
transform:
translate3d(
calc(-50% + var(--match3d-tray-clear-dx, 0px)),
calc(-50% + var(--match3d-tray-clear-dy, 0px)),
0
)
scale(0.38);
filter: blur(1px);
}
}
.match3d-tray-token-clear {
transform: translate3d(-50%, -50%, 0);
animation: match3d-tray-token-clear 0.46s cubic-bezier(0.2, 0.72, 0.18, 1)
both;
transform-origin: center;
will-change: transform, opacity;
}
@keyframes match3d-tray-clear-flash {
0% {
opacity: 0;
transform: translate(-50%, -50%) scale(0.2);
}
42% {
opacity: 0.95;
}
100% {
opacity: 0;
transform: translate(-50%, -50%) scale(1.45);
}
}
.match3d-tray-clear-flash {
width: 4rem;
height: 4rem;
border-radius: 9999px;
background:
radial-gradient(circle, rgba(255, 255, 255, 0.95) 0 10%, transparent 12%),
radial-gradient(circle, rgba(255, 236, 157, 0.48) 0 42%, transparent 64%);
box-shadow:
0 0 22px rgba(255, 255, 255, 0.62),
0 0 52px rgba(251, 191, 36, 0.34);
mix-blend-mode: screen;
animation: match3d-tray-clear-flash 0.46s ease-out both;
transform: translate(-50%, -50%);
}
@keyframes match3d-merge-feedback-pulse {
0% {
opacity: 0;
transform: scale(0.48);
}
42% {
opacity: 0.8;
}
100% {
opacity: 0;
transform: scale(1.28);
}
}
.match3d-merge-feedback-pulse {
animation: match3d-merge-feedback-pulse 0.52s ease-out both;
background:
radial-gradient(circle, rgba(255, 255, 255, 0.56) 0 18%, transparent 20%),
radial-gradient(circle, rgba(255, 255, 255, 0.28) 0 45%, transparent 68%);
}
@media (prefers-reduced-motion: reduce) {
.match3d-token-fly-to-tray {
.match3d-token-fly-to-tray,
.match3d-tray-token-shift,
.match3d-tray-token-clear,
.match3d-tray-clear-flash,
.match3d-merge-feedback-pulse {
animation-duration: 1ms;
}
}