<script setup lang="ts">
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import {
  ArrowRight,
  Bot,
  ClipboardList,
  Code2,
  Plus,
  Search,
  Server,
  Shield,
  Terminal,
  Users,
  Wifi,
  WifiOff,
} from '@lucide/vue'
import {
  getAgentProposalStatusMeta,
  useAgentProposalsQuery,
  type AgentProposalDto,
} from '../api/agentProposals'
import {
  projectOpenClawAgentNodes,
  useOpenClawAgentsQuery,
  useOpenClawOverviewQuery,
} from '../api/openclawRuntime'
import { useAuthStore } from '../stores/auth'
import type { OpenClawAgent } from '../types/openclaw'
import AsyncStatePanel from '../components/mission-control/AsyncStatePanel.vue'

const router = useRouter()
const auth = useAuthStore()
const isOwner = computed(() => auth.isOwner)
const overviewQuery = useOpenClawOverviewQuery()
const agentsQuery = useOpenClawAgentsQuery()
const proposalsQuery = useAgentProposalsQuery({ limit: 12 }, isOwner)

interface AgentCard {
  id: string
  name: string
  role: string
  description: string
  tags: string[]
  color: string
  icon: string
  model?: string
  statusLabel?: string
  statusKind?: 'connected' | 'thinking' | 'blocked' | 'ready' | 'stale' | 'error' | 'unsupported'
  statusDetail?: string | null
  isActive?: boolean
  progress?: number | null
  currentTask?: string | null
}

// Active presentation metadata only. OpenClaw remains authoritative for which
// agents exist; this table supplies labels/icons for matching known IDs.
const fallbackAgents: AgentCard[] = [
  {
    id: 'iris',
    name: 'Iris',
    role: 'Chief of Staff',
    description: 'Koordiniert, delegiert, hält das Team tight. Die erste Anlaufstelle zwischen Boss und Maschine.',
    tags: ['Orchestration', 'Delegation', 'Approval'],
    color: 'var(--a-purple)',
    icon: 'bot',
  },
  {
    id: 'programmer',
    name: 'Programmer',
    role: 'Lead Developer',
    description: 'Implementiert Features, schreibt Code, führt Builds und Tests aus. Arbeitet autonom im Scope.',
    tags: ['Coding', 'Development', 'Builds'],
    color: 'var(--a-blue)',
    icon: 'code',
  },
  {
    id: 'architekt',
    name: 'Architekt',
    role: 'Infrastructure Engineer',
    description: 'Verantwortlich für Docker, Nginx, Deployment und VPS-Infrastruktur.',
    tags: ['Infrastructure', 'Deployment', 'Docker'],
    color: 'var(--st-think)',
    icon: 'server',
  },
  {
    id: 'reviewer',
    name: 'Reviewer',
    role: 'Code QA',
    description: 'Prüft Code auf Bugs, Sicherheit und Wartbarkeit. Fixt Probleme eigenständig.',
    tags: ['QA', 'Security', 'Code Review'],
    color: 'var(--st-queue)',
    icon: 'shield',
  },
  {
    id: 'researcher',
    name: 'Researcher',
    role: 'Research Analyst',
    description: 'Recherchiert, analysiert Quellen, prüft Fakten. Nur Lese-Rechte, keine Aktionen.',
    tags: ['Research', 'Analysis', 'Fact-Checking'],
    color: 'var(--a-mid)',
    icon: 'search',
  },
  {
    id: 'executor',
    name: 'Executor',
    role: 'Host Executor',
    description: 'Führt Host-Kommandos auf dem VPS aus. Nur auf Iris-Befehl, niemals eigeninitiativ.',
    tags: ['Execution', 'Docker', 'VPS'],
    color: 'var(--st-work)',
    icon: 'terminal',
  },
]

