<template>
  <div class="min-h-screen flex relative dashboard-view" :class="{ 'glass-throw-active': showZoomIn }">
    <!-- Background container with 3D perspective - full width to avoid letterboxing -->
    <div class="bg-perspective-container">
      <!-- Background - primary layer (visible for all routes, transitions out only for detail pages) -->
      <div
        ref="bgDefault"
        class="bg-layer bg-fullwidth"
        :class="[
          { 'bg-transitioning-out': showAltBackground },
          { 'zoom-reveal-bg': showZoomIn }
        ]"
        :style="{ backgroundImage: `url(/assets/img/${backgroundImage})` }"
      />
      <!-- Background - detail layer (only visible during app/marketplace detail 3D transition) -->
      <div
        ref="bgAlt"
        class="bg-layer bg-fullwidth"
        :class="{ 'bg-transitioning-in': showAltBackground }"
        style="background-image: url(/assets/img/bg-intro-3.jpg)"
      />
      <!-- Glitch overlays - trigger on background change -->
      <div 
        class="bg-glitch-layer-1"
        :class="{ 'glitch-active': isGlitching }"
        :style="{ backgroundImage: `url(/assets/img/${backgroundImage})` }"
      />
      <div 
        class="bg-glitch-layer-2"
        :class="{ 'glitch-active': isGlitching }"
        :style="{ backgroundImage: `url(/assets/img/${backgroundImage})` }"
      />
      <div 
        class="bg-glitch-scan"
        :class="{ 'glitch-active': isGlitching }"
      />
      <!-- Glitch overlays removed — only intro glitch plays (via isGlitching) -->
    </div>

    <!-- Oomph accent - brief impact flash when dashboard loads -->
    <div
      v-if="showZoomIn"
      class="fixed inset-0 pointer-events-none z-[100] oomph-flash"
      aria-hidden="true"
    />
    <!-- Reveal flashes and glitch overlay - enthralling entrance -->
    <div
      v-if="showZoomIn"
      class="fixed inset-0 pointer-events-none z-[99] reveal-flash-glitch"
      aria-hidden="true"
    />

    <!-- Background overlay - 0.3 opacity default, 0.8 opacity for Web5, Network, and Settings -->
    <div 
      class="fixed inset-0 transition-opacity duration-500 pointer-events-none"
      :class="showDarkOverlay ? 'bg-black/80' : 'bg-black/30'"
      style="z-index: -5;"
    />

    <!-- Sidebar - Desktop Only, animates in at end with separate parts -->
    <aside
      v-show="!chatFullscreen"
      data-controller-zone="sidebar"
      class="hidden md:flex w-[256px] flex-shrink-0 relative flex-col z-10"
      :class="{ 'sidebar-animate': showZoomIn }"
    >
      <div class="sidebar-shell">
        <div class="sidebar-inner flex flex-col min-h-full">
          <div class="sidebar-logo flex items-center gap-3 mb-8 p-6 pb-0 shrink-0">
            <AnimatedLogo />
            <div class="min-w-0 flex-1">
              <h2 class="text-lg font-semibold text-white truncate">{{ serverName }}</h2>
              <p class="text-xs text-white/60">v{{ version }}</p>
            </div>
          </div>

          <nav class="sidebar-nav flex-1 min-h-0 space-y-2 p-6 pt-4">
            <RouterLink
              v-for="(item, idx) in desktopNavItems"
              :key="item.path"
              :to="item.path"
              class="sidebar-nav-item flex items-center gap-3 px-4 py-3 rounded-lg text-white/80 hover:bg-white/10 hover:text-white transition-colors"
              exact-active-class="nav-tab-active"
              :style="{ '--nav-stagger': idx }"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  v-for="(path, index) in getIconPath(item.icon)"
                  :key="index"
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  :d="path"
                />
              </svg>
              <span>{{ item.label }}</span>
            </RouterLink>

            <!-- Chat launcher button -->
            <button
              @click="router.push('/dashboard/chat')"
              class="chat-launcher-btn w-full flex items-center gap-3 px-4 py-3 rounded-lg transition-all duration-300"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path v-for="(path, index) in getIconPath('chat')" :key="index" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="path" />
              </svg>
              <span>Chat</span>
            </button>

            <!-- Logout - styled as nav item, below Settings -->
            <button
              @click="handleLogout"
              class="sidebar-logout-btn w-full flex items-center gap-3 px-4 py-3 rounded-lg text-white/80 hover:bg-white/10 hover:text-white transition-colors"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
              </svg>
              <span>Logout</span>
            </button>
          </nav>

          <div class="sidebar-controller px-6 pb-2 shrink-0">
            <ControllerIndicator />
          </div>

          <!-- Online status -->
          <div class="px-6 pb-2 shrink-0">
            <div class="rounded-lg bg-white/5 border border-white/10 px-4 py-2.5">
              <OnlineStatusPill />
            </div>
          </div>

          <!-- Mode switcher -->
          <div class="px-6 pb-6 shrink-0">
            <ModeSwitcher />
          </div>
        </div>
      </div>
    </aside>

    <!-- Main Content (Xbox: Right goes here from sidebar) -->
    <main
      data-controller-zone="main"
      class="flex-1 overflow-hidden relative pb-20 md:pb-0 glass-piece z-10"
      :class="{ 'glass-throw-main': showZoomIn }"
    >
      <div data-controller-main-entry class="absolute top-4 right-4 md:top-6 md:right-8 z-20">
        <!-- Controller zone entry point - no switcher -->
      </div>

      <!-- Connection Status Banner -->
      <div v-if="isOffline && !store.isReconnecting && store.isAuthenticated" class="path-option-card mx-6 mt-6 px-6 py-3 border-l-4 border-yellow-500">
        <div class="flex items-center gap-2 text-yellow-200">
          <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
          </svg>
          <span class="font-medium">
            {{ isRestarting ? 'Server is restarting...' : isShuttingDown ? 'Server is shutting down...' : 'Connection lost' }}
          </span>
        </div>
      </div>
      
      <!-- Reconnecting Banner -->
      <div v-if="store.isReconnecting && store.isAuthenticated" class="path-option-card mx-6 mt-6 px-6 py-3 border-l-4 border-blue-500">
        <div class="flex items-center gap-2 text-blue-200">
          <svg class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
          </svg>
          <span class="font-medium">Reconnecting...</span>
        </div>
      </div>

      <!-- Persistent Mobile Tabs for Apps/Marketplace - glass piece 3 -->
      <div
        v-if="showAppsTabs"
        class="md:hidden fixed top-0 left-0 right-0 z-40 px-4 pt-4 pb-2 glass-piece"
        :class="{ 'glass-throw-mobile-tabs': showZoomIn }"
        style="background: rgba(0, 0, 0, 0.25); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); transform: translateZ(0);"
      >
        <div class="glass-card p-2 rounded-lg flex gap-2 relative">
          <!-- Animated Active Indicator -->
          <div
            class="absolute top-2 bottom-2 rounded-lg bg-white/20 transition-all duration-300 ease-out"
            :style="{
              left: `${appsTabIndicatorLeft}px`,
              width: `${appsTabIndicatorWidth}px`,
            }"
          ></div>
          
          <RouterLink
            ref="appsTabRef"
            to="/dashboard/apps"
            class="flex-1 px-4 py-2 rounded-lg font-medium transition-all duration-300 text-center relative z-10"
            :class="{
              'bg-white/20 text-white': route.path === '/dashboard/apps' || route.path.startsWith('/dashboard/apps/'),
              'text-white/60 hover:text-white/80': !(route.path === '/dashboard/apps' || route.path.startsWith('/dashboard/apps/'))
            }"
          >
            My Apps
          </RouterLink>
          <RouterLink
            ref="marketplaceTabRef"
            to="/dashboard/marketplace"
            class="flex-1 px-4 py-2 rounded-lg font-medium transition-all duration-300 text-center relative z-10"
            :class="{
              'bg-white/20 text-white': route.path === '/dashboard/marketplace' || route.path.startsWith('/dashboard/marketplace/'),
              'text-white/60 hover:text-white/80': !(route.path === '/dashboard/marketplace' || route.path.startsWith('/dashboard/marketplace/'))
            }"
          >
            App Store
          </RouterLink>
        </div>
      </div>

      <!-- Persistent Mobile Tabs for Network/Cloud - glass piece 4 -->
      <div
        v-if="showNetworkTabs"
        class="md:hidden fixed top-0 left-0 right-0 z-40 px-4 pt-4 pb-2 glass-piece"
        :class="{ 'glass-throw-mobile-tabs-2': showZoomIn }"
        style="background: rgba(0, 0, 0, 0.25); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); transform: translateZ(0);"
        :style="{ top: showAppsTabs ? '80px' : '0' }"
      >
        <div class="glass-card p-2 rounded-lg flex gap-2 relative">
          <!-- Animated Active Indicator -->
          <div
            class="absolute top-2 bottom-2 rounded-lg bg-white/20 transition-all duration-300 ease-out"
            :style="{
              left: `${networkTabIndicatorLeft}px`,
              width: `${networkTabIndicatorWidth}px`,
            }"
          ></div>
          
          <RouterLink
            ref="cloudTabRef"
            to="/dashboard/cloud"
            class="flex-1 px-4 py-2 rounded-lg font-medium transition-all duration-300 text-center relative z-10"
            :class="{
              'bg-white/20 text-white': route.path === '/dashboard/cloud' || route.path.startsWith('/dashboard/cloud/'),
              'text-white/60 hover:text-white/80': !(route.path === '/dashboard/cloud' || route.path.startsWith('/dashboard/cloud/'))
            }"
          >
            Cloud
          </RouterLink>
          <RouterLink
            ref="serverTabRef"
            to="/dashboard/server"
            class="flex-1 px-4 py-2 rounded-lg font-medium transition-all duration-300 text-center relative z-10"
            :class="{
              'bg-white/20 text-white': route.path === '/dashboard/server' || route.path.startsWith('/dashboard/server/'),
              'text-white/60 hover:text-white/80': !(route.path === '/dashboard/server' || route.path.startsWith('/dashboard/server/'))
            }"
          >
            Network
          </RouterLink>
        </div>
      </div>

      <div class="perspective-container-wrapper glass-piece" :class="{ 'glass-throw-content': showZoomIn && !isHomeRoute }">
        <div class="perspective-container">
          <RouterView v-slot="{ Component, route }">
            <Transition :name="getTransitionName(route)">
              <div :key="route.path" class="view-wrapper">
                <div
                  v-if="route.path === '/dashboard/chat'"
                  class="h-full"
                >
                  <component :is="Component" />
                </div>
                <div
                  v-else
                  :class="[
                    'px-4 pt-4 md:pt-8 md:px-8 overflow-y-auto h-full',
                    needsMobileBackButtonSpace
                      ? 'pb-[calc(var(--mobile-tab-bar-height,_72px)+96px)] md:pb-8'
                      : 'pb-4 md:pb-8'
                  ]"
                  :style="mobileTabPaddingTop ? { paddingTop: (mobileTabPaddingTop + 16) + 'px' } : undefined"
                >
                  <component :is="Component" class="view-container" />
                </div>
              </div>
            </Transition>
          </RouterView>
        </div>
      </div>
    </main>

    <!-- Mobile Bottom Tab Bar - glass piece 5 -->
    <nav
      ref="mobileTabBar"
      data-mobile-tab-bar
      class="md:hidden fixed bottom-0 left-0 right-0 border-t border-glass-border shadow-glass z-50 glass-piece"
      :class="{ 'glass-throw-tabbar': showZoomIn }"
      style="background: rgba(0, 0, 0, 0.25); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); padding-bottom: env(safe-area-inset-bottom, 0px);"
    >
      <div class="flex justify-around items-center px-2 py-3 relative">
        <RouterLink
          v-for="item in mobileNavItems"
          :key="item.path"
          :to="item.path"
          class="flex items-center justify-center w-full py-3 rounded-lg text-white/70 transition-all duration-300 relative z-10"
          :class="{
            'nav-tab-active': item.isCombined
              ? (item.path === '/dashboard/apps'
                  ? (route.path.includes('/apps') || route.path.includes('/marketplace'))
                  : (route.path.includes('/cloud') || route.path.includes('/server')))
              : undefined
          }"
          :exact-active-class="item.isCombined ? undefined : 'nav-tab-active'"
        >
          <svg class="w-7 h-7 transition-all duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              v-for="(path, index) in getIconPath(item.icon)"
              :key="index"
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              :d="path"
            />
          </svg>
        </RouterLink>
        <!-- Chat launcher -->
        <button
          @click="router.push('/dashboard/chat')"
          class="chat-launcher-btn-mobile flex items-center justify-center w-full py-3 rounded-lg transition-all duration-300 relative z-10"
        >
          <svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path v-for="(path, index) in getIconPath('chat')" :key="index" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="path" />
          </svg>
        </button>
      </div>
    </nav>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { RouterLink, RouterView, useRouter, useRoute } from 'vue-router'
