<script setup lang="ts">
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useTranscriptDebug } from '@/composables/transcript-debug'
import { useVoiceInput } from '@/composables/useVoiceInput'
import { ChatContainer, AquaticBackground, AgentBadge, NewSessionModal } from '@/components/transcript-debug'
import type { AgentName } from '@/types/transcript-debug'

const props = defineProps<{
  modelValue: boolean
}>()

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
}>()

const isOpen = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

// ============================================================================
// TRANSCRIPT DEBUG STATE (composable)
// ============================================================================

const {
  selectedAgent,
  sessions,
  selectedSessionId,
  conversation,
  loading,
  transitioning,
  transitionError,
  error,
  isRealtime,
  processing,
  ephemeral,
  terminalReady,
  hookMeta,
  openTerminals,
  activeTerminalSessionId,
  init,
  switchAgent,
  selectSession,
  createNewSession,
  startTerminal,
  parkCurrentTerminal,
  fetchSessionContent,
  switchToTerminal,
  closeTerminal,
  disconnectRealtime,
  sendPrompt
} = useTranscriptDebug()

const voice = useVoiceInput({ language: 'es-419' })
const {
  isRecording: voiceRecording,
  transcript: voiceTranscript,
  interimTranscript: voiceInterim,
  voiceMode,
  whisperStatus,
  audioDevices,
  selectedDeviceId,
  lastAudioUrl,
  isPlayingAudio,
} = voice

const agents: { id: AgentName; label: string }[] = [
  { id: 'ejecutor', label: 'Ejecutor' },
  { id: 'nucleo000', label: 'nucleo000' },
  { id: 'claude', label: 'Claude' }
]

const showSelector = ref(false)
const showNewSessionModal = ref(false)
const chatRef = ref<InstanceType<typeof ChatContainer> | null>(null)
let initialized = false

// ============================================================================
// CHROME VISIBILITY (idle mode: hide UI chrome when not interacting)
// ============================================================================

const isHovered = ref(false)
const isFocusWithin = ref(false)

const showChrome = computed(() =>
  isHovered.value || isFocusWithin.value || isDragging.value ||
  isResizing.value || showSelector.value
)

// ============================================================================
// OCEAN LIFE STATE
// ============================================================================

const currentHour = ref(new Date().getHours())

const isNightTime = computed(() => currentHour.value >= 20 || currentHour.value < 6)
const isNoonTime = computed(() => currentHour.value >= 11 && currentHour.value <= 13)
const isDawnTime = computed(() => currentHour.value >= 5 && currentHour.value <= 7)
const isFridayTime = computed(() => new Date().getDay() === 5)
const isMidnightTime = computed(() => currentHour.value === 0)

const showComet = ref(false)
const showWhale = ref(false)
const showBottle = ref(false)
const showLeviathan = ref(false)

const oceanSeeds = Array.from({ length: 20 }, () => Math.random())
let oceanLifeTimer: ReturnType<typeof setInterval> | null = null

function tickOceanLife() {
  currentHour.value = new Date().getHours()
  if (!showComet.value && Math.random() < 0.04) {
    showComet.value = true
    setTimeout(() => { showComet.value = false }, 3000)
  }
  if (!showWhale.value && Math.random() < 0.07) {
    showWhale.value = true
    setTimeout(() => { showWhale.value = false }, 95000)
  }
  if (!showBottle.value && Math.random() < 0.025) {
    showBottle.value = true
    setTimeout(() => { showBottle.value = false }, 125000)
  }
  if (!showLeviathan.value && Math.random() < 0.008) {
    showLeviathan.value = true
    setTimeout(() => { showLeviathan.value = false }, 310000)
  }
}

// ============================================================================
// DRAG STATE
// ============================================================================

const windowRef = ref<HTMLElement | null>(null)
const isDragging = ref(false)
const position = ref({ x: 0, y: 0 })
const hasCustomPosition = ref(false)
const dragOffset = ref({ x: 0, y: 0 })

// Resize state
const isResizing = ref(false)
const size = ref({ w: 480, h: 600 })

// Zoom level for content scaling
const zoom = ref(1)

// Size mode: pin (small, anchored to FAB), medium (default), large
type SizeMode = 'pin' | 'medium' | 'large'
const savedSize = localStorage.getItem('transcript-size-mode') as SizeMode | null
const sizeMode = ref<SizeMode>(savedSize && ['pin', 'medium', 'large'].includes(savedSize) ? savedSize : 'medium')

// Readability overlay opacity
const savedOverlay = localStorage.getItem('transcript-overlay-opacity')
const overlayOpacity = ref(savedOverlay !== null ? parseFloat(savedOverlay) : 0.55)

function setOverlayOpacity(val: number) {
  overlayOpacity.value = val
  localStorage.setItem('transcript-overlay-opacity', String(val))
}

// Input textarea max lines
const savedMaxLines = localStorage.getItem('transcript-input-max-lines')
const inputMaxLines = ref(savedMaxLines !== null ? parseInt(savedMaxLines) : 6)

function setInputMaxLines(val: number) {
  inputMaxLines.value = val
  localStorage.setItem('transcript-input-max-lines', String(val))
}

// Scroll nav mode: 'scrollbar' | 'buttons' | 'none'
type ScrollNavMode = 'scrollbar' | 'buttons' | 'none'
const savedScrollNav = localStorage.getItem('transcript-scroll-nav') as ScrollNavMode | null
const scrollNavMode = ref<ScrollNavMode>(
  savedScrollNav && ['scrollbar', 'buttons', 'none'].includes(savedScrollNav) ? savedScrollNav : 'buttons'
)

function setScrollNavMode(val: ScrollNavMode) {
  scrollNavMode.value = val
  localStorage.setItem('transcript-scroll-nav', val)
}

// Scroll jump percent
const savedScrollJump = localStorage.getItem('transcript-scroll-jump')
const scrollJumpPercent = ref(savedScrollJump !== null ? parseInt(savedScrollJump) : 50)

function setScrollJumpPercent(val: number) {
  scrollJumpPercent.value = val
  localStorage.setItem('transcript-scroll-jump', String(val))
}

function scrollJump(direction: 'up' | 'down') {
  const el = (chatRef.value as any)?.$el?.querySelector('.messages-scroll') as HTMLElement | null
  if (!el) return
  const amount = el.clientHeight * (scrollJumpPercent.value / 100)
  el.scrollBy({ top: direction === 'up' ? -amount : amount, behavior: 'smooth' })
}

function scrollToEdge(edge: 'top' | 'bottom') {
  const el = (chatRef.value as any)?.$el?.querySelector('.messages-scroll') as HTMLElement | null
  if (!el) return
  el.scrollTo({ top: edge === 'top' ? 0 : el.scrollHeight, behavior: 'smooth' })
}

// Force mobile (bottom sheet) mode on desktop
const forceMobile = ref(false)
const effectiveMobile = computed(() => isMobile.value || forceMobile.value)

function toggleForceMobile() {
  if (isMobile.value) return // already native mobile
  forceMobile.value = !forceMobile.value
  if (forceMobile.value) {
    // Enter mobile: set sheet height based on current sizeMode
    const mobileSnaps: Record<SizeMode, number> = { pin: 20, medium: 55, large: 100 }
    sheetHeight.value = mobileSnaps[sizeMode.value]
    hasCustomPosition.value = false
  }
}

function cycleSizeMode() {
  const modes: SizeMode[] = ['pin', 'medium', 'large']
  const i = modes.indexOf(sizeMode.value)
  sizeMode.value = modes[(i + 1) % modes.length]
  localStorage.setItem('transcript-size-mode', sizeMode.value)
  hasCustomPosition.value = false

  // In mobile mode, also update sheet height
  if (effectiveMobile.value) {
    const mobileSnaps: Record<SizeMode, number> = { pin: 20, medium: 55, large: 100 }
    sheetHeight.value = mobileSnaps[sizeMode.value]
  }
}

// Mobile bottom sheet state
const isMobile = ref(false)
const sheetHeight = ref(55)

// ============================================================================
// MOBILE DETECTION
// ============================================================================

function checkMobile() {
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0
  const isSmallScreen = window.innerWidth <= 1024
  isMobile.value = isTouchDevice && isSmallScreen
}


// ============================================================================
// WINDOW DRAG
// ============================================================================

function startDrag(e: MouseEvent) {
  if (effectiveMobile.value) return

  isDragging.value = true
  const rect = windowRef.value?.getBoundingClientRect()
  if (rect) {
    if (!hasCustomPosition.value) {
      position.value = { x: rect.left, y: rect.top }
    }
    dragOffset.value = { x: e.clientX - rect.left, y: e.clientY - rect.top }
  }

  document.addEventListener('mousemove', onDrag)
  document.addEventListener('mouseup', stopDrag)
}

function onDrag(e: MouseEvent) {
  if (!isDragging.value) return

  const w = windowRef.value?.offsetWidth || 480
  const h = windowRef.value?.offsetHeight || 600
  const minX = -w * 0.75
  const maxX = window.innerWidth - w * 0.25
  const minY = -h * 0.75
  const maxY = window.innerHeight - h * 0.25

  position.value = {
    x: Math.max(minX, Math.min(e.clientX - dragOffset.value.x, maxX)),
    y: Math.max(minY, Math.min(e.clientY - dragOffset.value.y, maxY))
  }
}

