<script setup lang="ts">
/**
 * Protocoles & Fonctionnement — Boîte à outils de vote.
 *
 * Liste les protocoles de vote avec SectionLayout,
 * sidebar n8n workflow + simulateur de formules.
 */
const protocols = useProtocolsStore()
const auth = useAuthStore()

const activeStatus = ref<string | null>(null)
const searchQuery = ref('')
const showCreateModal = ref(false)
const creating = ref(false)

const newProtocol = reactive({
  name: '',
  description: '',
  vote_type: 'binary',
  formula_config_id: '',
})

onMounted(async () => {
  await Promise.all([
    protocols.fetchProtocols(),
    protocols.fetchFormulas(),
  ])
})

const voteTypeLabel = (voteType: string) => {
  switch (voteType) {
    case 'binary': return 'Binaire'
    case 'nuanced': return 'Nuancé'
    default: return voteType
  }
}

const voteTypeOptions = [
  { label: 'Binaire (Pour/Contre)', value: 'binary' },
  { label: 'Nuancé (6 niveaux)', value: 'nuanced' },
]

const formulaOptions = computed(() => {
  return protocols.formulas.map(f => ({
    label: f.name,
    value: f.id,
  }))
})

/** Status pills. */
const statuses = computed(() => [
  {
    id: 'binary',
    label: 'Binaire',
    count: protocols.protocols.filter(p => p.vote_type === 'binary').length,
    cssClass: 'status-vote',
  },
  {
    id: 'nuanced',
    label: 'Nuancé',
    count: protocols.protocols.filter(p => p.vote_type === 'nuanced').length,
    cssClass: 'status-prepa',
  },
])

/** Filtered protocols. */
const filteredProtocols = computed(() => {
  let list = [...protocols.protocols]

  if (activeStatus.value) {
    list = list.filter(p => p.vote_type === activeStatus.value)
  }

  if (searchQuery.value.trim()) {
    const q = searchQuery.value.toLowerCase()
    list = list.filter(p =>
      p.name.toLowerCase().includes(q)
      || (p.description && p.description.toLowerCase().includes(q)),
    )
  }

  return list
})

function openCreateModal() {
  newProtocol.name = ''
  newProtocol.description = ''
  newProtocol.vote_type = 'binary'
  newProtocol.formula_config_id = ''
  showCreateModal.value = true
}

async function createProtocol() {
  if (!newProtocol.name.trim() || !newProtocol.formula_config_id) return

  creating.value = true
  try {
    await protocols.createProtocol({
      name: newProtocol.name.trim(),
      description: newProtocol.description.trim() || null,
      vote_type: newProtocol.vote_type,
      formula_config_id: newProtocol.formula_config_id,
    })
    showCreateModal.value = false
    await protocols.fetchProtocols()
  }
  finally {
    creating.value = false
  }
}

/** Operational protocols (workflow templates). */
interface WorkflowStep {
  label: string
  actor: string
  icon: string
  type: string
}

interface LinkedRef {
  label: string
  icon: string
  to: string
  kind: 'document' | 'decision'
}

interface OperationalProtocol {
  slug: string
  name: string
  description: string
  category: string
  icon: string
  instancesLabel: string
  linkedRefs: LinkedRef[]
  steps: WorkflowStep[]
}