const runtimeAgents = computed(() => projectOpenClawAgentNodes(overviewQuery.data.value))
const agents = computed(() =>
  (agentsQuery.data.value?.items ?? []).map(item => enrichAgent(item)),
)
const loading = computed(() => agentsQuery.isPending.value)
const error = computed(() => {
  const queryError = agentsQuery.error.value
  return queryError instanceof Error
    ? queryError.message
    : queryError
      ? 'Agenten konnten nicht geladen werden'
      : ''
})
const gateway = computed(() => overviewQuery.data.value?.connection ?? null)
const agentCount = computed(() => agents.value.length)
const hasAgents = computed(() => agents.value.length > 0)
const proposals = computed(() => proposalsQuery.data.value?.items ?? [])
const gatewayWarning = computed(() => gateway.value?.connected ? '' : gateway.value?.recovery || '')
const gatewayLabel = computed(() => {
  if (!gateway.value) return 'Gateway wird geprüft'
  if (!gateway.value.connected) return gateway.value.message || 'Gateway offline'
  if (gateway.value.versionPinned && !gateway.value.versionMatches) return 'Version drift'
  if (gateway.value.gatewayVersion) return `OpenClaw ${gateway.value.gatewayVersion}`
  return 'Gateway verbunden'
})
const gatewayChipClass = computed(() => {
  if (!gateway.value) return 'neutral'
  if (!gateway.value.connected) return 'error'
  if (!gateway.value.versionMatches) return 'warn'
  return 'ok'
})

function enrichAgent(item: OpenClawAgent): AgentCard {
  const fallback = fallbackAgents.find(a => a.id === item.id)
  const runtime = runtimeAgents.value.find(agent => agent.id === item.id)
  const statusKind = runtime?.status === 'work'
    ? 'connected'
    : runtime?.status === 'think'
      ? 'thinking'
      : runtime?.status === 'block'
        ? 'blocked'
        : 'ready'
  return {
    id: item.id,
    name: item.name || fallback?.name || item.id,
    role: runtime?.role || fallback?.role || 'Agent',
    description: item.description || fallback?.description || 'OpenClaw agent',
    tags: fallback?.tags ?? [],
    color: fallback?.color ?? 'var(--st-idle)',
    icon: fallback?.icon ?? 'bot',
    model: runtime?.model || item.model || undefined,
    statusLabel: runtime?.statusLabel || item.status,
    statusKind,
    statusDetail: runtime?.statusDetail,
    isActive: runtime?.status === 'work' || runtime?.status === 'think',
    progress: runtime?.progress,
    currentTask: runtime?.task,
  }
}

function goToAgent(id: string) {
  router.push(`/agents/${id}`)
}

function resolveIcon(iconName: string) {
  switch (iconName) {
    case 'bot': return Bot
    case 'code': return Code2
    case 'server': return Server
    case 'shield': return Shield
    case 'search': return Search
    case 'terminal': return Terminal
    default: return Bot
  }
}

function statusTone(agent: AgentCard) {
  switch (agent.statusKind) {
    case 'connected': return 'connected'
    case 'thinking': return 'thinking'
    case 'blocked': return 'blocked'
    case 'stale': return 'stale'
    case 'error': return 'error'
    case 'unsupported': return 'unsupported'
    default: return agent.isActive ? 'connected' : 'ready'
  }
}

function statusCopy(agent: AgentCard) {
  if (agent.statusDetail) return agent.statusDetail
  if (agent.currentTask) return agent.currentTask
  switch (agent.statusKind) {
    case 'connected': return 'Session ist erreichbar.'
    case 'thinking': return 'Agent plant den nächsten Schritt.'
    case 'blocked': return 'Agent wartet auf Entblockung.'
    case 'stale': return 'Es gab länger kein neues Signal.'
    case 'error': return 'Gateway konnte den Session-Status nicht lesen.'
    case 'unsupported': return 'Session meldet einen nicht unterstützten Zustand.'
    default: return 'Keine aktive Aufgabe gemeldet.'
  }
}

function formatProposalDate(value: string): string {
  const parsed = new Date(value)
  if (Number.isNaN(parsed.getTime())) return value
  return new Intl.DateTimeFormat('de-DE', {
    dateStyle: 'medium',
    timeStyle: 'short',
  }).format(parsed)
}

function proposalStatus(proposal: AgentProposalDto) {
  return getAgentProposalStatusMeta(proposal.status)
}

</script>