function stopDrag() {
  isDragging.value = false
  hasCustomPosition.value = true
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
}

// ============================================================================
// WINDOW RESIZE
// ============================================================================

const resizeStart = ref({ x: 0, y: 0, w: 0, h: 0 })

function startResize(e: MouseEvent) {
  e.preventDefault()
  e.stopPropagation()
  isResizing.value = true
  resizeStart.value = { x: e.clientX, y: e.clientY, w: size.value.w, h: size.value.h }
  document.addEventListener('mousemove', onResize)
  document.addEventListener('mouseup', stopResize)
}

function onResize(e: MouseEvent) {
  if (!isResizing.value) return
  size.value = {
    w: Math.max(360, Math.min(resizeStart.value.w + e.clientX - resizeStart.value.x, window.innerWidth - 40)),
    h: Math.max(300, Math.min(resizeStart.value.h + e.clientY - resizeStart.value.y, window.innerHeight - 40))
  }
}

function stopResize() {
  isResizing.value = false
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
}

// ============================================================================
// COMPUTED STYLE
// ============================================================================

const sizeModePresets: Record<SizeMode, { w: number; h: number }> = {
  pin: { w: 240, h: 300 },
  medium: { w: 480, h: 600 },
  large: { w: 800, h: 760 }
}

const windowStyle = computed((): Record<string, string> => {
  if (effectiveMobile.value) {
    const isFullScreen = sheetHeight.value >= 100
    const headerEl = document.querySelector('.app-header') as HTMLElement | null
    const headerH = headerEl ? headerEl.offsetHeight : 40
    const style: Record<string, string> = {
      position: 'fixed',
      left: '0',
      right: '0',
      width: '100%',
    }

    style.bottom = '0'
    if (isFullScreen) {
      style.top = `${headerH}px`
      style.height = 'auto'
    } else {
      style.height = `${sheetHeight.value}dvh`
    }
    return style
  }

  const preset = sizeModePresets[sizeMode.value]

  // Custom position from dragging (uses current resize size or preset)
  if (hasCustomPosition.value) {
    const w = sizeMode.value === 'medium' ? size.value.w : preset.w
    const h = sizeMode.value === 'medium' ? size.value.h : preset.h
    return {
      width: `${w}px`,
      height: `${h}px`,
      top: `${position.value.y}px`,
      left: `${position.value.x}px`,
      bottom: 'auto',
      right: 'auto'
    }
  }

  // Pin: anchored to FAB button (bottom-left corner aligned)
  if (sizeMode.value === 'pin') {
    return {
      width: `${preset.w}px`,
      height: `${preset.h}px`,
      bottom: '20px',
      left: '80px'
    }
  }

  // Large: centered-ish, generous size
  if (sizeMode.value === 'large') {
    return {
      width: `${preset.w}px`,
      height: `${preset.h}px`,
      bottom: '16px',
      left: '90px'
    }
  }

  // Medium (default)
  return {
    width: `${size.value.w}px`,
    height: `${size.value.h}px`,
    bottom: '16px',
    left: '90px'
  }
})

// ============================================================================
// ACTIONS
// ============================================================================

function close() {
  isOpen.value = false
  showSelector.value = false
}

function openAtCursor(x: number, y: number) {
  if (effectiveMobile.value) {
    isOpen.value = !isOpen.value
    return
  }
  if (isOpen.value) {
    isOpen.value = false
    return
  }
  const preset = sizeModePresets[sizeMode.value]
  const w = sizeMode.value === 'medium' ? size.value.w : preset.w
  const h = sizeMode.value === 'medium' ? size.value.h : preset.h
  const pad = 8
  const vw = window.innerWidth
  const vh = window.innerHeight
  // Respect app header bar (~40px + safe-area)
  const headerEl = document.querySelector('.app-header') as HTMLElement | null
  const topBarrier = headerEl ? headerEl.getBoundingClientRect().bottom + pad : pad + 40

  // Cursor at bottom-center of window: window extends upward from cursor
  let left = x - w / 2
  let top = y - h

  // Clamp horizontally
  left = Math.max(pad, Math.min(left, vw - w - pad))

  // Clamp vertically: never above header, never below viewport
  top = Math.max(topBarrier, Math.min(top, vh - h - pad))

  position.value = { x: left, y: top }
  hasCustomPosition.value = true
  isOpen.value = true
  nextTick(() => {
    windowRef.value?.querySelector<HTMLTextAreaElement>('.input-field')?.focus()
  })
}

defineExpose({ openAtCursor, openTerminals, activeTerminalSessionId, switchToTerminal, handleCreateSession })

function handleAgentSwitch(agent: AgentName) {
  switchAgent(agent)
}

function handleSessionSelect(sessionId: string) {
  selectSession(sessionId)
  showSelector.value = false
}

function handleSend(message: string) {
  voice.clearTranscript()
  sendPrompt(message)
}

function handleCreateSession() {
  showNewSessionModal.value = true
}

async function handleModalCreateNew(agent: AgentName, initialPrompt: string) {
  showNewSessionModal.value = false
  if (agent !== selectedAgent.value) {
    await switchAgent(agent)
  }
  createNewSession(initialPrompt || undefined)
}

async function handleModalResume(sessionId: string, agent: AgentName) {
  showNewSessionModal.value = false
  if (agent !== selectedAgent.value) {
    await switchAgent(agent)
  }
  // Load transcript + create terminal with --resume
  parkCurrentTerminal()
  selectedSessionId.value = sessionId
  await fetchSessionContent(sessionId)
  await startTerminal(sessionId)
}

// ============================================================================
// WATCHERS
// ============================================================================

watch(isOpen, async (open) => {
  if (open && !initialized) {
    initialized = true
    await nextTick()
    init()
  }
})

// ============================================================================
// KEYBOARD SHORTCUTS (Ctrl+1..5 terminal switch, Ctrl+/- zoom)
// ============================================================================

function handleGlobalKeydown(e: KeyboardEvent) {
  if (!e.ctrlKey) return

  // Ctrl+1..5 → switch to terminal by index
  const num = parseInt(e.key)
  if (num >= 1 && num <= 5) {
    const terminal = openTerminals.value[num - 1]
    if (!terminal) return
    e.preventDefault()
    if (!isOpen.value) isOpen.value = true
    switchToTerminal(terminal.sessionId)
    return
  }

  // Zoom shortcuts (only when open)
  if (!isOpen.value) return
  if (e.key === '+' || e.key === '=') {
    e.preventDefault()
    zoom.value = Math.min(2, +(zoom.value + 0.1).toFixed(1))
  } else if (e.key === '-') {
    e.preventDefault()
    zoom.value = Math.max(0.5, +(zoom.value - 0.1).toFixed(1))
  }
}

// ============================================================================
// LIFECYCLE
// ============================================================================

onMounted(async () => {
  checkMobile()
  window.addEventListener('resize', checkMobile)
  document.addEventListener('keydown', handleGlobalKeydown)
  oceanLifeTimer = setInterval(tickOceanLife, 20000)
  tickOceanLife()
  await voice.init()
  // Terminal registry is now synced via centralized session state WS (no polling needed)
})

onBeforeUnmount(() => {
  if (oceanLifeTimer) clearInterval(oceanLifeTimer)
  disconnectRealtime()
  voice.cleanup()
  document.removeEventListener('keydown', handleGlobalKeydown)
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
  window.removeEventListener('resize', checkMobile)
})
</script>