const operationalProtocols: OperationalProtocol[] = [
  {
    slug: 'embarquement-forgeron',
    name: 'Embarquement Forgeron',
    description: 'Processus complet d\'intégration d\'un nouveau forgeron dans le réseau Duniter. Parcours en 5 jalons de la candidature à la mise en ligne du nœud validateur.',
    category: 'onboarding',
    icon: 'i-lucide-hammer',
    instancesLabel: '~10-50 / an',
    linkedRefs: [
      { label: 'Acte d\'engagement forgeron', icon: 'i-lucide-book-open', to: '/documents/engagement-forgeron', kind: 'document' },
    ],
    steps: [
      { label: 'Candidature', actor: 'Aspirant forgeron', icon: 'i-lucide-user-plus', type: 'checklist' },
      { label: 'Nœud miroir', actor: 'Candidat', icon: 'i-lucide-server', type: 'on_chain' },
      { label: 'Évaluation technique', actor: 'Certificateur', icon: 'i-lucide-clipboard-check', type: 'checklist' },
      { label: 'Certification Smith (×3)', actor: 'Certificateurs', icon: 'i-lucide-stamp', type: 'certification' },
      { label: 'Go online', actor: 'Candidat', icon: 'i-lucide-wifi', type: 'on_chain' },
    ],
  },
  {
    slug: 'soumission-runtime-upgrade',
    name: 'Soumission Runtime Upgrade',
    description: 'Protocole de soumission d\'une mise à jour du runtime Duniter V2 on-chain. Chaque upgrade suit un parcours strict en 5 étapes, de la qualification technique au suivi post-déploiement.',
    category: 'on-chain',
    icon: 'i-lucide-cpu',
    instancesLabel: '~2-6 / an',
    linkedRefs: [
      { label: 'Décision Runtime Upgrade', icon: 'i-lucide-scale', to: '/decisions', kind: 'decision' },
    ],
    steps: [
      { label: 'Qualification', actor: 'Proposant', icon: 'i-lucide-file-check', type: 'checklist' },
      { label: 'Revue technique', actor: 'Comité technique', icon: 'i-lucide-search', type: 'checklist' },
      { label: 'Vote communautaire', actor: 'Communauté WoT', icon: 'i-lucide-vote', type: 'on_chain' },
      { label: 'Exécution on-chain', actor: 'Proposant', icon: 'i-lucide-zap', type: 'on_chain' },
      { label: 'Suivi post-upgrade', actor: 'Forgerons', icon: 'i-lucide-activity', type: 'checklist' },
    ],
  },
]

/** n8n workflow demo items. */
const n8nWorkflows = [
  {
    name: 'Vote -> Notification',
    description: 'Notifie les membres lorsqu\'un nouveau vote démarre ou se termine.',
    icon: 'i-lucide-bell',
    status: 'actif',
  },
  {
    name: 'Seuil atteint -> Sanctuaire',
    description: 'Archive automatiquement le document valide sur IPFS quand le seuil est atteint.',
    icon: 'i-lucide-archive',
    status: 'actif',
  },
  {
    name: 'Décision → Étape suivante',
    description: 'Avance automatiquement une décision à l\'étape suivante après validation.',
    icon: 'i-lucide-git-branch',
    status: 'demo',
  },
  {
    name: 'Mandat expiré → Alerte',
    description: 'Envoie une alerte 7 jours avant l\'expiration d\'un mandat.',
    icon: 'i-lucide-alarm-clock',
    status: 'demo',
  },
]
</script>

