| <script lang="ts"> |
| import type { PicletInstance } from '$lib/db/schema'; |
| import type { BattleState } from '$lib/battle-engine/types'; |
| import ActionButtons from './ActionButtons.svelte'; |
| import TypewriterText from './TypewriterText.svelte'; |
| |
| export let currentMessage: string; |
| export let battlePhase: 'intro' | 'main' | 'moveSelect' | 'picletSelect' | 'ended'; |
| export let processingTurn: boolean; |
| export let battleEnded: boolean; |
| export let isWildBattle: boolean; |
| export let playerPiclet: PicletInstance; |
| export let enemyPiclet: PicletInstance; |
| export let rosterPiclets: PicletInstance[] = []; |
| export let battleState: BattleState | undefined = undefined; |
| export let onAction: (action: string) => void; |
| export let onMoveSelect: (move: any) => void; |
| export let onPicletSelect: (piclet: PicletInstance) => void; |
| export let onBack: () => void; |
| export let waitingForContinue: boolean = false; |
| export let onContinueTap: () => void; |
| |
| |
| $: availablePiclets = rosterPiclets; |
| </script> |
| |
| <div class="battle-controls"> |
| |
| <div class="message-bar {battleEnded ? 'special' : ''}"> |
| <p><TypewriterText text={currentMessage} speed={25} /></p> |
| </div> |
| |
| |
| <div class="action-area"> |
| {#if waitingForContinue} |
| |
| <div class="tap-continue-overlay" role="button" tabindex="0" onclick={onContinueTap} onkeydown={(e) => e.key === 'Enter' || e.key === ' ' ? onContinueTap() : null}> |
| <div class="tap-indicator"> |
| <span>Tap to continue</span> |
| </div> |
| </div> |
| {:else if battlePhase === 'main' && !processingTurn && !battleEnded} |
| <ActionButtons |
| {isWildBattle} |
| {playerPiclet} |
| {enemyPiclet} |
| {availablePiclets} |
| {processingTurn} |
| {battleState} |
| {onAction} |
| {onMoveSelect} |
| {onPicletSelect} |
| {onBack} |
| /> |
| {/if} |
| </div> |
| </div> |
| |
| <style> |
| .battle-controls { |
| flex: 1; |
| display: flex; |
| flex-direction: column; |
| background: white; |
| border-top: 1px solid #e0e0e0; |
| } |
| |
| .message-bar { |
| min-height: 60px; |
| padding: 1rem; |
| background: #f8f9fa; |
| border-bottom: 1px solid #e0e0e0; |
| text-align: left; |
| display: flex; |
| align-items: center; |
| justify-content: flex-start; |
| } |
| |
| .message-bar.special { |
| background: rgba(255, 152, 0, 0.1); |
| border-color: rgba(255, 152, 0, 0.3); |
| } |
| |
| .message-bar p { |
| margin: 0; |
| font-size: 1rem; |
| color: #333; |
| line-height: 1.4; |
| } |
| |
| .action-area { |
| flex: 1; |
| padding: 1rem; |
| display: flex; |
| flex-direction: column; |
| position: relative; |
| } |
| |
| .tap-continue-overlay { |
| position: absolute; |
| top: 0; |
| left: 0; |
| right: 0; |
| bottom: 0; |
| background: rgba(0, 0, 0, 0.05); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| cursor: pointer; |
| border-radius: 8px; |
| } |
| |
| .tap-indicator { |
| background: rgba(0, 0, 0, 0.15); |
| color: #666; |
| padding: 6px 12px; |
| border-radius: 16px; |
| font-size: 12px; |
| font-weight: 400; |
| border: 1px solid rgba(0, 0, 0, 0.1); |
| animation: subtlePulse 3s infinite; |
| } |
| |
| @keyframes subtlePulse { |
| 0%, 100% { |
| opacity: 0.7; |
| transform: scale(1); |
| } |
| 50% { |
| opacity: 0.9; |
| transform: scale(1.02); |
| } |
| } |
| </style> |