<script setup>
import { ref, computed } from 'vue'
import { useConfirm } from '../composables/useConfirm.js'
import { fetchSource } from '../api.js'
import SourceForm from './SourceForm.vue'

const props = defineProps({
  topics: { type: Array, required: true },
  selectedTopic: { type: String, default: null },
  stats: { type: Object, default: null },
  fortschritt: { type: Object, default: () => ({}) },
  uiError: { type: String, default: null },
  doneByFormat: { type: Object, default: () => ({}) },
  latestByFormat: { type: Object, default: () => ({}) },
  allGuides: { type: Array, default: () => [] },
  dismissedErrors: { type: Object, default: () => new Set() },
  blocks: { type: Object, default: () => ({ ready: false, generating: false, progress: null, error: null }) },
  activeBausteine: { type: Array, default: () => [] },
  pinned: { type: Boolean, default: true },
  dark: { type: Boolean, default: false },
  provider: { type: String, default: 'claude' },
  providers: { type: Array, default: () => [] },
  folders: { type: Object, default: () => ({ projekt: [], uni: [] }) },
  ansichtModus: { type: String, default: 'compact' }, // compact | erklärend
  stufeAnsicht: { type: Number, default: 4 },          // 1=A · 2=F · 3=E · 4=V
})

const emit = defineEmits(['select', 'createThema', 'updateSource', 'bausteineClick', 'deleteTopic', 'dismissError', 'dismissUiError', 'preview', 'openBausteineView', 'openGuideBoard', 'openGeneration', 'togglePin', 'sidebarLeave', 'toggleDark', 'setAnsicht', 'setStufe', 'generalExam', 'practice', 'setProvider'])

// Accordion: at most one panel open. IDs: 'blocks', 'fmt-<Format>', 'topic-<Name>'.
const openPanel = ref(null)
const isOpen = (id) => openPanel.value === id
function togglePanel(id) {
  openPanel.value = openPanel.value === id ? null : id
}

function providerAvailable(id) {
  const p = props.providers.find((x) => x.id === id)
  return p ? p.available : true
}

const PROVIDER_LABELS = { claude: 'Claude', minimax: 'MiniMax', lokal: 'Local' }

// Tracker at the top of the navigation: total topics, created/completed per format
const trackerItems = computed(() => {
  if (!props.stats) return []
  const f = props.stats.formats || {}
  const fmt = (k) => `${f[k]?.completed ?? 0}/${f[k]?.erstellt ?? 0}`
  return [
    { label: 'Topics', value: String(props.stats.topics ?? 0), title: 'Topics incl. projects' },
    { label: 'Guides', value: fmt('Guide'), title: 'completed/created' },
  ]
})

const formats = [
  { key: 'Guide', label: 'Guide' },
]

// Level views of the SINGLE guide (filtered by subblock depth).
const LEVEL_VIEWS = [
  { k: 'auto', label: '⟳', title: 'Auto — Stufe folgt deinem Prüfungs-Score je Block' },
  { k: 1, label: 'A', title: 'Beginner' },
  { k: 2, label: 'F', title: 'Beginner + Advanced' },
  { k: 3, label: 'E', title: 'up to Expert' },
  { k: 4, label: 'V', title: 'Complete (incl. edge)' },
]

const blocksState = computed(() => {
  if (props.blocks.generating) return 'generating'
  return props.blocks.ready ? 'done' : 'none'
})

// Re-run from a substep now happens in the blocks overview; the sidebar no longer has phase pills.

// Only OTHER topics — the selected topic shows its progress inline on the row
const activeGenerations = computed(() => {
  const blockLines = props.activeBausteine
    .filter((b) => b.topic !== props.selectedTopic)
    .map((b) => `${b.topic} – Blocks: ${b.progress || 'Waiting…'}`)
  const guideLines = props.allGuides
    .filter((g) => (g.status === 'generating' || g.status === 'queued') && g.topic !== props.selectedTopic)
    .map((g) => `${g.topic} – ${g.format}: ${g.progress || 'Waiting…'}`)
  return [...blockLines, ...guideLines]
})

const { pending: pendingConfirm, armOrRun } = useConfirm()

