<!--
|--------------------------------------------------------------------------
| DevRoadmapTab.vue — Fases + Items (CRUD + drag-drop + editar fase)
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, computed, onMounted } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import ConfirmDialog from 'primevue/confirmdialog';
import DevDrawer from './components/DevDrawer.vue';
import DevField from './components/DevField.vue';
import BlocoItems from './components/BlocoItems.vue';
import { reorderWithIndexes } from './composables/useDraggableList';

const toast = useToast();
const confirm = useConfirm();

const loading = ref(true);
const phases = ref([]);
const items = ref([]);
const activePhase = ref(null);
const filterStatus = ref('all');
const filterPrior = ref('all');
const search = ref('');

// Drawer item
const itemDrawerOpen = ref(false);
const itemSaving = ref(false);
const itemEditingId = ref(null);
const itemForm = ref(emptyItemForm());

// Drawer phase
const phaseDrawerOpen = ref(false);
const phaseSaving = ref(false);
const phaseEditingId = ref(null);
const phaseForm = ref(emptyPhaseForm());

function emptyItemForm() {
    return {
        phase_id: null,
        numero: null,
        bloco: '',
        feature: '',
        descricao: '',
        esforco: 'M',
        prioridade: 'alta',
        status: 'pendente',
        notas: '',
        assignee: '',
        data_inicio: null,
        data_conclusao: null
    };
}

function emptyPhaseForm() {
    return {
        numero: null,
        nome: '',
        objetivo: '',
        timeline_sugerida: '',
        criterio_saida: '',
        status: 'planejada',
        data_inicio: null,
        data_fim: null
    };
}

const STATUS_LABEL = {
    pendente: { label: 'Pendente', color: 'var(--text-color-secondary)', bg: 'var(--surface-border)' },
    em_andamento: { label: 'Em andamento', color: '#f59e0b', bg: 'rgba(245,158,11,.15)' },
    concluido: { label: 'Concluído', color: '#10b981', bg: 'rgba(16,185,129,.15)' },
    cancelado: { label: 'Cancelado', color: '#94a3b8', bg: 'rgba(148,163,184,.15)' },
    bloqueado: { label: 'Bloqueado', color: '#ef4444', bg: 'rgba(239,68,68,.15)' }
};

const PRIOR_LABEL = {
    bloqueador: { label: 'Bloqueador', color: '#ef4444' },
    alta: { label: 'Alta', color: '#f59e0b' },
    media: { label: 'Média', color: '#0ea5e9' },
    diferencial: { label: 'Diferencial', color: '#a855f7' }
};

const ESFORCO_LABEL = {
    S: { label: 'S', desc: '<1 semana', color: '#10b981' },
    M: { label: 'M', desc: '1-3 semanas', color: '#0ea5e9' },
    L: { label: 'L', desc: '3-8 semanas', color: '#f59e0b' },
    XL: { label: 'XL', desc: '2+ meses', color: '#ef4444' }
};

async function load() {
    loading.value = true;
    try {
        const [pRes, iRes] = await Promise.all([
            supabase.from('dev_roadmap_phases').select('*').order('ordem'),
            supabase.from('dev_roadmap_items').select('*').order('phase_id').order('ordem')
        ]);
        if (pRes.error) throw pRes.error;
        if (iRes.error) throw iRes.error;
        phases.value = pRes.data || [];
        items.value = iRes.data || [];
        if (phases.value.length && activePhase.value === null) {
            activePhase.value = phases.value[0].id;
        }
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
    } finally {
        loading.value = false;
    }
}

const activePhaseObj = computed(() => phases.value.find((p) => p.id === activePhase.value));