import { useAppStore } from '../stores/app'
import { useLoginTransitionStore } from '../stores/loginTransition'
import AnimatedLogo from '@/components/AnimatedLogo.vue'
import OnlineStatusPill from '@/components/OnlineStatusPill.vue'
import ControllerIndicator from '@/components/ControllerIndicator.vue'
import ModeSwitcher from '@/components/ModeSwitcher.vue'
import { useUIModeStore } from '@/stores/uiMode'
import { playDashboardLoadOomph } from '@/composables/useLoginSounds'

const uiMode = useUIModeStore()

// Chat fullscreen: hide sidebar + mobile nav when on /dashboard/chat (any mode)
const chatFullscreen = computed(() => route.path === '/dashboard/chat')


const router = useRouter()
const route = useRoute()
const store = useAppStore()
const loginTransition = useLoginTransitionStore()

const showZoomIn = ref(false)
const pendingTimers: ReturnType<typeof setTimeout>[] = []

function scheduledTimeout(fn: () => void, ms: number) {
  const id = setTimeout(fn, ms)
  pendingTimers.push(id)
  return id
}

function isDetailRoute(path: string) {
  return (path.includes('/apps/') && !path.endsWith('/apps')) ||
    (path.includes('/marketplace/') && !path.endsWith('/marketplace'))
}