// Name click = open the block overview (generate/resume/remove all live there now).
function onBlocksName() {
  emit('openBausteineView')
}

function guideStatus(format) {
  // Running generation takes precedence — otherwise an older finished
  // guide masks the run and ▶ would start duplicates.
  const latest = props.latestByFormat[format]
  if (latest && (latest.status === 'generating' || latest.status === 'queued')) return latest.status
  if (props.doneByFormat[format]) return 'done'
  if (!latest || latest.status === 'error') return 'none'
  return latest.status
}

function errorMsg(format) {
  const latest = props.latestByFormat[format]
  if (latest?.status !== 'error' || props.dismissedErrors.has(latest.id)) return ''
  if (aborted(format)) return '' // no red error — the Paused badge shows the state
  return latest.error_msg || 'Generation failed'
}

// Aborted run = partial progress present: ▶ resumes, ✕ deletes the progress
function aborted(format) {
  const latest = props.latestByFormat[format]
  return latest?.status === 'error' && (latest.error_msg || '').startsWith('Cancelled')
}

// Name click: finished guide → preview, otherwise the generation view (start/cancel live there).
function handleFormatClick(format) {
  const guide = props.doneByFormat[format]
  if (guide) emit('preview', guide)
  else emit('openGuideBoard', format)
}

// Flash-message behavior: × only hides, nothing is deleted
function dismissError(format) {
  const latest = props.latestByFormat[format]
  if (latest?.status === 'error') emit('dismissError', latest.id)
}

// Create area: inline expandable (name + more info + source type).
const dlg = ref(false)
const form = ref({ name: '', instructions: '', sourceType: 'thema', sourceOrt: '' })
const canCreate = computed(() => {
  if (!form.value.name.trim()) return false
  if (['link', 'projekt', 'uni'].includes(form.value.sourceType)) return !!form.value.sourceOrt.trim()
  return true
})

function toggleCreate() {
  if (!dlg.value) form.value = { name: '', instructions: '', sourceType: 'thema', sourceOrt: '' }
  dlg.value = !dlg.value
}

function createTopic() {
  if (!canCreate.value) return
  emit('createThema', {
    topic: form.value.name.trim(),
    instructions: form.value.instructions.trim(),
    sourceType: form.value.sourceType,
    sourceOrt: form.value.sourceOrt.trim(),
  })
  dlg.value = false
}

function confirmDeleteTopic(topic) {
  armOrRun('topic-' + topic, () => emit('deleteTopic', topic))
}

// --- Topic edit: name click only selects; the chevron toggles the sources form (default closed) ---
const editTopic = ref(null)
const editForm = ref({ type: 'thema', ort: '', spec: '' })
const editLoading = ref(false)
const canSave = computed(() => {
  if (['link', 'projekt', 'uni'].includes(editForm.value.type)) return !!editForm.value.ort.trim()
  return true
})

async function toggleTopicPanel(t) {
  emit('select', t)
  if (openPanel.value === 'topic-' + t) { openPanel.value = null; return }
  openPanel.value = 'topic-' + t
  editTopic.value = t
  editLoading.value = true
  try {
    const q = await fetchSource(t)
    editForm.value = { type: q.type || 'thema', ort: q.location || '', spec: q.spec || '' }
  } catch {
    editForm.value = { type: 'thema', ort: '', spec: '' }
  } finally {
    editLoading.value = false
  }
}

// v-model-Brücken für SourceForm ({type, ort}) auf die beiden State-Objekte
const createSource = computed({
  get: () => ({ type: form.value.sourceType, ort: form.value.sourceOrt }),
  set: (v) => { form.value.sourceType = v.type; form.value.sourceOrt = v.ort },
})
const editSource = computed({
  get: () => ({ type: editForm.value.type, ort: editForm.value.ort }),
  set: (v) => { editForm.value.type = v.type; editForm.value.ort = v.ort },
})

function saveSource() {
  if (!canSave.value || !editTopic.value) return
  emit('updateSource', {
    topic: editTopic.value,
    type: editForm.value.type,
    ort: editForm.value.ort.trim(),
    spec: editForm.value.spec.trim(),
  })
  openPanel.value = null
}
</script>