const itemsFiltered = computed(() => {
    let list = items.value.filter((i) => i.phase_id === activePhase.value);
    if (filterStatus.value !== 'all') list = list.filter((i) => i.status === filterStatus.value);
    if (filterPrior.value !== 'all') list = list.filter((i) => i.prioridade === filterPrior.value);
    if (search.value.trim()) {
        const q = search.value.toLowerCase();
        list = list.filter(
            (i) =>
                i.feature.toLowerCase().includes(q) ||
                (i.descricao || '').toLowerCase().includes(q) ||
                (i.bloco || '').toLowerCase().includes(q)
        );
    }
    return list;
});

const itemsByBloco = computed(() => {
    const groups = {};
    for (const item of itemsFiltered.value) {
        const key = item.bloco || 'Sem categoria';
        if (!groups[key]) groups[key] = [];
        groups[key].push(item);
    }
    return groups;
});

function countByStatus(phaseId, status) {
    return items.value.filter((i) => i.phase_id === phaseId && i.status === status).length;
}

// ── CRUD item ────────────────────────────────────────────────────
function openNewItem() {
    itemEditingId.value = null;
    itemForm.value = emptyItemForm();
    itemForm.value.phase_id = activePhase.value;
    itemDrawerOpen.value = true;
}

function openEditItem(item) {
    itemEditingId.value = item.id;
    itemForm.value = {
        phase_id: item.phase_id,
        numero: item.numero,
        bloco: item.bloco || '',
        feature: item.feature,
        descricao: item.descricao || '',
        esforco: item.esforco || 'M',
        prioridade: item.prioridade || 'alta',
        status: item.status,
        notas: item.notas || '',
        assignee: item.assignee || '',
        data_inicio: item.data_inicio || null,
        data_conclusao: item.data_conclusao || null
    };
    itemDrawerOpen.value = true;
}

async function saveItem() {
    if (!itemForm.value.feature.trim() || !itemForm.value.phase_id) return;
    itemSaving.value = true;
    try {
        const payload = {
            phase_id: itemForm.value.phase_id,
            numero: itemForm.value.numero ? Number(itemForm.value.numero) : null,
            bloco: itemForm.value.bloco.trim() || null,
            feature: itemForm.value.feature.trim(),
            descricao: itemForm.value.descricao.trim() || null,
            esforco: itemForm.value.esforco || null,
            prioridade: itemForm.value.prioridade || null,
            status: itemForm.value.status,
            notas: itemForm.value.notas.trim() || null,
            assignee: itemForm.value.assignee.trim() || null,
            data_inicio: itemForm.value.data_inicio || null,
            data_conclusao: itemForm.value.data_conclusao || null
        };
        if (itemEditingId.value) {
            const { error } = await supabase.from('dev_roadmap_items').update(payload).eq('id', itemEditingId.value);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Salvo', life: 2000 });
        } else {
            const maxOrdem = Math.max(
                0,
                ...items.value.filter((i) => i.phase_id === payload.phase_id).map((i) => i.ordem || 0)
            );
            payload.ordem = maxOrdem + 1;
            const { error } = await supabase.from('dev_roadmap_items').insert(payload);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Criado', life: 2000 });
        }
        itemDrawerOpen.value = false;
        await load();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 4000 });
    } finally {
        itemSaving.value = false;
    }
}

function askDeleteItem() {
    if (!itemEditingId.value) return;
    confirm.require({
        message: 'Excluir este item do roadmap?',
        header: 'Confirmar',
        icon: 'pi pi-exclamation-triangle',
        acceptClass: 'p-button-danger',
        accept: async () => {
            try {
                const { error } = await supabase.from('dev_roadmap_items').delete().eq('id', itemEditingId.value);
                if (error) throw error;
                toast.add({ severity: 'success', summary: 'Excluído', life: 2000 });
                itemDrawerOpen.value = false;
                await load();
            } catch (e) {
                toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
            }
        }
    });
}

// ── CRUD phase ───────────────────────────────────────────────────
function openNewPhase() {
    phaseEditingId.value = null;
    const maxNum = Math.max(0, ...phases.value.map((p) => p.numero || 0));
    phaseForm.value = emptyPhaseForm();
    phaseForm.value.numero = maxNum + 1;
    phaseDrawerOpen.value = true;
}

