<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { documentApi } from '@/api/document'
import { folderApi, type FolderTree } from '@/api/folder'
import FolderTreeComponent from '@/components/FolderTree.vue'
import {
  Upload, Search, FileText, Trash2, Loader, Database, Layers, Zap,
  Folder, FolderPlus, Edit2, Trash2 as Trash2Icon, Plus, X
} from 'lucide-vue-next'
import type { Document, SearchResult } from '@/api/document'

// Documents
const documents = ref<Document[]>([])
const searchQuery = ref('')
const searchMode = ref('hybrid')
const searchResults = ref<SearchResult[]>([])
const isUploading = ref(false)
const isSearching = ref(false)

// Folders
const folders = ref<FolderTree[]>([])
const selectedFolderId = ref<string | null>(null)

// New folder dialog
const showNewFolderDialog = ref(false)
const newFolderName = ref('')
const newFolderParentId = ref<string | null>(null)

// Rename dialog
const showRenameDialog = ref(false)
const renameFolderName = ref('')
const renamingFolder = ref<FolderTree | null>(null)

// Delete dialog
const showDeleteDialog = ref(false)
const deletingFolder = ref<FolderTree | null>(null)

// Upload validation
const uploadError = ref('')

// Load folder tree
async function loadFolders() {
  try {
    const res = await folderApi.getTree()
    folders.value = res.data
  } catch (e) {
    console.error('加载文件夹失败:', e)
  }
}

// Select a folder and load its documents
function onSelectFolder(folder: FolderTree) {
  selectedFolderId.value = folder.id
  loadDocumentsByFolder(folder.id)
}

// Load all documents (no folder selected)
async function loadAllDocuments() {
  selectedFolderId.value = null
  await loadDocuments()
}

// Load documents in a specific folder
async function loadDocumentsByFolder(folderId: string) {
  try {
    const response = await documentApi.list(folderId)
    documents.value = response.data
  } catch (e) {
    console.error('加载文档失败:', e)
  }
}

// Load all documents
async function loadDocuments() {
  try {
    const response = await documentApi.list()
    documents.value = response.data
  } catch (e) {
    console.error('加载文档失败:', e)
  }
}

// Handle upload - requires folder selection
async function handleUpload(event: Event) {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  if (!file) return

  if (!selectedFolderId.value) {
    uploadError.value = '请先在左侧选择目标文件夹'
    setTimeout(() => { uploadError.value = '' }, 3000)
    return
  }

  isUploading.value = true
  try {
    await documentApi.upload(file, selectedFolderId.value)
    await loadDocumentsByFolder(selectedFolderId.value)
  } catch (e) {
    console.error('上传失败:', e)
  }
  isUploading.value = false
}

async function handleDelete(id: string) {
  try {
    await documentApi.delete(id)
    if (selectedFolderId.value) {
      documents.value = documents.value.filter((d) => d.id !== id)
    } else {
      documents.value = documents.value.filter((d) => d.id !== id)
    }
  } catch (e) {
    console.error('删除失败:', e)
  }
}

async function handleSearch() {
  if (!searchQuery.value.trim()) return
  isSearching.value = true
  try {
    const response = await documentApi.search(searchQuery.value, 5, searchMode.value)
    searchResults.value = response.data
  } catch (e) {
    console.error('搜索失败:', e)
  }
  isSearching.value = false
}

function getFileTypeColor(type: string) {
  const colors: Record<string, string> = {
    pdf: '#f87171', md: '#60a5fa', txt: '#34d399', docx: '#a78bfa'
  }
  return colors[type] || '#9ca3af'
}

// New folder dialog
function openNewFolderDialog(parentId: string | null = null) {
  newFolderParentId.value = parentId
  newFolderName.value = ''
  showNewFolderDialog.value = true
}

async function createFolder() {
  if (!newFolderName.value.trim()) return
  try {
    await folderApi.create({
      name: newFolderName.value.trim(),
      parent_id: newFolderParentId.value
    })
    await loadFolders()
    showNewFolderDialog.value = false
  } catch (e) {
    console.error('创建文件夹失败:', e)
  }
}