<template>
  <aside class="sidebar" @mouseleave="emit('sidebarLeave')">
    <div class="stats-bar" v-if="trackerItems.length">
      <div class="stat" v-for="item in trackerItems" :key="item.label" :title="item.title">
        <span class="stat-value">{{ item.value }}</span>
        <span class="stat-label">{{ item.label }}</span>
      </div>
    </div>
    <div class="new-topic">
      <button
        class="pin-btn"
        :title="pinned ? 'Hide sidebar' : 'Pin sidebar'"
        @click="emit('togglePin')"
      >{{ pinned ? '⇤' : '⇥' }}</button>
      <button
        class="theme-btn"
        :title="dark ? 'Light mode' : 'Dark mode'"
        @click="emit('toggleDark')"
      >{{ dark ? '☀' : '🌙' }}</button>
      <div v-if="selectedTopic" class="ansicht-toggle">
        <button :class="{ active: ansichtModus === 'compact' }" title="Short text" @click="emit('setAnsicht', 'compact')">
          <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
            <rect x="2" y="5" width="12" height="1.6" rx="0.8" />
            <rect x="2" y="9" width="7" height="1.6" rx="0.8" />
          </svg>
        </button>
        <button :class="{ active: ansichtModus === 'erklärend' }" title="Long text" @click="emit('setAnsicht', 'erklärend')">
          <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
            <rect x="2" y="3" width="12" height="1.4" rx="0.7" />
            <rect x="2" y="6.3" width="12" height="1.4" rx="0.7" />
            <rect x="2" y="9.6" width="12" height="1.4" rx="0.7" />
            <rect x="2" y="12.9" width="8" height="1.4" rx="0.7" />
          </svg>
        </button>
      </div>
      <div v-if="selectedTopic" class="level-toggle" title="Depth of guide view">
        <button v-for="s in LEVEL_VIEWS" :key="s.k"
          :class="{ active: stufeAnsicht === s.k }" :title="s.title"
          @click="emit('setStufe', s.k)">{{ s.label }}</button>
      </div>
      <button class="new-topic-toggle" :class="{ active: dlg }" title="Create topic" @click="toggleCreate">+</button>
    </div>

    <!-- Create: inline expandable (no modal) -->
    <div v-if="dlg" class="thema-panel">
      <input class="dlg-input" v-model="form.name" placeholder="Themenname…" @keyup.enter="createTopic" autofocus />
      <textarea class="dlg-textarea" v-model="form.instructions" rows="2" placeholder="Mehr Infos (optional)…"></textarea>
      <SourceForm v-model="createSource" :folders="folders" @submit="createTopic" />
      <div class="dlg-actions">
        <button class="dlg-cancel" @click="dlg = false">Abbrechen</button>
        <button class="dlg-create" :disabled="!canCreate" @click="createTopic">Anlegen</button>
      </div>
    </div>
    <div class="provider-toggle" v-if="providers.length">
      <button
        v-for="p in providers"
        :key="p.id"
        :class="{ active: p.id === provider }"
        :disabled="!p.available"
        :title="p.available ? '' : 'Not configured (CLI/key missing)'"
        @click="emit('setProvider', p.id)"
      >{{ PROVIDER_LABELS[p.id] || p.id }}</button>
    </div>
    <div class="format-section" v-if="selectedTopic">
      <div class="format-error ui-error" v-if="uiError">
        <span class="format-error-text">{{ uiError }}</span>
        <button class="format-error-x" title="Ausblenden" @click="emit('dismissUiError')">×</button>
      </div>
      <div class="progress-info" v-if="activeGenerations.length">
        <div v-for="(line, i) in activeGenerations" :key="i">{{ line }}</div>
      </div>
      <div class="ord-blocks">
        <div
          class="format-row blocks-row"
          :class="{ 'is-active': blocksState === 'generating' || blocks.partial }"
        >
          <button class="format-name blocks-name" @click="onBlocksName">
            <span class="format-label">Blocks</span>
            <span
              v-if="blocks.partial && blocksState !== 'generating'"
              class="resume-badge"
              title="Aborted — can be resumed"
            >Paused</span>
          </button>
        </div>
        <div v-if="blocksState === 'generating'" class="format-progress">
          {{ blocks.progress || 'Waiting…' }}
        </div>
        <div v-if="blocks.error && !blocks.error.startsWith('Cancelled')" class="format-error">
          <span class="format-error-text">{{ blocks.error }}</span>
        </div>
        <div class="format-row">
          <button class="format-name" @click="emit('openGeneration')">
            <span class="format-label gen-label">Generierung</span>
            <span v-if="blocksState === 'generating'" class="gen-live-dot" title="Läuft"></span>
          </button>
        </div>
      </div>
