<script lang="ts">
  import { onMount, onDestroy } from "svelte";
  import { invoke } from "@tauri-apps/api/core";
  import { listen } from "@tauri-apps/api/event";
  import { get } from "svelte/store";
  import {
    initializeTauriListeners,
    cleanupTauriListeners,
    initializeDiscordRpc,
    stopDiscordRpc,
    updateDiscordRpc,
    setSkipNextGreeting,
  } from "$lib/tauri";
  import {
    configStore,
    applyTheme,
    applyFontSize,
    applyCustomFont,
    applyCustomUiFont,
    isCompactMode,
  } from "$lib/stores/config";
  import { readFile } from "@tauri-apps/plugin-fs";
  import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
  import { conversationsStore } from "$lib/stores/conversations";
  import { claudeStore, isClaudeProcessing } from "$lib/stores/claude";
  import { editorStore } from "$lib/stores/editor";
  import { getCurrentWindow, LogicalSize } from "@tauri-apps/api/window";
  import "$lib/notifications/testNotifications";
  import Terminal from "$lib/components/Terminal.svelte";
  import InputBar from "$lib/components/InputBar.svelte";
  import StatusBar from "$lib/components/StatusBar.svelte";
  import AnimeGirl from "$lib/components/AnimeGirl.svelte";
  import CompactMode from "$lib/components/CompactMode.svelte";
  import EditorPanel from "$lib/components/editor/EditorPanel.svelte";
  import { characterState } from "$lib/stores/character";
  import type { CharacterState } from "$lib/types/states";
  import PermissionModal from "$lib/components/PermissionModal.svelte";
  import UserQuestionModal from "$lib/components/UserQuestionModal.svelte";
  import ConfigSidebar from "$lib/components/ConfigSidebar.svelte";
  import AchievementsPanel from "$lib/components/AchievementsPanel.svelte";
  import ToastContainer from "$lib/components/ToastContainer.svelte";
  import CloseAppConfirmModal from "$lib/components/CloseAppConfirmModal.svelte";
  import type { UpdateInfo } from "$lib/types/messages";
  import { toastStore } from "$lib/stores/toasts";
  import { debugConsoleStore } from "$lib/stores/debugConsole";
  import { initializeTodoListener, cleanupTodoListener } from "$lib/stores/todos";

  let backgroundDataUrl = $state<string | null>(null);
  let backgroundOpacity = $state(0.3);

  const configValues = configStore.config;
  $effect(() => {
    const cfg = $configValues;
    backgroundOpacity = cfg.background_image_opacity;
    if (cfg.background_image_path) {
      void loadBackgroundImage(cfg.background_image_path);
    } else {
      backgroundDataUrl = null;
    }
  });

  async function loadBackgroundImage(path: string) {
    try {
      const data = await readFile(path);
      const chunks: string[] = [];
      const chunkSize = 8192;
      for (let i = 0; i < data.length; i += chunkSize) {
        chunks.push(String.fromCharCode(...data.slice(i, i + chunkSize)));
      }
      const ext = path.split(".").pop()?.toLowerCase() ?? "png";
      const mimeMap: Record<string, string> = {
        jpg: "image/jpeg",
        jpeg: "image/jpeg",
        png: "image/png",
        webp: "image/webp",
        gif: "image/gif",
        avif: "image/avif",
      };
      const mime = mimeMap[ext] ?? "image/png";
      backgroundDataUrl = `data:${mime};base64,${btoa(chunks.join(""))}`;
    } catch (error) {
      console.error("Failed to load background image:", error);
      backgroundDataUrl = null;
    }
  }

  let initialized = false;
  let achievementPanelOpen = $state(false);
  let currentCharacterState: CharacterState = $state("idle");
  let compactModeActive = $state(false);
  let closeConfirmModalOpen = $state(false);
  let hasActiveConversation = $state(false);

  // Editor state
  const isEditorVisible = editorStore.isEditorVisible;
  let lastInitializedCwd = "";

  // Track connection status and CWD for the editor
  const connectionStatus = claudeStore.connectionStatus;
  const currentWorkingDirectory = claudeStore.currentWorkingDirectory;

  // Initialize/update editor file tree when CWD changes while editor is visible
  $effect(() => {
    const visible = $isEditorVisible;
    const cwd = $currentWorkingDirectory;
    const connected = $connectionStatus === "connected";

    // Only initialize when editor is visible, connected, and CWD is set
    if (visible && connected && cwd && cwd !== lastInitializedCwd) {
      lastInitializedCwd = cwd;
      editorStore.initializeFileTree(cwd);
    }

    // Hide editor if disconnected
    if (!connected && visible) {
      editorStore.hideEditor();
    }
  });

  // Get reactive references to conversation stores
  const activeConversationId = conversationsStore.activeConversationId;
  const conversations = conversationsStore.conversations;

  // Update Discord RPC when active conversation or model changes
  $effect(() => {
    // Access stores directly (without get()) to create reactive dependencies
    const activeId = $activeConversationId;
    const convs = $conversations;
    const activeConv = activeId ? convs.get(activeId) : null;
    const config = configStore.getConfig();
    const model = config.model || "claude";

    if (activeConv && config.discord_rpc_enabled) {
      updateDiscordRpc(activeConv.name, model, activeConv.startedAt);
    }
  });

  // Window size constants
  const COMPACT_WIDTH = 280;
  const COMPACT_HEIGHT = 400;

  // Store the previous window size to restore when exiting compact mode
  let previousWindowSize: { width: number; height: number } | null = null;

  characterState.subscribe((state) => {
    currentCharacterState = state;
  });

  isCompactMode.subscribe((value) => {
    compactModeActive = value;
  });

  function getPanelGlowClass(): string {
    switch (currentCharacterState) {
      case "thinking":
        return "panel-glow-thinking";
      case "typing":
        return "panel-glow-typing";
      case "searching":
        return "panel-glow-searching";
      case "coding":
        return "panel-glow-coding";
      case "mcp":
        return "panel-glow-mcp";
      case "success":
        return "panel-glow-success";
      case "error":
        return "panel-glow-error";
      default:
        return "";
    }
  }

  // Resizable panel state
  let panelWidth = $state(320); // Default width in pixels
  let isResizing = $state(false);
  const MIN_PANEL_WIDTH = 200;
  const MAX_PANEL_WIDTH = 600;

  function startResize(event: MouseEvent) {
    isResizing = true;
    event.preventDefault();
    document.addEventListener("mousemove", handleResize);
    document.addEventListener("mouseup", stopResize);
  }

  function handleResize(event: MouseEvent) {
    if (!isResizing) return;
    const newWidth = event.clientX;
    panelWidth = Math.max(MIN_PANEL_WIDTH, Math.min(MAX_PANEL_WIDTH, newWidth));
  }

  function stopResize() {
    if (isResizing) {
      isResizing = false;
      document.removeEventListener("mousemove", handleResize);
      document.removeEventListener("mouseup", stopResize);
      // Save the panel width to config
      configStore.updateConfig({ character_panel_width: panelWidth });
    }
  }

  // Global keyboard shortcuts
  function handleGlobalKeydown(event: KeyboardEvent) {
    // Don't trigger shortcuts when typing in inputs (except for specific ones)
    const target = event.target as HTMLElement;
    const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA";

    // Escape closes panels (always works)
    if (event.key === "Escape") {
      // Check if any panels are open and close them
      if (achievementPanelOpen) {
        achievementPanelOpen = false;
        event.preventDefault();
        return;
      }
      // ConfigSidebar handles its own escape via store
      if (get(configStore.isSidebarOpen)) {
        configStore.closeSidebar();
        event.preventDefault();
        return;
      }
    }

    // Skip other shortcuts if user is typing in an input
    if (isInputFocused) return;

    // Ctrl+L - Clear terminal
    if (event.ctrlKey && event.key === "l") {
      event.preventDefault();
      claudeStore.clearTerminal();
      return;
    }

    // Ctrl+, - Open settings
    if (event.ctrlKey && event.key === ",") {
      event.preventDefault();
      configStore.openSidebar();
      return;
    }

    // Ctrl+C - Interrupt (only when processing AND no text is selected)
    if (event.ctrlKey && event.key === "c") {
      const hasSelection = Boolean(window.getSelection()?.toString());
      if (get(isClaudeProcessing) && !hasSelection) {
        event.preventDefault();
        handleInterrupt();
        return;
      }
    }

    // Ctrl++ or Ctrl+= - Increase font size
    if (event.ctrlKey && (event.key === "+" || event.key === "=")) {
      event.preventDefault();
      configStore.increaseFontSize();
      return;
    }

    // Ctrl+- - Decrease font size
    if (event.ctrlKey && event.key === "-") {
      event.preventDefault();
      configStore.decreaseFontSize();
      return;
    }

    // Ctrl+0 - Reset font size
    if (event.ctrlKey && event.key === "0") {
      event.preventDefault();
      configStore.resetFontSize();
      return;
    }

    // Ctrl+Shift+S - Toggle streamer mode
    if (event.ctrlKey && event.shiftKey && event.key === "S") {
      event.preventDefault();
      configStore.toggleStreamerMode();
      return;
    }

    // Ctrl+Shift+M - Toggle compact mode
    if (event.ctrlKey && event.shiftKey && event.key === "M") {
      event.preventDefault();
      toggleCompactMode();
      return;
    }

    // Ctrl+` - Toggle debug console
    if (event.ctrlKey && event.key === "`") {
      event.preventDefault();
      debugConsoleStore.toggle();
      return;
    }

    // Ctrl+E - Toggle editor panel (only when connected)
    if (event.ctrlKey && event.key === "e") {
      event.preventDefault();
      // Only allow opening the editor when connected
      if (get(claudeStore.connectionStatus) === "connected") {
        editorStore.toggleEditor();
      }
      return;
    }

    // Ctrl+B - Toggle file browser (when editor is visible)
    if (event.ctrlKey && event.key === "b" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      editorStore.toggleFileBrowser();
      return;
    }

    // Ctrl+S - Save current file (when editor is visible)
    if (event.ctrlKey && event.key === "s" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      editorStore.saveFile();
      return;
    }

    // Ctrl+W - Close current tab (when editor is visible)
    if (event.ctrlKey && event.key === "w" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      const activeTabId = get(editorStore.activeTabId);
      if (activeTabId) {
        editorStore.closeTab(activeTabId);
      }
      return;
    }

    // Ctrl+N - New file (when editor is visible)
    // Note: This just emits an event that FileBrowser listens to
    if (event.ctrlKey && event.key === "n" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      // Dispatch a custom event that FileBrowser will listen to
      window.dispatchEvent(new CustomEvent("editor-new-file"));
      return;
    }
  }

  async function checkForUpdates() {
    const config = configStore.getConfig();
    if (!config.update_checks_enabled) return;
    try {
      const info = await invoke<UpdateInfo>("check_for_updates");
      if (info.has_update) {
        toastStore.addUpdate(info.latest_version, info.current_version, info.release_url);
      }
    } catch (err) {
      console.error("Failed to check for updates:", err);
    }
  }

  async function handleInterrupt() {
    try {
      const conversationId = get(claudeStore.activeConversationId);
      if (!conversationId) return;

      // Set flag to preserve stats/permissions (don't treat next connect as new session)
      setSkipNextGreeting(true);

      await invoke("interrupt_claude", { conversationId });
      claudeStore.addLine("system", "Process interrupted by keyboard shortcut (Ctrl+C)");
    } catch (error) {
      console.error("Failed to interrupt:", error);
    }
  }

  async function enterCompactMode() {
    try {
      const window = getCurrentWindow();
      const currentSize = await window.innerSize();
      const scaleFactor = await window.scaleFactor();

      // Save current window size (convert from physical to logical pixels)
      // innerSize() returns physical pixels, but setSize() with LogicalSize expects logical
      previousWindowSize = {
        width: Math.round(currentSize.width / scaleFactor),
        height: Math.round(currentSize.height / scaleFactor),
      };

      // Resize to compact dimensions
      await window.setSize(new LogicalSize(COMPACT_WIDTH, COMPACT_HEIGHT));

      // Enable compact mode in config
      await configStore.setCompactMode(true);
    } catch (error) {
      console.error("Failed to enter compact mode:", error);
    }
  }

  async function exitCompactMode() {
    try {
      const window = getCurrentWindow();

      // Only resize if we have a saved previous size
      // (i.e., user entered compact mode during this session)
      // Otherwise, just expand to a reasonable default
      if (previousWindowSize) {
        await window.setSize(new LogicalSize(previousWindowSize.width, previousWindowSize.height));
        previousWindowSize = null;
      } else {
        // No saved size (e.g., app started in compact mode) - use modest default
        await window.setSize(new LogicalSize(900, 650));
      }

      // Disable compact mode in config
      await configStore.setCompactMode(false);
    } catch (error) {
      console.error("Failed to exit compact mode:", error);
    }
  }

  async function toggleCompactMode() {
    if (compactModeActive) {
      await exitCompactMode();
    } else {
      await enterCompactMode();
    }
  }

  async function handleCloseRequest() {
    // Check if there's an active conversation with Claude running
    const activeId = get(claudeStore.activeConversationId);
    if (activeId) {
      try {
        const isRunning = await invoke<boolean>("is_claude_running", {
          conversationId: activeId,
        });
        hasActiveConversation = isRunning;
      } catch (error) {
        console.error("Failed to check Claude status:", error);
        hasActiveConversation = false;
      }
    } else {
      hasActiveConversation = false;
    }

    // Always show confirmation modal
    closeConfirmModalOpen = true;
  }

  async function handleConfirmClose() {
    closeConfirmModalOpen = false;
    try {
      await invoke("close_application");
    } catch (error) {
      console.error("Failed to close application:", error);
    }
  }

  async function handleMinimizeToTray() {
    closeConfirmModalOpen = false;
    try {
      const window = getCurrentWindow();
      await window.hide();
    } catch (error) {
      console.error("Failed to minimize to tray:", error);
    }
  }

  function handleCancelClose() {
    closeConfirmModalOpen = false;
  }

  onMount(async () => {
    if (!initialized) {
      initialized = true;

      // Initialize conversations store first to ensure activeConversationId is set
      conversationsStore.initialize();

      await initializeTauriListeners();
      await configStore.loadConfig();

      // Apply saved settings on startup
      const config = configStore.getConfig();
      applyTheme(config.theme, config.custom_theme_colors);
      applyFontSize(config.font_size);
      await applyCustomFont(config.custom_font_path, config.custom_font_family);
      await applyCustomUiFont(config.custom_ui_font_path, config.custom_ui_font_family);

      // Apply always-on-top setting
      if (config.always_on_top) {
        const window = getCurrentWindow();
        await window.setAlwaysOnTop(true);
      }

      // Load saved panel width
      if (config.character_panel_width) {
        panelWidth = config.character_panel_width;
      }

      // Initialize notification settings sync
      initNotificationSync();

      // Add global keyboard shortcut listener
      window.addEventListener("keydown", handleGlobalKeydown);

      // Check for updates on startup
      await checkForUpdates();

      // Apply compact mode if saved (resize window)
      if (config.compact_mode) {
        const window = getCurrentWindow();
        await window.setSize(new LogicalSize(COMPACT_WIDTH, COMPACT_HEIGHT));
      }

      // Initialize Discord RPC
      await initializeDiscordRpc();

      // Initialize todo listener
      await initializeTodoListener();

      // Listen for window close requests
      const unlisten = await listen("window-close-requested", () => {
        handleCloseRequest();
      });

      // Store the unlisten function for cleanup
      window.addEventListener("beforeunload", () => {
        unlisten();
      });
    }
  });

  onDestroy(() => {
    if (initialized) {
      cleanupTauriListeners();
      cleanupNotificationSync();
      cleanupTodoListener();
      stopDiscordRpc();
      window.removeEventListener("keydown", handleGlobalKeydown);
      initialized = false;
    }
  });