<template>
  <Teleport to="body">
    <Transition name="win-slide">
      <div
        v-show="isOpen"
        ref="windowRef"
        class="aero-win"
        :class="{
          dragging: isDragging,
          resizing: isResizing,
          mobile: effectiveMobile,
          'chrome-visible': showChrome,
          'selector-open': showSelector,
          'nav-scrollbar': scrollNavMode === 'scrollbar',
          'nav-buttons': scrollNavMode === 'buttons',
          'nav-none': scrollNavMode === 'none'
        }"
        :style="windowStyle"
        @mouseenter="isHovered = true"
        @mouseleave="isHovered = false"
        @focusin="isFocusWithin = true"
        @focusout="isFocusWithin = false"
      >
        <div class="glass" :style="{ zoom: zoom !== 1 ? zoom : undefined }">
          <!-- Thin drag edge (replaces full titlebar drag) -->
          <div
            v-if="!effectiveMobile"
            class="drag-edge"
            @mousedown="startDrag"
          ></div>

          <!-- Titlebar -->
          <div class="titlebar">
            <!-- Ocean Life Ecosystem -->
            <div class="ocean-life">
              <!-- Always visible -->
              <i class="cr fish-school" :style="{ animationDelay: `-${oceanSeeds[0] * 10}s` }"></i>
              <i class="cr fish-school-2" :style="{ animationDelay: `-${oceanSeeds[1] * 14}s` }"></i>
              <i class="cr dolphin" :style="{ animationDelay: `-${oceanSeeds[2] * 12}s` }"></i>
              <i class="cr jellyfish" :style="{ animationDelay: `-${oceanSeeds[3] * 25}s` }"></i>
              <i class="cr seahorse" :style="{ animationDelay: `-${oceanSeeds[4] * 35}s` }"></i>
              <i class="cr turtle" :style="{ animationDelay: `-${oceanSeeds[5] * 50}s` }"></i>
              <i class="cr pirate-ship" :style="{ animationDelay: `-${oceanSeeds[6] * 180}s` }"></i>
              <i class="cr bubble b1" :style="{ animationDelay: `-${oceanSeeds[7] * 6}s` }"></i>
              <i class="cr bubble b2" :style="{ animationDelay: `-${oceanSeeds[8] * 9}s` }"></i>
              <i class="cr bubble b3" :style="{ animationDelay: `-${oceanSeeds[9] * 11}s` }"></i>
              <!-- Night only -->
              <template v-if="isNightTime">
                <i class="cr satellite" :style="{ animationDelay: `-${oceanSeeds[10] * 15}s` }"></i>
                <i class="cr anglerfish" :style="{ animationDelay: `-${oceanSeeds[11] * 40}s` }"></i>
                <i class="cr biolum bl1" :style="{ animationDelay: `-${oceanSeeds[12] * 3.5}s` }"></i>
                <i class="cr biolum bl2" :style="{ animationDelay: `-${oceanSeeds[13] * 4.5}s` }"></i>
                <i class="cr biolum bl3" :style="{ animationDelay: `-${oceanSeeds[14] * 5.5}s` }"></i>
              </template>
              <!-- Rare random -->
              <i v-if="showComet" class="cr comet"></i>
              <i v-if="showWhale" class="cr whale" :style="{ animationDelay: `-${oceanSeeds[15] * 90}s` }"></i>
              <i v-if="showBottle" class="cr bottle" :style="{ animationDelay: `-${oceanSeeds[16] * 120}s` }"></i>
              <i v-if="showLeviathan" class="cr leviathan" :style="{ animationDelay: `-${oceanSeeds[17] * 300}s` }"></i>
              <!-- Time-of-day -->
              <i v-if="isNoonTime" class="cr sun-ray"></i>
              <i v-if="isDawnTime" class="cr dawn-glow"></i>
              <!-- Easter eggs -->
              <i v-if="isFridayTime" class="cr party-fish" :style="{ animationDelay: `-${oceanSeeds[18] * 8}s` }"></i>
              <i v-if="isMidnightTime" class="cr ghost-ship" :style="{ animationDelay: `-${oceanSeeds[19] * 240}s` }"></i>
            </div>
            <div class="left">
              <AgentBadge
                v-if="selectedAgent"
                :agent="selectedAgent"
                :connected="isRealtime"
                :terminals="openTerminals"
                :active-session-id="activeTerminalSessionId"
                :model="conversation?.model"
                :version="conversation?.version"
                @switch-terminal="switchToTerminal"
                @close-terminal="closeTerminal"
              />
            </div>
            <div class="window-controls">
              <button
                v-if="!isMobile"
                @click.stop="toggleForceMobile"
                class="mobile-btn"
                :class="{ active: forceMobile }"
                title="Toggle mobile panel"
              >
                <!-- Phone/panel-from-bottom icon -->
                <svg width="10" height="10" viewBox="0 0 10 10" shape-rendering="crispEdges">
                  <rect x="2" y="0" width="6" height="10" fill="currentColor" opacity="0.25"/>
                  <rect x="3" y="1" width="4" height="7" fill="currentColor"/>
                  <rect x="4" y="9" width="2" height="1" fill="currentColor" opacity="0.5"/>
                </svg>
              </button>
              <button @click.stop="cycleSizeMode" class="size-btn" :title="`Size: ${sizeMode}`">
                <!-- Pin icon: small square bottom-left -->
                <svg v-if="sizeMode === 'pin'" width="10" height="10" viewBox="0 0 10 10" shape-rendering="crispEdges">
                  <rect x="0" y="6" width="4" height="4" fill="currentColor"/>
                </svg>
                <!-- Medium icon: medium square centered -->
                <svg v-else-if="sizeMode === 'medium'" width="10" height="10" viewBox="0 0 10 10" shape-rendering="crispEdges">
                  <rect x="2" y="2" width="6" height="6" fill="currentColor" opacity="0.35"/>
                  <rect x="3" y="3" width="4" height="4" fill="currentColor"/>
                </svg>
                <!-- Large icon: full square -->
                <svg v-else width="10" height="10" viewBox="0 0 10 10" shape-rendering="crispEdges">
                  <rect x="0" y="0" width="10" height="10" fill="currentColor" opacity="0.35"/>
                  <rect x="1" y="1" width="8" height="8" fill="currentColor"/>
                </svg>
              </button>
              <button
                @click.stop="chatRef?.collapseAllExceptLast()"
                :class="{ active: chatRef?.allCollapsed }"
                class="collapse-all-btn"
                title="Collapse all except last"
              >
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <polyline v-if="chatRef?.allCollapsed" points="6 9 12 15 18 9"/>
                  <template v-else>
                    <polyline points="18 15 12 9 6 15"/>
                  </template>
                </svg>
              </button>
              <button @click.stop="chatRef?.toggleSelectMode()" :class="{ active: chatRef?.selectMode }" title="Select messages">
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <polyline v-if="chatRef?.selectMode" points="20 6 9 17 4 12"/>
                  <template v-else>
                    <rect x="3" y="3" width="7" height="7" rx="1"/>
                    <rect x="14" y="3" width="7" height="7" rx="1"/>
                    <rect x="3" y="14" width="7" height="7" rx="1"/>
                    <rect x="14" y="14" width="7" height="7" rx="1"/>
                  </template>
                </svg>
              </button>
              <button @click.stop="showSelector = !showSelector" :class="{ active: showSelector }" title="Agent/Session">
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <circle cx="12" cy="12" r="3"/>
                  <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
                </svg>
              </button>
              <button class="x" @click="close" title="Close">
                <svg width="8" height="8" viewBox="0 0 10 10">
                  <line x1="0" y1="0" x2="10" y2="10" stroke="currentColor" stroke-width="1.5"/>
                  <line x1="10" y1="0" x2="0" y2="10" stroke="currentColor" stroke-width="1.5"/>
                </svg>
              </button>
            </div>
          </div>

          <!-- Error -->
          <div v-if="error" class="error-bar">{{ error }}</div>

          <!-- Content -->
          <div class="content">
            <AquaticBackground />
            <div class="readability-overlay" :style="{ background: `rgba(0, 0, 0, ${overlayOpacity})` }" />
            <Transition name="terminal-loading">
              <div v-if="transitioning" class="terminal-loading-overlay">
                <div class="terminal-loading-spinner" />
              </div>
            </Transition>
            <Transition name="terminal-loading">
              <div v-if="transitionError" class="terminal-error-overlay" @click="transitionError = null">
                <div class="terminal-error-content">
                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2">
                    <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
                  </svg>
                  <span class="terminal-error-msg">{{ transitionError }}</span>
                  <span class="terminal-error-hint">Click to dismiss</span>
                </div>
              </div>
            </Transition>
            <ChatContainer
              ref="chatRef"
              v-if="conversation"
              :conversation="conversation"
              :processing="processing"
              :terminal-ready="terminalReady"
              :terminal="ephemeral"
              :show-selector="showSelector"
              :agents="agents"
              :selected-agent="selectedAgent"
              :sessions="sessions"
              :selected-session-id="selectedSessionId"
              :sessions-loading="loading"
              :voice-mode="voiceMode"
              :whisper-status="whisperStatus"
              :audio-devices="audioDevices"
              :selected-device-id="selectedDeviceId"
              :is-recording="voiceRecording"
              :voice-transcript="voiceTranscript + voiceInterim"
              :last-audio-url="lastAudioUrl"
              :is-playing-audio="isPlayingAudio"
              :overlay-opacity="overlayOpacity"
              :input-max-lines="inputMaxLines"
              :scroll-jump-percent="scrollJumpPercent"
              :scroll-nav-mode="scrollNavMode"
              :hook-permission-mode="hookMeta.permissionMode"
              @send="handleSend"
              @switch-agent="handleAgentSwitch"
              @select-session="handleSessionSelect"
              @create-session="handleCreateSession"
              @close-session="closeTerminal"
              @start-recording="voice.startRecording()"
              @stop-recording="voice.stopRecording()"
              @set-voice-mode="voice.setMode($event)"
              @select-microphone="voice.selectMicrophone($event)"
              @play-last-audio="voice.playLastAudio()"
              @update:overlay-opacity="setOverlayOpacity"
              @update:input-max-lines="setInputMaxLines"
              @update:scroll-jump-percent="setScrollJumpPercent"
              @update:scroll-nav-mode="setScrollNavMode"
            />
            <div v-else class="empty-state">
              <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
              </svg>
              <span>Select a session to begin</span>
              <small>{{ sessions.length }} sessions available</small>
            </div>
          </div>

          <!-- Scroll arrows (visible only in idle mode) -->
          <Transition name="scroll-arrows">
            <div v-if="showChrome && conversation && scrollNavMode === 'buttons'" class="scroll-arrows">
              <!-- Top: double chevron up + wave accent -->
              <button class="scroll-arrow sa-surface" @click="scrollToEdge('top')" title="Scroll to top">
                <svg width="20" height="22" viewBox="0 0 20 22" shape-rendering="crispEdges">
                  <!-- Wave line -->
                  <rect x="0" y="0" width="4" height="2" fill="#0ea5e9" opacity="0.5"/>
                  <rect x="4" y="1" width="3" height="2" fill="#22d3ee" opacity="0.4"/>
                  <rect x="7" y="0" width="6" height="2" fill="#0ea5e9" opacity="0.5"/>
                  <rect x="13" y="1" width="3" height="2" fill="#22d3ee" opacity="0.4"/>
                  <rect x="16" y="0" width="4" height="2" fill="#0ea5e9" opacity="0.5"/>
                  <rect x="1" y="2" width="2" height="1" fill="white" opacity="0.15"/>
                  <rect x="9" y="2" width="2" height="1" fill="white" opacity="0.12"/>
                  <!-- Chevron 1 -->
                  <rect x="9" y="6" width="2" height="2" fill="#67e8f9" opacity="0.75"/>
                  <rect x="7" y="8" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="11" y="8" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="5" y="10" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <rect x="13" y="10" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <!-- Chevron 2 -->
                  <rect x="9" y="13" width="2" height="2" fill="#67e8f9" opacity="0.55"/>
                  <rect x="7" y="15" width="2" height="2" fill="#67e8f9" opacity="0.4"/>
                  <rect x="11" y="15" width="2" height="2" fill="#67e8f9" opacity="0.4"/>
                  <rect x="5" y="17" width="2" height="2" fill="#67e8f9" opacity="0.3"/>
                  <rect x="13" y="17" width="2" height="2" fill="#67e8f9" opacity="0.3"/>
                </svg>
              </button>
              <!-- Up: single chevron + bubbles -->
              <button class="scroll-arrow sa-up" @click="scrollJump('up')" title="Scroll up">
                <svg width="20" height="16" viewBox="0 0 20 16" shape-rendering="crispEdges">
                  <!-- Chevron -->
                  <rect x="9" y="2" width="2" height="2" fill="#67e8f9" opacity="0.75"/>
                  <rect x="7" y="4" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="11" y="4" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="5" y="6" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <rect x="13" y="6" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <!-- Bubble accents -->
                  <rect x="15" y="1" width="2" height="2" fill="#67e8f9" opacity="0.25"/>
                  <rect x="16" y="1" width="1" height="1" fill="white" opacity="0.2"/>
                  <rect x="3" y="3" width="1" height="1" fill="#67e8f9" opacity="0.18"/>
                  <!-- Trail -->
                  <rect x="9" y="11" width="2" height="1" fill="#67e8f9" opacity="0.18"/>
                  <rect x="11" y="13" width="1" height="1" fill="#67e8f9" opacity="0.12"/>
                </svg>
              </button>
              <!-- Down: single chevron + bubbles -->
              <button class="scroll-arrow sa-down" @click="scrollJump('down')" title="Scroll down">
                <svg width="20" height="16" viewBox="0 0 20 16" shape-rendering="crispEdges">
                  <!-- Trail -->
                  <rect x="8" y="2" width="1" height="1" fill="#67e8f9" opacity="0.12"/>
                  <rect x="9" y="4" width="2" height="1" fill="#67e8f9" opacity="0.18"/>
                  <!-- Chevron -->
                  <rect x="5" y="7" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <rect x="13" y="7" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <rect x="7" y="9" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="11" y="9" width="2" height="2" fill="#67e8f9" opacity="0.6"/>
                  <rect x="9" y="11" width="2" height="2" fill="#67e8f9" opacity="0.75"/>
                  <!-- Bubble accents -->
                  <rect x="3" y="12" width="2" height="2" fill="#67e8f9" opacity="0.25"/>
                  <rect x="4" y="12" width="1" height="1" fill="white" opacity="0.2"/>
                  <rect x="16" y="10" width="1" height="1" fill="#67e8f9" opacity="0.18"/>
                </svg>
              </button>
              <!-- Bottom: double chevron down + sand -->
              <button class="scroll-arrow sa-seabed" @click="scrollToEdge('bottom')" title="Scroll to bottom">
                <svg width="20" height="22" viewBox="0 0 20 22" shape-rendering="crispEdges">
                  <!-- Chevron 1 (pointing down) -->
                  <rect x="5" y="1" width="2" height="2" fill="#67e8f9" opacity="0.3"/>
                  <rect x="13" y="1" width="2" height="2" fill="#67e8f9" opacity="0.3"/>
                  <rect x="7" y="3" width="2" height="2" fill="#67e8f9" opacity="0.35"/>
                  <rect x="11" y="3" width="2" height="2" fill="#67e8f9" opacity="0.35"/>
                  <rect x="9" y="5" width="2" height="2" fill="#67e8f9" opacity="0.45"/>
                  <!-- Chevron 2 (pointing down) -->
                  <rect x="5" y="8" width="2" height="2" fill="#67e8f9" opacity="0.5"/>
                  <rect x="13" y="8" width="2" height="2" fill="#67e8f9" opacity="0.5"/>
                  <rect x="7" y="10" width="2" height="2" fill="#67e8f9" opacity="0.65"/>
                  <rect x="11" y="10" width="2" height="2" fill="#67e8f9" opacity="0.65"/>
                  <rect x="9" y="12" width="2" height="2" fill="#67e8f9" opacity="0.75"/>
                  <!-- Sand floor -->
                  <rect x="0" y="17" width="20" height="2" fill="#d4a06a" opacity="0.3"/>
                  <rect x="0" y="19" width="20" height="3" fill="#c4956a" opacity="0.35"/>
                  <rect x="4" y="17" width="1" height="1" fill="#e8c088" opacity="0.25"/>
                  <rect x="12" y="18" width="1" height="1" fill="#e8c088" opacity="0.2"/>
                  <rect x="17" y="17" width="1" height="1" fill="#e8c088" opacity="0.22"/>
                </svg>
              </button>
            </div>
          </Transition>

          <!-- Resize handle -->
          <div v-if="!effectiveMobile" class="resize-handle" @mousedown="startResize"></div>
        </div>
      </div>
    </Transition>

    <NewSessionModal
      :visible="showNewSessionModal"
      :agents="agents"
      :current-agent="selectedAgent"
      @close="showNewSessionModal = false"
      @create-new="handleModalCreateNew"
      @resume="handleModalResume"
    />
  </Teleport>