<!-- Formats come after the blocks row via CSS order (order 2) -->
      <div v-for="f in formats" :key="f.key" :style="{ order: 3 }">
        <div :class="['format-row', 'fmt-' + guideStatus(f.key), { 'fmt-paused': aborted(f.key) }]">
          <button class="format-name" @click="handleFormatClick(f.key)">
            <span class="format-label">{{ f.label }}</span>
            <span
              v-if="aborted(f.key)"
              class="resume-badge"
              title="Aborted — can be resumed"
            >Paused</span>
          </button>
        </div>
        <div
          v-if="guideStatus(f.key) === 'generating' || guideStatus(f.key) === 'queued'"
          class="format-progress"
        >{{ latestByFormat[f.key]?.progress || 'Waiting…' }}</div>
        <div v-if="errorMsg(f.key)" class="format-error">
          <span class="format-error-text">{{ errorMsg(f.key) }}</span>
          <button class="format-error-x" title="Ausblenden" @click="dismissError(f.key)">×</button>
        </div>
      </div>
      <div class="format-row ord-exam">
        <button class="format-name elements-btn" @click="emit('generalExam')">
          <span class="format-label">General Exam</span>
        </button>
      </div>
      <div class="format-row ord-practice">
        <button class="format-name elements-btn" @click="emit('practice')">
          <span class="format-label">Üben</span>
        </button>
      </div>
    </div>

    <ul class="topic-list">
      <li
        v-for="t in topics"
        :key="t"
        :class="{ active: t === selectedTopic, 'li-open': isOpen('topic-' + t) }"
      >
        <div class="topic-row">
          <span class="topic-name" @click="emit('select', t)">{{ t }}</span>
          <button class="panel-toggle" :class="{ open: isOpen('topic-' + t) }" title="Optionen" @click.stop="toggleTopicPanel(t)">▾</button>
        </div>
        <div v-if="isOpen('topic-' + t)" class="thema-panel edit-panel" @click.stop>
          <p v-if="editLoading" class="dlg-hint">Lädt…</p>
          <template v-else>
            <textarea class="dlg-textarea" v-model="editForm.spec" rows="2" placeholder="Mehr Infos (optional)…"></textarea>
            <SourceForm v-model="editSource" :folders="folders" @submit="saveSource" />
            <div class="dlg-actions">
              <button
                class="dlg-delete"
                :class="{ armed: pendingConfirm === 'topic-' + t }"
                @click="confirmDeleteTopic(t)"
              >{{ pendingConfirm === 'topic-' + t ? 'Sicher?' : 'Löschen' }}</button>
              <button class="dlg-create" :disabled="!canSave" @click="saveSource">Aktualisieren</button>
            </div>
          </template>
        </div>
      </li>
    </ul>
  </aside>
</template>

<style scoped>
.sidebar {
  width: 300px;
  min-width: 300px;
  background: var(--panel);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  height: 100dvh;
}

.new-topic {
  display: flex;
  gap: 4px;
  padding: 0.75rem;
  border-bottom: 1px solid var(--border);
}

.new-topic input {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  font-size: 0.85rem;
  outline: none;
}

.new-topic input:focus {
  border-color: var(--accent);
}

.new-topic button {
  padding: 6px 10px;
  border: none;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: 6px;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
}

.new-topic button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.new-topic .pin-btn {
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  font-weight: 600;
  padding: 6px 8px;
}

.new-topic .pin-btn:hover {
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-color: var(--accent-border);
}