function openEditPhase() {
    if (!activePhaseObj.value) return;
    const p = activePhaseObj.value;
    phaseEditingId.value = p.id;
    phaseForm.value = {
        numero: p.numero,
        nome: p.nome,
        objetivo: p.objetivo || '',
        timeline_sugerida: p.timeline_sugerida || '',
        criterio_saida: p.criterio_saida || '',
        status: p.status,
        data_inicio: p.data_inicio || null,
        data_fim: p.data_fim || null
    };
    phaseDrawerOpen.value = true;
}

async function savePhase() {
    if (!phaseForm.value.nome.trim() || !phaseForm.value.numero) return;
    phaseSaving.value = true;
    try {
        const payload = {
            numero: Number(phaseForm.value.numero),
            nome: phaseForm.value.nome.trim(),
            objetivo: phaseForm.value.objetivo.trim() || null,
            timeline_sugerida: phaseForm.value.timeline_sugerida.trim() || null,
            criterio_saida: phaseForm.value.criterio_saida.trim() || null,
            status: phaseForm.value.status,
            data_inicio: phaseForm.value.data_inicio || null,
            data_fim: phaseForm.value.data_fim || null
        };
        if (phaseEditingId.value) {
            const { error } = await supabase.from('dev_roadmap_phases').update(payload).eq('id', phaseEditingId.value);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Salvo', life: 2000 });
        } else {
            payload.ordem = (phases.value.length || 0) + 1;
            const { error } = await supabase.from('dev_roadmap_phases').insert(payload);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Criado', life: 2000 });
        }
        phaseDrawerOpen.value = false;
        await load();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
    } finally {
        phaseSaving.value = false;
    }
}

function askDeletePhase() {
    if (!phaseEditingId.value) return;
    const phaseItemCount = items.value.filter((i) => i.phase_id === phaseEditingId.value).length;
    confirm.require({
        message: `Excluir esta fase? ${phaseItemCount > 0 ? `Ela tem ${phaseItemCount} item(s), que serão excluídos junto.` : ''}`,
        header: 'Confirmar exclusão',
        icon: 'pi pi-exclamation-triangle',
        acceptClass: 'p-button-danger',
        accept: async () => {
            try {
                const { error } = await supabase.from('dev_roadmap_phases').delete().eq('id', phaseEditingId.value);
                if (error) throw error;
                toast.add({ severity: 'success', summary: 'Fase excluída', life: 2000 });
                phaseDrawerOpen.value = false;
                activePhase.value = null;
                await load();
            } catch (e) {
                toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
            }
        }
    });
}

// ── Drag & drop ───────────────────────────────────────────────────
async function handleReorderBloco(blocoItems, fromIdx, toIdx) {
    const hasFilter = filterStatus.value !== 'all' || filterPrior.value !== 'all' || search.value.trim();
    if (hasFilter) {
        toast.add({
            severity: 'warn',
            summary: 'Limpe os filtros pra reordenar',
            life: 3500
        });
        return;
    }
    // Reordena items dentro do bloco + atualiza ordem global
    const reordered = reorderWithIndexes(blocoItems, fromIdx, toIdx);
    try {
        // Pega a ordem base do primeiro item do bloco e incrementa
        const base = Math.min(...blocoItems.map((i) => i.ordem || 0));
        const updates = reordered.map((item, idx) =>
            supabase.from('dev_roadmap_items').update({ ordem: base + idx }).eq('id', item.id)
        );
        await Promise.all(updates);
        await load();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao reordenar', detail: e.message, life: 4000 });
    }
}

onMounted(load);
</script>