// Rename folder dialog
function openRenameDialog(folder: FolderTree) {
  renamingFolder.value = folder
  renameFolderName.value = folder.name
  showRenameDialog.value = true
}

async function renameFolder() {
  if (!renamingFolder.value || !renameFolderName.value.trim()) return
  try {
    await folderApi.rename(renamingFolder.value.id, { name: renameFolderName.value.trim() })
    await loadFolders()
    showRenameDialog.value = false
    renamingFolder.value = null
  } catch (e) {
    console.error('重命名文件夹失败:', e)
  }
}

// Delete folder dialog
function openDeleteDialog(folder: FolderTree) {
  deletingFolder.value = folder
  showDeleteDialog.value = true
}

async function deleteFolder() {
  if (!deletingFolder.value) return
  try {
    await folderApi.delete(deletingFolder.value.id)
    if (selectedFolderId.value === deletingFolder.value.id) {
      selectedFolderId.value = null
      await loadDocuments()
    }
    await loadFolders()
    showDeleteDialog.value = false
    deletingFolder.value = null
  } catch (e) {
    console.error('删除文件夹失败:', e)
  }
}

onMounted(() => {
  loadFolders()
  loadDocuments()
})
</script>

<template>
  <div class="knowledge-view">
    <!-- Header -->
    <div class="page-header">
      <div class="header-left">
        <div class="header-icon"><Database :size="20" /></div>
        <div class="header-text">
          <h1>KNOWLEDGE BASE</h1>
          <span class="header-sub">{{ documents.length }} documents</span>
        </div>
      </div>
      <div class="header-actions">
        <button class="btn" @click="openNewFolderDialog(null)">
          <FolderPlus :size="14" /> 新建文件夹
        </button>
        <button class="btn primary" @click="(document.querySelector('.upload-area input') as HTMLInputElement)?.click()">
          <Upload :size="14" /> 上传文档
        </button>
      </div>
    </div>

    <!-- Main layout: sidebar + content -->
    <div class="main-layout">
      <!-- Left sidebar: folder tree -->
      <aside class="folder-sidebar">
        <div class="sidebar-header">
          <Folder :size="14" />
          <span>文件夹</span>
          <button class="add-btn" @click="openNewFolderDialog(null)" title="新建文件夹">
            <Plus :size="12" />
          </button>
        </div>
        <div class="folder-list">
          <!-- All documents option -->
          <div
            class="folder-row all-docs"
            :class="{ selected: selectedFolderId === null }"
            @click="loadAllDocuments"
          >
            <Folder :size="14" class="folder-icon" />
            <span class="folder-name">全部文档</span>
          </div>
          <FolderTreeComponent
            :folders="folders"
            :selected-id="selectedFolderId"
            :on-select="onSelectFolder"
            :on-create="openNewFolderDialog"
            :on-rename="openRenameDialog"
            :on-delete="openDeleteDialog"
          />
        </div>
      </aside>

      <!-- Right content area -->
      <main class="content-area">
        <!-- Upload zone -->
        <div class="upload-zone">
          <div class="upload-inner">
            <label class="upload-area">
              <input type="file" @change="handleUpload" accept=".pdf,.md,.txt,.docx" />
              <div class="upload-content">
                <div class="upload-icon-wrap">
                  <Upload :size="22" />
                  <Loader v-if="isUploading" :size="22" class="spin" />
                </div>
                <div class="upload-text">
                  <span class="upload-main">DROP FILE OR CLICK TO UPLOAD</span>
                  <span class="upload-hint">PDF · Markdown · TXT · DOCX</span>
                </div>
              </div>
            </label>
          </div>
          <div v-if="uploadError" class="upload-error">
            {{ uploadError }}
          </div>
          <div v-if="selectedFolderId" class="upload-folder-hint">
            将上传到选中的文件夹
          </div>
          <div v-else class="upload-folder-hint upload-folder-warning">
            请先在左侧选择文件夹后再上传
          </div>
        </div>

        <!-- Search -->
        <div class="search-panel">
          <div class="search-header">
            <Zap :size="14" />
            <span>SEMANTIC SEARCH</span>
          </div>
          <div class="search-bar">
            <Search :size="16" class="search-icon" />
            <input
              v-model="searchQuery"
              placeholder="Query the knowledge base..."
              @keyup.enter="handleSearch"
            />
            <select v-model="searchMode" class="mode-select">
              <option value="hybrid">HYBRID</option>
              <option value="semantic">SEMANTIC</option>
              <option value="keyword">KEYWORD</option>
            </select>
            <button class="search-btn" @click="handleSearch" :disabled="isSearching">
              <Loader v-if="isSearching" :size="14" class="spin" />
              <Search v-else :size="14" />
              SEARCH
            </button>
          </div>
        </div>

        <!-- Search results -->
        <div v-if="searchResults.length" class="results-section">
          <div class="section-header">
            <Layers :size="14" />
            <span>SEARCH RESULTS ({{ searchResults.length }})</span>
          </div>
          <div class="results-grid">
            <div v-for="result in searchResults" :key="result.chunk_id" class="result-card">
              <div class="result-score-bar">
                <div class="score-fill" :style="{ width: (result.score * 100) + '%' }"></div>
              </div>
              <div class="result-doc-title">{{ result.document_title }}</div>
              <div class="result-content">{{ result.content }}</div>
              <div class="result-score">
                <span class="score-label">RELEVANCE</span>
                <span class="score-value">{{ (result.score * 100).toFixed(1) }}%</span>
              </div>
            </div>
          </div>
        </div>

        <!-- Document list -->
        <div class="docs-section">
          <div class="section-header">
            <FileText :size="14" />
            <span>INDEXED DOCUMENTS ({{ documents.length }})</span>
          </div>
          <div class="docs-grid">
            <div v-if="documents.length === 0" class="empty-state">
              <FileText :size="32" />
              <span>No documents indexed</span>
              <span class="empty-sub">Upload files to begin indexing</span>
            </div>
            <div v-for="doc in documents" :key="doc.id" class="doc-card">
              <div class="doc-type-badge" :style="{ color: getFileTypeColor(doc.file_type), borderColor: getFileTypeColor(doc.file_type) + '40' }">
                {{ doc.file_type.toUpperCase() }}
              </div>
              <div class="doc-icon" :style="{ color: getFileTypeColor(doc.file_type) }">
                <FileText :size="22" />
              </div>
              <div class="doc-info">
                <div class="doc-title">{{ doc.title }}</div>
                <div class="doc-meta">
                  <span>{{ (doc.file_size / 1024).toFixed(1) }} KB</span>
                  <span class="sep">·</span>
                  <span>{{ doc.chunk_count }} chunks</span>
                  <span class="sep">·</span>
                  <span :class="doc.is_indexed ? 'indexed' : 'pending'">
                    {{ doc.is_indexed ? 'INDEXED' : 'INDEXING...' }}
                  </span>
                </div>
              </div>
              <button class="delete-btn" @click="handleDelete(doc.id)">
                <Trash2 :size="14" />
              </button>
            </div>
          </div>
        </div>
      </main>
    </div>

    <!-- New folder dialog -->
    <div v-if="showNewFolderDialog" class="dialog-overlay" @click.self="showNewFolderDialog = false">
      <div class="dialog">
        <div class="dialog-header">
          <h3>新建文件夹</h3>
          <button class="close-btn" @click="showNewFolderDialog = false">
            <X :size="16" />
          </button>
        </div>
        <input
          v-model="newFolderName"
          class="dialog-input"
          placeholder="文件夹名称"
          @keyup.enter="createFolder"
          autofocus
        />
        <div class="dialog-actions">
          <button class="btn" @click="showNewFolderDialog = false">取消</button>
          <button class="btn primary" @click="createFolder">创建</button>
        </div>
      </div>
    </div>

    <!-- Rename folder dialog -->
    <div v-if="showRenameDialog" class="dialog-overlay" @click.self="showRenameDialog = false">
      <div class="dialog">
        <div class="dialog-header">
          <h3>重命名文件夹</h3>
          <button class="close-btn" @click="showRenameDialog = false">
            <X :size="16" />
          </button>
        </div>
        <input
          v-model="renameFolderName"
          class="dialog-input"
          placeholder="文件夹名称"
          @keyup.enter="renameFolder"
          autofocus
        />
        <div class="dialog-actions">
          <button class="btn" @click="showRenameDialog = false">取消</button>
          <button class="btn primary" @click="renameFolder">重命名</button>
        </div>
      </div>
    </div>

    <!-- Delete folder dialog -->
    <div v-if="showDeleteDialog" class="dialog-overlay" @click.self="showDeleteDialog = false">
      <div class="dialog">
        <div class="dialog-header">
          <h3>删除文件夹</h3>
          <button class="close-btn" @click="showDeleteDialog = false">
            <X :size="16" />
          </button>
        </div>
        <p class="dialog-body">
          确定要删除文件夹「{{ deletingFolder?.name }}」吗？该操作不可恢复。
        </p>
        <div class="dialog-actions">
          <button class="btn" @click="showDeleteDialog = false">取消</button>
          <button class="btn danger" @click="deleteFolder">删除</button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.knowledge-view {
  height: 100%;
  overflow-y: auto;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Header */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 14px;
}

.header-icon {
  color: var(--accent-cyan);
  filter: drop-shadow(0 0 8px var(--accent-cyan));
}

h1 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--text-primary);
  margin: 0;
}

.header-sub {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 0.1em;
}

.header-actions {
  display: flex;
  gap: 10px;
}

/* Main layout */
.main-layout {
  display: flex;
  gap: 20px;
  flex: 1;
  min-height: 0;
}

/* Folder sidebar */
.folder-sidebar {
  width: 220px;
  flex-shrink: 0;
  background: var(--bg-card);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.sidebar-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: rgba(0, 245, 212, 0.04);
  border-bottom: 1px solid var(--border-dim);
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--text-dim);
}

.sidebar-header .add-btn {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 2px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  transition: all var(--transition-fast);
}

.sidebar-header .add-btn:hover {
  color: var(--accent-cyan);
  background: rgba(0, 245, 212, 0.1);
}

.folder-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.all-docs {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all var(--transition-fast);
  color: var(--text-primary);
  margin-bottom: 4px;
}

.all-docs:hover {
  background: rgba(0, 245, 212, 0.04);
}

.all-docs.selected {
  background: var(--accent-cyan-dim);
  border: 1px solid rgba(0, 245, 212, 0.2);
}

/* Content area */
.content-area {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Upload */
.upload-zone { }
.upload-inner { }

.upload-area {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  background: var(--bg-card);
  border: 1px dashed var(--border-mid);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: all var(--transition-mid);
}

.upload-area:hover {
  border-color: var(--accent-cyan);
  background: var(--accent-cyan-dim);
  box-shadow: var(--glow-cyan);
}

.upload-area input { display: none; }

.upload-content {
  display: flex;
  align-items: center;
  gap: 16px;
}

.upload-icon-wrap {
  color: var(--accent-cyan);
  filter: drop-shadow(0 0 6px var(--accent-cyan));
}

.spin { animation: spin 1s linear infinite; }

.upload-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.upload-main {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.15em;
  color: var(--accent-cyan);
}

.upload-hint {
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 0.1em;
}

.upload-error {
  text-align: center;
  color: var(--accent-red);
  font-size: 12px;
  padding: 6px 0;
}

.upload-folder-hint {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
  padding: 4px 0;
  letter-spacing: 0.08em;
}

.upload-folder-warning {
  color: var(--accent-amber);
}

/* Search panel */
.search-panel {
  background: var(--bg-card);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.search-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: rgba(0, 245, 212, 0.04);
  border-bottom: 1px solid var(--border-dim);
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--accent-cyan);
}

.search-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}

.search-icon { color: var(--text-dim); flex-shrink: 0; }

.search-bar input {
  flex: 1;
  font-size: 13px;
}

.mode-select {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  padding: 6px 10px;
  background: var(--bg-panel);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  cursor: pointer;
}

.mode-select:focus { border-color: var(--accent-cyan); outline: none; }

.search-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: var(--accent-cyan-dim);
  border: 1px solid var(--border-mid);
  border-radius: var(--radius-md);
  color: var(--accent-cyan);
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: 0.12em;
  transition: all var(--transition-fast);
}

.search-btn:hover:not(:disabled) {
  background: rgba(0, 245, 212, 0.2);
  box-shadow: var(--glow-cyan);
}

/* Section header */
.section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--text-dim);
  margin-bottom: 14px;
}

/* Results */
.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 12px;
}

.result-card {
  background: var(--bg-card);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-md);
  padding: 16px;
  position: relative;
  overflow: hidden;
  transition: all var(--transition-mid);
}

.result-card:hover {
  border-color: var(--border-mid);
  box-shadow: 0 0 16px rgba(0, 245, 212, 0.06);
}

.result-score-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--bg-panel);
}

.score-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-cyan), var(--accent-amber));
  transition: width 0.5s ease;
}

.result-doc-title {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--accent-cyan);
  margin-bottom: 8px;
}