.new-topic .theme-btn {
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  font-weight: 600;
  padding: 6px 8px;
}

.new-topic .theme-btn:hover {
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-color: var(--accent-border);
}

/* View switcher: two icon buttons (short / long text) */
.ansicht-toggle { display: inline-flex; }
.new-topic .ansicht-toggle button {
  padding: 4px 7px;
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  display: inline-flex;
  align-items: center;
}
.new-topic .ansicht-toggle button:first-child { border-radius: 6px 0 0 6px; }
.new-topic .ansicht-toggle button:last-child { border-radius: 0 6px 6px 0; border-left: none; }
.new-topic .ansicht-toggle button:hover { color: var(--accent-hover); }
.new-topic .ansicht-toggle button.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.ansicht-toggle svg { fill: currentColor; display: block; }
.level-toggle { display: inline-flex; margin-left: 4px; }
.new-topic .level-toggle button {
  padding: 4px 6px;
  background: var(--bg);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  font-size: 11px;
  font-weight: 600;
  min-width: 20px;
}
.new-topic .level-toggle button:first-child { border-radius: 6px 0 0 6px; }
.new-topic .level-toggle button:last-child { border-radius: 0 6px 6px 0; }
.new-topic .level-toggle button:not(:first-child) { border-left: none; }
.new-topic .level-toggle button:hover { color: var(--accent-hover); }
.new-topic .level-toggle button.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.stats-bar {
  display: flex;
  padding: 0.5rem 0.75rem;
  gap: 4px;
  border-bottom: 1px solid var(--border);
}

.stat {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 7px 2px 4px;
  background: var(--panel-soft);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: default;
}

.stat-value {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--text);
}

/* Mini title sits on the top edge of the badge (legend look) */
.stat-label {
  position: absolute;
  top: -0.42rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0 3px;
  font-size: 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-faint);
  background: var(--panel);
  white-space: nowrap;
}

.provider-toggle {
  display: flex;
  gap: 0;
  padding: 0.5rem 0.75rem 0;
}

.provider-toggle button {
  flex: 1;
  padding: 5px 8px;
  font-size: 0.78rem;
  font-weight: 600;
  border: 1px solid var(--border-strong);
  background: var(--bg);
  color: var(--text-muted);
  cursor: pointer;
}

.provider-toggle button:first-child {
  border-radius: 6px 0 0 6px;
}

.provider-toggle button:last-child {
  border-radius: 0 6px 6px 0;
  border-left: none;
}

.provider-toggle button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.provider-toggle button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.topic-list {
  list-style: none;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.5rem 0;
  border-top: 1px solid var(--border);
}

.topic-list li {
  font-size: 0.9rem;
  color: var(--text);
}

.topic-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 0.6rem 1rem;
  cursor: pointer;
  transition: background 0.15s;
}

.topic-row:hover {
  background: var(--accent-soft);
}

.topic-list li.active .topic-row {
  background: var(--accent-soft);
  color: var(--accent-hover);
  font-weight: 600;
}

.topic-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Format section */
.blocks-name {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}



.format-section {
  flex-shrink: 0;
  max-height: 60vh;
  overflow-y: auto;
  padding: 0.5rem 0;
  /* flex + order: blocks (order 2) before the formats (order 3) */
  display: flex;
  flex-direction: column;
}

.gen-label { color: var(--text-muted); font-size: 0.86em; }
.gen-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse-soft 1.2s ease-in-out infinite;
}

.ord-blocks {
  order: 2;
}

.ord-exam {
  order: 4;
}

.ord-practice {
  order: 5;
}

.elements-btn {
  cursor: pointer;
  color: var(--text);
}

.elements-btn:hover {
  background: var(--panel-soft);
}

.progress-info {
  padding: 0.4rem 0.75rem;
  font-size: 0.75rem;
  color: var(--warning);
  background: var(--warning-soft);
  margin-bottom: 0.25rem;
  animation: pulse 1.5s ease-in-out infinite;
}

/* Rejected action (409/400) — above all format rows */
.ui-error {
  order: 0;
  padding: 0.4rem 0.75rem;
  background: var(--warning-soft);
}