const showAltBackground = ref(false)
const isHomeRoute = computed(() => route.path === '/dashboard' || route.path === '/dashboard/')
const isGlitching = ref(false)

const ROUTE_BACKGROUNDS: Record<string, string> = {
  '/dashboard': 'bg-home.jpg',
  '/dashboard/': 'bg-home.jpg',
  '/dashboard/apps': 'bg-myapps.jpg',
  '/dashboard/marketplace': 'bg-appstore.jpg',
  '/dashboard/cloud': 'bg-cloud.jpg',
  '/dashboard/server': 'bg-network.jpg',
  '/dashboard/web5': 'bg-web5.jpg',
  '/dashboard/settings': 'bg-settings.jpg',
  '/dashboard/chat': 'bg-home.jpg',
}

const backgroundImage = computed(() => {
  if (isDetailRoute(route.path)) return 'bg-intro.jpg'
  return ROUTE_BACKGROUNDS[route.path] || 'bg-home.jpg'
})

const isDarkRoute = computed(() => {
  const p = route.path
  return p.includes('/dashboard/web5') ||
         p.includes('/dashboard/server') ||
         p.includes('/dashboard/settings') ||
         (p.includes('/dashboard/apps') && !isDetailRoute(p)) ||
         p.includes('/dashboard/marketplace') ||
         p.includes('/dashboard/cloud')
})

const showDarkOverlay = ref(isDarkRoute.value)
let overlayTimer: ReturnType<typeof setTimeout> | null = null

watch(isDarkRoute, (dark) => {
  if (overlayTimer) { clearTimeout(overlayTimer); overlayTimer = null }
  if (dark) {
    showDarkOverlay.value = true
  } else {
    overlayTimer = scheduledTimeout(() => { showDarkOverlay.value = false }, 450)
  }
})

const mobileTabBar = ref<HTMLElement | null>(null)
const appsTabRef = ref<HTMLElement | null>(null)
const marketplaceTabRef = ref<HTMLElement | null>(null)
const appsTabIndicatorLeft = ref(0)
const appsTabIndicatorWidth = ref(0)

const serverTabRef = ref<HTMLElement | null>(null)
const cloudTabRef = ref<HTMLElement | null>(null)
const networkTabIndicatorLeft = ref(0)
const networkTabIndicatorWidth = ref(0)

watch(() => route.path, (newPath) => {
  const isAppDetails = isDetailRoute(newPath)
  const wasAppDetails = showAltBackground.value

  showAltBackground.value = isAppDetails

  if (isAppDetails && !wasAppDetails) {
    scheduledTimeout(() => {
      isGlitching.value = true
      scheduledTimeout(() => { isGlitching.value = false }, 375)
    }, 500)
  }
})

const needsMobileBackButtonSpace = computed(() => isDetailRoute(route.path))


// Show persistent tabs for Apps/Marketplace on mobile
const showAppsTabs = computed(() => {
  if (typeof window === 'undefined') return false
  if (window.innerWidth >= 768) return false
  return route.path.includes('/apps') || route.path.includes('/marketplace')
})

// Show persistent tabs for Network/Cloud on mobile
const showNetworkTabs = computed(() => {
  if (typeof window === 'undefined') return false
  if (window.innerWidth >= 768) return false
  if (route.name === 'cloud-folder') return false
  return route.path.includes('/server') || route.path.includes('/cloud')
})

// Top padding for content div to clear fixed mobile tab overlays
const mobileTabPaddingTop = computed(() => {
  if (typeof window === 'undefined' || window.innerWidth >= 768) return 0
  if (showAppsTabs.value && showNetworkTabs.value) return 160
  if (showAppsTabs.value || showNetworkTabs.value) return 80
  return 0
})

function updateTabBarHeight() {
  if (typeof window === 'undefined') return
  if (mobileTabBar.value) {
    const height = mobileTabBar.value.offsetHeight
    document.documentElement.style.setProperty('--mobile-tab-bar-height', `${height}px`)
  }
}

function updateAppsTabIndicator() {
  if (typeof window === 'undefined' || window.innerWidth >= 768) return
  
  const isAppsActive = route.path === '/dashboard/apps' || route.path.startsWith('/dashboard/apps/')
  const activeTab = isAppsActive ? appsTabRef.value : marketplaceTabRef.value
  
  if (!activeTab) return
  
  const container = activeTab.parentElement
  if (!container) return
  
  const containerRect = container.getBoundingClientRect()
  const tabRect = activeTab.getBoundingClientRect()
  
  appsTabIndicatorLeft.value = tabRect.left - containerRect.left
  appsTabIndicatorWidth.value = tabRect.width
}

function updateNetworkTabIndicator() {
  if (typeof window === 'undefined' || window.innerWidth >= 768) return
  
  const isCloudActive = route.path === '/dashboard/cloud' || route.path.startsWith('/dashboard/cloud/')
  const activeTab = isCloudActive ? cloudTabRef.value : serverTabRef.value
  
  if (!activeTab) return
  
  const container = activeTab.parentElement
  if (!container) return
  
  const containerRect = container.getBoundingClientRect()
  const tabRect = activeTab.getBoundingClientRect()
  
  networkTabIndicatorLeft.value = tabRect.left - containerRect.left
  networkTabIndicatorWidth.value = tabRect.width
}