<template>
  <div class="agents-page nexus-page">
    <!-- Header -->
    <div class="page-header nexus-page-header">
      <div class="nexus-page-header__identity">
        <div class="header-icon-wrap nexus-page-header__icon">
          <Users :size="22" aria-hidden="true" />
        </div>
        <div class="header-text">
          <h1>Agents</h1>
          <p class="header-subtitle">{{ agentCount }} agents · {{ gatewayLabel }}</p>
        </div>
      </div>
      <div class="header-actions">
        <div class="gateway-chip nexus-status" :class="gatewayChipClass" role="status">
          <Wifi v-if="gateway?.connected" :size="13" aria-hidden="true" />
          <WifiOff v-else :size="13" aria-hidden="true" />
          {{ gateway?.gatewayVersion || gatewayLabel }}
        </div>
        <RouterLink v-if="isOwner" class="create-agent-link nexus-button nexus-button--primary" to="/agents/new">
          <Plus :size="16" aria-hidden="true" />
          Agent vorschlagen
        </RouterLink>
      </div>
    </div>

    <AsyncStatePanel
      v-if="loading"
      state="loading"
      title="Agenten werden geladen"
      compact
    />
    <AsyncStatePanel
      v-else-if="error"
      state="error"
      title="Agenten konnten nicht geladen werden"
      :problem="agentsQuery.error.value"
      compact
      @action="agentsQuery.refetch()"
    />
    <div v-if="gatewayWarning" class="gateway-warning nexus-state nexus-status--warning" role="status">
      {{ gatewayWarning }}
    </div>

    <section class="proposal-panel nexus-panel" aria-labelledby="agent-proposals-title">
      <div class="proposal-heading">
        <div>
          <span class="proposal-eyebrow">Approval Queue</span>
          <h2 id="agent-proposals-title">Agent-Vorschläge</h2>
          <p>Manuelle und von Iris vorbereitete Agenten werden vor der OpenClaw-Provisionierung sichtbar geprüft.</p>
        </div>
        <ClipboardList :size="20" aria-hidden="true" />
      </div>

      <div v-if="!isOwner" class="proposal-state proposal-state--empty">
        Agent-Vorschläge und OpenClaw-Provisionierung sind ausschließlich für Owner sichtbar.
      </div>
      <div v-else-if="proposalsQuery.isPending.value" class="proposal-state" role="status">
        Agent-Vorschläge werden geladen…
      </div>
      <div v-else-if="proposalsQuery.isError.value" class="proposal-state proposal-state--error" role="alert">
        <span>{{ proposalsQuery.error.value?.message || 'Agent-Vorschläge konnten nicht geladen werden.' }}</span>
        <button type="button" class="nexus-button" @click="proposalsQuery.refetch()">Erneut laden</button>
      </div>
      <div v-else-if="proposals.length" class="proposal-list">
        <RouterLink
          v-for="proposal in proposals"
          :key="proposal.id"
          class="proposal-row"
          :to="{ name: 'AgentProposalDetail', params: { proposalId: proposal.id } }"
        >
          <span class="proposal-avatar">
            <Bot :size="17" aria-hidden="true" />
          </span>
          <span class="proposal-copy">
            <strong>{{ proposal.requestedName }}</strong>
            <small>
              {{ proposal.source === 'iris' ? 'Von Iris vorbereitet' : `Von ${proposal.requestedBy}` }}
              · {{ formatProposalDate(proposal.updatedAt) }}
            </small>
          </span>
          <span
            class="proposal-status nexus-status"
            :class="`proposal-status--${proposalStatus(proposal).tone}`"
          >
            {{ proposalStatus(proposal).label }}
          </span>
          <ArrowRight :size="15" aria-hidden="true" />
        </RouterLink>
      </div>
      <div v-else class="proposal-state proposal-state--empty">
        <span>Noch keine Agent-Vorschläge. Bestehende OpenClaw-Agenten bleiben davon unberührt.</span>
        <RouterLink class="nexus-button" to="/agents/new">Ersten Vorschlag anlegen</RouterLink>
      </div>
    </section>

    <!-- Agent grid -->
    <div v-if="hasAgents" class="agents-grid nexus-grid">
      <article
        v-for="agent in agents"
        :key="agent.id"
        class="agent-card nexus-card nexus-card--interactive"
        :class="`status-${statusTone(agent)}`"
        :style="{ '--card-color': agent.color }"
        role="link"
        tabindex="0"
        :aria-label="`${agent.name}, ${agent.role}: View Profile`"
        @click="goToAgent(agent.id)"
        @keydown.enter="goToAgent(agent.id)"
        @keydown.space.prevent="goToAgent(agent.id)"
      >
        <div class="card-stripe"></div>
        <div class="card-content">
          <div class="card-header">
            <div class="card-icon-wrap">
              <component :is="resolveIcon(agent.icon)" :size="18" aria-hidden="true" />
            </div>
            <div class="card-info">
              <h3 class="card-name">{{ agent.name }}</h3>
              <span class="card-role">{{ agent.role }}</span>
            </div>
          </div>
          <p class="card-desc">{{ agent.description }}</p>
          <div class="agent-runtime">
            <span :class="['runtime-dot', statusTone(agent)]"></span>
            <span>{{ agent.statusLabel || (agent.isActive ? 'Arbeitet' : 'Bereit') }}</span>
            <span v-if="agent.model" class="runtime-model">{{ agent.model }}</span>
          </div>
          <p class="runtime-detail">{{ statusCopy(agent) }}</p>
          <div
            v-if="agent.progress !== null && agent.progress !== undefined"
            class="progress-track"
            :aria-label="`${agent.progress}% von OpenClaw gemeldet`"
          >
            <span :style="{ width: `${agent.progress ?? 0}%` }"></span>
          </div>
          <div class="card-tags">
            <span
              v-for="tag in agent.tags"
              :key="tag"
              class="card-tag"
            >
              {{ tag }}
            </span>
          </div>
        </div>
        <div class="card-footer">
          <span class="footer-label">View Profile</span>
          <ArrowRight class="footer-arrow" :size="14" aria-hidden="true" />
        </div>
      </article>
    </div>
    <AsyncStatePanel
      v-else-if="!loading"
      state="empty"
      title="Keine Agenten sichtbar"
      message="Mission Control hat aktuell keine Agenten erhalten. Prüfe Gateway-Erreichbarkeit und Agent-Konfiguration."
    />
  </div>