/* Progress text directly below the running format row */
.format-progress {
  padding: 0 0.75rem 5px calc(0.75rem + 8px);
  font-size: 0.72rem;
  color: var(--warning);
  line-height: 1.3;
  animation: pulse 1.5s ease-in-out infinite;
}

.resume-badge {
  flex: 0 0 auto;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--warning);
  background: var(--warning-soft);
  border: 1px solid var(--warning-border);
  border-radius: 4px;
  padding: 1px 5px;
}

.format-row {
  display: flex;
  align-items: center;
  padding: 0.4rem 0.75rem;
  transition: background 0.15s;
}

.format-row:hover {
  background: var(--panel-soft);
}

.format-name {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  text-align: left;
  font-size: 0.85rem;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* Accordion: arrow toggle + expanding action panel */
.panel-toggle {
  flex: 0 0 auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-faint);
  font-size: 0.8rem;
  line-height: 1;
  padding: 4px 8px;
  transition: transform 0.15s, color 0.15s;
}
.panel-toggle.open { transform: rotate(180deg); color: var(--text); }
.panel-toggle:hover { color: var(--accent); }

.format-row.row-open,
.topic-list li.li-open .topic-row { background: var(--panel-soft); }


.panel-btn.danger:hover { border-color: var(--danger); }
.panel-btn.armed { background: var(--danger); color: #fff; border-color: var(--danger); }

.format-error-x.armed,
.delete-topic.armed {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--danger);
  color: #fff;
  border-radius: 4px;
  padding: 2px 6px;
}

.fmt-done .format-name {
  color: var(--success);
  font-weight: 600;
  cursor: pointer;
  background: var(--success-soft);
  border: 1px solid var(--success-border);
}

.fmt-done .format-name:hover {
  background: var(--success-soft-hover);
}

.fmt-generating .format-name,
.fmt-queued .format-name {
  color: var(--warning);
  background: var(--warning-soft);
  border: 1px solid var(--warning-border);
  animation: pulse 1.5s ease-in-out infinite;
}

.format-error {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  padding: 2px 0.75rem 6px calc(0.75rem + 8px);
  font-size: 0.72rem;
  color: var(--danger);
  line-height: 1.3;
}

.format-error-text {
  flex: 1;
  word-break: break-word;
}

.format-error-x {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: var(--danger);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  opacity: 0.6;
}

.format-error-x:hover {
  opacity: 1;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.65; }
}

/* Create — inline expandable (no modal) */
.new-topic-toggle {
  margin-left: auto;       /* right-aligned instead of full width */
  padding: 6px 12px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--accent);
  color: var(--on-accent);
  cursor: pointer;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  text-align: center;
}
.new-topic-toggle:hover { background: var(--accent-hover); }
.new-topic-toggle.active { background: var(--accent-hover); }
.thema-panel {
  margin: 0.4rem 0;
  padding: 0.5rem;
  background: var(--panel-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.85rem;
}
.dlg-input, .dlg-textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
}
.dlg-input:focus, .dlg-textarea:focus { outline: none; border-color: var(--accent); }
.dlg-textarea { resize: vertical; min-height: 2rem; }
.dlg-hint { margin: 0; font-size: 0.75rem; color: var(--text-faint); }
.dlg-actions { display: flex; justify-content: flex-end; gap: 0.4rem; margin-top: 0.1rem; }
.dlg-actions button {
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel-soft);
  color: var(--text);
  cursor: pointer;
}
.dlg-create { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dlg-create:disabled { opacity: 0.45; cursor: default; }

/* Topic edit panel: subtly inserted into the list — no box, just a left accent */
.edit-panel {
  margin: 0;
  padding: 0.5rem 1rem 0.7rem 1.25rem;
  background: var(--accent-soft);
  border: none;
  border-left: 3px solid var(--accent-border);
  border-radius: 0;
}
.dlg-delete { margin-right: auto; color: var(--danger); }
.dlg-delete.armed { background: var(--danger); border-color: var(--danger); color: #fff; font-weight: 700; }
select.dlg-input { cursor: pointer; }

</style>