<template>
    <ConfirmDialog />

    <div v-if="loading" class="loading">
        <i class="pi pi-spin pi-spinner text-2xl text-indigo-500" />
    </div>

    <div v-else class="roadmap">
        <!-- Seletor de fase -->
        <div class="phase-selector">
            <button
                v-for="phase in phases"
                :key="phase.id"
                :class="['phase-btn', { active: phase.id === activePhase }]"
                @click="activePhase = phase.id"
            >
                <span class="phase-btn-num">{{ phase.numero }}</span>
                <div class="phase-btn-info">
                    <strong>{{ phase.nome }}</strong>
                    <small>{{ phase.timeline_sugerida }}</small>
                </div>
                <div class="phase-btn-counts">
                    <span class="done">{{ countByStatus(phase.id, 'concluido') }}</span>
                    <span class="total">/ {{ items.filter((i) => i.phase_id === phase.id).length }}</span>
                </div>
            </button>
            <button class="phase-btn phase-add" @click="openNewPhase" title="Nova fase">
                <i class="pi pi-plus" />
            </button>
        </div>

        <!-- Header da fase ativa -->
        <div v-if="activePhaseObj" class="phase-header">
            <div class="flex-1 min-w-0">
                <h2 class="phase-title">
                    <span class="phase-chip">Fase {{ activePhaseObj.numero }}</span>
                    {{ activePhaseObj.nome }}
                </h2>
                <p class="phase-desc">{{ activePhaseObj.objetivo }}</p>
                <div class="phase-meta">
                    <span v-if="activePhaseObj.timeline_sugerida"><i class="pi pi-clock text-xs" /> {{ activePhaseObj.timeline_sugerida }}</span>
                    <span v-if="activePhaseObj.criterio_saida">
                        <i class="pi pi-check-circle text-xs" /> {{ activePhaseObj.criterio_saida }}
                    </span>
                </div>
            </div>
            <button class="btn-icon" @click="openEditPhase" title="Editar fase">
                <i class="pi pi-pencil" />
            </button>
        </div>

        <!-- Toolbar -->
        <div class="toolbar">
            <input v-model="search" type="search" placeholder="Buscar feature..." class="filter-search" />
            <select v-model="filterStatus" class="filter-sel">
                <option value="all">Todos os status</option>
                <option value="pendente">Pendente</option>
                <option value="em_andamento">Em andamento</option>
                <option value="concluido">Concluído</option>
                <option value="cancelado">Cancelado</option>
                <option value="bloqueado">Bloqueado</option>
            </select>
            <select v-model="filterPrior" class="filter-sel">
                <option value="all">Todas as prioridades</option>
                <option value="bloqueador">Bloqueador</option>
                <option value="alta">Alta</option>
                <option value="media">Média</option>
                <option value="diferencial">Diferencial</option>
            </select>
            <button class="btn-primary" @click="openNewItem">
                <i class="pi pi-plus" /> Novo item
            </button>
        </div>

        <!-- Itens agrupados por bloco -->
        <div v-if="!itemsFiltered.length" class="empty">
            Nenhum item encontrado. Use "Novo item" pra adicionar.
        </div>

        <div v-for="(blocoItems, bloco) in itemsByBloco" :key="bloco" class="bloco">
            <h3 class="bloco-title">
                <i class="pi pi-folder-open" />
                {{ bloco }}
                <span class="bloco-count">{{ blocoItems.length }}</span>
            </h3>
            <BlocoItems :items="blocoItems" :reorder-fn="handleReorderBloco" :on-edit="openEditItem" />
        </div>

        <!-- Drawer: Item -->
        <DevDrawer
            :open="itemDrawerOpen"
            :title="itemEditingId ? 'Editar item' : 'Novo item de roadmap'"
            :subtitle="itemEditingId ? `#${itemEditingId}` : ''"
            :can-save="!!itemForm.feature.trim() && !!itemForm.phase_id"
            :saving="itemSaving"
            :danger="!!itemEditingId"
            @close="itemDrawerOpen = false"
            @save="saveItem"
            @delete="askDeleteItem"
        >
            <DevField label="Fase" required>
                <select v-model="itemForm.phase_id">
                    <option v-for="p in phases" :key="p.id" :value="p.id">
                        Fase {{ p.numero }} — {{ p.nome }}
                    </option>
                </select>
            </DevField>

            <div class="form-row">
                <DevField label="Bloco" hint="Ex.: Monetização, Compliance BR, IA">
                    <input v-model="itemForm.bloco" />
                </DevField>

                <DevField label="Nº" hint="Opcional (pra referência)">
                    <input v-model="itemForm.numero" type="number" min="1" />
                </DevField>
            </div>

            <DevField label="Feature" required>
                <input v-model="itemForm.feature" placeholder="Ex.: Integração com gateway de pagamento" />
            </DevField>

            <DevField label="Descrição">
                <textarea v-model="itemForm.descricao" rows="3" />
            </DevField>

            <div class="form-row three">
                <DevField label="Esforço">
                    <select v-model="itemForm.esforco">
                        <option value="">—</option>
                        <option value="S">S (&lt;1 sem)</option>
                        <option value="M">M (1-3 sem)</option>
                        <option value="L">L (3-8 sem)</option>
                        <option value="XL">XL (2+ meses)</option>
                    </select>
                </DevField>

                <DevField label="Prioridade">
                    <select v-model="itemForm.prioridade">
                        <option value="">—</option>
                        <option value="bloqueador">Bloqueador</option>
                        <option value="alta">Alta</option>
                        <option value="media">Média</option>
                        <option value="diferencial">Diferencial</option>
                    </select>
                </DevField>

                <DevField label="Status">
                    <select v-model="itemForm.status">
                        <option value="pendente">Pendente</option>
                        <option value="em_andamento">Em andamento</option>
                        <option value="concluido">Concluído</option>
                        <option value="cancelado">Cancelado</option>
                        <option value="bloqueado">Bloqueado</option>
                    </select>
                </DevField>
            </div>

            <DevField label="Notas/Observações" hint="Contexto extra, decisões, caveats">
                <textarea v-model="itemForm.notas" rows="3" />
            </DevField>

            <div class="form-row">
                <DevField label="Início">
                    <input v-model="itemForm.data_inicio" type="date" />
                </DevField>
                <DevField label="Conclusão">
                    <input v-model="itemForm.data_conclusao" type="date" />
                </DevField>
            </div>

            <DevField label="Assignee">
                <input v-model="itemForm.assignee" placeholder="Nome/email" />
            </DevField>
        </DevDrawer>

        <!-- Drawer: Phase -->
        <DevDrawer
            :open="phaseDrawerOpen"
            :title="phaseEditingId ? 'Editar fase' : 'Nova fase'"
            :can-save="!!phaseForm.nome.trim() && !!phaseForm.numero"
            :saving="phaseSaving"
            :danger="!!phaseEditingId"
            @close="phaseDrawerOpen = false"
            @save="savePhase"
            @delete="askDeletePhase"
        >
            <div class="form-row">
                <DevField label="Número" required>
                    <input v-model="phaseForm.numero" type="number" min="1" />
                </DevField>

                <DevField label="Status">
                    <select v-model="phaseForm.status">
                        <option value="planejada">Planejada</option>
                        <option value="em_andamento">Em andamento</option>
                        <option value="concluida">Concluída</option>
                        <option value="arquivada">Arquivada</option>
                    </select>
                </DevField>
            </div>

            <DevField label="Nome da fase" required>
                <input v-model="phaseForm.nome" placeholder="Ex.: MVP Launch" />
            </DevField>

            <DevField label="Objetivo">
                <textarea v-model="phaseForm.objetivo" rows="3" />
            </DevField>

            <DevField label="Timeline sugerida">
                <input v-model="phaseForm.timeline_sugerida" placeholder="Ex.: 4-6 semanas" />
            </DevField>

            <DevField label="Critério de saída">
                <textarea v-model="phaseForm.criterio_saida" rows="2" />
            </DevField>

            <div class="form-row">
                <DevField label="Data de início">
                    <input v-model="phaseForm.data_inicio" type="date" />
                </DevField>
                <DevField label="Data de fim">
                    <input v-model="phaseForm.data_fim" type="date" />
                </DevField>
            </div>
        </DevDrawer>
    </div>