</template>

<style scoped>
.agents-page {
  max-width: 960px;
  margin: 0 auto;
  padding-bottom: 40px;
}

/* Page header */
.page-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 28px;
}
.header-icon-wrap {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  background: color-mix(in srgb, var(--a-mid) 10%, transparent);
  color: var(--a-mid);
  flex-shrink: 0;
}
.header-text h1 {
  margin: 0 0 2px;
  font-size: 22px;
  font-weight: 600;
  color: var(--tx);
}
.header-subtitle {
  margin: 0;
  font-size: 11px;
  color: var(--tx-3);
}
.gateway-chip {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--tx-2);
  font-size: 10px;
}
.gateway-chip.ok {
  color: var(--st-work);
  border-color: color-mix(in srgb, var(--st-work) 25%, transparent);
}
.gateway-chip.warn {
  color: var(--st-review);
  border-color: color-mix(in srgb, var(--st-review) 28%, transparent);
}
.gateway-chip.error {
  color: var(--st-block);
  border-color: color-mix(in srgb, var(--st-block) 30%, transparent);
}
.load-error {
  margin-bottom: 14px;
  color: var(--st-review);
  font-size: 11px;
}
.gateway-warning,
.empty-state {
  margin-bottom: 16px;
  padding: 14px 16px;
  border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--st-review) 24%, transparent);
  background: color-mix(in srgb, var(--st-review) 8%, transparent);
  color: var(--tx);
  font-size: 11px;
  line-height: 1.5;
}
.empty-state {
  border-color: var(--line);
  background: color-mix(in srgb, var(--tx) 3%, transparent);
  color: var(--tx-2);
}
.empty-state h3 {
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--tx);
}
.empty-state p {
  margin: 0;
}

/* Agent grid */
.agents-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 14px;
}

/* Agent card */
.agent-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}
.agent-card:hover {
  border-color: var(--card-color);
  box-shadow: 0 0 20px color-mix(in srgb, var(--card-color) 10%, transparent);
  transform: translateY(-2px);
}
.agent-card.status-error {
  border-color: color-mix(in srgb, var(--st-block) 22%, transparent);
}
.agent-card.status-unsupported {
  border-color: color-mix(in srgb, var(--st-review) 22%, transparent);
}
.agent-card.status-stale {
  border-color: color-mix(in srgb, var(--st-review) 22%, transparent);
}