</script>

{#if backgroundDataUrl}
  <div
    class="fixed inset-0 bg-cover bg-center pointer-events-none"
    style="background-image: url('{backgroundDataUrl}'); opacity: {backgroundOpacity}; z-index: 0;"
  ></div>
{/if}

{#if compactModeActive}
  <!-- Compact mode: minimal widget interface -->
  <div
    class="app-container compact-app h-screen w-screen flex flex-col bg-[var(--bg-primary)] overflow-hidden"
    style={backgroundDataUrl ? "background: transparent;" : ""}
  >
    <CompactMode onExpand={exitCompactMode} />
  </div>
{:else}
  <!-- Full mode: standard interface -->
  <div
    class="app-container h-screen w-screen flex flex-col bg-[var(--bg-primary)] overflow-hidden"
    style={backgroundDataUrl ? "background: transparent;" : ""}
  >
    <StatusBar
      onToggleAchievements={() => (achievementPanelOpen = !achievementPanelOpen)}
      onToggleCompact={enterCompactMode}
    />

    <main class="flex-1 flex overflow-hidden">
      <!-- Left panel: Character display -->
      <div
        class="character-panel {getPanelGlowClass()} flex flex-col items-center justify-center {backgroundDataUrl
          ? ''
          : 'bg-[var(--bg-secondary)]/50'}"
        style="width: {panelWidth}px; min-width: {MIN_PANEL_WIDTH}px; max-width: {MAX_PANEL_WIDTH}px;{backgroundDataUrl
          ? ' background: transparent !important;'
          : ''}"
      >
        <AnimeGirl />
      </div>

      <!-- Resize handle -->
      <!-- svelte-ignore a11y_no_static_element_interactions -->
      <div
        class="resize-handle w-1 cursor-col-resize bg-[var(--border-color)] hover:bg-[var(--accent-primary)] transition-colors flex-shrink-0"
        class:bg-[var(--accent-primary)]={isResizing}
        onmousedown={startResize}
      ></div>

      <!-- Right panel: Terminal/Editor and input -->
      <div class="terminal-panel flex-1 flex flex-col min-w-0">
        {#if $isEditorVisible}
          <EditorPanel />
        {:else}
          <Terminal />
          <InputBar />
        {/if}
      </div>
    </main>

    <PermissionModal />
    <UserQuestionModal />
    <ConfigSidebar />
    <AchievementsPanel
      bind:isOpen={achievementPanelOpen}
      onClose={() => (achievementPanelOpen = false)}
    />
    <ToastContainer />
    <CloseAppConfirmModal
      isOpen={closeConfirmModalOpen}
      {hasActiveConversation}
      onClose={handleConfirmClose}
      onMinimize={handleMinimizeToTray}
      onCancel={handleCancelClose}
    />
  </div>
{/if}

<style>
  .app-container {
    font-family: var(
      --ui-font-family,
      "Inter",
      -apple-system,
      BlinkMacSystemFont,
      "Segoe UI",
      Roboto,
      sans-serif
    );
  }

  .character-panel {
    background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
    transition: all 0.5s ease;
    position: relative;
  }

  .character-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    padding: 3px;
    background: transparent;
    -webkit-mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
    mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0;
    transition: opacity 0.5s ease;
    pointer-events: none;
  }

  /* Trans pride gradient glow effects for the character panel */
  .panel-glow-thinking {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #9333ea) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(147, 51, 234, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-thinking::before {
    background: linear-gradient(180deg, #9333ea, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-typing {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #3b82f6) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(59, 130, 246, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.15),
      0 0 40px rgba(91, 206, 250, 0.25),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-typing::before {
    background: linear-gradient(180deg, #3b82f6, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-searching {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #eab308) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(234, 179, 8, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-searching::before {
    background: linear-gradient(180deg, #eab308, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-coding {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #22c55e) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(34, 197, 94, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-coding::before {
    background: linear-gradient(180deg, #22c55e, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-mcp {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 80%, var(--trans-blue)) 0%,
      color-mix(in srgb, var(--bg-primary) 85%, var(--trans-pink)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 100%
    );
    box-shadow:
      inset 0 0 80px rgba(91, 206, 250, 0.2),
      inset 0 0 120px rgba(245, 169, 184, 0.15),
      0 0 60px rgba(91, 206, 250, 0.3),
      0 0 100px rgba(245, 169, 184, 0.2);
  }

  .panel-glow-mcp::before {
    background: var(--trans-gradient-vibrant);
    opacity: 1;
  }

  .panel-glow-success {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #10b981) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(16, 185, 129, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-success::before {
    background: linear-gradient(180deg, #10b981, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-error {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 80%, #ef4444) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 50%,
      color-mix(in srgb, var(--bg-primary) 95%, var(--trans-blue)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(239, 68, 68, 0.2),
      inset 0 0 100px rgba(245, 169, 184, 0.1),
      0 0 40px rgba(245, 169, 184, 0.2),
      0 0 80px rgba(239, 68, 68, 0.15);
  }

  .panel-glow-error::before {
    background: linear-gradient(180deg, #ef4444, var(--trans-pink), var(--trans-blue));
    opacity: 1;
  }

  .resize-handle:hover,
  .resize-handle:active {
    width: 4px;
  }
</style>