<template>
  <SectionLayout
    title="Protocoles & Fonctionnement"
    subtitle="Boîte à outils de vote, formules de seuil, workflows automatisés"
    :statuses="statuses"
    :active-status="activeStatus"
    @update:active-status="activeStatus = $event"
  >
    <!-- Search slot -->
    <template #search>
      <input
        v-model="searchQuery"
        type="text"
        class="proto-search"
        placeholder="Rechercher un protocole..."
      />
      <button
        v-if="auth.isAuthenticated"
        class="proto-add-btn"
        @click="openCreateModal"
      >
        <UIcon name="i-lucide-plus" class="text-xs" />
        <span>Nouveau</span>
      </button>
    </template>

    <!-- Loading -->
    <template v-if="protocols.loading">
      <div class="proto-loading">
        <LoadingSkeleton v-for="i in 3" :key="i" :lines="4" card />
      </div>
    </template>

    <!-- Error -->
    <template v-else-if="protocols.error">
      <div class="proto-error">
        <UIcon name="i-lucide-alert-circle" class="text-lg" />
        <span>{{ protocols.error }}</span>
      </div>
    </template>

    <!-- Protocol list -->
    <template v-else>
      <div v-if="filteredProtocols.length === 0" class="proto-empty">
        <UIcon name="i-lucide-settings" class="text-2xl" />
        <p>Aucun protocole trouvé</p>
      </div>

      <div v-else class="proto-list">
        <NuxtLink
          v-for="protocol in filteredProtocols"
          :key="protocol.id"
          :to="`/protocols/${protocol.id}`"
          class="proto-item"
        >
          <div class="proto-item__left">
            <div class="proto-item__icon">
              <UIcon
                :name="protocol.vote_type === 'nuanced' ? 'i-lucide-bar-chart-3' : 'i-lucide-check-circle'"
                class="text-lg"
              />
            </div>
          </div>
          <div class="proto-item__body">
            <div class="proto-item__head">
              <h3 class="proto-item__name">{{ protocol.name }}</h3>
              <span class="proto-item__type" :class="protocol.vote_type === 'nuanced' ? 'proto-item__type--nuanced' : ''">
                {{ voteTypeLabel(protocol.vote_type) }}
              </span>
            </div>
            <p v-if="protocol.description" class="proto-item__desc">
              {{ protocol.description }}
            </p>
            <div class="proto-item__meta">
              <span v-if="protocol.mode_params" class="proto-item__params">
                {{ protocol.mode_params }}
              </span>
              <span class="proto-item__formula">
                {{ protocol.formula_config.name }}
              </span>
              <span class="proto-item__detail">
                {{ protocol.formula_config.duration_days }}j · {{ protocol.formula_config.majority_pct }}%
              </span>
            </div>
          </div>
          <div class="proto-item__arrow">
            <UIcon name="i-lucide-chevron-right" class="text-sm" />
          </div>
        </NuxtLink>
      </div>

      <!-- Formulas table -->
      <div class="proto-formulas">
        <h3 class="proto-formulas__title">
          <UIcon name="i-lucide-calculator" class="text-sm" />
          Configurations de formule
          <span class="proto-formulas__count">{{ protocols.formulas.length }}</span>
        </h3>
        <div class="proto-formulas__table-wrap">
          <table class="proto-formulas__table">
            <thead>
              <tr>
                <th>Nom</th>
                <th>Durée</th>
                <th>Majorité</th>
                <th>B</th>
                <th>G</th>
                <th>Smith</th>
                <th>TechComm</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="formula in protocols.formulas" :key="formula.id">
                <td class="proto-formulas__name">{{ formula.name }}</td>
                <td>{{ formula.duration_days }}j</td>
                <td>{{ formula.majority_pct }}%</td>
                <td>{{ formula.base_exponent }}</td>
                <td>{{ formula.gradient_exponent }}</td>
                <td>{{ formula.smith_exponent ?? '-' }}</td>
                <td>{{ formula.techcomm_exponent ?? '-' }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </template>

    <!-- Operational protocols (always visible, frontend-only data) -->
    <div class="proto-ops">
      <h3 class="proto-ops__title">
        <UIcon name="i-lucide-git-branch" class="text-sm" />
        Protocoles opérationnels
        <span class="proto-ops__count">{{ operationalProtocols.length }}</span>
      </h3>

      <div
        v-for="op in operationalProtocols"
        :key="op.slug"
        class="proto-ops__card"
      >
        <div class="proto-ops__card-head">
          <div class="proto-ops__card-icon">
            <UIcon :name="op.icon" class="text-lg" />
          </div>
          <div class="proto-ops__card-info">
            <h4 class="proto-ops__card-name">{{ op.name }}</h4>
            <p class="proto-ops__card-desc">{{ op.description }}</p>
            <span class="proto-ops__card-meta">{{ op.instancesLabel }}</span>
          </div>
        </div>

        <!-- Linked references -->
        <div v-if="op.linkedRefs.length > 0" class="proto-ops__refs">
          <NuxtLink
            v-for="ref in op.linkedRefs"
            :key="ref.to"
            :to="ref.to"
            class="proto-ops__ref"
            :class="`proto-ops__ref--${ref.kind}`"
          >
            <UIcon :name="ref.icon" class="text-xs" />
            <span>{{ ref.label }}</span>
            <UIcon name="i-lucide-arrow-right" class="text-xs proto-ops__ref-arrow" />
          </NuxtLink>
        </div>

        <!-- Step timeline -->
        <div class="proto-ops__timeline">
          <div
            v-for="(step, idx) in op.steps"
            :key="idx"
            class="proto-ops__step"
          >
            <div class="proto-ops__step-dot" :class="`proto-ops__step-dot--${step.type}`">
              <UIcon :name="step.icon" class="text-xs" />
            </div>
            <div class="proto-ops__step-body">
              <span class="proto-ops__step-label">{{ step.label }}</span>
              <span class="proto-ops__step-actor">{{ step.actor }}</span>
            </div>
            <div v-if="idx < op.steps.length - 1" class="proto-ops__step-line" />
          </div>
        </div>
      </div>
    </div>

    <!-- Toolbox sidebar -->
    <template #toolbox>
      <!-- Workflow milestones -->
      <ToolboxSection title="Jalons de protocole" icon="i-lucide-git-branch">
        <WorkflowMilestones />
      </ToolboxSection>

      <!-- Simulateur -->
      <ToolboxVignette
        title="Simulateur de formules"
        :bullets="['WoT, Smith, TechComm', 'Paramètres en temps réel', 'Visualise les seuils']"
        :actions="[
          { label: 'Ouvrir', icon: 'i-lucide-calculator', to: '/protocols/formulas', primary: true },
        ]"
      />

      <!-- n8n Workflows -->
      <ToolboxSection title="Automatisations" icon="i-lucide-workflow">
        <div class="n8n-workflows">
          <div
            v-for="wf in n8nWorkflows"
            :key="wf.name"
            class="n8n-wf"
          >
            <div class="n8n-wf__icon">
              <UIcon :name="wf.icon" class="text-xs" />
            </div>
            <div class="n8n-wf__body">
              <div class="n8n-wf__head">
                <span class="n8n-wf__name">{{ wf.name }}</span>
                <span
                  class="n8n-wf__status"
                  :class="wf.status === 'actif' ? 'n8n-wf__status--active' : 'n8n-wf__status--demo'"
                >
                  {{ wf.status }}
                </span>
              </div>
              <p class="n8n-wf__desc">{{ wf.description }}</p>
            </div>
          </div>
        </div>
      </ToolboxSection>

      <!-- Meta-gouvernance -->
      <ToolboxVignette
        title="Méta-gouvernance"
        :bullets="['Les formules sont soumises au vote', 'Seuils modifiables collectivement', 'Transparence totale']"
        :actions="[
          { label: 'Démarrer', icon: 'i-lucide-play', emit: 'meta', primary: true },
        ]"
      />
    </template>
  </SectionLayout>

  <!-- Create protocol modal -->
  <UModal v-model:open="showCreateModal">
    <template #content>
      <div class="proto-modal">
        <h3 class="proto-modal__title">Nouveau protocole de vote</h3>

        <div class="proto-modal__fields">
          <div class="proto-modal__field">
            <label class="proto-modal__label">Nom du protocole</label>
            <input
              v-model="newProtocol.name"
              type="text"
              class="proto-modal__input"
              placeholder="Ex: Vote standard G1"
            />
          </div>

          <div class="proto-modal__field">
            <label class="proto-modal__label">Description</label>
            <textarea
              v-model="newProtocol.description"
              class="proto-modal__textarea"
              placeholder="Description du protocole..."
              rows="2"
            />
          </div>

          <div class="proto-modal__field">
            <label class="proto-modal__label">Type de vote</label>
            <USelect
              v-model="newProtocol.vote_type"
              :items="voteTypeOptions"
              value-key="value"
            />
          </div>

          <div class="proto-modal__field">
            <label class="proto-modal__label">Configuration de formule</label>
            <USelect
              v-model="newProtocol.formula_config_id"
              :items="formulaOptions"
              placeholder="Sélectionnez une formule..."
              value-key="value"
            />
          </div>
        </div>

        <div class="proto-modal__actions">
          <button class="proto-modal__cancel" @click="showCreateModal = false">
            Annuler
          </button>
          <button
            class="proto-modal__submit"
            :disabled="!newProtocol.name.trim() || !newProtocol.formula_config_id || creating"
            @click="createProtocol"
          >
            <UIcon v-if="creating" name="i-lucide-loader-2" class="animate-spin text-xs" />
            <span>Créer</span>
          </button>
        </div>
      </div>
    </template>
  </UModal>