</template>

<style scoped>
.loading { text-align: center; padding: 60px; }

.roadmap {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.phase-selector {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 10px;
}

.phase-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--surface-card, #fff);
    border: 1.5px solid var(--surface-border, #e2e8f0);
    border-radius: 10px;
    padding: 12px 14px;
    cursor: pointer;
    text-align: left;
    transition: all 0.15s;
    color: var(--text-color);
}
.phase-btn:hover {
    border-color: color-mix(in srgb, var(--primary-color) 40%, transparent);
}
.phase-btn.active {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 5%, transparent);
}

.phase-btn-num {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: var(--primary-color);
    color: white;
    font-weight: 700;
    font-size: 14px;
    flex-shrink: 0;
}

.phase-btn-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.phase-btn-info strong { font-size: 13px; font-weight: 600; }
.phase-btn-info small { font-size: 11px; color: var(--text-color-secondary); margin-top: 2px; }

.phase-btn-counts {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 13px;
    font-weight: 600;
}
.phase-btn-counts .done { color: #10b981; }
.phase-btn-counts .total { color: var(--text-color-secondary); font-size: 11px; }

.phase-add {
    justify-content: center;
    border-style: dashed;
    color: var(--text-color-secondary);
    font-size: 16px;
    min-height: 64px;
}
.phase-add:hover { color: var(--primary-color); }

.phase-header {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-radius: 10px;
    padding: 16px;
    display: flex;
    align-items: flex-start;
    gap: 12px;
}
.phase-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 18px;
    font-weight: 700;
    color: var(--text-color);
}
.phase-chip {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background: var(--primary-color);
    color: white;
    padding: 3px 8px;
    border-radius: 4px;
    font-weight: 700;
}
.phase-desc {
    font-size: 13px;
    color: var(--text-color-secondary);
    line-height: 1.55;
    margin: 8px 0;
}
.phase-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    font-size: 11px;
    color: var(--text-color-secondary);
    margin-top: 8px;
}
.phase-meta span { display: flex; align-items: center; gap: 4px; }