</template>

<style scoped>
.aero-win {
  position: fixed;
  min-width: 200px;
  min-height: 200px;
  z-index: 9999;
  transition: width 0.3s ease, height 0.3s ease, top 0.3s ease, left 0.3s ease, bottom 0.3s ease;
}

/* ── Dynamic glow from ocean background ── */
.aero-win::before {
  content: '';
  position: absolute;
  inset: -12px;
  z-index: -1;
  border-radius: 18px;
  background: linear-gradient(
    180deg,
    rgba(0, 12, 35, 0.35) 0%,
    rgba(0, 30, 65, 0.30) 25%,
    rgba(4, 52, 78, 0.35) 50%,
    rgba(6, 58, 72, 0.30) 70%,
    rgba(18, 50, 45, 0.35) 100%
  );
  filter: blur(18px);
  opacity: 0.7;
  transition: opacity 0.5s ease, filter 0.5s ease;
  pointer-events: none;
}

.aero-win:hover::before,
.aero-win.chrome-visible::before {
  opacity: 1;
  filter: blur(22px);
}

.aero-win.dragging::before,
.aero-win.resizing::before {
  transition: none;
}

.aero-win.dragging,
.aero-win.resizing {
  transition: none;
}

.glass {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.05);
  box-shadow:
    0 0 0 1px rgba(0,0,0,0.6),
    0 16px 56px rgba(0,0,0,0.6),
    0 4px 16px rgba(0,0,0,0.4);
  overflow: hidden;
  transition: border-color 0.35s ease, box-shadow 0.35s ease;
}

/* ══════════════════════════════════════════════════════════════════════════
   IDLE MODE: When not hovering/focused, hide all chrome.
   Only the messages + ocean background fill the entire window.
   ══════════════════════════════════════════════════════════════════════════ */

/* Transition all chrome elements smoothly */
.titlebar,
.error-bar,
.resize-handle {
  transition: opacity 0.35s ease, max-height 0.35s ease, padding 0.35s ease;
}

/* Idle: hide drag edge */
.aero-win:not(.chrome-visible) .drag-edge {
  pointer-events: none;
}

/* Idle: slide titlebar up and fade out */
.aero-win:not(.chrome-visible) .titlebar {
  opacity: 0;
  transform: translateY(-100%);
  pointer-events: none;
}

/* Idle: hide error bar */
.aero-win:not(.chrome-visible) .error-bar {
  opacity: 0;
  max-height: 0;
  padding: 0;
  border-bottom-width: 0;
  overflow: hidden;
}

/* Idle: hide resize handle */
.aero-win:not(.chrome-visible) .resize-handle {
  opacity: 0;
  pointer-events: none;
}

/* Chat-header: only visible when settings/selector is open */
.aero-win:not(.selector-open) .content :deep(.chat-header) {
  opacity: 0 !important;
  transform: translateY(-150%) !important;
  pointer-events: none !important;
}

/* Idle: slide bottom-overlay down and fade out */
.aero-win:not(.chrome-visible) .content :deep(.bottom-overlay) {
  opacity: 0 !important;
  transform: translateY(100%) !important;
  pointer-events: none !important;
}

/* Keep bottom-overlay visible when textarea has text */
.aero-win:not(.chrome-visible) .content :deep(.bottom-overlay:has(.input-field:not(:placeholder-shown))) {
  opacity: 1 !important;
  transform: none !important;
  pointer-events: auto !important;
}