function onResize() {
  updateTabBarHeight()
  updateAppsTabIndicator()
  updateNetworkTabIndicator()
}

onMounted(() => {
  document.body.classList.add('dashboard-active')
  if (loginTransition.justLoggedIn) {
    playDashboardLoadOomph()
    showZoomIn.value = true
    loginTransition.setPendingWelcomeTyping(true)
    loginTransition.setJustLoggedIn(false)
    const triggerRevealGlitch = () => {
      isGlitching.value = true
      scheduledTimeout(() => { isGlitching.value = false }, 380)
    }
    scheduledTimeout(triggerRevealGlitch, 500)
    scheduledTimeout(triggerRevealGlitch, 1200)
    scheduledTimeout(triggerRevealGlitch, 2000)
    scheduledTimeout(() => { showZoomIn.value = false }, 8000)
    scheduledTimeout(() => {
      loginTransition.setStartWelcomeTyping(true)
      loginTransition.setPendingWelcomeTyping(false)
    }, 4000)
  }

  onResize()
  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  document.body.classList.remove('dashboard-active')
  window.removeEventListener('resize', onResize)
  for (const id of pendingTimers) clearTimeout(id)
  pendingTimers.length = 0
  if (overlayTimer) { clearTimeout(overlayTimer); overlayTimer = null }
})

// Watch route changes to update indicator position
watch(() => route.path, () => {
  nextTick(() => {
    updateAppsTabIndicator()
    updateNetworkTabIndicator()
  })
})

const serverName = computed(() => store.serverName)
const version = computed(() => store.serverInfo?.version || '0.0.0')
const isOffline = computed(() => store.isOffline)
const isRestarting = computed(() => store.isRestarting)
const isShuttingDown = computed(() => store.isShuttingDown)

// Navigation items — reactive based on UI mode
interface NavItem {
  path: string
  label: string
  icon: string
  isCombined?: boolean
}

const gamerDesktopNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'My Apps', icon: 'apps' },
  { path: '/dashboard/marketplace', label: 'App Store', icon: 'marketplace' },
  { path: '/dashboard/cloud', label: 'Cloud', icon: 'cloud' },
  { path: '/dashboard/server', label: 'Network', icon: 'server' },
  { path: '/dashboard/web5', label: 'Web5', icon: 'web5' },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const easyDesktopNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'My Apps', icon: 'apps' },
  { path: '/dashboard/cloud', label: 'Cloud', icon: 'cloud' },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const chatDesktopNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'My Apps', icon: 'apps' },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const desktopNavItems = computed(() => {
  if (uiMode.isEasy) return easyDesktopNav
  if (uiMode.isChat) return chatDesktopNav
  return gamerDesktopNav
})

const gamerMobileNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'Apps', icon: 'apps', isCombined: true },
  { path: '/dashboard/cloud', label: 'Network', icon: 'server', isCombined: true },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const easyMobileNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'Apps', icon: 'apps' },
  { path: '/dashboard/cloud', label: 'Cloud', icon: 'cloud' },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const chatMobileNav: NavItem[] = [
  { path: '/dashboard', label: 'Home', icon: 'home' },
  { path: '/dashboard/apps', label: 'Apps', icon: 'apps' },
  { path: '/dashboard/settings', label: 'Settings', icon: 'settings' },
]

const mobileNavItems = computed(() => {
  if (uiMode.isEasy) return easyMobileNav
  if (uiMode.isChat) return chatMobileNav
  return gamerMobileNav
})

function getIconPath(iconName: string): string[] {
  const icons: Record<string, string[]> = {
    home: ['M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6'],
    apps: ['M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z'],
    marketplace: ['M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z'],
    cloud: ['M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z'],
    server: ['M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01'],
    web5: ['M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9'],
    chat: ['M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z'],
    settings: [
      'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
      'M15 12a3 3 0 11-6 0 3 3 0 016 0z',
    ],
  }
  return icons[iconName] || []
}

async function handleLogout() {
  try {
    await store.logout()
  } catch {
    /* proceed to login regardless */
  }
  router.push('/login').catch(() => {
    window.location.href = '/login'
  })
}

// Track previous route for transition logic
let previousPath = ''

// Tab order for vertical transitions
const tabOrder = [
  '/dashboard',
  '/dashboard/apps',
  '/dashboard/marketplace',
  '/dashboard/cloud',
  '/dashboard/server',
  '/dashboard/web5',
  '/dashboard/chat',
  '/dashboard/settings'
]

