/* =========================================== ADAPTIVE TACTICS - Transitions Stylesheet =========================================== */ /* Screen Transitions */ .screen { transition: opacity 0.4s ease-in-out; } .screen.fade-in { animation: fadeIn 0.4s ease-in-out forwards; } .screen.fade-out { animation: fadeOut 0.4s ease-in-out forwards; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } /* Transition Screen Entrance */ #transition-screen.active .transition-content { animation: transitionSlideIn 0.6s ease-out forwards; } @keyframes transitionSlideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* Portrait Reveal */ #transition-portrait { animation: portraitReveal 0.8s ease-out 0.2s both; } @keyframes portraitReveal { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } /* Quote Fade In */ .transition-quote { animation: quoteFadeIn 0.6s ease-out 0.4s both; } .transition-hint { animation: quoteFadeIn 0.6s ease-out 0.6s both; } @keyframes quoteFadeIn { from { opacity: 0; } to { opacity: 1; } } /* Phase Banner */ .phase-banner { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); font-family: var(--font-display); font-size: 2rem; color: var(--gold); text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8); z-index: 500; pointer-events: none; animation: phaseBannerShow 1.5s ease-in-out forwards; } .phase-banner--enemy { color: var(--crimson); } @keyframes phaseBannerShow { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); } 15% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 85% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.1); } } /* Victory Banner */ .victory-banner { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); font-family: var(--font-display); font-size: 2.5rem; color: var(--gold); text-shadow: 0 0 20px rgba(212, 168, 75, 0.6); z-index: 500; pointer-events: none; animation: victoryBannerShow 2s ease-in-out forwards; } @keyframes victoryBannerShow { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); } 20% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); } 30% { transform: translate(-50%, -50%) scale(1); } 80% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1); } } /* Defeat Flash */ .defeat-flash { position: fixed; inset: 0; background: var(--crimson); z-index: 400; pointer-events: none; animation: defeatFlash 0.5s ease-out forwards; } @keyframes defeatFlash { 0% { opacity: 0.6; } 100% { opacity: 0; } } /* Unit Move Animation */ .unit-sprite--moving { transition: left 0.2s ease, top 0.2s ease; } /* Combat Shake */ .tile--shake { animation: combatShake 0.3s ease; } @keyframes combatShake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-2px); } 40% { transform: translateX(2px); } 60% { transform: translateX(-2px); } 80% { transform: translateX(1px); } } /* Button Press Effect */ button:active:not(:disabled) { transform: scale(0.98); } /* Loading Spinner (for async operations) */ .loading-spinner { width: 40px; height: 40px; border: 3px solid var(--border-mid); border-top-color: var(--gold); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Modal Transitions */ .modal { transition: opacity 0.3s ease; } .modal .modal-content { transition: transform 0.3s ease; } .modal.active .modal-content { animation: modalSlideIn 0.3s ease forwards; } @keyframes modalSlideIn { from { transform: translateY(-20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }