<template>
  <div class="app" v-if="authenticated">
    <aside class="sidebar">
      <div class="sidebar-header">
        <h2>MarkdownHub</h2>
        <div class="sidebar-actions">
          <button @click="toggleTheme" title="Toggle theme">{{ dark ? '☀️' : '🌙' }}</button>
          <button @click="createFolder" title="New folder">📁+</button>
          <button @click="createFile" title="New file">📄+</button>
        </div>
      </div>
      <div class="search-box">
        <input v-model="searchQuery" placeholder="Search files..." @input="filterFiles" />
      </div>
      <div class="sidebar-nav">
        <button :class="{active: view === 'files'}" @click="view = 'files'">📄 My Files</button>
        <button :class="{active: view === 'shared'}" @click="view = 'shared'">🤝 Shared</button>
        <button :class="{active: view === 'prefs'}" @click="view = 'prefs'">⚙️ Preferences</button>
        <button v-if="isAdmin" :class="{active: view === 'admin'}" @click="view = 'admin'">👤 Admin</button>
      </div>
      <FileTree v-if="view === 'files'" :files="filteredFiles" :selected="currentFile" @select="openFile" @delete="deleteItem" />
      <FileTree v-if="view === 'shared'" :files="sharedFiles" :selected="currentFile" @select="openFile" @delete="deleteItem" />
    </aside>
    <main class="editor-area" v-if="view === 'files' || view === 'shared'">
      <div class="toolbar">
        <div class="mode-switcher">
          <button :class="{active: mode === 'wysiwyg'}" @click="mode = 'wysiwyg'">WYSIWYG</button>
          <button :class="{active: mode === 'raw'}" @click="mode = 'raw'">Raw</button>
          <button :class="{active: mode === 'split'}" @click="mode = 'split'">Split</button>
        </div>
        <div class="format-toolbar" v-if="currentFile">
          <button @click="insertFormat('**', '**')" title="Bold (Ctrl+B)"><b>B</b></button>
          <button @click="insertFormat('*', '*')" title="Italic (Ctrl+I)"><i>I</i></button>
          <button @click="insertFormat('~~', '~~')" title="Strikethrough"><s>S</s></button>
          <button @click="insertPrefix('# ')" title="H1">H1</button>
          <button @click="insertPrefix('## ')" title="H2">H2</button>
          <button @click="insertPrefix('### ')" title="H3">H3</button>
          <button @click="insertPrefix('- ')" title="List">•</button>
          <button @click="insertPrefix('1. ')" title="Numbered list">1.</button>
          <button @click="insertPrefix('- [ ] ')" title="Checkbox">☐</button>
          <button @click="insertPrefix('> ')" title="Quote">❝</button>
          <button @click="insertFormat('`', '`')" title="Inline code (Ctrl+`)">&lt;/&gt;</button>
          <button @click="insertCodeBlock()" title="Code block">```</button>
          <button @click="insertFormat('[', '](url)')" title="Link (Ctrl+K)">🔗</button>
          <button @click="insertPrefix('---\n')" title="Horizontal rule">―</button>
        </div>
        <div class="toolbar-right">
          <span class="file-name">{{ currentFile || 'No file open' }}</span>
          <span class="file-meta" v-if="fileMeta">{{ fileMeta }}</span>
          <button v-if="currentFile" class="toolbar-btn" @click="showHistory = !showHistory" title="History">📜</button>
          <button v-if="currentFile" class="toolbar-btn" @click="showShareDialog = !showShareDialog" title="Share">🤝</button>
          <button v-if="currentFile" class="toolbar-btn" @click="aiVerify" title="Verify with AI">🤖 Verify</button>
          <button class="git-btn" :class="{dirty: gitDirty > 0}" @click="gitSync" :title="gitDirty > 0 ? gitDirty + ' uncommitted changes' : 'All synced'">
            {{ gitDirty > 0 ? '🔴' : '🟢' }} Git
          </button>
          <div class="export-actions" v-if="currentFile">
            <button @click="exportPDF" title="Export PDF">PDF</button>
            <button @click="exportHTML" title="Export HTML">HTML</button>
            <button @click="exportMD" title="Download .md">MD</button>
          </div>
          <button class="save-btn" :class="{dirty: isDirty}" @click="saveFile">
            {{ isDirty ? 'Save*' : 'Saved' }}
          </button>
        </div>
      </div>
      <div class="editor-container" :class="mode">
        <div v-if="mode === 'raw' || mode === 'split'" class="raw-pane">
          <textarea
            ref="editor"
            v-model="content"
            @input="isDirty = true"
            @keydown="handleKeydown"
            placeholder="Start writing markdown..."
          ></textarea>
        </div>
        <div v-if="mode === 'wysiwyg'" class="wysiwyg-pane">
          <MilkdownEditor
            :key="currentFile"
            v-model="content"
            @update:modelValue="isDirty = true"
          />
        </div>
        <div v-if="mode === 'split'" class="preview-pane">
          <div v-if="rendered" v-html="rendered"></div>
          <p v-else style="color:#6c7086;font-style:italic">Preview will appear here...</p>
        </div>
      </div>
      <!-- History Panel -->
      <div class="history-panel" v-if="showHistory">
        <div class="panel-header">
          <h3>History: {{ currentFile }}</h3>
          <button @click="showHistory = false">✕</button>
        </div>
        <div class="history-list">
          <div v-for="c in history" :key="c.hash" class="history-item" @click="restoreVersion(c.hash)">
            <span class="history-hash">{{ c.hash.slice(0, 7) }}</span>
            <span class="history-msg">{{ c.message }}</span>
            <span class="history-date">{{ c.date }}</span>
          </div>
          <p v-if="!history.length" style="color:var(--text-muted);padding:12px">No history yet</p>
        </div>
      </div>
      <!-- Share Dialog -->
      <div class="share-dialog" v-if="showShareDialog">
        <div class="panel-header">
          <h3>Share: {{ currentFile }}</h3>
          <button @click="showShareDialog = false">✕</button>
        </div>
        <form @submit.prevent="shareFile" class="share-form">
          <input v-model="shareUsername" placeholder="Username to share with" />
          <select v-model="shareLevel">
            <option value="ro">Read only</option>
            <option value="rw">Read & Write</option>
          </select>
          <button type="submit">Share</button>
        </form>
        <p v-if="shareMsg" class="share-msg">{{ shareMsg }}</p>
      </div>
      <!-- AI Panel -->
      <div class="ai-panel" v-if="aiResult">
        <div class="panel-header">
          <h3>AI Response</h3>
          <button @click="aiResult = ''">✕</button>
        </div>
        <div class="ai-content" v-html="renderMarkdown(aiResult)"></div>
      </div>
    </main>
    <main class="panel" v-if="view === 'prefs'">
      <h2>Preferences</h2>
      <div class="panel-section">
        <label>Timezone</label>
        <select v-model="prefs.timezone" @change="savePrefs">
          <option v-for="tz in timezones" :key="tz" :value="tz">{{ tz }}</option>
        </select>
      </div>
      <div class="panel-section">
        <label>Default editor mode</label>
        <select v-model="prefs.defaultMode" @change="savePrefs">
          <option value="split">Split</option>
          <option value="raw">Raw</option>
          <option value="wysiwyg">WYSIWYG</option>
        </select>
      </div>
      <div class="panel-section">
        <label>Theme</label>
        <select v-model="prefs.theme" @change="applyThemeFromPrefs">
          <option value="dark">Dark</option>
          <option value="light">Light</option>
        </select>
      </div>
    </main>
    <!-- Admin Panel -->
    <main class="panel" v-if="view === 'admin' && isAdmin">
      <h2>Admin — User Management</h2>
      <div class="panel-section">
        <h3>Create User</h3>
        <form @submit.prevent="adminCreateUser" class="admin-form">
          <input v-model="newUser.username" placeholder="Username" required />
          <input v-model="newUser.email" placeholder="Email" required />
          <input v-model="newUser.password" type="password" placeholder="Password" required />
          <label><input type="checkbox" v-model="newUser.isAdmin" /> Admin</label>
          <button type="submit">Create User</button>
        </form>
        <p v-if="adminMsg" class="admin-msg">{{ adminMsg }}</p>
      </div>
      <div class="panel-section">
        <h3>Users</h3>
        <table class="user-table">
          <thead><tr><th>Username</th><th>Email</th><th>Admin</th><th>Created</th></tr></thead>
          <tbody>
            <tr v-for="u in users" :key="u.id">
              <td>{{ u.username }}</td>
              <td>{{ u.email }}</td>
              <td>{{ u.isAdmin ? '✓' : '' }}</td>
              <td>{{ formatDate(u.createdAt) }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </main>
  </div>
  <div class="login" v-else>
    <form @submit.prevent="login">
      <h1>MarkdownHub</h1>
      <input v-model="email" type="email" placeholder="Email" required />
      <input v-model="password" type="password" placeholder="Password" required />
      <button type="submit">Login</button>
      <p v-if="loginError" class="error">{{ loginError }}</p>
    </form>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import FileTree from './components/FileTree.vue'
import MilkdownEditor from './components/MilkdownEditor.vue'
import { api, setToken } from './lib/api.js'
import { renderMarkdown } from './lib/markdown.js'

const authenticated = ref(false)
const email = ref('')
const password = ref('')
const loginError = ref('')
const token = ref('')

const fileTree = ref([])
const filteredFiles = ref([])
const searchQuery = ref('')
const currentFile = ref('')
const content = ref('')
const isDirty = ref(false)
const mode = ref('split')
const editor = ref(null)
const dark = ref(true)
const view = ref('files')
const isAdmin = ref(false)
const fileMeta = ref('')
const sharedFiles = ref([])
const showHistory = ref(false)
const history = ref([])
const showShareDialog = ref(false)
const shareUsername = ref('')
const shareLevel = ref('ro')
const shareMsg = ref('')
const gitDirty = ref(0)
const aiResult = ref('')

// Preferences
const prefs = ref({ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, defaultMode: 'split', theme: 'dark' })
const timezones = Intl.supportedValuesOf ? Intl.supportedValuesOf('timeZone') : ['UTC', 'Europe/Stockholm', 'America/New_York', 'Asia/Tokyo']

// Admin
const users = ref([])
const newUser = ref({ username: '', email: '', password: '', isAdmin: false })
const adminMsg = ref('')

const rendered = computed(() => renderMarkdown(content.value))

watch(showHistory, (val) => { if (val) loadHistory() })

function toggleTheme() {
  dark.value = !dark.value
  document.documentElement.setAttribute('data-theme', dark.value ? 'dark' : 'light')
}

// ─── Auth ────────────────────────────────────────────────────────────────────

async function login() {
  try {
    const res = await api('/api/auth/login', { email: email.value, password: password.value })
    token.value = res.token
    setToken(res.token)
    authenticated.value = true
    isAdmin.value = res.isAdmin
    loginError.value = ''
    loadFiles()
    loadShared()
    if (isAdmin.value) loadUsers()
  } catch (e) {
    loginError.value = 'Invalid credentials'
  }
}

// ─── Files ───────────────────────────────────────────────────────────────────

async function loadFiles() {
  fileTree.value = await api('/api/files/list', {})
  filteredFiles.value = fileTree.value
}

function filterFiles() {
  if (!searchQuery.value) {
    filteredFiles.value = fileTree.value
    return
  }
  const q = searchQuery.value.toLowerCase()
  filteredFiles.value = filterTree(fileTree.value, q)
}

function filterTree(items, query) {
  const result = []
  for (const item of items) {
    if (item.isDir) {
      const children = filterTree(item.children || [], query)
      if (children.length > 0) {
        result.push({ ...item, children })
      }
    } else if (item.name.toLowerCase().includes(query)) {
      result.push(item)
    }
  }
  return result
}

async function openFile(path) {
  if (isDirty.value && !confirm('Discard unsaved changes?')) return
  const res = await api('/api/files/read', { path })
  currentFile.value = path
  content.value = res.content
  fileMeta.value = res.created ? `Created: ${formatDate(res.created)}` : ''
  isDirty.value = false
  view.value = 'files'
  showHistory.value = false
  showShareDialog.value = false
  aiResult.value = ''
  loadHistory()
  checkGitStatus()
}

async function saveFile() {
  if (!currentFile.value) return
  await api('/api/files/write', { path: currentFile.value, content: content.value })
  isDirty.value = false
  setTimeout(checkGitStatus, 1000)
}

async function createFile() {
  const name = prompt('File name (e.g. notes.md):')
  if (!name) return
  let path = name
  if (!path.endsWith('.md') && !path.endsWith('.txt')) {
    path += '.md'
  }
  await api('/api/files/create', { path, content: '' })
  await loadFiles()
  openFile(path)
}

async function createFolder() {
  const name = prompt('Folder name (e.g. projects):')
  if (!name) return
  await api('/api/files/create-folder', { path: name })
  await loadFiles()
}

async function deleteItem(item) {
  const msg = item.isDir
    ? `Delete folder "${item.name}" and all files in it?`
    : `Delete "${item.name}"?`
  if (!confirm(msg)) return
  await api('/api/files/delete', { path: item.path })
  if (currentFile.value === item.path) {
    currentFile.value = ''
    content.value = ''
    isDirty.value = false
  }
  await loadFiles()
}

// ─── Shared ──────────────────────────────────────────────────────────────────

async function loadShared() {
  try {
    sharedFiles.value = await api('/api/files/shared', {})
  } catch (e) {
    sharedFiles.value = []
  }
}

// ─── Preferences ─────────────────────────────────────────────────────────────

function savePrefs() {
  localStorage.setItem('mh_prefs', JSON.stringify(prefs.value))
}

function applyThemeFromPrefs() {
  dark.value = prefs.value.theme === 'dark'
  document.documentElement.setAttribute('data-theme', prefs.value.theme)
  savePrefs()
}

// ─── Admin ───────────────────────────────────────────────────────────────────

async function loadUsers() {
  try {
    users.value = await api('/api/users/list', {})
  } catch (e) { /* not admin */ }
}

async function adminCreateUser() {
  try {
    await api('/api/users/create', newUser.value)
    adminMsg.value = `User "${newUser.value.username}" created`
    newUser.value = { username: '', email: '', password: '', isAdmin: false }
    loadUsers()
  } catch (e) {
    adminMsg.value = 'Failed to create user'
  }
}

function formatDate(d) {
  if (!d) return ''
  try {
    return new Date(d).toLocaleString(undefined, { timeZone: prefs.value.timezone })
  } catch { return d }
}

// ─── Git ─────────────────────────────────────────────────────────────────────

async function checkGitStatus() {
  try {
    const res = await api('/api/git/status', {})
    gitDirty.value = res.dirty || 0
  } catch { gitDirty.value = 0 }
}

async function gitSync() {
  await api('/api/git/commit', { message: 'Manual sync' })
  await checkGitStatus()
}

// ─── History ─────────────────────────────────────────────────────────────────

async function loadHistory() {
  if (!currentFile.value) return
  try {
    history.value = await api('/api/git/log', { path: currentFile.value, limit: 20 })
  } catch { history.value = [] }
}

async function restoreVersion(hash) {
  if (!confirm(`Restore ${currentFile.value} to commit ${hash.slice(0, 7)}?`)) return
  await api('/api/git/restore', { path: currentFile.value, hash })
  const res = await api('/api/files/read', { path: currentFile.value })
  content.value = res.content
  isDirty.value = false
  showHistory.value = false
}

// ─── Sharing ─────────────────────────────────────────────────────────────────

async function shareFile() {
  if (!shareUsername.value) return
  try {
    await api('/api/share', { path: currentFile.value, username: shareUsername.value, level: shareLevel.value })
    shareMsg.value = `Shared with ${shareUsername.value} (${shareLevel.value})`
    shareUsername.value = ''
  } catch (e) {
    shareMsg.value = 'Failed to share'
  }
}

// ─── AI ──────────────────────────────────────────────────────────────────────

async function aiVerify() {
  if (!currentFile.value) return
  aiResult.value = 'Verifying...'
  try {
    const res = await api('/api/ai/verify', { path: currentFile.value })
    aiResult.value = res.feedback || 'No response'
  } catch (e) {
    aiResult.value = 'AI verification failed. Check MH_AI_ENDPOINT configuration.'
  }
}

// ─── Formatting ──────────────────────────────────────────────────────────────

function insertFormat(before, after) {
  const ta = editor.value
  if (!ta) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const selected = content.value.substring(start, end)
  const replacement = before + (selected || 'text') + after
  content.value = content.value.substring(0, start) + replacement + content.value.substring(end)
  isDirty.value = true
  // Set cursor position after insert
  const cursorPos = start + before.length + (selected ? selected.length : 4)
  requestAnimationFrame(() => {
    ta.focus()
    ta.setSelectionRange(cursorPos, cursorPos)
  })
}

function insertPrefix(prefix) {
  const ta = editor.value
  if (!ta) return
  const start = ta.selectionStart
  // Find start of current line
  const lineStart = content.value.lastIndexOf('\n', start - 1) + 1
  content.value = content.value.substring(0, lineStart) + prefix + content.value.substring(lineStart)
  isDirty.value = true
  const cursorPos = start + prefix.length
  requestAnimationFrame(() => {
    ta.focus()
    ta.setSelectionRange(cursorPos, cursorPos)
  })
}

function insertCodeBlock() {
  const ta = editor.value
  if (!ta) return
  const start = ta.selectionStart
  const end = ta.selectionEnd
  const selected = content.value.substring(start, end)
  const block = '\n```\n' + (selected || '') + '\n```\n'
  content.value = content.value.substring(0, start) + block + content.value.substring(end)
  isDirty.value = true
  const cursorPos = start + 5 + (selected ? selected.length : 0)
  requestAnimationFrame(() => {
    ta.focus()
    ta.setSelectionRange(cursorPos, cursorPos)
  })
}

// ─── Keyboard Shortcuts ──────────────────────────────────────────────────────

function handleKeydown(e) {
  const ctrl = e.ctrlKey || e.metaKey
  if (ctrl && e.key === 's') {
    e.preventDefault()
    saveFile()
  } else if (ctrl && e.key === 'b') {
    e.preventDefault()
    insertFormat('**', '**')
  } else if (ctrl && e.key === 'i') {
    e.preventDefault()
    insertFormat('*', '*')
  } else if (ctrl && e.key === 'k') {
    e.preventDefault()
    insertFormat('[', '](url)')
  } else if (ctrl && e.key === '`') {
    e.preventDefault()
    insertFormat('`', '`')
  } else if (e.key === 'Tab') {
    e.preventDefault()
    const ta = editor.value
    const start = ta.selectionStart
    content.value = content.value.substring(0, start) + '  ' + content.value.substring(ta.selectionEnd)
    isDirty.value = true
    requestAnimationFrame(() => {
      ta.setSelectionRange(start + 2, start + 2)
    })
  }
}

// ─── Export ──────────────────────────────────────────────────────────────────

function exportMD() {
  download(currentFile.value, content.value, 'text/markdown')
}

function exportHTML() {
  const html = `<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>${currentFile.value}</title>
<style>body{font-family:-apple-system,sans-serif;max-width:800px;margin:40px auto;padding:0 20px;line-height:1.7}
code{background:#f0f0f0;padding:2px 6px;border-radius:3px}pre{background:#f0f0f0;padding:16px;border-radius:6px;overflow-x:auto}
table{border-collapse:collapse;width:100%}th,td{border:1px solid #ddd;padding:8px 12px}th{background:#f5f5f5}
blockquote{border-left:4px solid #0969da;padding:0 16px;color:#656d76}</style>
</head><body>${rendered.value}</body></html>`
  download(currentFile.value.replace(/\.md$/, '.html'), html, 'text/html')
}

function exportPDF() {
  const win = window.open('', '_blank')
  win.document.write(`<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>${currentFile.value}</title>
<style>body{font-family:-apple-system,sans-serif;max-width:800px;margin:40px auto;padding:0 20px;line-height:1.7}
code{background:#f0f0f0;padding:2px 6px;border-radius:3px}pre{background:#f0f0f0;padding:16px;border-radius:6px;overflow-x:auto}
table{border-collapse:collapse;width:100%}th,td{border:1px solid #ddd;padding:8px 12px}th{background:#f5f5f5}
blockquote{border-left:4px solid #0969da;padding:0 16px;color:#656d76}</style>
</head><body>${rendered.value}</body></html>`)
  win.document.close()
  setTimeout(() => { win.print() }, 300)
}

function download(filename, content, mime) {
  const blob = new Blob([content], { type: mime })
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = filename
  a.click()
  URL.revokeObjectURL(a.href)
}
</script>

<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }

:root, [data-theme="dark"] {
  --bg-primary: #1e1e2e;
  --bg-secondary: #181825;
  --bg-tertiary: #11111b;
  --bg-hover: #313244;
  --bg-selected: #45475a;
  --border: #313244;
  --text: #cdd6f4;
  --text-muted: #a6adc8;
  --accent: #89b4fa;
  --success: #a6e3a1;
  --danger: #f38ba8;
  --code-bg: #313244;
}

[data-theme="light"] {
  --bg-primary: #ffffff;
  --bg-secondary: #f5f5f5;
  --bg-tertiary: #fafafa;
  --bg-hover: #e8e8e8;
  --bg-selected: #d0d0d0;
  --border: #e0e0e0;
  --text: #1e1e2e;
  --text-muted: #656d76;
  --accent: #0969da;
  --success: #1a7f37;
  --danger: #cf222e;
  --code-bg: #f0f0f0;
}

.app {
  display: flex;
  height: 100vh;
}

/* ─── Sidebar ─────────────────────────────────────────────────────────────── */

.sidebar {
  width: 260px;
  background: var(--bg-primary);
  color: var(--text);
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border);
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid var(--border);
}

.sidebar-header h2 { font-size: 16px; }
.sidebar-header button {
  background: var(--accent);
  color: var(--bg-primary);
  border: none;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
}
.sidebar-actions { display: flex; gap: 4px; }

.search-box {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.search-box input {
  width: 100%;
  padding: 6px 10px;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-size: 13px;
  outline: none;
}
.search-box input:focus { border-color: var(--accent); }

/* ─── Toolbar ─────────────────────────────────────────────────────────────── */

.editor-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.mode-switcher button {
  background: var(--bg-hover);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 12px;
  cursor: pointer;
  font-size: 13px;
}
.mode-switcher button.active {
  background: var(--accent);
  color: var(--bg-primary);
}
.mode-switcher button:first-child { border-radius: 4px 0 0 4px; }
.mode-switcher button:last-child { border-radius: 0 4px 4px 0; }

.format-toolbar {
  display: flex;
  gap: 2px;
  padding: 0 8px;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
}
.format-toolbar button {
  background: transparent;
  color: var(--text);
  border: none;
  padding: 4px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 13px;
  min-width: 28px;
}
.format-toolbar button:hover { background: var(--bg-hover); }

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.file-name { color: var(--text-muted); font-size: 13px; }

.export-actions { display: flex; gap: 4px; }
.export-actions button {
  background: var(--bg-hover);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}
.export-actions button:hover { background: var(--bg-selected); }

.save-btn {
  background: var(--success);
  color: var(--bg-primary);
  border: none;
  padding: 6px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
}
.save-btn.dirty { background: var(--danger); }

/* ─── Editor ──────────────────────────────────────────────────────────────── */

.editor-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}
.editor-container.raw .raw-pane { flex: 1; }
.editor-container.wysiwyg .wysiwyg-pane { flex: 1; }
.editor-container.split .raw-pane,
.editor-container.split .preview-pane { flex: 1; }
.editor-container.split .raw-pane { border-right: 1px solid var(--border); }

.wysiwyg-pane {
  overflow-y: auto;
  background: var(--bg-primary);
  color: var(--text);
}

.raw-pane textarea {
  width: 100%;
  height: 100%;
  background: var(--bg-primary);
  color: var(--text);
  border: none;
  padding: 20px;
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 14px;
  line-height: 1.6;
  resize: none;
  outline: none;
  tab-size: 2;
}

/* ─── Preview ─────────────────────────────────────────────────────────────── */

.preview-pane {
  padding: 20px;
  overflow-y: auto;
  background: var(--bg-tertiary);
  color: var(--text);
  line-height: 1.7;
  font-size: 15px;
}
.preview-pane h1 { font-size: 2em; margin: 0.67em 0; padding-bottom: 0.3em; border-bottom: 1px solid var(--border); color: var(--text); }
.preview-pane h2 { font-size: 1.5em; margin: 0.83em 0; padding-bottom: 0.3em; border-bottom: 1px solid var(--border); color: var(--text); }
.preview-pane h3 { font-size: 1.25em; margin: 1em 0; color: var(--text); }
.preview-pane h4, .preview-pane h5, .preview-pane h6 { margin: 1em 0; color: var(--text-muted); }
.preview-pane p { margin: 0 0 16px; }
.preview-pane code { background: var(--code-bg); padding: 2px 6px; border-radius: 3px; font-size: 85%; font-family: 'JetBrains Mono', 'Fira Code', monospace; }
.preview-pane pre { background: var(--code-bg); padding: 16px; border-radius: 6px; overflow-x: auto; margin: 0 0 16px; }
.preview-pane pre code { background: none; padding: 0; font-size: 85%; }
.preview-pane ul, .preview-pane ol { padding-left: 2em; margin: 0 0 16px; }
.preview-pane li { margin: 4px 0; }
.preview-pane blockquote { border-left: 4px solid var(--accent); padding: 0 16px; color: var(--text-muted); margin: 0 0 16px; }
.preview-pane table { border-collapse: collapse; width: 100%; margin: 0 0 16px; }
.preview-pane th, .preview-pane td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; }
.preview-pane th { background: var(--code-bg); }
.preview-pane hr { border: none; border-top: 1px solid var(--border); margin: 24px 0; }
.preview-pane a { color: var(--accent); text-decoration: none; }
.preview-pane a:hover { text-decoration: underline; }
.preview-pane img { max-width: 100%; border-radius: 4px; }
.preview-pane input[type="checkbox"] { margin-right: 6px; }

/* ─── Login ───────────────────────────────────────────────────────────────── */

.login {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background: var(--bg-primary);
}
.login form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 300px;
}
.login h1 { color: var(--text); text-align: center; margin-bottom: 12px; }
.login input {
  padding: 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-hover);
  color: var(--text);
  font-size: 14px;
}
.login button {
  padding: 10px;
  background: var(--accent);
  color: var(--bg-primary);
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
}
.login .error { color: var(--danger); text-align: center; font-size: 13px; }

/* ─── Sidebar Nav ─────────────────────────────────────────────────────────── */

.sidebar-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 8px;
  border-bottom: 1px solid var(--border);
}
.sidebar-nav button {
  flex: 1;
  background: transparent;
  color: var(--text-muted);
  border: none;
  padding: 6px 4px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 11px;
  white-space: nowrap;
}
.sidebar-nav button.active { background: var(--bg-hover); color: var(--text); }
.sidebar-nav button:hover { background: var(--bg-hover); }

/* ─── Panels ──────────────────────────────────────────────────────────────── */

.panel {
  flex: 1;
  padding: 32px;
  overflow-y: auto;
  background: var(--bg-tertiary);
  color: var(--text);
}
.panel h2 { margin-bottom: 24px; }
.panel h3 { margin: 16px 0 8px; }
.panel-section { margin-bottom: 24px; }
.panel-section label { display: block; margin-bottom: 6px; color: var(--text-muted); font-size: 13px; }
.panel-section select, .panel-section input[type="text"] {
  padding: 8px 12px;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-size: 14px;
  min-width: 200px;
}

.admin-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.admin-form input {
  padding: 8px 12px;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-size: 14px;
}
.admin-form button {
  padding: 8px 16px;
  background: var(--accent);
  color: var(--bg-primary);
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.admin-msg { margin-top: 8px; color: var(--success); font-size: 13px; }

.user-table { width: 100%; border-collapse: collapse; margin-top: 12px; }
.user-table th, .user-table td { padding: 8px 12px; border: 1px solid var(--border); text-align: left; font-size: 13px; }
.user-table th { background: var(--bg-hover); }

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

.toolbar-btn {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}
.toolbar-btn:hover { background: var(--bg-hover); }

.git-btn {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}
.git-btn.dirty { border-color: var(--danger); }

.history-panel, .share-dialog, .ai-panel {
  position: absolute;
  right: 0;
  top: 50px;
  width: 360px;
  max-height: calc(100vh - 60px);
  overflow-y: auto;
  background: var(--bg-primary);
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  z-index: 20;
  box-shadow: -2px 2px 8px rgba(0,0,0,0.3);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.panel-header h3 { font-size: 14px; }
.panel-header button { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 18px; }

.history-list { padding: 8px; }
.history-item {
  display: flex;
  gap: 8px;
  padding: 8px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  align-items: center;
}
.history-item:hover { background: var(--bg-hover); }
.history-hash { color: var(--accent); font-family: monospace; }
.history-msg { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-date { color: var(--text-muted); font-size: 11px; white-space: nowrap; }

.share-form {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  align-items: center;
}
.share-form input, .share-form select {
  padding: 6px 10px;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-size: 13px;
}
.share-form button {
  padding: 6px 12px;
  background: var(--accent);
  color: var(--bg-primary);
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.share-msg { padding: 0 16px 12px; font-size: 12px; color: var(--success); }

.ai-content { padding: 16px; font-size: 14px; line-height: 1.6; }
.ai-content h1, .ai-content h2, .ai-content h3 { margin: 12px 0 6px; }
.ai-content p { margin: 0 0 12px; }
.ai-content code { background: var(--code-bg); padding: 2px 6px; border-radius: 3px; }
.ai-content ul, .ai-content ol { padding-left: 2em; margin: 0 0 12px; }

/* ─── Responsive ──────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
  .sidebar { position: fixed; left: -260px; z-index: 10; transition: left 0.2s; }
  .sidebar.open { left: 0; }
  .format-toolbar { display: none; }
}
</style>