// Determine transition direction based on route depth
function getTransitionName(currentRoute: any) {
  const currentPath = currentRoute.path
  
  // If no previous path, use fade transition for initial load
  if (!previousPath) {
    previousPath = currentPath
    return 'fade'
  }

  // Chat transitions: directional slide (chat from/to left, dashboard from/to right)
  const isChat = currentPath === '/dashboard/chat'
  const wasChat = previousPath === '/dashboard/chat'
  if (isChat) {
    previousPath = currentPath
    return 'chat-open'
  }
  if (wasChat) {
    previousPath = currentPath
    return 'chat-close'
  }
  
  const isAppDetails = currentPath.includes('/apps/') && !currentPath.endsWith('/apps')
  const isAppsList = currentPath === '/dashboard/apps'
  const wasAppDetails = previousPath.includes('/apps/') && !previousPath.endsWith('/apps')
  const wasAppsList = previousPath === '/dashboard/apps'
  
  // Marketplace detail transitions
  const isMarketplaceDetails = currentPath.includes('/marketplace/') && !currentPath.endsWith('/marketplace')
  const isMarketplaceList = currentPath === '/dashboard/marketplace'
  const wasMarketplaceDetails = previousPath.includes('/marketplace/') && !previousPath.endsWith('/marketplace')
  const wasMarketplaceList = previousPath === '/dashboard/marketplace'
  
  // Cloud folder transitions
  const isCloudFolder = currentPath.includes('/cloud/') && !currentPath.endsWith('/cloud')
  const isCloudList = currentPath === '/dashboard/cloud'
  const wasCloudFolder = previousPath.includes('/cloud/') && !previousPath.endsWith('/cloud')
  const wasCloudList = previousPath === '/dashboard/cloud'
  
  let transitionName = 'fade'
  
  // Mobile: Horizontal slide transitions between Apps and Marketplace (check first on mobile)
  if (typeof window !== 'undefined' && window.innerWidth < 768) {
    // From Marketplace to Apps: slide right
    if (wasMarketplaceList && isAppsList) {
      transitionName = 'slide-right'
    }
    // From Apps to Marketplace: slide left
    else if (wasAppsList && isMarketplaceList) {
      transitionName = 'slide-left'
    }
    // From Network to Cloud: slide right
    else if (previousPath === '/dashboard/server' && isCloudList) {
      transitionName = 'slide-right'
    }
    // From Cloud to Network: slide left
    else if (wasCloudList && currentPath === '/dashboard/server') {
      transitionName = 'slide-left'
    }
    // Vertical transition: between main tabs (mobile fallback)
    else {
      const currentIndex = tabOrder.indexOf(currentPath)
      const previousIndex = tabOrder.indexOf(previousPath)
      
      if (currentIndex !== -1 && previousIndex !== -1 && currentIndex !== previousIndex) {
        // Moving down the menu (visual down)
        if (currentIndex > previousIndex) {
          transitionName = 'slide-down'
        }
        // Moving up the menu (visual up)
        else {
          transitionName = 'slide-up'
        }
      }
    }
  }
  // Horizontal depth transition: apps list <-> app details
  else if (wasAppsList && isAppDetails) {
    transitionName = 'depth-forward'
  } else if (wasAppDetails && isAppsList) {
    transitionName = 'depth-back'
  }
  // Horizontal depth transition: marketplace list <-> marketplace details
  else if (wasMarketplaceList && isMarketplaceDetails) {
    transitionName = 'depth-forward'
  } else if (wasMarketplaceDetails && isMarketplaceList) {
    transitionName = 'depth-back'
  }
  // Horizontal depth transition: cloud list <-> cloud folder
  else if (wasCloudList && isCloudFolder) {
    transitionName = 'depth-forward'
  } else if (wasCloudFolder && isCloudList) {
    transitionName = 'depth-back'
  }
  // Horizontal depth transition: marketplace list <-> installed app details
  // (when clicking installed app from marketplace)
  else if (wasMarketplaceList && isAppDetails) {
    transitionName = 'depth-forward'
  } else if (wasAppDetails && isMarketplaceList) {
    transitionName = 'depth-back'
  }
  // Vertical transition: between main tabs (desktop)
  else {
    const currentIndex = tabOrder.indexOf(currentPath)
    const previousIndex = tabOrder.indexOf(previousPath)
    
    if (currentIndex !== -1 && previousIndex !== -1 && currentIndex !== previousIndex) {
      // Moving down the menu (visual down)
      if (currentIndex > previousIndex) {
        transitionName = 'slide-down'
      }
      // Moving up the menu (visual up)
      else {
        transitionName = 'slide-up'
      }
    }
  }
  
  // Update previous path for next transition
  previousPath = currentPath
  
  return transitionName
}
</script>

<style>
/* 2advanced-style: fluid, cinematic, layered motion */
/* Strong easeInOut - smooth acceleration/deceleration, no bounce */

/* Background - zoom in from depth with motion blur */
.zoom-reveal-bg {
  animation: zoom-reveal 2.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  transform-origin: center center;
  opacity: 0;
  transform: scale(0.15);
  filter: blur(24px);
}