/* Idle: also hide selection bar */
.aero-win:not(.chrome-visible) .content :deep(.selection-bar) {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Idle: softer glass border + dimmed glow */
.aero-win:not(.chrome-visible) .glass {
  border-color: rgba(255,255,255,0.02);
  box-shadow:
    0 0 0 1px rgba(0,0,0,0.3),
    0 8px 32px rgba(0,0,0,0.4);
}

.aero-win:not(.chrome-visible)::before {
  opacity: 0.4;
  filter: blur(14px);
}

/* Smooth transitions for chrome show/hide */
.content :deep(.chat-header) {
  transition: opacity 0.35s ease, transform 0.35s ease !important;
}

.content :deep(.bottom-overlay) {
  transition: opacity 0.35s ease, transform 0.35s ease !important;
}

/* ── Drag edge: thin strip at top for window dragging ── */
.drag-edge {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 5px;
  z-index: 11;
  cursor: grab;
}

.drag-edge:active {
  cursor: grabbing;
}

.aero-win.dragging .drag-edge {
  cursor: grabbing;
}

/* ── Titlebar: absolute overlay at top of .glass ── */
.titlebar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 28px;
  padding: 0 5px 0 8px;
  background:
    /* Pixel art sea surface: sky, moon, waves, fish, bubbles */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='28' viewBox='0 0 120 28' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='120' height='12' fill='%230a1628' opacity='0.5'/%3E%3Crect x='0' y='12' width='120' height='16' fill='%230c2d4a' opacity='0.45'/%3E%3Crect x='8' y='3' width='1' height='1' fill='white' opacity='0.3'/%3E%3Crect x='25' y='5' width='1' height='1' fill='white' opacity='0.22'/%3E%3Crect x='45' y='2' width='1' height='1' fill='white' opacity='0.18'/%3E%3Crect x='70' y='4' width='1' height='1' fill='white' opacity='0.28'/%3E%3Crect x='95' y='6' width='1' height='1' fill='white' opacity='0.22'/%3E%3Crect x='110' y='3' width='1' height='1' fill='white' opacity='0.18'/%3E%3Crect x='36' y='7' width='1' height='1' fill='%23fde68a' opacity='0.15'/%3E%3Crect x='85' y='2' width='3' height='3' fill='%23fef3c7' opacity='0.3'/%3E%3Crect x='86' y='1' width='2' height='1' fill='%23fef3c7' opacity='0.2'/%3E%3Crect x='86' y='5' width='2' height='1' fill='%23fde68a' opacity='0.15'/%3E%3Crect x='50' y='4' width='4' height='2' fill='%23475569' opacity='0.15'/%3E%3Crect x='51' y='3' width='2' height='1' fill='%23475569' opacity='0.1'/%3E%3Crect x='8' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='12' y='11' width='10' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='22' y='10' width='6' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='28' y='11' width='12' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='40' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='44' y='11' width='14' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='58' y='10' width='6' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='64' y='11' width='10' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='74' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='78' y='11' width='12' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='90' y='10' width='6' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='96' y='11' width='14' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='110' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.3'/%3E%3Crect x='114' y='11' width='6' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='0' y='11' width='8' height='2' fill='%230ea5e9' opacity='0.25'/%3E%3Crect x='8' y='10' width='2' height='1' fill='white' opacity='0.12'/%3E%3Crect x='22' y='10' width='2' height='1' fill='white' opacity='0.1'/%3E%3Crect x='40' y='10' width='2' height='1' fill='white' opacity='0.12'/%3E%3Crect x='58' y='10' width='2' height='1' fill='white' opacity='0.1'/%3E%3Crect x='74' y='10' width='2' height='1' fill='white' opacity='0.12'/%3E%3Crect x='90' y='10' width='2' height='1' fill='white' opacity='0.1'/%3E%3Crect x='110' y='10' width='2' height='1' fill='white' opacity='0.12'/%3E%3Crect x='0' y='14' width='120' height='2' fill='%230369a1' opacity='0.18'/%3E%3Crect x='0' y='18' width='120' height='2' fill='%23075985' opacity='0.12'/%3E%3Crect x='0' y='22' width='120' height='2' fill='%230c4a6e' opacity='0.08'/%3E%3Crect x='15' y='16' width='3' height='1' fill='%23f97316' opacity='0.3'/%3E%3Crect x='14' y='16' width='1' height='1' fill='%23fb923c' opacity='0.2'/%3E%3Crect x='55' y='20' width='3' height='1' fill='%23818cf8' opacity='0.22'/%3E%3Crect x='58' y='20' width='1' height='1' fill='%23a78bfa' opacity='0.15'/%3E%3Crect x='100' y='17' width='3' height='1' fill='%2322c55e' opacity='0.22'/%3E%3Crect x='99' y='17' width='1' height='1' fill='%234ade80' opacity='0.15'/%3E%3Crect x='30' y='15' width='1' height='1' fill='white' opacity='0.1'/%3E%3Crect x='65' y='22' width='1' height='1' fill='white' opacity='0.08'/%3E%3Crect x='82' y='14' width='1' height='1' fill='white' opacity='0.1'/%3E%3C/svg%3E") repeat-x left top / auto 100%,
    rgba(0, 8, 20, 0.3);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(255,255,255,0.04);
  user-select: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
  animation: titlebar-ocean 8s linear infinite;
}

.left {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  color: rgba(255,255,255,0.6);
  font: 500 10px/1 'Courier New', monospace;
}

.window-controls {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 2px;
}

.window-controls button {
  width: 20px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 0;
  color: rgba(255,255,255,0.4);
  cursor: pointer;
  transition: all 0.15s;
}

.window-controls button:hover {
  background: rgba(255,255,255,0.1);
  color: rgba(255,255,255,0.8);
}

.window-controls button.active {
  background: rgba(99, 102, 241, 0.2);
  border-color: rgba(99, 102, 241, 0.3);
  color: #a5b4fc;
}

.window-controls .mobile-btn {
  color: #a78bfa;
}

.window-controls .mobile-btn:hover {
  color: #c4b5fd;
  background: rgba(167, 139, 250, 0.15);
  border-color: rgba(167, 139, 250, 0.25);
}

.window-controls .mobile-btn.active {
  background: rgba(167, 139, 250, 0.2);
  border-color: rgba(167, 139, 250, 0.3);
  color: #c4b5fd;
}

.window-controls .collapse-all-btn {
  color: #2dd4bf;
}

.window-controls .collapse-all-btn:hover {
  color: #5eead4;
  background: rgba(45, 212, 191, 0.15);
  border-color: rgba(45, 212, 191, 0.25);
}

.window-controls .collapse-all-btn.active {
  background: rgba(45, 212, 191, 0.2);
  border-color: rgba(45, 212, 191, 0.3);
  color: #5eead4;
}

.window-controls .size-btn {
  color: #0ea5e9;
}

.window-controls .size-btn:hover {
  color: #38bdf8;
  background: rgba(14, 165, 233, 0.15);
  border-color: rgba(14, 165, 233, 0.25);
}

.window-controls button.x:hover {
  background: rgba(239, 68, 68, 0.3);
  border-color: rgba(239, 68, 68, 0.4);
  color: #fca5a5;
}

/* ── Error Bar ── */
.error-bar {
  padding: 4px 10px;
  background: rgba(239, 68, 68, 0.1);
  border-bottom: 1px solid rgba(239, 68, 68, 0.2);
  color: #fca5a5;
  font-size: 10px;
  font-family: 'Courier New', monospace;
  flex-shrink: 0;
}

/* ── Content ── */
.content {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  /* Background handled by AquaticBackground component */
}

/* Dark readability overlay: between ocean bg (z-index:0) and chat (z-index:1) */
.readability-overlay {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
}

.aero-win.chrome-visible .readability-overlay {
  opacity: 1;
}

/* ── Terminal switching loading overlay ── */
.terminal-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(4px);
}

.terminal-loading-spinner {
  width: 28px;
  height: 28px;
  border: 2.5px solid rgba(255, 255, 255, 0.15);
  border-top-color: rgba(255, 255, 255, 0.7);
  border-radius: 50%;
  animation: tl-spin 0.7s linear infinite;
}

@keyframes tl-spin {
  to { transform: rotate(360deg); }
}

.terminal-error-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
  cursor: pointer;
}

.terminal-error-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  max-width: 80%;
  padding: 1.2rem 1.5rem;
  background: rgba(30, 30, 30, 0.85);
  border: 1px solid rgba(248, 113, 113, 0.3);
  border-radius: 10px;
}

.terminal-error-msg {
  font-size: 12px;
  color: #fca5a5;
  text-align: center;
  line-height: 1.4;
  word-break: break-word;
}

.terminal-error-hint {
  font-size: 10px;
  color: rgba(255, 255, 255, 0.35);
}

.terminal-loading-enter-active { transition: opacity 0.15s ease; }
.terminal-loading-leave-active { transition: opacity 0.25s ease; }
.terminal-loading-enter-from,
.terminal-loading-leave-to { opacity: 0; }

/* Override ChatContainer backgrounds: glass-transparent */
.content :deep(.chat-container) {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  position: relative;
  z-index: 1;
  flex: 1 !important;
  min-height: 0 !important;
}

