feat(h5): refine report layout, add finger-following tabs and optimize images

This commit is contained in:
xsl
2026-10-12 22:36:44 +08:00
parent bcf198ca6f
commit 63c9e065a9
22 changed files with 2027 additions and 1535 deletions
+26 -11
View File
@@ -75,20 +75,12 @@
/* Fourth feedback adds a fast one-second round trip to original PSD pixels.
The stage/mask share one contain transform, including short/landscape screens. */
#p-analyzing { background: #000; overflow: hidden; }
.scan-stage { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(100vw, 480px, calc(100dvh * 1080 / 2091)); height: min(100dvh, calc(min(100vw, 480px) * 2091 / 1080)); overflow: hidden; }
.scan-stage { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(100vw, 480px, calc(100dvh * 1080 / 2091)); height: min(100dvh, calc(min(100vw, 480px) * 2091 / 1080)); }
@supports not (height: 100dvh) { .scan-stage { width: min(100vw, 480px, calc(100vh * 1080 / 2091)); height: min(100vh, calc(min(100vw, 480px) * 2091 / 1080)); } }
.scan-artwork { width: 100%; height: 100%; object-fit: contain; }
.scan-face { position: absolute; inset: 0; background: #111; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; overflow: hidden; }
/* Same centered cover crop as the camera; never stretch the captured JPEG.
The PSD mask clips the real face, covering the original white placeholder. */
.scan-photo { position: absolute; left: 50%; top: 50%; width: min(100vw, 480px); height: 100vh; height: 100dvh; max-width: none; object-fit: cover; transform: translate(-50%, -50%); }
.scan-photo.mirror { transform: translate(-50%, -50%) scaleX(-1); }
.scan-photo:not([src]) { visibility: hidden; }
.scan-face { position: absolute; inset: 0; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; overflow: hidden; }
.scan-beam { position: absolute; left: 0; right: 0; top: 20%; height: 18%; background: linear-gradient(to bottom, #F5F078 0%, #F5F078 35%, rgba(245,240,120,0) 100%); }
#p-analyzing:not(.scan-artwork-ready) .scan-artwork { visibility: hidden; }
#p-analyzing:not(.scan-artwork-ready) .scan-face { -webkit-mask-image: none !important; mask-image: none !important; }
#p-analyzing:not(.scan-artwork-ready) .scan-photo { opacity: .6; }
#p-analyzing:not(.scan-artwork-ready) .scan-beam { visibility: hidden; }
#p-analyzing:not(.scan-artwork-ready) .scan-stage { visibility: hidden; }
.scan-running .scan-beam { animation: report-scan var(--scan-cycle, 1000ms) ease-in-out infinite; }
@keyframes report-scan { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(166%); } }
.scan-running:not(.scan-artwork-ready) .scan-status { animation: report-scan-fallback var(--scan-cycle, 1000ms) ease-in-out infinite; }
@@ -114,3 +106,26 @@
#dims-note::before { left: 12px; top: 10px; bottom: 10px; }
#dims-note .dims-note-l1 { font-size: 12px; line-height: 1.5; }
#dims-note .dims-note-l2 { font-size: 11px; line-height: 1.5; margin-top: 3px; }
/* Labels share a top baseline outside the dial; center the score digits, not
digits plus unit, inside the yellow ring. */
.sum-score, .sum-age { flex-direction: column; align-items: center; justify-content: flex-start; gap: calc(6 * var(--u)); }
.sum-age { align-self: stretch; }
.sum-score > .stat-label, .sum-age > .stat-label { font-size: 12px; line-height: 1.5; }
.score-dial, .age-dial { position: relative; width: calc(108 * var(--u)); height: calc(108 * var(--u)); }
.age-dial { display: flex; align-items: center; justify-content: center; }
.age-dial .stat-age { margin-top: 0; }
#stat-score { position: relative; }
#stat-score b { display: block; letter-spacing: 0; }
#stat-score i { position: absolute; left: 100%; bottom: 3px; margin-left: 2px; }
.card-care .card-heading { text-align: left; }
.detail-viewport { overflow: hidden; touch-action: pan-y; transition: height .32s ease; }
.detail-viewport.dragging { transition: none; }
.detail-panels { display: flex; align-items: flex-start; transition: transform .32s cubic-bezier(.22,.61,.36,1); }
.detail-panels.dragging { transition: none; will-change: transform; }
.detail-panels .dpanel { display: block; flex: 0 0 100%; min-width: 0; padding-top: calc(10 * var(--u)); animation: none; }
.detail-panels .ditem-img { -webkit-user-drag: none; }
@media (prefers-reduced-motion: reduce) {
.detail-panels, .detail-viewport { transition-duration: .01ms; }
}