</template>

<style scoped>
/* --- Search --- */
.proto-search {
  flex: 1;
  min-width: 10rem;
  padding: 0.625rem 1rem;
  font-size: 0.9375rem;
  color: var(--mood-text);
  background: var(--mood-accent-soft);
  border-radius: 12px;
  outline: none;
  transition: box-shadow 0.15s ease;
}
.proto-search:focus {
  box-shadow: 0 0 0 3px var(--mood-accent-soft);
}
.proto-search::placeholder {
  color: var(--mood-text-muted);
  opacity: 0.4;
}

.proto-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.625rem 1.25rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--mood-accent-text);
  background: var(--mood-accent);
  border-radius: 20px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.proto-add-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px var(--mood-shadow);
}

/* --- States --- */
.proto-loading { display: flex; flex-direction: column; gap: 0.75rem; }
.proto-error {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 1rem 1.25rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--mood-error);
  background: rgba(196, 43, 43, 0.08);
  border-radius: 16px;
}
.proto-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 3rem;
  text-align: center;
  color: var(--mood-text-muted);
  font-size: 1rem;
}

/* --- Protocol list --- */
.proto-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.proto-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem;
  background: var(--mood-surface);
  border-radius: 16px;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

@media (min-width: 640px) {
  .proto-item {
    gap: 1rem;
    padding: 1.25rem;
  }
}

.proto-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 24px var(--mood-shadow);
}

.proto-item:active {
  transform: translateY(0);
}