.card-stripe {
  height: 3px;
  flex-shrink: 0;
}

.card-content {
  padding: 16px 16px 12px;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.card-icon-wrap {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  flex-shrink: 0;
}

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

.card-name {
  margin: 0 0 1px;
  font-size: 13px;
  font-weight: 600;
  color: var(--tx);
}

.card-role {
  display: block;
  font-size: 9px;
  color: var(--tx-3);
  letter-spacing: 0.02em;
}

.card-desc {
  font-size: 10.5px;
  color: var(--tx-3);
  line-height: 1.5;
  margin: 0 0 10px;
  flex: 1;
}
.agent-runtime {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  color: var(--tx-3);
  font-size: 9.5px;
  min-width: 0;
}
.runtime-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--tx-3);
  flex-shrink: 0;
}
.runtime-dot.on {
  background: var(--st-work);
}
.runtime-dot.connected { background: var(--st-work); }
.runtime-dot.thinking { background: var(--a-mid); }
.runtime-dot.blocked { background: var(--st-block); }
.runtime-dot.stale { background: var(--st-queue); }
.runtime-dot.error { background: var(--st-block); }
.runtime-dot.unsupported { background: var(--st-review); }
.runtime-dot.ready { background: var(--tx-3); }
.runtime-model {
  margin-left: auto;
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
  color: var(--tx-3);
}
.runtime-detail {
  margin: 0 0 10px;
  min-height: 28px;
  color: var(--tx-3);
  font-size: 10px;
  line-height: 1.4;
}
.progress-track {
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tx) 6%, transparent);
  overflow: hidden;
  margin-bottom: 10px;
}
.progress-track span {
  display: block;
  height: 100%;
  border-radius: inherit;
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.card-tag {
  display: inline-block;
  font-size: 8.5px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 4px;
  border: 1px solid transparent;
  letter-spacing: 0.02em;
}

.card-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  padding: 8px 16px;
  border-top: 1px solid var(--line);
  font-size: 9px;
  font-weight: 600;
  color: var(--tx-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: color 0.15s;
}
.agent-card:hover .card-footer {
  color: var(--card-color);
}

.footer-arrow {
  font-size: 12px;
  line-height: 1;
}

/* Responsive */
@media (max-width: 820px) {
  .agents-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 540px) {
  .agents-grid {
    grid-template-columns: 1fr;
  }
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
}

/* V2 presentation contract */
.agents-page {
  max-width: none;
  padding-bottom: 40px;
}

.page-header {
  align-items: center;
  margin-bottom: 0;
}

.header-icon-wrap {
  color: var(--a-mid);
}

.header-text h1 {
  margin: 0;
}

.header-subtitle {
  margin: 3px 0 0;
  color: var(--tx-2);
}

.gateway-chip {
  flex: 0 0 auto;
  margin-left: 0;
  color: var(--tx-2);
  font-size: 11px;
}

.gateway-chip.ok {
  color: var(--st-work);
  border-color: var(--status-work-line);
  background: var(--status-work-bg);
}

.gateway-chip.warn {
  color: var(--st-queue);
  border-color: var(--status-queue-line);
  background: var(--status-queue-bg);
}

.gateway-chip.error {
  color: var(--st-block);
  border-color: var(--status-block-line);
  background: var(--status-block-bg);
}

.load-error,
.gateway-warning,
.empty-state {
  margin: 0;
  color: var(--tx-2);
  font-size: 12px;
}

.empty-state {
  border-color: var(--line);
  background: var(--glass);
}

.empty-state h3 {
  color: var(--tx);
}

.agents-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.agent-card {
  background: var(--glass);
  border-color: var(--line);
  border-radius: var(--r);
}

.agent-card:hover {
  border-color: var(--card-color);
  box-shadow: 0 0 24px color-mix(in srgb, var(--card-color) 18%, transparent);
}

.agent-card.status-error {
  border-color: var(--status-block-line);
}

.agent-card.status-unsupported,
.agent-card.status-stale {
  border-color: var(--status-queue-line);
}

.card-stripe {
  background: var(--card-color);
}

.card-content {
  padding: 17px 17px 13px;
}

.card-icon-wrap {
  border: 1px solid color-mix(in srgb, var(--card-color) 24%, transparent);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--card-color) 10%, transparent);
  color: var(--card-color);
}

