Files
Ajasra 6772e0cf37 perf(booth): optimize assets and result flow
WebP reduces UI payload; JPEG keeps portrait saves compatible.\nFinish ends the visit without prompting another portrait.
2026-10-30 00:00:16 +08:00

481 lines
11 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
/* Local Standalone Self-Hosted Fonts (Zero 3rd-party dependencies) */
@font-face {
font-family: 'CinzelTitle';
src: url('/fonts/Cinzel.ttf') format('truetype');
font-weight: 700 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'DojoFun';
src: url('/fonts/ZCOOLKuaiLe.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
.font-cinzel {
font-family: 'CinzelTitle', 'Georgia', serif;
}
.font-dojo {
font-family: 'DojoFun', 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
/* Fantasy Game UI & Spooky UI Elements */
.game-panel {
background: linear-gradient(180deg, #1f1438 0%, #120a22 100%);
border: 2px solid #5b358a;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.15),
inset 0 -2px 0 rgba(0, 0, 0, 0.6),
0 8px 24px rgba(0, 0, 0, 0.7),
0 0 15px rgba(168, 85, 247, 0.2);
border-radius: 16px;
position: relative;
}
.game-panel-amber {
background: linear-gradient(180deg, #241432 0%, #150920 100%);
border: 2px solid #9a531e;
box-shadow:
inset 0 1px 0 rgba(251, 191, 36, 0.25),
inset 0 -2px 0 rgba(0, 0, 0, 0.7),
0 8px 24px rgba(0, 0, 0, 0.8),
0 0 20px rgba(249, 115, 22, 0.25);
border-radius: 18px;
position: relative;
}
.game-btn-gold {
background: linear-gradient(180deg, #ff9d00 0%, #ea580c 45%, #c2410c 100%);
border-top: 2px solid #fef08a;
border-left: 2px solid #f59e0b;
border-right: 2px solid #f59e0b;
border-bottom: 3px solid #7c2d12;
box-shadow:
0 6px 0 #431407,
0 10px 25px rgba(234, 88, 12, 0.5),
inset 0 1px 0 rgba(255, 255, 255, 0.4);
color: #ffffff;
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.8);
border-radius: 14px;
transition: all 0.15s ease;
}
.game-btn-gold:hover {
filter: brightness(1.1);
}
.game-btn-gold:active {
transform: translateY(4px);
box-shadow:
0 2px 0 #431407,
0 4px 10px rgba(234, 88, 12, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.game-btn-dark {
background: linear-gradient(180deg, #2d1a4d 0%, #1b0e32 100%);
border-top: 1.5px solid #a855f7;
border-left: 1.5px solid #7e22ce;
border-right: 1.5px solid #7e22ce;
border-bottom: 2.5px solid #3b0764;
box-shadow:
0 4px 0 #090314,
inset 0 1px 0 rgba(255, 255, 255, 0.2);
color: #f3e8ff;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
border-radius: 14px;
transition: all 0.15s ease;
}
.game-btn-dark:active {
transform: translateY(2px);
box-shadow: 0 2px 0 #090314;
}
/* Ornate RPG Ribbon Banner Header */
.game-ribbon {
background: linear-gradient(180deg, #7c3aed 0%, #581c87 100%);
border: 1.5px solid #f59e0b;
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.6),
0 0 12px rgba(245, 158, 11, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.35);
position: relative;
}
:root {
--brand-primary: #ff6d00;
--brand-accent: #22c55e;
--brand-bg: #0f091f;
--brand-surface: #1e1136;
--brand-text: #ffffff;
--brand-muted: rgba(238, 230, 255, 0.75);
--sat: env(safe-area-inset-top, 0px);
--sab: env(safe-area-inset-bottom, 0px);
--sal: env(safe-area-inset-left, 0px);
--sar: env(safe-area-inset-right, 0px);
}
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
user-select: none;
}
body {
margin: 0;
padding: 0;
background-color: var(--brand-bg);
color: var(--brand-text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
overflow: hidden;
height: 100vh;
height: 100dvh;
width: 100vw;
width: 100dvw;
overscroll-behavior: none;
touch-action: manipulation;
}
/* Kiosk and Responsive Container */
.kiosk-viewport {
width: 100%;
height: 100%;
height: 100dvh;
max-width: 540px; /* Optimal vertical kiosk aspect on desktop */
max-height: 960px;
position: relative;
overflow: hidden;
box-shadow: 0 25px 60px -10px rgba(0, 0, 0, 0.7), 0 0 40px rgba(168, 85, 247, 0.15);
display: flex;
flex-direction: column;
}
@media (max-width: 640px) {
.kiosk-viewport {
width: 100vw;
width: 100dvw;
height: 100vh;
height: 100dvh;
max-width: 100vw;
max-height: 100dvh;
border-radius: 0 !important;
border-width: 0 !important;
box-shadow: none !important;
}
/* Tailwind's 12px text-xs was too small for the touch-first booth screens. */
.kiosk-viewport .text-xs {
font-size: 0.875rem;
line-height: 1.25rem;
}
.kiosk-viewport [class~="text-[10px]"],
.kiosk-viewport [class~="text-[11px]"],
.kiosk-viewport [class~="text-[12px]"] {
font-size: 0.875rem;
line-height: 1.25rem;
}
.kiosk-viewport .kiosk-footer-label {
font-size: 0.625rem !important;
line-height: 0.875rem !important;
}
}
/* Fullscreen Mode URL parameter reset (?mode=fullscreen) */
body:has([data-fullscreen="true"]) {
padding: 0 !important;
background-color: var(--brand-bg);
}
/* Subtle border vignette */
.bg-radial-vignette {
background: radial-gradient(circle at center, transparent 60%, rgba(10, 4, 20, 0.6) 100%);
}
/* Spooky Halloween Animations */
@keyframes auroraWave {
0%, 100% {
transform: translateX(-5%) skewY(-2deg) scaleY(0.9);
opacity: 0.35;
}
50% {
transform: translateX(5%) skewY(2deg) scaleY(1.15);
opacity: 0.55;
}
}
@keyframes auroraPulse {
0%, 100% {
transform: scale(0.95);
opacity: 0.25;
}
50% {
transform: scale(1.05);
opacity: 0.45;
}
}
@keyframes cloudDrift {
0% {
transform: translateX(-15px);
opacity: 0.4;
}
50% {
transform: translateX(20px);
opacity: 0.7;
}
100% {
transform: translateX(-15px);
opacity: 0.4;
}
}
@keyframes batFlutter {
0%, 100% {
transform: translate(0, 0) rotate(0deg) scale(1);
}
25% {
transform: translate(6px, -8px) rotate(6deg) scale(1.05);
}
50% {
transform: translate(-4px, -12px) rotate(-4deg) scale(0.95);
}
75% {
transform: translate(8px, -4px) rotate(4deg) scale(1.02);
}
}
@keyframes ghostFloat {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-12px) rotate(3deg);
}
}
@keyframes leafDrift {
0% {
transform: translateY(-20px) translateX(0) rotate(0deg);
opacity: 0;
}
15% {
opacity: 0.85;
}
50% {
transform: translateY(400px) translateX(30px) rotate(180deg);
opacity: 0.8;
}
85% {
opacity: 0.7;
}
100% {
transform: translateY(960px) translateX(-20px) rotate(360deg);
opacity: 0;
}
}
.animate-aurora-wave {
animation: auroraWave 12s ease-in-out infinite alternate;
}
.animate-aurora-pulse {
animation: auroraPulse 8s ease-in-out infinite alternate;
}
.animate-cloud-drift {
animation: cloudDrift 18s ease-in-out infinite;
}
.bat-1 {
animation: batFlutter 6s ease-in-out infinite;
}
.bat-2 {
animation: batFlutter 8s ease-in-out 1.5s infinite;
}
.bat-3 {
animation: batFlutter 7s ease-in-out 3s infinite;
}
.spooky-ghost {
animation: ghostFloat 4.5s ease-in-out infinite;
}
.leaf-1 {
animation: leafDrift 14s linear infinite;
}
.leaf-2 {
animation: leafDrift 18s linear 4s infinite;
}
.leaf-3 {
animation: leafDrift 16s linear 8s infinite;
}
/* Accessible Reduced Motion Settings */
@media (prefers-reduced-motion: reduce) {
.animate-aurora-wave,
.animate-aurora-pulse,
.animate-cloud-drift,
.bat-1,
.bat-2,
.bat-3,
.spooky-ghost,
.leaf-1,
.leaf-2,
.leaf-3 {
animation: none !important;
transform: none !important;
}
}
/* Pulsing loader dots */
@keyframes dotPulse {
0%, 100% {
transform: scale(0.8);
opacity: 0.4;
}
50% {
transform: scale(1.3);
opacity: 1;
}
}
.animate-dot-1 {
animation: dotPulse 1.4s ease-in-out infinite;
}
.animate-dot-2 {
animation: dotPulse 1.4s ease-in-out 0.2s infinite;
}
.animate-dot-3 {
animation: dotPulse 1.4s ease-in-out 0.4s infinite;
}
/* Cartoon UI Utilities (Tactile, chunky, playful) */
.btn-cartoon-orange {
background: linear-gradient(180deg, #ff9100 0%, #ff6d00 50%, #ea580c 100%);
border: 3px solid #1a0826;
box-shadow: 0 6px 0 #9a3412, 0 10px 15px rgba(0, 0, 0, 0.4);
transition: all 0.12s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-cartoon-orange:hover {
filter: brightness(1.08);
transform: translateY(-2px);
box-shadow: 0 8px 0 #9a3412, 0 14px 20px rgba(0, 0, 0, 0.5);
}
.btn-cartoon-orange:active {
transform: translateY(4px);
box-shadow: 0 2px 0 #9a3412, 0 4px 6px rgba(0, 0, 0, 0.4);
}
.btn-cartoon-purple {
background: linear-gradient(180deg, #a855f7 0%, #7e22ce 50%, #581c87 100%);
border: 3px solid #1a0826;
box-shadow: 0 6px 0 #3b0764, 0 10px 15px rgba(0, 0, 0, 0.4);
transition: all 0.12s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-cartoon-purple:hover {
filter: brightness(1.08);
transform: translateY(-2px);
box-shadow: 0 8px 0 #3b0764, 0 14px 20px rgba(0, 0, 0, 0.5);
}
.btn-cartoon-purple:active {
transform: translateY(4px);
box-shadow: 0 2px 0 #3b0764, 0 4px 6px rgba(0, 0, 0, 0.4);
}
.btn-cartoon-instagram {
background: linear-gradient(135deg, #833ab4 0%, #c13584 30%, #e1306c 60%, #fd1d1d 80%, #f77737 100%);
border: 3px solid #1a0826;
box-shadow: 0 6px 0 #4c0519, 0 10px 15px rgba(0, 0, 0, 0.4);
transition: all 0.12s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-cartoon-instagram:hover {
filter: brightness(1.08);
transform: translateY(-2px);
box-shadow: 0 8px 0 #4c0519, 0 14px 20px rgba(0, 0, 0, 0.5);
}
.btn-cartoon-instagram:active {
transform: translateY(4px);
box-shadow: 0 2px 0 #4c0519, 0 4px 6px rgba(0, 0, 0, 0.4);
}
.btn-cartoon-dark {
background: linear-gradient(180deg, #2e1065 0%, #1e0e38 100%);
border: 3px solid #090314;
box-shadow: 0 5px 0 #090314, 0 8px 12px rgba(0, 0, 0, 0.4);
transition: all 0.12s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-cartoon-dark:hover {
transform: translateY(-2px);
box-shadow: 0 7px 0 #090314, 0 12px 16px rgba(0, 0, 0, 0.5);
}
.btn-cartoon-dark:active {
transform: translateY(3px);
box-shadow: 0 2px 0 #090314, 0 4px 6px rgba(0, 0, 0, 0.4);
}
.card-cartoon {
border: 3px solid #1a0826;
box-shadow: 0 6px 0 rgba(10, 4, 20, 0.8), 0 12px 20px rgba(0, 0, 0, 0.5);
}
.card-cartoon-selected {
border: 3px solid #ff9100;
box-shadow: 0 6px 0 #9a3412, 0 0 24px rgba(255, 145, 0, 0.5);
}
@keyframes cartoonWobble {
0%, 100% {
transform: rotate(0deg) scale(1);
}
25% {
transform: rotate(-3deg) scale(1.03);
}
75% {
transform: rotate(3deg) scale(1.03);
}
}
.animate-cartoon-wobble {
animation: cartoonWobble 3s ease-in-out infinite;
}
/* Media Print Optimization */
@media print {
body {
background: #ffffff !important;
color: #000000 !important;
}
.no-print {
display: none !important;
}
.print-only-container {
display: flex !important;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.print-photo {
max-width: 100%;
max-height: 100%;
object-fit: contain;
page-break-inside: avoid;
}
}