.toolbar {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

.filter-search, .filter-sel {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-radius: 7px;
    padding: 7px 11px;
    font-size: 12px;
    color: var(--text-color);
    outline: none;
}
.filter-search { flex: 1; min-width: 200px; }
.filter-sel { min-width: 160px; cursor: pointer; }

.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--primary-color);
    color: white;
    border: none;
    border-radius: 7px;
    padding: 8px 13px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.15s;
}
.btn-primary:hover { opacity: 0.9; }

.btn-icon {
    background: transparent;
    border: none;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    color: var(--text-color-secondary);
    cursor: pointer;
    font-size: 13px;
    transition: all 0.15s;
    flex-shrink: 0;
}
.btn-icon:hover {
    background: var(--surface-ground);
    color: var(--primary-color);
}

.bloco {
    background: var(--surface-card, #fff);
    border: 1px solid var(--surface-border);
    border-radius: 10px;
    padding: 14px;
}

.bloco-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 700;
    color: var(--text-color);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--surface-border);
}
.bloco-title i { color: var(--primary-color); }
.bloco-count {
    margin-left: auto;
    font-size: 11px;
    font-family: 'IBM Plex Mono', monospace;
    background: var(--surface-border);
    padding: 2px 8px;
    border-radius: 10px;
    text-transform: none;
    letter-spacing: 0;
}

.empty {
    text-align: center;
    padding: 40px;
    color: var(--text-color-secondary);
    background: var(--surface-card, #fff);
    border: 1px dashed var(--surface-border);
    border-radius: 10px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.form-row.three {
    grid-template-columns: 1fr 1fr 1fr;
}
</style>