@keyframes zoom-reveal {
  0% {
    opacity: 0;
    transform: scale(0.15);
    filter: blur(24px);
  }
  35% {
    opacity: 0.5;
    transform: scale(0.5);
    filter: blur(20px);
  }
  65% {
    opacity: 0.85;
    transform: scale(0.88);
    filter: blur(6px);
  }
  100% {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
}

/* 2advanced-style glass assembly - fluid, layered, deliberate timing */
.glass-throw-active {
  perspective: 1400px;
}

.glass-piece {
  will-change: transform, opacity;
}

/* Sidebar - animates in at end with separate parts (like cards) */
.sidebar-shell {
  width: 100%;
  height: 100%;
  min-height: 100vh;
  background: rgba(0, 0, 0, 0.25);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-right: 1px solid transparent;
  box-shadow: 4px 0 24px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

.sidebar-animate .sidebar-shell {
  animation: sidebar-shell-fly 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: 5.2s;
  opacity: 0;
  transform: translateX(-100%);
}

@keyframes sidebar-shell-fly {
  0% {
    opacity: 0;
    transform: translateX(-100%);
    border-color: transparent;
  }
  70% {
    opacity: 1;
    transform: translateX(0);
    border-color: transparent;
  }
  100% {
    opacity: 1;
    transform: translateX(0);
    border-color: rgba(255, 255, 255, 0.18);
  }
}

.sidebar-inner {
  overflow: hidden;
  opacity: 0;
}

.sidebar-animate .sidebar-inner {
  animation: sidebar-inner-draw 0.7s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: 6.1s;
}

@keyframes sidebar-inner-draw {
  0% {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
  }
  20% { opacity: 1; }
  100% {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
}

.sidebar-nav-item {
  opacity: 0;
  transform: translateX(-12px);
}

.sidebar-animate .sidebar-nav-item {
  animation: sidebar-nav-item-in 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: calc(6.3s + var(--nav-stagger, 0) * 0.06s);
}

@keyframes sidebar-nav-item-in {
  0% {
    opacity: 0;
    transform: translateX(-12px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

.sidebar-controller {
  opacity: 0;
}

.sidebar-animate .sidebar-controller {
  animation: sidebar-fade-in 0.4s ease-out forwards;
  animation-delay: 6.9s;
}

.sidebar-logout-btn {
  opacity: 0;
  transform: scale(0.95);
}

.sidebar-animate .sidebar-logout-btn {
  animation: sidebar-logout-pop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  animation-delay: 7.1s;
}

@keyframes sidebar-fade-in {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes sidebar-logout-pop {
  0% {
    opacity: 0;
    transform: scale(0.95);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.sidebar-logo {
  opacity: 0;
  transform: translateY(-8px);
}

.sidebar-animate .sidebar-logo {
  animation: sidebar-logo-in 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: 6.15s;
}

@keyframes sidebar-logo-in {
  0% {
    opacity: 0;
    transform: translateY(-8px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* When not animating, show everything (direct load / hard refresh) */
aside:not(.sidebar-animate) .sidebar-shell {
  border-color: rgba(255, 255, 255, 0.18);
  opacity: 1;
  transform: none;
}
aside:not(.sidebar-animate) .sidebar-inner,
aside:not(.sidebar-animate) .sidebar-logo,
aside:not(.sidebar-animate) .sidebar-nav-item,
aside:not(.sidebar-animate) .sidebar-controller,
aside:not(.sidebar-animate) .sidebar-logout-btn {
  opacity: 1;
  transform: none;
  animation: none;
  clip-path: none;
}

/* Smooth easeInOut - no overshoot, refined deceleration */

.glass-throw-main {
  animation: glass-throw-main 1.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.15s forwards;
  opacity: 0;
  transform: translateX(20%) scale(0.2);
  filter: blur(14px);
}

.glass-throw-content {
  animation: glass-throw-content 1.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.22s forwards;
  opacity: 0;
  transform: translateY(12%) scale(0.25);
  filter: blur(10px);
}

.glass-throw-mobile-tabs {
  animation: glass-throw-top 1.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.08s forwards;
  opacity: 0;
  transform: translateY(-90%) scale(0.28);
  filter: blur(10px);
}

.glass-throw-mobile-tabs-2 {
  animation: glass-throw-top 1.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.18s forwards;
  opacity: 0;
  transform: translateY(-90%) scale(0.28);
  filter: blur(10px);
}

.glass-throw-tabbar {
  animation: glass-throw-bottom 1.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.2s forwards;
  opacity: 0;
  transform: translateY(85%) scale(0.25);
  filter: blur(10px);
}

/* Motion blur peaks mid-transition, smooth settle */
@keyframes glass-throw-sidebar {
  0% {
    opacity: 0;
    transform: translateX(-100%) scale(0.25);
    filter: blur(12px);
  }
  45% {
    opacity: 0.9;
    transform: translateX(-15%) scale(0.85);
    filter: blur(8px);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scale(1);
    filter: blur(0);
  }
}

@keyframes glass-throw-main {
  0% {
    opacity: 0;
    transform: translateX(20%) scale(0.2);
    filter: blur(14px);
  }
  50% {
    opacity: 0.85;
    transform: translateX(0) scale(0.9);
    filter: blur(6px);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scale(1);
    filter: blur(0);
  }
}

@keyframes glass-throw-content {
  0% {
    opacity: 0;
    transform: translateY(12%) scale(0.25);
    filter: blur(10px);
  }
  50% {
    opacity: 0.9;
    transform: translateY(0) scale(0.9);
    filter: blur(4px);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

@keyframes glass-throw-top {
  0% {
    opacity: 0;
    transform: translateY(-90%) scale(0.28);
    filter: blur(10px);
  }
  50% {
    opacity: 0.9;
    transform: translateY(0) scale(0.95);
    filter: blur(4px);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

@keyframes glass-throw-bottom {
  0% {
    opacity: 0;
    transform: translateY(85%) scale(0.25);
    filter: blur(10px);
  }
  50% {
    opacity: 0.9;
    transform: translateY(0) scale(0.95);
    filter: blur(4px);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

/* Oomph accent - subtle 2advanced-style flash synced with boot thud */
.oomph-flash {
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.08) 0%, transparent 65%);
  animation: oomph-flash 0.7s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes oomph-flash {
  0% { opacity: 0; }
  25% { opacity: 0.9; }
  100% { opacity: 0; }
}

/* Reveal flashes - enthralling entrance during zoom */
.reveal-flash-glitch {
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.12) 0%, transparent 70%);
  animation: reveal-flash-sequence 2.8s ease-out forwards;
}

@keyframes reveal-flash-sequence {
  0% { opacity: 0; }
  12% { opacity: 0.6; }
  18% { opacity: 0; }
  42% { opacity: 0.4; }
  48% { opacity: 0; }
  70% { opacity: 0.35; }
  78% { opacity: 0; }
  100% { opacity: 0; }
}

/* Wrapper to contain perspective without clipping */
.perspective-container-wrapper {
  position: relative;
  overflow: hidden;
  height: 100%;
}

/* Perspective container for 3D depth effect */
.perspective-container {
  perspective: 2000px;
  perspective-origin: 50% 50%;
  position: relative;
  height: 100%;
  overflow: hidden;
}

/* View wrapper - allows smooth transitions with absolute positioning */
.view-wrapper {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  will-change: transform, opacity;
  opacity: 1;
}

.view-container {
  height: 100%;
  min-height: 100%;
}

/* Forward transition: 2advanced fluid depth */
.depth-forward-enter-active.view-wrapper,
.depth-forward-leave-active.view-wrapper {
  transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.depth-forward-enter-from.view-wrapper {
  opacity: 0;
  transform: translateZ(-800px) scale(0.75);
  filter: blur(4px);
}

.depth-forward-enter-to.view-wrapper {
  opacity: 1;
  transform: translateZ(0) scale(1);
  filter: blur(0px);
}

.depth-forward-leave-from.view-wrapper {
  opacity: 1;
  transform: translateZ(0) scale(1);
  filter: blur(0px);
}

.depth-forward-leave-to.view-wrapper {
  opacity: 0;
  transform: translateZ(400px) scale(1.2);
  filter: blur(8px);
}

/* Back transition: 2advanced fluid depth */
.depth-back-enter-active.view-wrapper,
.depth-back-leave-active.view-wrapper {
  transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.depth-back-enter-from.view-wrapper {
  opacity: 0;
  transform: translateZ(400px) scale(1.2);
  filter: blur(8px);
}

.depth-back-enter-to.view-wrapper {
  opacity: 1;
  transform: translateZ(0) scale(1);
  filter: blur(0px);
}

.depth-back-leave-from.view-wrapper {
  opacity: 1;
  transform: translateZ(0) scale(1);
  filter: blur(0px);
}

.depth-back-leave-to.view-wrapper {
  opacity: 0;
  transform: translateZ(-800px) scale(0.75);
  filter: blur(4px);
}

/* Subtle 3D tilt - 2advanced layered depth */
@media (min-width: 768px) {
  .depth-forward-enter-from.view-wrapper {
    transform: translateZ(-800px) scale(0.75) rotateX(5deg);
  }
  
  .depth-forward-leave-to.view-wrapper {
    transform: translateZ(400px) scale(1.2) rotateX(-4deg);
  }
  
  .depth-back-enter-from.view-wrapper {
    transform: translateZ(400px) scale(1.2) rotateX(-4deg);
  }
  
  .depth-back-leave-to.view-wrapper {
    transform: translateZ(-800px) scale(0.75) rotateX(5deg);
  }
}

/* Chat open transition — chat slides in from left, dashboard slides out to right */
.chat-open-enter-active.view-wrapper,
.chat-open-leave-active.view-wrapper {
  transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1), transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.chat-open-enter-from.view-wrapper {
  opacity: 0;
  transform: translateX(-60px) scale(0.96);
}

.chat-open-enter-to.view-wrapper {
  opacity: 1;
  transform: translateX(0) scale(1);
}

.chat-open-leave-from.view-wrapper {
  opacity: 1;
  transform: translateX(0) scale(1);
}

.chat-open-leave-to.view-wrapper {
  opacity: 0;
  transform: translateX(60px) scale(0.96);
}

/* Chat close transition — chat slides out to left, dashboard slides in from right */
.chat-close-enter-active.view-wrapper,
.chat-close-leave-active.view-wrapper {
  transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1), transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.chat-close-enter-from.view-wrapper {
  opacity: 0;
  transform: translateX(60px) scale(0.96);
}

.chat-close-enter-to.view-wrapper {
  opacity: 1;
  transform: translateX(0) scale(1);
}

.chat-close-leave-from.view-wrapper {
  opacity: 1;
  transform: translateX(0) scale(1);
}

.chat-close-leave-to.view-wrapper {
  opacity: 0;
  transform: translateX(-60px) scale(0.96);
}

/* Fade transition for initial loads and default cases */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.fade-enter-to,
.fade-leave-from {
  opacity: 1;
}

/* Mobile: Slide left transition (Apps -> Marketplace) */
.slide-left-enter-active.view-wrapper,
.slide-left-leave-active.view-wrapper {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-left-enter-from.view-wrapper {
  transform: translateX(100%);
}

.slide-left-enter-to.view-wrapper {
  transform: translateX(0);
}

.slide-left-leave-from.view-wrapper {
  transform: translateX(0);
}

.slide-left-leave-to.view-wrapper {
  transform: translateX(-100%);
}

/* Mobile: Slide right transition (Marketplace -> Apps) */
.slide-right-enter-active.view-wrapper,
.slide-right-leave-active.view-wrapper {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-right-enter-from.view-wrapper {
  transform: translateX(-100%);
}

.slide-right-enter-to.view-wrapper {
  transform: translateX(0);
}

.slide-right-leave-from.view-wrapper {
  transform: translateX(0);
}

.slide-right-leave-to.view-wrapper {
  transform: translateX(100%);
}

/* Slide down: Moving down the menu (content slides up like a scroll) */
.slide-down-enter-active.view-wrapper {
  transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.slide-down-leave-active.view-wrapper {
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94),
              opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-down-enter-from.view-wrapper {
  opacity: 0;
  transform: translateY(40vh);
}

.slide-down-enter-to.view-wrapper {
  opacity: 1;
  transform: translateY(0);
}

.slide-down-leave-from.view-wrapper {
  opacity: 1;
  transform: translateY(0);
}

.slide-down-leave-to.view-wrapper {
  opacity: 0;
  transform: translateY(-30vh);
}

/* Slide up: Moving up the menu (content slides down like a scroll) */
.slide-up-enter-active.view-wrapper {
  transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.slide-up-leave-active.view-wrapper {
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94),
              opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-up-enter-from.view-wrapper {
  opacity: 0;
  transform: translateY(-40vh);
}

.slide-up-enter-to.view-wrapper {
  opacity: 1;
  transform: translateY(0);
}

.slide-up-leave-from.view-wrapper {
  opacity: 1;
  transform: translateY(0);
}

.slide-up-leave-to.view-wrapper {
  opacity: 0;
  transform: translateY(30vh);
}

/* Background 3D container - full width, black fill during zoom to avoid letterboxing */
.dashboard-view .bg-perspective-container {
  position: fixed;
  inset: 0;
  z-index: -10;
  perspective: 1000px;
  perspective-origin: 50% 50%;
  overflow: hidden;
  left: 0 !important;
  right: 0 !important;
  width: 100% !important;
  min-width: 100% !important;
  background: #000;
}

/* Background layers with 3D transitions - full width like login */
.dashboard-view .bg-layer {
  position: absolute;
  inset: 0;
  background-size: cover !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  transition: all 0.45s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transform-style: preserve-3d;
  will-change: transform, opacity;
}

/* Default state - bg-intro visible, bg-intro-3 hidden back */
.dashboard-view .bg-layer:first-of-type {
  opacity: 1;
  transform: translateZ(0) scale(1);
}

.dashboard-view .bg-layer:nth-of-type(2) {
  opacity: 0;
  transform: translateZ(-200px) scale(0.9) rotateY(-15deg);
}

/* Transitioning out - current background moves away with zoom */
.dashboard-view .bg-layer.bg-transitioning-out {
  opacity: 0;
  transform: translateZ(200px) scale(1.15) rotateY(15deg) !important;
}

/* Transitioning in - new background comes forward with zoom */
.dashboard-view .bg-layer.bg-transitioning-in {
  opacity: 1;
  transform: translateZ(0) scale(1.05) rotateY(0deg) !important;
}

/* Background glitch effect layers - World Fair style */
.bg-glitch-layer-1,
.bg-glitch-layer-2,
.bg-glitch-scan {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
}

.bg-glitch-layer-1 {
  background-size: cover;
  background-position: center;
  mix-blend-mode: lighten;
  filter: brightness(1.8) contrast(2) saturate(1.5) hue-rotate(180deg);
  will-change: transform, clip-path, opacity;
}

.bg-glitch-layer-2 {
  background-size: cover;
  background-position: center;
  mix-blend-mode: color-dodge;
  filter: brightness(2) contrast(2) saturate(2) hue-rotate(90deg);
  will-change: transform, clip-path, opacity;
}

.bg-glitch-scan {
  background: 
    linear-gradient(90deg, 
      rgba(255,0,255,0.2) 0%, 
      rgba(0,255,255,0.2) 25%, 
      rgba(255,255,0,0.2) 50%,
      rgba(0,255,255,0.2) 75%, 
      rgba(255,0,255,0.2) 100%
    ),
    repeating-linear-gradient(0deg, 
      rgba(255,255,255,0.05) 0px, 
      rgba(255,255,255,0.05) 2px, 
      transparent 2px, 
      transparent 4px
    );
  will-change: transform, opacity;
}

/* Trigger glitch animation when active */
.bg-glitch-layer-1.glitch-active {
  animation: bg-glitch-shift 0.375s steps(15, end) forwards;
}

.bg-glitch-layer-2.glitch-active {
  animation: bg-glitch-shift-2 0.375s steps(12, end) forwards;
}

.bg-glitch-scan.glitch-active {
  animation: bg-glitch-scan 0.375s linear forwards;
}

/* World Fair style - visible but tasteful glitch */
@keyframes bg-glitch-shift {
  0% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
  5% { opacity: 0.5; }
  12% { transform: translate(15px,-8px); clip-path: inset(12% 0 70% 0); }
  20% { transform: translate(-20px,10px); clip-path: inset(45% 0 35% 0); }
  28% { transform: translate(18px,-5px); clip-path: inset(68% 0 15% 0); }
  36% { transform: translate(-15px,12px); clip-path: inset(20% 0 60% 0); }
  44% { transform: translate(22px,-10px); clip-path: inset(52% 0 28% 0); }
  52% { transform: translate(-18px,8px); clip-path: inset(10% 0 75% 0); }
  60% { transform: translate(12px,-6px); clip-path: inset(58% 0 22% 0); }
  68% { transform: translate(-10px,15px); clip-path: inset(32% 0 48% 0); }
  76% { transform: translate(16px,-4px); clip-path: inset(72% 0 12% 0); }
  84% { transform: translate(-12px,7px); clip-path: inset(18% 0 65% 0); }
  92% { transform: translate(8px,-3px); clip-path: inset(42% 0 40% 0); }
  96% { opacity: 0.4; }
  100% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
}

@keyframes bg-glitch-shift-2 {
  0% { transform: translate(0,0) skewX(0deg); clip-path: inset(0% 0 0 0); opacity: 0; }
  8% { opacity: 0.5; }
  15% { transform: translate(-18px,10px) skewX(4deg); clip-path: inset(25% 0 55% 0); }
  23% { transform: translate(22px,-12px) skewX(-5deg); clip-path: inset(50% 0 30% 0); }
  31% { transform: translate(-16px,8px) skewX(3deg); clip-path: inset(72% 0 12% 0); }
  39% { transform: translate(20px,-15px) skewX(-4deg); clip-path: inset(18% 0 65% 0); }
  47% { transform: translate(-22px,12px) skewX(5deg); clip-path: inset(42% 0 38% 0); }
  55% { transform: translate(18px,-8px) skewX(-3deg); clip-path: inset(62% 0 20% 0); }
  63% { transform: translate(-14px,14px) skewX(4deg); clip-path: inset(30% 0 52% 0); }
  71% { transform: translate(16px,-6px) skewX(-2deg); clip-path: inset(8% 0 78% 0); }
  79% { transform: translate(-12px,10px) skewX(3deg); clip-path: inset(55% 0 28% 0); }
  87% { transform: translate(10px,-4px) skewX(-2deg); clip-path: inset(35% 0 45% 0); }
  95% { opacity: 0.4; }
  100% { transform: translate(0,0) skewX(0deg); clip-path: inset(0% 0 0 0); opacity: 0; }
}

@keyframes bg-glitch-scan {
  0% { opacity: 0; transform: translateX(-120%); }
  5% { opacity: 0.5; }
  15% { opacity: 0.55; transform: translateX(-80%); }
  30% { opacity: 0.6; transform: translateX(-40%); }
  50% { opacity: 0.6; transform: translateX(0%); }
  70% { opacity: 0.55; transform: translateX(40%); }
  85% { opacity: 0.5; transform: translateX(80%); }
  95% { opacity: 0.45; }
  100% { opacity: 0; transform: translateX(120%); }
}

/* Full width background - same as login */
.dashboard-view .bg-fullwidth {
  min-width: 100%;
  width: 100%;
  background-size: cover !important;
  background-position: center center !important;
}

/* Continuous glitch overlays - same as login, every 5s */
.dashboard-glitch-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0;
}

.dashboard-glitch-1 {
  mix-blend-mode: screen;
  filter: hue-rotate(22deg) saturate(1.35);
  animation: dashboard-glitch-shift 5s steps(10, end) infinite;
  background-size: cover !important;
  background-position: center center !important;
}

.dashboard-glitch-2 {
  mix-blend-mode: screen;
  filter: hue-rotate(-30deg) saturate(1.45);
  animation: dashboard-glitch-shift-2 5s steps(9, end) infinite;
  background-size: cover !important;
  background-position: center center !important;
}

.dashboard-glitch-scan {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 6;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.16), rgba(0,0,0,0) 60%),
    repeating-linear-gradient(180deg, rgba(255,255,255,0.05) 0 2px, rgba(0,0,0,0) 2px 4px),
    radial-gradient(ellipse at center, rgba(0,0,0,0) 40%, rgba(0,0,0,0.35) 100%);
  opacity: 0;
  animation: dashboard-glitch-scan 5s ease-out infinite;
}

@keyframes dashboard-glitch-shift {
  0%, 82% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
  82.1% { opacity: 0.28; }
  84% { transform: translate(6px,-2px); clip-path: inset(8% 0 70% 0); }
  86% { transform: translate(-5px,2px); clip-path: inset(42% 0 40% 0); }
  88% { transform: translate(3px,0); clip-path: inset(68% 0 10% 0); }
  91% { transform: translate(-4px,3px); clip-path: inset(18% 0 60% 0); }
  93% { transform: translate(5px,-3px); clip-path: inset(55% 0 20% 0); }
  95% { transform: translate(-3px,1px); clip-path: inset(10% 0 80% 0); }
  100% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
}

@keyframes dashboard-glitch-shift-2 {
  0%, 82% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
  82.1% { opacity: 0.24; }
  84% { transform: translate(-6px,2px); clip-path: inset(12% 0 65% 0); }
  86% { transform: translate(5px,-1px) skewX(0.6deg); clip-path: inset(36% 0 42% 0); }
  89% { transform: translate(-3px,2px); clip-path: inset(72% 0 8% 0); }
  92% { transform: translate(4px,-3px); clip-path: inset(22% 0 58% 0); }
  95% { transform: translate(-4px,1px); clip-path: inset(50% 0 26% 0); }
  100% { transform: translate(0,0); clip-path: inset(0% 0 0 0); opacity: 0; }
}

@keyframes dashboard-glitch-scan {
  0%, 82% { opacity: 0; transform: translateY(-20%); }
  84% { opacity: 0.5; }
  90% { opacity: 0.35; }
  100% { opacity: 0; transform: translateY(115%); }
}
</style>