.proto-item__left { flex-shrink: 0; }

.proto-item__icon {
  width: 2.25rem;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
  font-size: 1rem;
}

@media (min-width: 640px) {
  .proto-item__icon {
    width: 2.75rem;
    height: 2.75rem;
    font-size: 1.25rem;
  }
}

.proto-item__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

@media (min-width: 640px) {
  .proto-item__body {
    gap: 0.375rem;
  }
}

.proto-item__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.375rem;
}

@media (min-width: 640px) {
  .proto-item__head {
    gap: 0.625rem;
  }
}

.proto-item__name {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--mood-text);
  margin: 0;
}

@media (min-width: 640px) {
  .proto-item__name {
    font-size: 1.0625rem;
  }
}

.proto-item__type {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 10px;
  border-radius: 20px;
  background: var(--mood-status-vote-bg);
  color: var(--mood-status-vote);
}
.proto-item__type--nuanced {
  background: var(--mood-status-prepa-bg);
  color: var(--mood-status-prepa);
}

.proto-item__desc {
  font-size: 0.875rem;
  color: var(--mood-text-muted);
  line-height: 1.5;
  margin: 0;
}

.proto-item__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.125rem;
  font-size: 0.75rem;
  color: var(--mood-text-muted);
}

@media (min-width: 640px) {
  .proto-item__meta {
    gap: 0.5rem;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
  }
}

.proto-item__params {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-weight: 700;
  color: var(--mood-accent);
  background: var(--mood-accent-soft);
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 0.75rem;
}

.proto-item__formula {
  font-weight: 600;
}

.proto-item__detail {
  opacity: 0.7;
}

.proto-item__arrow {
  flex-shrink: 0;
  color: var(--mood-text-muted);
  opacity: 0.3;
  margin-top: 0.375rem;
  transition: opacity 0.12s;
}
.proto-item:hover .proto-item__arrow {
  opacity: 1;
  color: var(--mood-accent);
}

/* --- Formulas --- */
.proto-formulas {
  margin-top: 0.75rem;
}

@media (min-width: 640px) {
  .proto-formulas {
    margin-top: 1rem;
  }
}

.proto-formulas__title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--mood-text);
  margin: 0 0 0.5rem;
}

@media (min-width: 640px) {
  .proto-formulas__title {
    font-size: 1rem;
    margin: 0 0 0.75rem;
  }
}

.proto-formulas__count {
  font-size: 0.6875rem;
  font-weight: 700;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
  padding: 2px 8px;
  border-radius: 20px;
}

.proto-formulas__table-wrap {
  background: var(--mood-surface);
  border-radius: 16px;
  overflow-x: auto;
}

.proto-formulas__table {
  width: 100%;
  font-size: 0.875rem;
  border-collapse: collapse;
}

.proto-formulas__table th {
  text-align: left;
  padding: 0.5rem 0.625rem;
  font-weight: 700;
  font-size: 0.6875rem;
  color: var(--mood-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

@media (min-width: 640px) {
  .proto-formulas__table th {
    padding: 0.75rem 1rem;
    font-size: 0.75rem;
  }
}

.proto-formulas__table td {
  padding: 0.5rem 0.625rem;
  color: var(--mood-text-muted);
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 0.75rem;
}

@media (min-width: 640px) {
  .proto-formulas__table td {
    padding: 0.75rem 1rem;
    font-size: 0.8125rem;
  }
}

.proto-formulas__name {
  font-weight: 700;
  color: var(--mood-text) !important;
  font-family: inherit !important;
}

.n8n-workflows {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-top: 0.25rem;
}

.n8n-wf {
  display: flex;
  gap: 0.5rem;
  padding: 0.5rem;
  border-radius: 10px;
  transition: background 0.1s;
}
.n8n-wf:hover {
  background: var(--mood-surface);
}

.n8n-wf__icon {
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--mood-surface);
  color: var(--mood-tertiary, var(--mood-accent));
}

.n8n-wf__body {
  min-width: 0;
  flex: 1;
}

.n8n-wf__head {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.n8n-wf__name {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--mood-text);
}

.n8n-wf__status {
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 20px;
}
.n8n-wf__status--active {
  background: var(--mood-status-vigueur-bg);
  color: var(--mood-success);
}
.n8n-wf__status--demo {
  background: var(--mood-surface);
  color: var(--mood-text-muted);
}

.n8n-wf__desc {
  font-size: 0.6875rem;
  color: var(--mood-text-muted);
  line-height: 1.4;
  margin: 0;
}

/* --- Operational protocols --- */
.proto-ops {
  margin-top: 1.5rem;
}

.proto-ops__title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--mood-text);
  margin: 0 0 0.75rem;
}