/* Chat header: absolute overlay below titlebar, floats over messages */
.content :deep(.chat-header) {
  position: absolute !important;
  top: 28px !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 3 !important;
  background: rgba(0, 6, 18, 0.5) !important;
  backdrop-filter: blur(8px) !important;
  -webkit-backdrop-filter: blur(8px) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  padding: 0.3rem 0.6rem !important;
}

/* Messages: fill entire container, pad top/bottom for overlaid titlebar+header / input */
.content :deep(.messages-scroll) {
  background: transparent !important;
  padding-top: 5rem !important;
  padding-bottom: 5rem !important;
  flex: 1 !important;
}

/* Hide scrollbar for buttons and none modes */
.aero-win:not(.nav-scrollbar) .content :deep(.messages-scroll) {
  scrollbar-width: none !important;
}

.aero-win:not(.nav-scrollbar) .content :deep(.messages-scroll)::-webkit-scrollbar {
  display: none !important;
}

/* Pixel art scrollbar (only in scrollbar mode) */
.aero-win.nav-scrollbar .content :deep(.messages-scroll) {
  scrollbar-gutter: stable !important;
}

.aero-win.nav-scrollbar .content :deep(.messages-scroll)::-webkit-scrollbar {
  width: 8px;
}

/* Idle: hide scrollbar visuals (gutter stays) */
.aero-win.nav-scrollbar:not(.chrome-visible) .content :deep(.messages-scroll)::-webkit-scrollbar-track {
  background: transparent !important;
}

.aero-win.nav-scrollbar:not(.chrome-visible) .content :deep(.messages-scroll)::-webkit-scrollbar-thumb {
  background: transparent !important;
  border-color: transparent !important;
}

.aero-win.nav-scrollbar .content :deep(.messages-scroll)::-webkit-scrollbar-track {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='8' height='8' fill='%230c2d4a' opacity='0.4'/%3E%3Crect x='2' y='2' width='2' height='2' fill='%23075985' opacity='0.15'/%3E%3Crect x='6' y='6' width='2' height='2' fill='%23075985' opacity='0.1'/%3E%3C/svg%3E") repeat;
}

.aero-win.nav-scrollbar .content :deep(.messages-scroll)::-webkit-scrollbar-thumb {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 8 16' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='8' height='16' fill='%230ea5e9' opacity='0.3'/%3E%3Crect x='2' y='2' width='4' height='2' fill='%2322d3ee' opacity='0.25'/%3E%3Crect x='2' y='6' width='4' height='2' fill='%2367e8f9' opacity='0.2'/%3E%3Crect x='2' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.25'/%3E%3Crect x='2' y='14' width='4' height='2' fill='%2367e8f9' opacity='0.15'/%3E%3C/svg%3E") repeat;
  border: 1px solid rgba(14, 165, 233, 0.15);
}

.aero-win.nav-scrollbar .content :deep(.messages-scroll)::-webkit-scrollbar-thumb:hover {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 8 16' shape-rendering='crispEdges'%3E%3Crect x='0' y='0' width='8' height='16' fill='%230ea5e9' opacity='0.45'/%3E%3Crect x='2' y='2' width='4' height='2' fill='%2322d3ee' opacity='0.35'/%3E%3Crect x='2' y='6' width='4' height='2' fill='%2367e8f9' opacity='0.3'/%3E%3Crect x='2' y='10' width='4' height='2' fill='%2322d3ee' opacity='0.35'/%3E%3Crect x='2' y='14' width='4' height='2' fill='%2367e8f9' opacity='0.25'/%3E%3C/svg%3E") repeat;
  border-color: rgba(14, 165, 233, 0.3);
}

.content :deep(.meta-badge) {
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.4);
  border-radius: 0;
  font-family: 'Courier New', monospace;
}

.content :deep(.meta-badge.model) {
  background: rgba(99, 102, 241, 0.1);
  color: #a5b4fc;
}

.content :deep(.meta-cwd),
.content :deep(.meta-duration),
.content :deep(.meta-count) {
  color: rgba(255,255,255,0.25);
}

.content :deep(.copy-id-btn) {
  color: rgba(255,255,255,0.25);
}

.content :deep(.copy-id-btn:hover) {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.6);
}

.content :deep(.select-mode-btn) {
  border-color: rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.35);
  border-radius: 0;
}

.content :deep(.select-mode-btn:hover) {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.7);
}

.content :deep(.select-mode-btn.active) {
  background: rgba(99, 102, 241, 0.25);
  border-color: rgba(99, 102, 241, 0.35);
  color: #c7d2fe;
}


/* Bottom overlay: absolute container for lifecycle + input + status */
.content :deep(.bottom-overlay) {
  position: absolute !important;
  bottom: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 3 !important;
  display: flex !important;
  flex-direction: column !important;
  background: rgba(0, 6, 18, 0.5) !important;
  backdrop-filter: blur(8px) !important;
  -webkit-backdrop-filter: blur(8px) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
}

.content :deep(.status-bar) {
  background: transparent !important;
  border-top: 1px solid rgba(255, 255, 255, 0.04) !important;
  border-bottom: none !important;
  padding: 0.15rem 0.5rem !important;
}

.content :deep(.status-id) {
  color: rgba(255,255,255,0.35) !important;
}

.content :deep(.status-bar .copy-id-btn) {
  color: rgba(255,255,255,0.25) !important;
}

.content :deep(.status-bar .copy-id-btn:hover) {
  color: rgba(255,255,255,0.6) !important;
}

.content :deep(.status-bar .meta-badge) {
  border-radius: 0 !important;
  font-family: 'Courier New', monospace !important;
}

.content :deep(.status-bar .meta-badge.model) {
  background: rgba(99, 102, 241, 0.1) !important;
  color: #a5b4fc !important;
}

.content :deep(.status-bar .meta-badge.version) {
  background: rgba(255,255,255,0.04) !important;
  color: rgba(255,255,255,0.3) !important;
}

.content :deep(.status-bar .meta-count),
.content :deep(.status-bar .meta-duration) {
  color: rgba(255,255,255,0.2) !important;
}

/* UserInput: inside bottom-overlay, no absolute positioning needed */
.content :deep(.user-input) {
  background: transparent !important;
  border-top: 1px solid rgba(255, 255, 255, 0.04) !important;
  padding: 0.3rem 0.5rem !important;
}

/* Lifecycle ribbon: inside bottom-overlay, flows naturally above user-input */
.content :deep(.lifecycle-ribbon) {
  background: transparent !important;
  pointer-events: none !important;
}

/* Dark overlay on input-container so text is readable */
.content :deep(.input-container) {
  background: rgba(0, 6, 18, 0.8) !important;
  border-color: rgba(14, 165, 233, 0.1) !important;
  border-radius: 0 !important;
  padding: 0.3rem 0.4rem !important;
}

.content :deep(.input-container:focus-within) {
  border-color: rgba(14, 165, 233, 0.25) !important;
  background: rgba(0, 6, 18, 0.85) !important;
}

.content :deep(.input-field) {
  color: rgba(255,255,255,0.85);
  font-family: 'Courier New', monospace;
  font-size: 12px;
}

/* Send button: pixel art daytime ocean, no border */
.content :deep(.send-btn) {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' shape-rendering='crispEdges'%3E%3Crect width='28' height='6' fill='%2387ceeb'/%3E%3Crect y='6' width='28' height='4' fill='%2356b3d9'/%3E%3Crect y='10' width='28' height='4' fill='%232d9abf'/%3E%3Crect y='14' width='28' height='4' fill='%231a7fa5'/%3E%3Crect y='18' width='28' height='4' fill='%23106888'/%3E%3Crect y='22' width='28' height='6' fill='%23c2b280'/%3E%3Crect x='24' y='4' width='3' height='3' fill='%23fffde0' opacity='0.8'/%3E%3Crect x='25' y='3' width='2' height='1' fill='%23fffde0' opacity='0.5'/%3E%3Crect x='2' y='5' width='4' height='2' fill='white' opacity='0.35'/%3E%3Crect x='10' y='4' width='6' height='2' fill='white' opacity='0.25'/%3E%3Crect x='20' y='6' width='3' height='1' fill='white' opacity='0.2'/%3E%3Crect x='5' y='12' width='3' height='2' fill='%23f97316' opacity='0.7'/%3E%3Crect x='4' y='13' width='1' height='1' fill='%23fdba74' opacity='0.5'/%3E%3Crect x='18' y='16' width='2' height='1' fill='%232563eb' opacity='0.5'/%3E%3Crect x='20' y='16' width='1' height='1' fill='%2393c5fd' opacity='0.4'/%3E%3Crect x='8' y='18' width='1' height='1' fill='white' opacity='0.2'/%3E%3Crect x='22' y='12' width='1' height='1' fill='white' opacity='0.2'/%3E%3Crect x='14' y='20' width='1' height='1' fill='white' opacity='0.15'/%3E%3Crect x='3' y='23' width='4' height='3' fill='%23059669' opacity='0.5'/%3E%3Crect x='4' y='22' width='2' height='1' fill='%2310b981' opacity='0.4'/%3E%3Crect x='20' y='24' width='3' height='2' fill='%23059669' opacity='0.4'/%3E%3Crect x='12' y='25' width='3' height='2' fill='%23ec4899' opacity='0.45'/%3E%3Crect x='13' y='24' width='2' height='1' fill='%23f472b6' opacity='0.35'/%3E%3C/svg%3E") !important;
  border: none !important;
  border-radius: 0 !important;
  width: 28px !important;
  height: 28px !important;
  color: white !important;
  image-rendering: pixelated;
  box-shadow: none !important;
  transition: color 0.15s ease !important;
}