.result-content {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.6;
  margin-bottom: 12px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.result-score {
  display: flex;
  align-items: center;
  gap: 8px;
}

.score-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--text-dim);
}

.score-value {
  font-family: var(--font-display);
  font-size: 11px;
  color: var(--accent-amber);
}

/* Documents */
.docs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.empty-state {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48px;
  gap: 8px;
  color: var(--text-dim);
  font-size: 13px;
}

.empty-sub { font-size: 11px; color: var(--text-muted); }

.doc-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  transition: all var(--transition-fast);
}

.doc-card:hover {
  border-color: var(--border-mid);
  background: var(--bg-card-hover);
}

.doc-type-badge {
  font-family: var(--font-display);
  font-size: 8px;
  letter-spacing: 0.1em;
  padding: 2px 6px;
  border: 1px solid;
  border-radius: 3px;
  flex-shrink: 0;
}

.doc-info { flex: 1; min-width: 0; }

.doc-title {
  font-size: 13px;
  color: var(--text-primary);
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.doc-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 4px;
}

.sep { opacity: 0.4; }

.indexed { color: var(--accent-green); }
.pending { color: var(--accent-amber); }

.delete-btn {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
  border-radius: 3px;
  transition: all var(--transition-fast);
  opacity: 0;
}

.doc-card:hover .delete-btn { opacity: 1; }
.delete-btn:hover { color: var(--accent-red); background: rgba(255,71,87,0.1); }

/* Dialogs */
.dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.dialog {
  background: var(--bg-card);
  border: 1px solid var(--border-mid);
  border-radius: var(--radius-lg);
  padding: 24px;
  width: 400px;
  max-width: 90vw;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.dialog-header h3 {
  font-family: var(--font-display);
  font-size: 14px;
  letter-spacing: 0.1em;
  color: var(--text-primary);
  margin: 0;
}

.close-btn {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  transition: all var(--transition-fast);
}

.close-btn:hover {
  color: var(--text-primary);
  background: var(--bg-panel);
}

.dialog-input {
  width: 100%;
  padding: 10px 14px;
  background: var(--bg-panel);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: 13px;
  margin-bottom: 16px;
  box-sizing: border-box;
}

.dialog-input:focus {
  border-color: var(--accent-cyan);
  outline: none;
}

.dialog-body {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 0 0 16px 0;
  line-height: 1.5;
}

.dialog-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: var(--bg-panel);
  border: 1px solid var(--border-mid);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: all var(--transition-fast);
}

.btn:hover {
  border-color: var(--border-mid);
  background: var(--bg-card-hover);
}

.btn.primary {
  background: var(--accent-cyan-dim);
  border-color: rgba(0, 245, 212, 0.3);
  color: var(--accent-cyan);
}

.btn.primary:hover {
  background: rgba(0, 245, 212, 0.2);
  box-shadow: var(--glow-cyan);
}

.btn.danger {
  background: rgba(255, 71, 87, 0.1);
  border-color: rgba(255, 71, 87, 0.3);
  color: var(--accent-red);
}

.btn.danger:hover {
  background: rgba(255, 71, 87, 0.2);
  box-shadow: 0 0 12px rgba(255, 71, 87, 0.2);
}
</style>