.proto-ops__count {
  font-size: 0.6875rem;
  font-weight: 700;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
  padding: 2px 8px;
  border-radius: 20px;
}

.proto-ops__card {
  background: var(--mood-surface);
  border-radius: 16px;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.proto-ops__card-head {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.proto-ops__card-icon {
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
}

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

.proto-ops__card-name {
  font-size: 1.0625rem;
  font-weight: 800;
  color: var(--mood-text);
  margin: 0;
}

.proto-ops__card-desc {
  font-size: 0.8125rem;
  color: var(--mood-text-muted);
  line-height: 1.4;
  margin: 0.125rem 0 0;
}

.proto-ops__card-meta {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--mood-accent);
  opacity: 0.7;
}

/* Linked references */
.proto-ops__refs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.proto-ops__ref {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 20px;
  text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.proto-ops__ref:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px var(--mood-shadow);
}

.proto-ops__ref--document {
  background: color-mix(in srgb, var(--mood-accent) 12%, transparent);
  color: var(--mood-accent);
}

.proto-ops__ref--decision {
  background: color-mix(in srgb, var(--mood-secondary, var(--mood-accent)) 12%, transparent);
  color: var(--mood-secondary, var(--mood-accent));
}

.proto-ops__ref-arrow {
  opacity: 0.4;
  transition: opacity 0.12s;
}

.proto-ops__ref:hover .proto-ops__ref-arrow {
  opacity: 1;
}

/* Timeline */
.proto-ops__timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding-left: 0.25rem;
}

.proto-ops__step {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  position: relative;
  padding: 0.375rem 0;
}

.proto-ops__step-dot {
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--mood-accent-soft);
  color: var(--mood-accent);
  z-index: 1;
}

.proto-ops__step-dot--on_chain {
  background: color-mix(in srgb, var(--mood-success) 15%, transparent);
  color: var(--mood-success);
}

.proto-ops__step-dot--checklist {
  background: color-mix(in srgb, var(--mood-warning) 15%, transparent);
  color: var(--mood-warning);
}

.proto-ops__step-dot--certification {
  background: color-mix(in srgb, var(--mood-secondary) 15%, transparent);
  color: var(--mood-secondary, var(--mood-accent));
}

.proto-ops__step-body {
  display: flex;
  flex-direction: column;
}

.proto-ops__step-label {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--mood-text);
}

.proto-ops__step-actor {
  font-size: 0.6875rem;
  color: var(--mood-text-muted);
}

.proto-ops__step-line {
  position: absolute;
  left: calc(0.875rem - 1px);
  top: calc(0.375rem + 1.75rem);
  width: 2px;
  height: calc(100% - 1.75rem + 0.375rem);
  background: color-mix(in srgb, var(--mood-accent) 15%, transparent);
}

/* --- Modal --- */
.proto-modal {
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

@media (min-width: 640px) {
  .proto-modal {
    padding: 2rem;
    gap: 1.5rem;
  }
}

.proto-modal__title {
  font-size: 1.125rem;
  font-weight: 800;
  color: var(--mood-text);
  margin: 0;
}

@media (min-width: 640px) {
  .proto-modal__title {
    font-size: 1.375rem;
  }
}

.proto-modal__fields {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.proto-modal__field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.proto-modal__label {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--mood-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.proto-modal__input,
.proto-modal__textarea {
  width: 100%;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
  color: var(--mood-text);
  background: var(--mood-accent-soft);
  border-radius: 12px;
  outline: none;
  transition: box-shadow 0.15s ease;
  font-family: inherit;
  resize: vertical;
}
.proto-modal__input:focus,
.proto-modal__textarea:focus {
  box-shadow: 0 0 0 3px var(--mood-accent-soft);
}

.proto-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
}

.proto-modal__cancel {
  padding: 0.625rem 1.25rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--mood-text-muted);
  background: none;
  border-radius: 12px;
  cursor: pointer;
}
.proto-modal__cancel:hover { color: var(--mood-text); background: var(--mood-accent-soft); }

.proto-modal__submit {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.625rem 1.5rem;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--mood-accent-text);
  background: var(--mood-accent);
  border-radius: 16px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.proto-modal__submit:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px var(--mood-shadow);
}
.proto-modal__submit:disabled { opacity: 0.4; cursor: not-allowed; }
</style>