.content :deep(.send-btn:hover:not(:disabled)) {
  color: #fffde0 !important;
  filter: none !important;
  box-shadow: 0 0 12px rgba(135, 206, 235, 0.5), 0 0 4px rgba(255, 253, 224, 0.3) !important;
}

.content :deep(.send-btn:disabled) {
  opacity: 0.25 !important;
  filter: saturate(0.3) !important;
}

/* Selection bar */
.content :deep(.selection-bar) {
  background: rgba(8, 8, 12, 0.92);
  border-color: rgba(255,255,255,0.06);
  border-radius: 0;
}

.content :deep(.selection-count) {
  color: rgba(255,255,255,0.4);
  font-family: 'Courier New', monospace;
}

.content :deep(.selection-btn.toggle-all) {
  background: rgba(255,255,255,0.06);
  color: rgba(255,255,255,0.5);
  border-radius: 0;
}

.content :deep(.message-wrapper.selected) {
  background: rgba(99, 102, 241, 0.06);
}

/* ── Empty State ── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  gap: 8px;
  color: rgba(255,255,255,0.3);
  position: relative;
  z-index: 1;
}

.empty-state svg {
  opacity: 0.2;
}

.empty-state span {
  font-size: 11px;
  font-family: 'Courier New', monospace;
  color: rgba(255,255,255,0.35);
  letter-spacing: 0.5px;
}

.empty-state small {
  font-size: 10px;
  font-family: 'Courier New', monospace;
  color: rgba(255,255,255,0.2);
}

/* ── Resize Handle ── */
.resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' shape-rendering='crispEdges'%3E%3Crect x='12' y='12' width='2' height='2' fill='%23818cf8' opacity='0.25'/%3E%3Crect x='8' y='12' width='2' height='2' fill='%23818cf8' opacity='0.15'/%3E%3Crect x='12' y='8' width='2' height='2' fill='%23818cf8' opacity='0.15'/%3E%3Crect x='4' y='12' width='2' height='2' fill='%23818cf8' opacity='0.08'/%3E%3Crect x='12' y='4' width='2' height='2' fill='%23818cf8' opacity='0.08'/%3E%3Crect x='8' y='8' width='2' height='2' fill='%23818cf8' opacity='0.08'/%3E%3C/svg%3E") no-repeat center center;
  border-radius: 0 0 10px 0;
}

.resize-handle:hover {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' shape-rendering='crispEdges'%3E%3Crect x='12' y='12' width='2' height='2' fill='%23a5b4fc' opacity='0.4'/%3E%3Crect x='8' y='12' width='2' height='2' fill='%23a5b4fc' opacity='0.25'/%3E%3Crect x='12' y='8' width='2' height='2' fill='%23a5b4fc' opacity='0.25'/%3E%3Crect x='4' y='12' width='2' height='2' fill='%23a5b4fc' opacity='0.15'/%3E%3Crect x='12' y='4' width='2' height='2' fill='%23a5b4fc' opacity='0.15'/%3E%3Crect x='8' y='8' width='2' height='2' fill='%23a5b4fc' opacity='0.15'/%3E%3C/svg%3E") no-repeat center center;
}

.aero-win.resizing {
  user-select: none;
}

.aero-win.resizing .content {
  pointer-events: none;
}

/* ── Transitions ── */
.win-slide-enter-active,
.win-slide-leave-active {
  transition: all .2s ease;
}

.win-slide-enter-from,
.win-slide-leave-to {
  opacity: 0;
  transform: translateY(16px) scale(0.98);
}


/* ══════════════════════════════════════════════════════════════════════════
   OCEAN LIFE ECOSYSTEM
   ══════════════════════════════════════════════════════════════════════════ */

.ocean-life {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.cr {
  position: absolute;
  width: 1px;
  height: 1px;
  background: transparent;
  font-style: normal;
}

/* ── 1. Fish School (3 orange fish, swim left) ── */
.fish-school {
  top: 16px;
  animation: swim-left 10s linear infinite;
  box-shadow:
    0 0 #f97316, 1px 0 #f97316, -1px 0 #fb923c,
    5px 3px #f97316, 6px 3px #f97316, 4px 3px #fb923c,
    3px -2px #f97316, 4px -2px #f97316, 2px -2px #fb923c;
}

/* ── 2. Fish School 2 (2 blue fish, swim right) ── */
.fish-school-2 {
  top: 20px;
  animation: swim-right 14s linear infinite;
  box-shadow:
    0 0 #818cf8, -1px 0 #818cf8, 1px 0 #a5b4fc,
    -4px 2px #818cf8, -5px 2px #818cf8, -3px 2px #a5b4fc;
}

/* ── 3. Dolphin (grey-blue, arc jump) ── */
.dolphin {
  top: 14px;
  animation: dolphin-arc 12s linear infinite;
  box-shadow:
    0 0 #94a3b8, 1px 0 #94a3b8, 2px 0 #94a3b8, 3px 0 #cbd5e1, -1px 0 #64748b,
    0 1px #64748b, 1px 1px #64748b, 2px 1px #94a3b8,
    -1px 2px #94a3b8;
}

/* ── 4. Jellyfish (purple, bob) ── */
.jellyfish {
  top: 18px;
  animation: swim-left 25s linear infinite, jelly-bob 3s ease-in-out infinite;
  box-shadow:
    0 -1px #c084fc,
    -1px 0 #a855f7, 0 0 #a855f7, 1px 0 #a855f7,
    0 1px #c084fc,
    -1px 2px #7c3aed, 1px 2px #7c3aed,
    0 3px #7c3aed;
}

/* ── 5. Seahorse (yellow-orange, slow drift) ── */
.seahorse {
  top: 15px;
  animation: swim-left 35s linear infinite, jelly-bob 4s ease-in-out infinite;
  box-shadow:
    0 -1px #fbbf24,
    0 0 #f59e0b, 1px 0 #f59e0b,
    0 1px #d97706,
    0 2px #d97706,
    1px 3px #b45309;
}

/* ── 6. Turtle (green, slow) ── */
.turtle {
  top: 14px;
  animation: swim-left 50s linear infinite;
  box-shadow:
    2px -1px #4ade80,
    -1px 0 #16a34a, 0 0 #16a34a, 1px 0 #22c55e, 2px 0 #22c55e, 3px 0 #16a34a,
    -1px 1px #4ade80, 3px 1px #4ade80;
}

/* ── 7. Pirate Ship (dark silhouette, very slow) ── */
.pirate-ship {
  top: 7px;
  animation: swim-right 180s linear infinite;
  box-shadow:
    3px -3px #334155, 3px -2px #334155, 3px -1px #475569,
    1px 0 #1e293b, 2px 0 #1e293b, 3px 0 #1e293b, 4px 0 #1e293b, 5px 0 #1e293b,
    0 1px #1e293b, 1px 1px #1e293b, 2px 1px #1e293b, 3px 1px #1e293b, 4px 1px #1e293b, 5px 1px #1e293b, 6px 1px #1e293b,
    1px 2px #0f172a, 2px 2px #0f172a, 3px 2px #0f172a, 4px 2px #0f172a, 5px 2px #0f172a;
}

/* ── 8-10. Bubbles (rising white dots) ── */
.bubble {
  animation: bubble-rise 6s linear infinite;
  box-shadow: 0 0 rgba(255,255,255,0.45);
}
.bubble.b1 { left: 25%; animation-duration: 6s; }
.bubble.b2 { left: 55%; animation-duration: 9s; }
.bubble.b3 { left: 80%; animation-duration: 11s; }

/* ── 11. Satellite (night, metallic + blue panels) ── */
.satellite {
  top: 3px;
  animation: swim-left 15s linear infinite;
  box-shadow:
    -2px 0 #3b82f6, -1px 0 #3b82f6, 0 0 #94a3b8, 1px 0 #94a3b8, 2px 0 #3b82f6, 3px 0 #3b82f6;
}

/* ── 12. Anglerfish (night, dark body + glowing lure) ── */
.anglerfish {
  top: 22px;
  animation: swim-left 40s linear infinite;
  box-shadow:
    -2px -1px #fbbf24, -2px -2px rgba(251,191,36,0.4),
    0 0 #1e293b, 1px 0 #1e293b, 2px 0 #1e293b, 3px 0 #334155,
    0 1px #0f172a, 1px 1px #0f172a, 2px 1px #1e293b;
}

/* ── 13-15. Bioluminescence (night, pulsing cyan dots) ── */
.biolum {
  box-shadow: 0 0 #22d3ee;
  animation: bio-pulse 3.5s ease-in-out infinite;
}
.biolum.bl1 { top: 19px; left: 20%; animation-duration: 3.5s; }
.biolum.bl2 { top: 23px; left: 50%; animation-duration: 4.5s; }
.biolum.bl3 { top: 17px; left: 75%; animation-duration: 5.5s; }

/* ── 16. Comet (rare, fast diagonal streak) ── */
.comet {
  top: 2px;
  right: 0;
  animation: comet-streak 2.5s linear forwards;
  box-shadow:
    0 0 #fef3c7, -1px 0 #fef3c7,
    -2px 1px #fde68a, -3px 1px #fde68a,
    -4px 2px rgba(251,191,36,0.6),
    -5px 3px rgba(251,191,36,0.3),
    -6px 4px rgba(251,191,36,0.15);
}

/* ── 17. Whale (rare, large blue silhouette) ── */
.whale {
  top: 14px;
  animation: swim-left 90s linear infinite;
  box-shadow:
    4px -1px #2563eb, 5px -1px #2563eb,
    1px 0 #1d4ed8, 2px 0 #1d4ed8, 3px 0 #1d4ed8, 4px 0 #2563eb, 5px 0 #2563eb, 6px 0 #2563eb, 7px 0 #1d4ed8,
    0 1px #1e40af, 1px 1px #1e40af, 2px 1px #1d4ed8, 3px 1px #1d4ed8, 4px 1px #1d4ed8, 5px 1px #1d4ed8, 6px 1px #1d4ed8, 7px 1px #1e40af, 8px 1px #1e40af,
    2px 2px #1e40af, 3px 2px #1e40af, 4px 2px #1e40af, 5px 2px #1e40af, 6px 2px #1e40af,
    7px 3px #1e40af;
}

/* ── 18. Bottle (rare, message in a bottle) ── */
.bottle {
  top: 11px;
  animation: swim-left 120s linear infinite, jelly-bob 5s ease-in-out infinite;
  box-shadow:
    0 -1px #d97706,
    -1px 0 #92400e, 0 0 #92400e, 1px 0 #fef3c7,
    -1px 1px #92400e, 0 1px #92400e;
}

/* ── 19. Leviathan (rare, enormous faint shadow) ── */
.leviathan {
  top: 20px;
  animation: swim-left 300s linear infinite;
  opacity: 0.15;
  box-shadow:
    2px -1px #1e293b, 3px -1px #1e293b, 4px -1px #1e293b, 5px -1px #1e293b, 6px -1px #1e293b, 7px -1px #1e293b, 8px -1px #1e293b, 9px -1px #1e293b,
    0 0 #0f172a, 1px 0 #0f172a, 2px 0 #0f172a, 3px 0 #0f172a, 4px 0 #0f172a, 5px 0 #0f172a, 6px 0 #0f172a, 7px 0 #0f172a, 8px 0 #0f172a, 9px 0 #0f172a, 10px 0 #0f172a, 11px 0 #0f172a, 12px 0 #0f172a,
    1px 1px #0f172a, 2px 1px #0f172a, 3px 1px #0f172a, 4px 1px #0f172a, 5px 1px #0f172a, 6px 1px #0f172a, 7px 1px #0f172a, 8px 1px #0f172a, 9px 1px #0f172a, 10px 1px #0f172a, 11px 1px #0f172a,
    3px 2px #0f172a, 4px 2px #0f172a, 5px 2px #0f172a, 6px 2px #0f172a, 7px 2px #0f172a, 8px 2px #0f172a, 9px 2px #0f172a;
}

/* ── 20. Sun Ray (noon, golden beam) ── */
.sun-ray {
  top: 0;
  left: 40%;
  width: 20px;
  height: 100%;
  background: linear-gradient(180deg, rgba(251,191,36,0.12) 0%, rgba(251,191,36,0.04) 40%, transparent 100%);
  animation: sun-ray-pulse 5s ease-in-out infinite;
}

/* ── 21. Dawn Glow (dawn, warm orange) ── */
.dawn-glow {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, rgba(251,146,60,0.1) 0%, transparent 40%);
  animation: sun-ray-pulse 8s ease-in-out infinite;
}