.card-name {
  color: var(--tx);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 650;
}

.card-role,
.runtime-model {
  color: var(--tx-3);
  font-family: var(--font-mono-v2);
  font-size: 11px;
}

.card-desc,
.runtime-detail {
  color: var(--tx-2);
  font-size: 12px;
}

.agent-runtime {
  color: var(--tx-2);
  font-family: var(--font-mono-v2);
  font-size: 11px;
}

.runtime-dot {
  background: var(--st-idle);
}

.runtime-dot.on,
.runtime-dot.connected {
  background: var(--st-work);
}

.runtime-dot.thinking {
  background: var(--st-think);
}

.runtime-dot.blocked,
.runtime-dot.error {
  background: var(--st-block);
}

.runtime-dot.stale,
.runtime-dot.unsupported {
  background: var(--st-queue);
}

.runtime-dot.ready {
  background: var(--st-idle);
}

.progress-track {
  height: 4px;
  background: var(--line);
}

.progress-track span {
  background: var(--card-color);
}

.card-tag {
  padding: 3px 7px;
  border-color: color-mix(in srgb, var(--card-color) 24%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--card-color) 8%, transparent);
  color: var(--card-color);
  font-family: var(--font-mono-v2);
  font-size: 11px;
}

.card-footer {
  color: var(--tx-3);
  font-family: var(--font-mono-v2);
  font-size: 11px;
}

.footer-arrow {
  flex: 0 0 auto;
}

.header-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.header-actions .gateway-chip {
  margin-left: 0;
}

.create-agent-link {
  text-decoration: none;
}

.proposal-panel {
  display: grid;
  gap: 14px;
}

.proposal-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding-bottom: 13px;
  border-bottom: 1px solid var(--line);
}

.proposal-heading > svg {
  color: var(--a-mid);
}

.proposal-eyebrow {
  display: block;
  margin-bottom: 4px;
  color: var(--a-mid);
  font-family: var(--font-mono-v2);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.proposal-heading h2 {
  margin: 0;
  font-size: 16px;
}

.proposal-heading p {
  max-width: 720px;
  margin: 5px 0 0;
  color: var(--tx-2);
  line-height: 1.5;
}

.proposal-list {
  display: grid;
}

.proposal-row {
  min-height: 64px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 6px;
  border-bottom: 1px solid var(--line);
  color: var(--tx);
  text-decoration: none;
}

.proposal-row:last-child {
  border-bottom: 0;
}

.proposal-row:hover,
.proposal-row:focus-visible {
  color: var(--tx);
  background: var(--accent-wash);
  outline: none;
}

.proposal-avatar {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--grad-soft);
  color: var(--a-mid);
}

.proposal-copy {
  display: grid;
  gap: 4px;
}

.proposal-copy strong {
  font-family: var(--font-display);
  font-size: 13px;
}

.proposal-copy small {
  color: var(--tx-3);
  font-family: var(--font-mono-v2);
  font-size: 10px;
}

.proposal-status {
  font-family: var(--font-mono-v2);
  font-size: 10px;
  white-space: nowrap;
}

.proposal-status--success {
  border-color: var(--status-work-line);
  background: var(--status-work-bg);
  color: var(--st-work);
}

.proposal-status--info {
  border-color: var(--status-think-line);
  background: var(--status-think-bg);
  color: var(--st-think);
}

.proposal-status--warning {
  border-color: var(--status-queue-line);
  background: var(--status-queue-bg);
  color: var(--st-queue);
}

.proposal-status--danger {
  border-color: var(--status-block-line);
  background: var(--status-block-bg);
  color: var(--st-block);
}

.proposal-state {
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--tx-2);
}

.proposal-state--error {
  color: var(--st-block);
}

.proposal-state a {
  text-decoration: none;
}

@media (max-width: 1024px) {
  .agents-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .agents-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .page-header {
    align-items: stretch;
  }

  .header-actions {
    justify-content: flex-start;
    padding-left: 51px;
  }

  .proposal-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .proposal-status {
    grid-column: 2;
    grid-row: 2;
  }

  .proposal-row > svg {
    grid-column: 3;
    grid-row: 1 / span 2;
  }

  .proposal-state {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>