/* ── 22. Party Fish (Fridays, rainbow nyan) ── */
.party-fish {
  top: 15px;
  animation: swim-right 8s linear infinite;
  box-shadow:
    -4px 0 #ef4444, -3px 0 #f97316, -2px 0 #eab308, -1px 0 #22c55e, 0 0 #3b82f6, 1px 0 #8b5cf6,
    -3px 1px #f97316, -2px 1px #eab308, -1px 1px #22c55e, 0 1px #3b82f6;
}

/* ── 23. Ghost Ship (midnight, ethereal) ── */
.ghost-ship {
  top: 7px;
  animation: swim-left 240s linear infinite;
  opacity: 0.3;
  box-shadow:
    3px -3px rgba(255,255,255,0.6), 3px -2px rgba(255,255,255,0.5), 3px -1px rgba(255,255,255,0.4),
    1px 0 rgba(255,255,255,0.3), 2px 0 rgba(255,255,255,0.3), 3px 0 rgba(255,255,255,0.3), 4px 0 rgba(255,255,255,0.3), 5px 0 rgba(255,255,255,0.3),
    0 1px rgba(255,255,255,0.2), 1px 1px rgba(255,255,255,0.2), 2px 1px rgba(255,255,255,0.2), 3px 1px rgba(255,255,255,0.2), 4px 1px rgba(255,255,255,0.2), 5px 1px rgba(255,255,255,0.2), 6px 1px rgba(255,255,255,0.2),
    1px 2px rgba(255,255,255,0.15), 2px 2px rgba(255,255,255,0.15), 3px 2px rgba(255,255,255,0.15), 4px 2px rgba(255,255,255,0.15), 5px 2px rgba(255,255,255,0.15);
}

/* ── Ocean Life Keyframes ── */

@keyframes swim-left {
  from { left: calc(100% + 15px); }
  to { left: -15px; }
}

@keyframes swim-right {
  from { left: -15px; }
  to { left: calc(100% + 15px); }
}

@keyframes dolphin-arc {
  0% { left: calc(100% + 15px); top: 14px; }
  35% { top: 14px; }
  50% { top: 4px; }
  65% { top: 14px; }
  100% { left: -15px; top: 14px; }
}

@keyframes jelly-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

@keyframes bubble-rise {
  0% { top: 28px; opacity: 0.5; }
  80% { opacity: 0.3; }
  100% { top: -2px; opacity: 0; }
}

@keyframes bio-pulse {
  0%, 100% { opacity: 0; }
  50% { opacity: 0.5; }
}

@keyframes comet-streak {
  0% { top: 1px; left: 100%; opacity: 0.9; }
  100% { top: 18px; left: -20px; opacity: 0; }
}

@keyframes sun-ray-pulse {
  0%, 100% { opacity: 0.05; }
  50% { opacity: 0.18; }
}

@keyframes titlebar-ocean {
  from { background-position: 0 0, 0 0; }
  to { background-position: 120px 0, 0 0; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ── Mobile ── */
.aero-win.mobile {
  min-width: unset;
  min-height: unset;
  max-width: 100%;
  transition: height 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              bottom 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.aero-win.mobile .glass {
  border-radius: 16px 16px 0 0;
  padding-bottom: env(safe-area-inset-bottom, 0);
}


.aero-win.mobile .resize-handle {
  display: none;
}

.aero-win.mobile .content {
  flex: 1;
  min-height: 100px;
  touch-action: pan-y;
  overflow: hidden;
}

.aero-win.mobile.win-slide-enter-active {
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
}

.aero-win.mobile.win-slide-leave-active {
  transition: transform 0.25s cubic-bezier(0.4, 0, 1, 1) !important;
}

.aero-win.mobile.win-slide-enter-from,
.aero-win.mobile.win-slide-leave-to {
  transform: translateY(100%) !important;
  opacity: 1 !important;
}

/* ── Scroll arrows (aquatic pixel art) ── */
.scroll-arrows {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 5;
  pointer-events: auto;
}

.scroll-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  min-height: 24px;
  border: 1px solid rgba(14, 165, 233, 0.12);
  background: rgba(0, 10, 30, 0.45);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  cursor: pointer;
  padding: 0;
  transition: all 0.2s ease;
}

.scroll-arrow:hover {
  background: rgba(14, 165, 233, 0.08);
  border-color: rgba(14, 165, 233, 0.3);
  transform: scale(1.1);
}

.scroll-arrow:active {
  transform: scale(0.92);
}

.scroll-arrow.sa-surface svg { animation: sa-float 3s ease-in-out infinite; }
.scroll-arrow.sa-up svg      { animation: sa-bob-up 2.5s ease-in-out infinite; }
.scroll-arrow.sa-down svg    { animation: sa-bob-down 2.5s ease-in-out infinite; }
.scroll-arrow.sa-seabed svg  { animation: sa-sway 4s ease-in-out infinite; }

@keyframes sa-float    { 0%,100% { transform: translateY(0); }  50% { transform: translateY(-1px); } }
@keyframes sa-bob-up   { 0%,100% { transform: translateY(0); }  50% { transform: translateY(-1.5px); } }
@keyframes sa-bob-down { 0%,100% { transform: translateY(0); }  50% { transform: translateY(1.5px); } }
@keyframes sa-sway     { 0%,100% { transform: translateX(0); }  50% { transform: translateX(0.5px); } }

/* Transition for scroll arrows appear/disappear */
.scroll-arrows-enter-active,
.scroll-arrows-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.scroll-arrows-enter-from,
.scroll-arrows-leave-to {
  opacity: 0;
  transform: translateY(-50%) translateX(8px);
}
</style>
