<script setup>
/*
 * MelissaAgendador — Pagina nativa Melissa pra "Agendador Online".
 *
 * Substitui o embed cfg-agendador que vivia dentro do MelissaConfiguracoes.
 * Layout 2-col:
 *   - COL 1 (sidebar) — Card "Status" (toggle ativo + tag PRO + link
 *     publico com copy/open + slug personalizado) + Card "Resumos"
 *     (6 atalhos clicaveis pras secoes do main)
 *   - COL 2 (main) — 6 cards: Identidade Visual / Perfil Publico /
 *     Fluxo de Agendamento / Pagamento / Triagem & LGPD / Textos da
 *     Jornada. Cada um com seu botao "Salvar" proprio (saveCard).
 *
 * Logica espelhada do ConfiguracoesAgendadorPage (tabela
 * agendador_configuracoes + bucket agendador + payment_settings).
 */
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';
import MelissaConfigList from './MelissaConfigList.vue';
import JoditTextEditor from '@/components/ui/JoditTextEditor.vue';
import AgendadorPreview from '@/components/agendador/AgendadorPreview.vue';
import { useToast } from 'primevue/usetoast';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';
import { useEntitlementsStore } from '@/stores/entitlementsStore';
// InputText/Select/SelectButton/Textarea/RadioButton/Checkbox/ColorPicker/
// ToggleSwitch/Tag/Skeleton: auto via PrimeVueResolver
// (PrimeVue <Editor> trocado por JoditTextEditor — Quill colapsava em
// flex layouts com 3 editores empilhados, Jodit faz layout imperativo
// via JS sem depender de medicao do flex pai.)

const emit = defineEmits(['close']);

const toast = useToast();
const tenantStore = useTenantStore();
const entitlements = useEntitlementsStore();

const hasAgendador = computed(() => entitlements.can('online_scheduling.manage'));
const hasLinkPersonalizado = computed(() => entitlements.can('agendador.link_personalizado'));

const AGENDADOR_BUCKET = 'agendador';

// ── Breakpoints + drawer ───────────────────────────────────
const drawerOpen = ref(false);
const isMobile = ref(false);
const isWideDesktop = ref(false); // >= 1340px — preview vira painel flutuante fora do fake dialog
let _mqMobile = null;
let _mqWide = null;
function _onMqMobileChange(e) {
    isMobile.value = e.matches;
    if (!e.matches) drawerOpen.value = false;
}
function _onMqWideChange(e) { isWideDesktop.value = e.matches; }
function toggleDrawer() { drawerOpen.value = !drawerOpen.value; }
function fecharDrawer() { drawerOpen.value = false; }

// Onde o preview do celular e renderizado:
//   - mobile: dentro do main, no topo do conteudo (acima de tudo)
//   - mid-desktop (1024-1339): dentro da sidebar inline (apos Status/Resumos)
//   - wide-desktop (>=1340): painel flutuante fora do fake dialog
const previewTarget = computed(() => {
    if (isMobile.value) return '#mag-main-preview-target';
    if (isWideDesktop.value) return '#mag-floating-preview-target';
    return '#mag-sidebar-preview-target';
});

// Toggle entre cards (default) e lista de configs (alterna inline na sidebar)
const cfgOpen = ref(false);
function toggleCfg() { cfgOpen.value = !cfgOpen.value; }
function fecharCfg() { cfgOpen.value = false; }

// ── Estado ─────────────────────────────────────────────────
const loading = ref(true);
const ownerId = ref(null);
const savingCard = ref(null);
const uploadingField = ref(null);
const fileInputLogo = ref(null);
const fileInputHeader = ref(null);
const fileInputFundo = ref(null);

const linkCopied = ref(false);
let _copyTimer = null;

const DEFAULT_CFG = {
    ativo: false,
    link_slug: '',
    imagem_fundo_url: '',
    imagem_header_url: '',
    logomarca_url: '',
    cor_primaria: '#4b6bff',
    nome_exibicao: '',
    endereco: '',
    botao_como_chegar_ativo: true,
    maps_url: '',
    modo_aprovacao: 'aprovacao',
    modalidade: 'presencial',
    tipos_habilitados: ['primeira', 'retorno'],
    duracao_sessao_min: 50,
    antecedencia_minima_horas: 24,
    prazo_resposta_horas: 2,
    reserva_horas: 2,
    pagamento_obrigatorio: false,
    pagamento_modo: 'sem_pagamento',
    pagamento_metodos_visiveis: [],
    pix_chave: '',
    pix_countdown_minutos: 20,
    triagem_motivo: true,
    triagem_como_conheceu: false,
    verificacao_email: false,
    exigir_aceite_lgpd: true,
    mensagem_boas_vindas: '',
    texto_como_se_preparar: '',
    texto_termos_lgpd: ''
};

const cfg = ref({ ...DEFAULT_CFG });
const paymentSettings = ref({});

// ── Opções ─────────────────────────────────────────────────
const tiposOptions = [
    { label: 'Primeira Entrevista', value: 'primeira' },
    { label: 'Retorno', value: 'retorno' },
    { label: 'Reagendar', value: 'reagendar' }
];
const modalidadeOptions = [
    { label: 'Presencial', value: 'presencial' },
    { label: 'Online (vídeo)', value: 'online' },
    { label: 'Ambos', value: 'ambos' }
];
const modoOptions = [
    { label: 'Aprovação manual', value: 'aprovacao' },
    { label: 'Automático', value: 'automatico' }
];
const duracoesOptions = [
    { label: '30 min', value: 30 },
    { label: '40 min', value: 40 },
    { label: '45 min', value: 45 },
    { label: '50 min', value: 50 },
    { label: '55 min', value: 55 },
    { label: '1 hora', value: 60 },
    { label: '1h 30', value: 90 },
    { label: '2 horas', value: 120 }
];
const antecedenciaOptions = [
    { label: 'Sem limite', value: 0 },
    { label: '1 hora', value: 1 },
    { label: '2 horas', value: 2 },
    { label: '6 horas', value: 6 },
    { label: '12 horas', value: 12 },
    { label: '24 horas', value: 24 },
    { label: '48 horas', value: 48 },
    { label: '72 horas', value: 72 }
];
const reservaOptions = [
    { label: '1 hora', value: 1 },
    { label: '2 horas', value: 2 },
    { label: '4 horas', value: 4 },
    { label: '6 horas', value: 6 },
    { label: '12 horas', value: 12 },
    { label: '24 horas', value: 24 },
    { label: '48 horas', value: 48 }
];
const pixCountdownOptions = [
    { label: '5 min', value: 5 },
    { label: '10 min', value: 10 },
    { label: '15 min', value: 15 },
    { label: '20 min', value: 20 },
    { label: '30 min', value: 30 },
    { label: '60 min', value: 60 }
];
const prazoRespostaOptions = [
    { label: '1 hora', value: 1 },
    { label: '2 horas', value: 2 },
    { label: '4 horas', value: 4 },
    { label: '6 horas', value: 6 },
    { label: '12 horas', value: 12 },
    { label: '24 horas', value: 24 },
    { label: '48 horas', value: 48 },
    { label: '72 horas', value: 72 }
];
const modosPagamento = [
    {
        value: 'sem_pagamento',
        label: 'Sem cobrança antecipada',
        desc: 'O horário fica reservado sem exigir pagamento.',
        icon: 'pi-calendar-clock'
    },
    {
        value: 'pagar_na_hora',
        label: 'Pagar na hora da sessão',
        desc: 'O paciente vê as formas aceitas e paga no dia.',
        icon: 'pi-wallet'
    },
    {
        value: 'pix_antecipado',
        label: 'Pix antecipado obrigatório',
        desc: 'O paciente paga via Pix antes do agendamento.',
        icon: 'pi-qrcode'
    }
];
// METODO_LABEL removido — nao e mais usado nos resumos da sidebar
// (resumoPagamento agora mostra contagem de metodos em vez de labels).

// ── Link público ───────────────────────────────────────────
const linkPublico = computed(() => {
    if (!cfg.value.link_slug) return '';
    return `${window.location.origin}/agendar/${cfg.value.link_slug}`;
});

async function copyLink() {
    try {
        await navigator.clipboard.writeText(linkPublico.value);
        linkCopied.value = true;
        clearTimeout(_copyTimer);
        _copyTimer = setTimeout(() => { linkCopied.value = false; }, 2000);
    } catch {
        toast.add({
            severity: 'warn',
            summary: 'Copie manualmente',
            detail: linkPublico.value,
            life: 5000
        });
    }
}

function abrirLinkPublico() {
    if (!linkPublico.value) return;
    window.open(linkPublico.value, '_blank', 'noopener');
}

// ── Resumos pra sidebar ────────────────────────────────────
const resumoIdentidade = computed(() => {
    const parts = [];
    if (cfg.value.nome_exibicao) parts.push(cfg.value.nome_exibicao);
    if (cfg.value.cor_primaria) parts.push(cfg.value.cor_primaria);
    return parts.join('  ·  ') || 'Não configurado';
});
const resumoPerfil = computed(() => {
    const parts = [];
    if (cfg.value.endereco) parts.push(cfg.value.endereco.slice(0, 40) + (cfg.value.endereco.length > 40 ? '…' : ''));
    if (cfg.value.botao_como_chegar_ativo) parts.push('Como chegar ativo');
    return parts.join('  ·  ') || 'Não configurado';
});
const resumoFluxo = computed(() => {
    const modo = cfg.value.modo_aprovacao === 'aprovacao' ? 'Aprovação manual' : 'Automático';
    const tipos = (cfg.value.tipos_habilitados || []).length;
    return `${modo} · ${tipos} tipo${tipos !== 1 ? 's' : ''} · ${cfg.value.duracao_sessao_min}min`;
});
const resumoPagamento = computed(() => {
    const modo = cfg.value.pagamento_modo;
    if (modo === 'pix_antecipado') return `Pix antecipado · ${cfg.value.pix_countdown_minutos}min`;
    if (modo === 'pagar_na_hora') {
        const ativos = cfg.value.pagamento_metodos_visiveis || [];
        return ativos.length
            ? `Pagar na hora · ${ativos.length} método${ativos.length !== 1 ? 's' : ''}`
            : 'Pagar na hora';
    }
    return 'Sem cobrança antecipada';
});
const resumoTriagem = computed(() => {
    const campos = [];
    if (cfg.value.triagem_motivo) campos.push('Motivo');
    if (cfg.value.triagem_como_conheceu) campos.push('Origem');
    if (cfg.value.verificacao_email) campos.push('E-mail');
    if (cfg.value.exigir_aceite_lgpd) campos.push('LGPD');
    return campos.join(' · ') || 'Sem triagem extra';
});
const resumoTextos = computed(() => {
    const bv = cfg.value.mensagem_boas_vindas?.trim();
    const cp = cfg.value.texto_como_se_preparar?.trim();
    if (bv || cp) return 'Textos configurados';
    return 'Nenhum texto configurado';
});

// Métodos pra "pagar na hora"
const metodosDisponiveis = computed(() => {
    const ps = paymentSettings.value;
    return [
        { key: 'pix', label: 'Pix', icon: 'pi-qrcode', ativo: ps.pix_ativo },
        { key: 'deposito', label: 'Depósito/TED', icon: 'pi-building-columns', ativo: ps.deposito_ativo },
        { key: 'dinheiro', label: 'Dinheiro', icon: 'pi-wallet', ativo: ps.dinheiro_ativo },
        { key: 'cartao', label: 'Cartão', icon: 'pi-credit-card', ativo: ps.cartao_ativo },
        { key: 'convenio', label: 'Convênio', icon: 'pi-heart', ativo: ps.convenio_ativo }
    ];
});
const algumMetodoConfigurado = computed(() => metodosDisponiveis.value.some((m) => m.ativo));

function toggleMetodoVisivel(key) {
    const arr = [...(cfg.value.pagamento_metodos_visiveis || [])];
    const idx = arr.indexOf(key);
    if (idx === -1) arr.push(key);
    else arr.splice(idx, 1);
    cfg.value.pagamento_metodos_visiveis = arr;
}
function isMetodoVisivel(key) {
    return (cfg.value.pagamento_metodos_visiveis || []).includes(key);
}

function toggleTipo(value) {
    const list = [...(cfg.value.tipos_habilitados || [])];
    const idx = list.indexOf(value);
    if (idx >= 0) list.splice(idx, 1);
    else list.push(value);
    cfg.value.tipos_habilitados = list;
}

// ── Auth / tenant ──────────────────────────────────────────
async function getOwnerId() {
    const { data, error } = await supabase.auth.getUser();
    if (error) throw error;
    return data?.user?.id;
}
async function getActiveTenantId(uid) {
    const fromStore = tenantStore.activeTenantId || tenantStore.tenantId || tenantStore.tenant?.id || null;
    if (fromStore) return fromStore;
    const { data } = await supabase
        .from('tenant_members')
        .select('tenant_id')
        .eq('user_id', uid)
        .eq('status', 'active')
        .limit(1)
        .maybeSingle();
    return data?.tenant_id || null;
}

// ── Load ───────────────────────────────────────────────────
async function loadPaymentSettings(uid) {
    try {
        const { data } = await tenantDb().from('payment_settings')
            .select('pix_ativo, pix_chave, pix_tipo, deposito_ativo, dinheiro_ativo, cartao_ativo, convenio_ativo')
            .eq('owner_id', uid)
            .maybeSingle();
        paymentSettings.value = data || {};
    } catch {
        paymentSettings.value = {};
    }
}

async function load() {
    loading.value = true;
    try {
        const uid = await getOwnerId();
        ownerId.value = uid;

        const [{ data, error }] = await Promise.all([
            supabase.from('agendador_configuracoes').select('*').eq('owner_id', uid).maybeSingle(),
            loadPaymentSettings(uid)
        ]);
        if (error) throw error;

        if (data) {
            const loaded = {
                ...DEFAULT_CFG,
                ...data,
                tipos_habilitados: Array.isArray(data.tipos_habilitados)
                    ? data.tipos_habilitados
                    : DEFAULT_CFG.tipos_habilitados,
                pagamento_metodos_visiveis: Array.isArray(data.pagamento_metodos_visiveis)
                    ? data.pagamento_metodos_visiveis
                    : []
            };
            if (!data.pagamento_modo) {
                loaded.pagamento_modo = data.pagamento_obrigatorio ? 'pix_antecipado' : 'sem_pagamento';
            }
            cfg.value = loaded;
        } else {
            cfg.value = { ...DEFAULT_CFG };
            if (tenantStore.tenant?.name) cfg.value.nome_exibicao = tenantStore.tenant.name;
        }
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar', detail: e.message, life: 4000 });
    } finally {
        loading.value = false;
    }
}

// ── Toggle ativo ───────────────────────────────────────────
async function toggleAtivo() {
    const uid = ownerId.value;
    if (!uid) return;
    const novoAtivo = !cfg.value.ativo;
    cfg.value.ativo = novoAtivo;
    try {
        const tenantId = await getActiveTenantId(uid);
        const { error } = await supabase
            .from('agendador_configuracoes')
            .upsert(
                { owner_id: uid, tenant_id: tenantId, ativo: novoAtivo, updated_at: new Date().toISOString() },
                { onConflict: 'owner_id' }
            );
        if (error) throw error;
        toast.add({
            severity: novoAtivo ? 'success' : 'info',
            summary: novoAtivo ? 'Agendador ativado' : 'Agendador desativado',
            life: 3000
        });
        if (novoAtivo) await load();
    } catch (e) {
        cfg.value.ativo = !novoAtivo;
        toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
    }
}

// ── Save card ──────────────────────────────────────────────
function buildPayload(cardKey) {
    const c = cfg.value;
    if (cardKey === 'identidade') {
        return {
            imagem_fundo_url: c.imagem_fundo_url,
            imagem_header_url: c.imagem_header_url,
            logomarca_url: c.logomarca_url,
            cor_primaria: c.cor_primaria
        };
    }
    if (cardKey === 'perfil') {
        return {
            nome_exibicao: c.nome_exibicao,
            endereco: c.endereco,
            botao_como_chegar_ativo: c.botao_como_chegar_ativo,
            maps_url: c.maps_url
        };
    }
    if (cardKey === 'fluxo') {
        return {
            modo_aprovacao: c.modo_aprovacao,
            modalidade: c.modalidade,
            tipos_habilitados: c.tipos_habilitados,
            duracao_sessao_min: c.duracao_sessao_min,
            antecedencia_minima_horas: c.antecedencia_minima_horas,
            prazo_resposta_horas: c.prazo_resposta_horas
        };
    }
    if (cardKey === 'pagamento') {
        const modo = c.pagamento_modo || 'sem_pagamento';
        return {
            pagamento_modo: modo,
            pagamento_obrigatorio: modo === 'pix_antecipado',
            pagamento_metodos_visiveis: c.pagamento_metodos_visiveis || [],
            pix_chave: c.pix_chave?.trim() ?? '',
            pix_countdown_minutos: c.pix_countdown_minutos,
            reserva_horas: c.reserva_horas
        };
    }
    if (cardKey === 'triagem') {
        return {
            triagem_motivo: c.triagem_motivo,
            triagem_como_conheceu: c.triagem_como_conheceu,
            verificacao_email: c.verificacao_email,
            exigir_aceite_lgpd: c.exigir_aceite_lgpd
        };
    }
    if (cardKey === 'textos') {
        return {
            mensagem_boas_vindas: c.mensagem_boas_vindas,
            texto_como_se_preparar: c.texto_como_se_preparar,
            texto_termos_lgpd: c.texto_termos_lgpd
        };
    }
    if (cardKey === 'slug') {
        return {
            link_slug:
                c.link_slug
                    ?.trim()
                    .toLowerCase()
                    .replace(/[^a-z0-9-]/g, '-') || null
        };
    }
    return {};
}

async function saveCard(cardKey) {
    savingCard.value = cardKey;
    try {
        const uid = ownerId.value;
        const tenantId = await getActiveTenantId(uid);
        const payload = buildPayload(cardKey);
        const { error } = await supabase
            .from('agendador_configuracoes')
            .upsert(
                { owner_id: uid, tenant_id: tenantId, ...payload, updated_at: new Date().toISOString() },
                { onConflict: 'owner_id' }
            );
        if (error) throw error;
        toast.add({ severity: 'success', summary: 'Salvo', life: 2500 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 4000 });
    } finally {
        savingCard.value = null;
    }
}

// ── Upload imagens ─────────────────────────────────────────
async function uploadImagem(file, field) {
    if (!file || !ownerId.value) return null;
    uploadingField.value = field;
    try {
        const ext = file.name.split('.').pop() || 'jpg';
        const path = `${ownerId.value}/${field}-${Date.now()}.${ext}`;
        const { error: upErr } = await supabase.storage
            .from(AGENDADOR_BUCKET)
            .upload(path, file, { upsert: true, contentType: file.type });
        if (upErr) throw upErr;
        const { data } = supabase.storage.from(AGENDADOR_BUCKET).getPublicUrl(path);
        return data?.publicUrl || null;
    } finally {
        uploadingField.value = null;
    }
}

async function onFileSelected(event, field) {
    const file = event.target.files?.[0];
    if (!file) return;
    try {
        const url = await uploadImagem(file, field);
        if (url) {
            if (field === 'logomarca') cfg.value.logomarca_url = url;
            if (field === 'header') cfg.value.imagem_header_url = url;
            if (field === 'fundo') cfg.value.imagem_fundo_url = url;
            const uid = ownerId.value;
            const tenantId = await getActiveTenantId(uid);
            await supabase
                .from('agendador_configuracoes')
                .upsert(
                    { owner_id: uid, tenant_id: tenantId, ...buildPayload('identidade'), updated_at: new Date().toISOString() },
                    { onConflict: 'owner_id' }
                );
            toast.add({ severity: 'success', summary: 'Imagem salva', life: 2000 });
        }
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro no upload', detail: e.message, life: 4000 });
    }
}

// ── Ancora pra sessao ──────────────────────────────────────
function scrollToCard(cardKey) {
    if (isMobile.value) drawerOpen.value = false;
    nextTick(() => {
        const el = document.getElementById('mag-sec-' + cardKey);
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    });
}

// ── Lifecycle ──────────────────────────────────────────────
onMounted(async () => {
    if (typeof window !== 'undefined' && window.matchMedia) {
        _mqMobile = window.matchMedia('(max-width: 1023px)');
        isMobile.value = _mqMobile.matches;
        try { _mqMobile.addEventListener('change', _onMqMobileChange); }
        catch { _mqMobile.addListener(_onMqMobileChange); }

        _mqWide = window.matchMedia('(min-width: 1340px)');
        isWideDesktop.value = _mqWide.matches;
        try { _mqWide.addEventListener('change', _onMqWideChange); }
        catch { _mqWide.addListener(_onMqWideChange); }
    }
    await tenantStore.ensureLoaded();
    await load();
});

onBeforeUnmount(() => {
    if (_mqMobile) {
        try { _mqMobile.removeEventListener('change', _onMqMobileChange); }
        catch { _mqMobile.removeListener(_onMqMobileChange); }
    }
    if (_mqWide) {
        try { _mqWide.removeEventListener('change', _onMqWideChange); }
        catch { _mqWide.removeListener(_onMqWideChange); }
    }
    clearTimeout(_copyTimer);
});

const summaryItems = computed(() => [
    { key: 'identidade', label: 'Identidade Visual', icon: 'pi pi-palette', color: '#a855f7', resumo: resumoIdentidade.value },
    { key: 'perfil',     label: 'Perfil Público',    icon: 'pi pi-map-marker', color: '#3b82f6', resumo: resumoPerfil.value },
    { key: 'fluxo',      label: 'Fluxo',             icon: 'pi pi-sitemap',    color: '#06b6d4', resumo: resumoFluxo.value },
    { key: 'pagamento',  label: 'Pagamento',         icon: 'pi pi-credit-card', color: '#10b981', resumo: resumoPagamento.value },
    { key: 'triagem',    label: 'Triagem & LGPD',    icon: 'pi pi-shield',     color: '#f97316', resumo: resumoTriagem.value },
    { key: 'textos',     label: 'Textos',            icon: 'pi pi-file-edit',  color: '#ec4899', resumo: resumoTextos.value }
]);
</script>

<template>
    <Transition name="mag-drawer-fade">
        <div
            v-show="isMobile && drawerOpen"
            class="mag-mobile-drawer"
            :class="{ 'is-open': drawerOpen }"
        >
            <div id="mag-mobile-drawer-target" class="mag-mobile-drawer__scroll" />
        </div>
    </Transition>
    <Transition name="mag-drawer-fade">
        <div
            v-show="isMobile && drawerOpen"
            class="mag-mobile-drawer__backdrop"
            @click="fecharDrawer"
        />
    </Transition>

    <!-- Painel flutuante do Preview (wide-desktop >=1340px). Vive FORA do
         fake dialog, ancorado a sua right edge + 14px gap. Em mobile o
         preview teleporta pro #mag-main-preview-target (topo do main); em
         mid-desktop (1024-1339) teleporta pro #mag-sidebar-preview-target. -->
    <aside id="mag-floating-preview-target" class="mag-floating-preview" aria-label="Pré-visualização do agendador"></aside>

    <section class="mag-page">
        <header class="mag-page__head">
            <button
                class="mag-menu-btn mag-menu-btn--mobile-only"
                v-tooltip.bottom="'Status & Resumos'"
                @click="toggleDrawer"
            >
                <i class="pi pi-bars" />
                <span>Menu</span>
            </button>
            <div class="mag-page__title">
                <i class="pi pi-calendar-clock mag-page__title-icon" />
                <span>Agendador Online</span>
                <Tag value="PRO" severity="contrast" class="mag-page__pro" />
                <Tag
                    v-if="cfg.ativo"
                    value="Ativo"
                    severity="success"
                />
                <Tag
                    v-else
                    value="Inativo"
                    severity="secondary"
                />
            </div>
            <div class="mag-page__actions">
                <button class="mag-close" v-tooltip.bottom="'Voltar (Esc)'" @click="emit('close')">
                    <i class="pi pi-times" />
                </button>
            </div>
        </header>

        <div class="mag-subheader">
            <i class="pi pi-info-circle mag-subheader__icon" />
            <span class="mag-subheader__text">
                Configure o link público que seus pacientes usarão para
                solicitar horários online. Cada card abaixo tem seu próprio
                botão de salvar.
            </span>
        </div>

        <div class="mag-body">
            <Teleport to="#mag-mobile-drawer-target" :disabled="!isMobile">
                <aside class="mag-side">
                    <button class="mag-cfg-btn" :class="{ 'is-open': cfgOpen }" @click="toggleCfg">
                        <i :class="cfgOpen ? 'pi pi-arrow-left' : 'pi pi-cog'" />
                        <span>{{ cfgOpen ? 'Voltar' : 'Configurações' }}</span>
                        <i v-if="!cfgOpen" class="pi pi-chevron-down mag-cfg-btn__chev" />
                    </button>
                    <div v-if="cfgOpen" class="mag-side__scroll mag-side__scroll--cfg">
                        <MelissaConfigList @select="fecharCfg" />
                    </div>
                    <div v-else class="mag-side__scroll">
                        <!-- Card: Status -->
                        <div class="mag-w mag-w--side">
                            <div class="mag-w__head">
                                <div class="mag-w__icon"><i class="pi pi-calendar-clock" /></div>
                                <div class="mag-w__title">
                                    <div class="mag-w__title-text">Status</div>
                                    <div class="mag-w__sub">Ativar e link público</div>
                                </div>
                            </div>
                            <div class="mag-w__body">
                                <!-- Toggle ativar -->
                                <div class="mag-toggle-row">
                                    <div class="mag-toggle-row__text">
                                        <div class="mag-toggle-row__label">
                                            {{ cfg.ativo ? 'Agendador ativo' : 'Agendador inativo' }}
                                        </div>
                                        <div class="mag-toggle-row__hint">
                                            <template v-if="hasAgendador">
                                                {{ cfg.ativo
                                                    ? 'Pacientes podem solicitar horários.'
                                                    : 'Ative pra liberar o link público.' }}
                                            </template>
                                            <template v-else>
                                                Seu plano não inclui o Agendador Online.
                                            </template>
                                        </div>
                                    </div>
                                    <ToggleSwitch
                                        v-if="hasAgendador"
                                        :modelValue="cfg.ativo"
                                        @update:modelValue="toggleAtivo"
                                    />
                                    <ToggleSwitch
                                        v-else
                                        :modelValue="false"
                                        disabled
                                        v-tooltip.left="'Seu plano não inclui o Agendador'"
                                    />
                                </div>

                                <!-- Link público -->
                                <template v-if="cfg.ativo && hasAgendador">
                                    <div v-if="!cfg.link_slug" class="mag-link-loading">
                                        <i class="pi pi-spin pi-spinner" />
                                        <span>Gerando link…</span>
                                    </div>
                                    <template v-else>
                                        <div class="mag-link-label">Link público</div>
                                        <div class="mag-link-row">
                                            <input
                                                :value="linkPublico"
                                                readonly
                                                class="mag-link-input"
                                                @click="$event.target.select()"
                                            />
                                            <button
                                                class="mag-icon-btn"
                                                v-tooltip.top="linkCopied ? 'Copiado!' : 'Copiar'"
                                                @click="copyLink"
                                            >
                                                <i :class="linkCopied ? 'pi pi-check' : 'pi pi-copy'" />
                                            </button>
                                            <button
                                                class="mag-icon-btn"
                                                v-tooltip.top="'Abrir'"
                                                @click="abrirLinkPublico"
                                            >
                                                <i class="pi pi-external-link" />
                                            </button>
                                        </div>

                                        <!-- Slug personalizado -->
                                        <div v-if="hasLinkPersonalizado" class="mag-slug">
                                            <div class="mag-slug__label">Apelido personalizado</div>
                                            <div class="mag-slug__row">
                                                <span class="mag-slug__prefix">/agendar/</span>
                                                <input
                                                    v-model="cfg.link_slug"
                                                    placeholder="dra-ana-silva"
                                                    class="mag-slug__input"
                                                />
                                            </div>
                                            <button
                                                class="mag-btn mag-btn--primary mag-btn--full mag-btn--sm"
                                                :disabled="savingCard === 'slug'"
                                                @click="saveCard('slug')"
                                            >
                                                <i :class="savingCard === 'slug' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                                <span>Salvar apelido</span>
                                            </button>
                                        </div>
                                        <div v-else class="mag-upgrade">
                                            <i class="pi pi-lock" />
                                            <div>
                                                <strong>Apelido personalizado</strong> — disponível em planos superiores.
                                            </div>
                                        </div>
                                    </template>
                                </template>
                                <div v-else class="mag-empty-link">
                                    Ative o agendador acima pra gerar o link público.
                                </div>
                            </div>
                        </div>

                        <!-- Card: Resumos -->
                        <div class="mag-w mag-w--side">
                            <div class="mag-w__head">
                                <div class="mag-w__icon"><i class="pi pi-list" /></div>
                                <div class="mag-w__title">
                                    <div class="mag-w__title-text">Configurações</div>
                                    <div class="mag-w__sub">Click pra ir à seção</div>
                                </div>
                            </div>
                            <div class="mag-w__body">
                                <button
                                    v-for="s in summaryItems"
                                    :key="s.key"
                                    type="button"
                                    class="mag-summary-item"
                                    @click="scrollToCard(s.key)"
                                >
                                    <div
                                        class="mag-summary-item__icon"
                                        :style="{
                                            background: s.color + '22',
                                            color: s.color
                                        }"
                                    >
                                        <i :class="s.icon" />
                                    </div>
                                    <div class="mag-summary-item__text">
                                        <div class="mag-summary-item__label">{{ s.label }}</div>
                                        <div class="mag-summary-item__resumo">{{ s.resumo }}</div>
                                    </div>
                                    <i class="pi pi-chevron-right mag-summary-item__chev" />
                                </button>
                            </div>
                        </div>

                        <!-- Target do Teleport do Preview pra modo sidebar (mid-desktop 1024-1339).
                             Em mobile o preview teleporta pro #mag-main-preview-target (topo do main);
                             em wide-desktop (>=1340px) teleporta pro #mag-floating-preview-target. -->
                        <div id="mag-sidebar-preview-target" class="mag-sidebar-preview-target" />
                    </div>
                </aside>
            </Teleport>

            <div class="mag-main">
                <!-- Target do Teleport do Preview pra modo mobile (acima de tudo no main).
                     Em desktop fica oculto via CSS e o preview teleporta pra sidebar/floating. -->
                <div id="mag-main-preview-target" class="mag-main-preview-target" />

                <!-- Loading -->
                <template v-if="loading">
                    <div class="mag-w" v-for="n in 3" :key="`sk-${n}`">
                        <div class="mag-w__body">
                            <Skeleton width="40%" height="20px" class="mb-3" />
                            <Skeleton v-for="m in 4" :key="`sk-${n}-${m}`" width="100%" height="36px" class="mb-2" />
                        </div>
                    </div>
                </template>

                <template v-else>
                    <!-- ── Identidade Visual ── -->
                    <div id="mag-sec-identidade" class="mag-w">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--purple"><i class="pi pi-palette" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Identidade Visual</div>
                                <div class="mag-w__sub">Logomarca, cor e imagens</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-grid-2">
                                <div class="mag-field">
                                    <label class="mag-label">Nome de exibição</label>
                                    <InputText
                                        v-model="cfg.nome_exibicao"
                                        placeholder="Ex: Dra. Ana Silva — Psicóloga"
                                        class="w-full"
                                    />
                                    <span class="mag-hint">Aparece no topo do agendador.</span>
                                </div>
                                <div class="mag-field">
                                    <label class="mag-label">Cor principal</label>
                                    <div class="mag-color">
                                        <ColorPicker v-model="cfg.cor_primaria" format="hex" />
                                        <InputText
                                            v-model="cfg.cor_primaria"
                                            placeholder="#4b6bff"
                                            class="mag-color__input"
                                            maxlength="7"
                                        />
                                        <div
                                            class="mag-color__swatch"
                                            :style="{ background: cfg.cor_primaria }"
                                        />
                                    </div>
                                    <span class="mag-hint">Botões e destaques.</span>
                                </div>
                            </div>

                            <div class="mag-divider" />

                            <div class="mag-uploads">
                                <!-- Logomarca -->
                                <div class="mag-upload">
                                    <div class="mag-upload__head">
                                        <i class="pi pi-user-circle" />
                                        <span>Logomarca</span>
                                    </div>
                                    <div class="mag-upload__body">
                                        <div class="mag-upload__hint">Avatar circular — 300×300</div>
                                        <div v-if="cfg.logomarca_url" class="mag-upload__preview">
                                            <img :src="cfg.logomarca_url" alt="Logomarca" class="mag-upload__img mag-upload__img--circle" />
                                        </div>
                                        <button
                                            type="button"
                                            class="mag-upload__zone"
                                            @click="fileInputLogo?.click()"
                                        >
                                            <i :class="uploadingField === 'logomarca' ? 'pi pi-spin pi-spinner' : 'pi pi-upload'" />
                                            <span>{{ uploadingField === 'logomarca' ? 'Enviando…' : 'Clique para enviar' }}</span>
                                        </button>
                                        <input
                                            ref="fileInputLogo"
                                            type="file"
                                            accept="image/*"
                                            hidden
                                            @change="(e) => onFileSelected(e, 'logomarca')"
                                        />
                                        <InputText
                                            v-model="cfg.logomarca_url"
                                            placeholder="ou cole uma URL…"
                                            class="w-full"
                                        />
                                    </div>
                                </div>

                                <!-- Header -->
                                <div class="mag-upload">
                                    <div class="mag-upload__head">
                                        <i class="pi pi-image" />
                                        <span>Header</span>
                                    </div>
                                    <div class="mag-upload__body">
                                        <div class="mag-upload__hint">Faixa superior — 1400×300</div>
                                        <div v-if="cfg.imagem_header_url" class="mag-upload__preview">
                                            <img :src="cfg.imagem_header_url" alt="Header" class="mag-upload__img" />
                                        </div>
                                        <button
                                            type="button"
                                            class="mag-upload__zone"
                                            @click="fileInputHeader?.click()"
                                        >
                                            <i :class="uploadingField === 'header' ? 'pi pi-spin pi-spinner' : 'pi pi-upload'" />
                                            <span>{{ uploadingField === 'header' ? 'Enviando…' : 'Clique para enviar' }}</span>
                                        </button>
                                        <input
                                            ref="fileInputHeader"
                                            type="file"
                                            accept="image/*"
                                            hidden
                                            @change="(e) => onFileSelected(e, 'header')"
                                        />
                                        <InputText
                                            v-model="cfg.imagem_header_url"
                                            placeholder="ou cole uma URL…"
                                            class="w-full"
                                        />
                                    </div>
                                </div>

                                <!-- Fundo -->
                                <div class="mag-upload">
                                    <div class="mag-upload__head">
                                        <i class="pi pi-stop" />
                                        <span>Fundo</span>
                                    </div>
                                    <div class="mag-upload__body">
                                        <div class="mag-upload__hint">Fundo da página — 1920×1080</div>
                                        <div v-if="cfg.imagem_fundo_url" class="mag-upload__preview">
                                            <img :src="cfg.imagem_fundo_url" alt="Fundo" class="mag-upload__img" />
                                        </div>
                                        <button
                                            type="button"
                                            class="mag-upload__zone"
                                            @click="fileInputFundo?.click()"
                                        >
                                            <i :class="uploadingField === 'fundo' ? 'pi pi-spin pi-spinner' : 'pi pi-upload'" />
                                            <span>{{ uploadingField === 'fundo' ? 'Enviando…' : 'Clique para enviar' }}</span>
                                        </button>
                                        <input
                                            ref="fileInputFundo"
                                            type="file"
                                            accept="image/*"
                                            hidden
                                            @change="(e) => onFileSelected(e, 'fundo')"
                                        />
                                        <InputText
                                            v-model="cfg.imagem_fundo_url"
                                            placeholder="ou cole uma URL…"
                                            class="w-full"
                                        />
                                    </div>
                                </div>
                            </div>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'identidade'"
                                    @click="saveCard('identidade')"
                                >
                                    <i :class="savingCard === 'identidade' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar identidade</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ── Perfil Público ── -->
                    <div id="mag-sec-perfil" class="mag-w">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--blue"><i class="pi pi-map-marker" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Perfil Público</div>
                                <div class="mag-w__sub">Endereço e botão "Como chegar"</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-field">
                                <label class="mag-label">Endereço</label>
                                <InputText
                                    v-model="cfg.endereco"
                                    placeholder="Rua das Flores, 123, Centro — São Paulo, SP"
                                    class="w-full"
                                />
                            </div>

                            <div class="mag-toggle-row">
                                <div class="mag-toggle-row__text">
                                    <div class="mag-toggle-row__label">Botão "Como chegar"</div>
                                    <div class="mag-toggle-row__hint">Abre o mapa pro paciente.</div>
                                </div>
                                <ToggleSwitch v-model="cfg.botao_como_chegar_ativo" />
                            </div>

                            <div v-if="cfg.botao_como_chegar_ativo" class="mag-field">
                                <label class="mag-label">URL do Google Maps <span class="mag-label__opt">(opcional)</span></label>
                                <InputText
                                    v-model="cfg.maps_url"
                                    placeholder="https://maps.google.com/..."
                                    class="w-full"
                                />
                                <span class="mag-hint">Vazio: abre uma busca pelo endereço acima.</span>
                            </div>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'perfil'"
                                    @click="saveCard('perfil')"
                                >
                                    <i :class="savingCard === 'perfil' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar perfil</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ── Fluxo de Agendamento ── -->
                    <div id="mag-sec-fluxo" class="mag-w">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--cyan"><i class="pi pi-sitemap" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Fluxo de Agendamento</div>
                                <div class="mag-w__sub">Aprovação, modalidade, tipos e duração</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-group-title">Aprovação</div>
                            <div class="mag-radio-list">
                                <button
                                    v-for="opt in modoOptions"
                                    :key="opt.value"
                                    type="button"
                                    class="mag-radio"
                                    :class="{ 'is-active': cfg.modo_aprovacao === opt.value }"
                                    @click="cfg.modo_aprovacao = opt.value"
                                >
                                    <RadioButton :modelValue="cfg.modo_aprovacao" :value="opt.value" />
                                    <div>
                                        <div class="mag-radio__label">{{ opt.label }}</div>
                                        <div class="mag-radio__desc">
                                            <template v-if="opt.value === 'aprovacao'">
                                                Você analisa cada solicitação. Horário fica reservado.
                                            </template>
                                            <template v-else>
                                                Confirmados automaticamente. Sem revisão.
                                            </template>
                                        </div>
                                    </div>
                                </button>
                            </div>

                            <div v-if="cfg.modo_aprovacao === 'aprovacao'" class="mag-field">
                                <label class="mag-label">Prazo para responder</label>
                                <Select
                                    v-model="cfg.prazo_resposta_horas"
                                    :options="prazoRespostaOptions"
                                    optionLabel="label"
                                    optionValue="value"
                                    class="w-full"
                                />
                                <span class="mag-hint">Sem resposta: paciente notificado e horário liberado.</span>
                            </div>

                            <div class="mag-divider" />

                            <div class="mag-group-title">Atendimento</div>
                            <div class="mag-field">
                                <label class="mag-label">Modalidade</label>
                                <SelectButton
                                    v-model="cfg.modalidade"
                                    :options="modalidadeOptions"
                                    optionLabel="label"
                                    optionValue="value"
                                />
                            </div>

                            <div class="mag-field">
                                <label class="mag-label">Tipos de agendamento</label>
                                <div class="mag-chips">
                                    <button
                                        v-for="opt in tiposOptions"
                                        :key="opt.value"
                                        type="button"
                                        class="mag-chip"
                                        :class="{ 'is-active': cfg.tipos_habilitados?.includes(opt.value) }"
                                        @click="toggleTipo(opt.value)"
                                    >
                                        <i v-if="cfg.tipos_habilitados?.includes(opt.value)" class="pi pi-check" />
                                        <span>{{ opt.label }}</span>
                                    </button>
                                </div>
                            </div>

                            <div class="mag-divider" />

                            <div class="mag-group-title">Horários</div>
                            <div class="mag-grid-2">
                                <div class="mag-field">
                                    <label class="mag-label">Duração da sessão</label>
                                    <Select
                                        v-model="cfg.duracao_sessao_min"
                                        :options="duracoesOptions"
                                        optionLabel="label"
                                        optionValue="value"
                                        class="w-full"
                                    />
                                </div>
                                <div class="mag-field">
                                    <label class="mag-label">Antecedência mínima</label>
                                    <Select
                                        v-model="cfg.antecedencia_minima_horas"
                                        :options="antecedenciaOptions"
                                        optionLabel="label"
                                        optionValue="value"
                                        class="w-full"
                                    />
                                </div>
                            </div>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'fluxo'"
                                    @click="saveCard('fluxo')"
                                >
                                    <i :class="savingCard === 'fluxo' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar fluxo</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ── Pagamento ── -->
                    <div id="mag-sec-pagamento" class="mag-w">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--green"><i class="pi pi-credit-card" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Pagamento</div>
                                <div class="mag-w__sub">Como o paciente vai pagar</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-radio-list">
                                <button
                                    v-for="modo in modosPagamento"
                                    :key="modo.value"
                                    type="button"
                                    class="mag-radio mag-radio--mode"
                                    :class="{ 'is-active': cfg.pagamento_modo === modo.value }"
                                    @click="cfg.pagamento_modo = modo.value"
                                >
                                    <div
                                        class="mag-radio__icon"
                                        :class="{ 'is-active': cfg.pagamento_modo === modo.value }"
                                    >
                                        <i :class="['pi', modo.icon]" />
                                    </div>
                                    <div class="mag-radio__text">
                                        <div class="mag-radio__label">{{ modo.label }}</div>
                                        <div class="mag-radio__desc">{{ modo.desc }}</div>
                                    </div>
                                    <i v-if="cfg.pagamento_modo === modo.value" class="pi pi-check-circle mag-radio__check" />
                                </button>
                            </div>

                            <!-- Pagar na hora -->
                            <template v-if="cfg.pagamento_modo === 'pagar_na_hora'">
                                <div class="mag-divider" />
                                <div class="mag-group-title">Formas aceitas</div>
                                <div v-if="!algumMetodoConfigurado" class="mag-warn">
                                    <i class="pi pi-exclamation-triangle" />
                                    <span>Nenhuma forma de pagamento configurada. Vá em Configurações &rsaquo; Pagamento.</span>
                                </div>
                                <div class="mag-methods">
                                    <label
                                        v-for="m in metodosDisponiveis"
                                        :key="m.key"
                                        class="mag-method"
                                        :class="{
                                            'is-disabled': !m.ativo,
                                            'is-active': m.ativo && isMetodoVisivel(m.key)
                                        }"
                                    >
                                        <Checkbox
                                            :modelValue="isMetodoVisivel(m.key)"
                                            :disabled="!m.ativo"
                                            binary
                                            @change="m.ativo && toggleMetodoVisivel(m.key)"
                                        />
                                        <i :class="['pi', m.icon]" />
                                        <span class="mag-method__label">{{ m.label }}</span>
                                        <Tag v-if="!m.ativo" value="Não configurado" severity="secondary" class="mag-method__tag" />
                                    </label>
                                </div>
                            </template>

                            <!-- Pix antecipado -->
                            <template v-if="cfg.pagamento_modo === 'pix_antecipado'">
                                <div class="mag-divider" />
                                <div class="mag-group-title">Configurações do Pix</div>
                                <div class="mag-grid-2">
                                    <div class="mag-field">
                                        <label class="mag-label">Chave Pix</label>
                                        <InputText
                                            v-model="cfg.pix_chave"
                                            :placeholder="paymentSettings.pix_chave ? `Usando: ${paymentSettings.pix_chave}` : 'CPF, e-mail, telefone…'"
                                            class="w-full"
                                        />
                                        <span v-if="!cfg.pix_chave && paymentSettings.pix_chave" class="mag-hint">
                                            Vazio: usa a chave de Pagamento ({{ paymentSettings.pix_chave }}).
                                        </span>
                                    </div>
                                    <div class="mag-field">
                                        <label class="mag-label">Tempo para pagar</label>
                                        <Select
                                            v-model="cfg.pix_countdown_minutos"
                                            :options="pixCountdownOptions"
                                            optionLabel="label"
                                            optionValue="value"
                                            class="w-full"
                                        />
                                        <span class="mag-hint">Sem pagamento no prazo: horário liberado.</span>
                                    </div>
                                </div>
                            </template>

                            <div class="mag-divider" />

                            <div class="mag-group-title">Reserva do horário</div>
                            <div class="mag-field">
                                <label class="mag-label">Tempo de reserva</label>
                                <Select
                                    v-model="cfg.reserva_horas"
                                    :options="reservaOptions"
                                    optionLabel="label"
                                    optionValue="value"
                                    class="w-full"
                                />
                                <span class="mag-hint">
                                    <template v-if="cfg.pagamento_modo === 'pix_antecipado'">
                                        Horário bloqueado aguardando o pagamento Pix.
                                    </template>
                                    <template v-else>
                                        Horário bloqueado enquanto a solicitação está pendente.
                                    </template>
                                </span>
                            </div>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'pagamento'"
                                    @click="saveCard('pagamento')"
                                >
                                    <i :class="savingCard === 'pagamento' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar pagamento</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ── Triagem & LGPD ── -->
                    <div id="mag-sec-triagem" class="mag-w">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--orange"><i class="pi pi-shield" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Triagem & LGPD</div>
                                <div class="mag-w__sub">Campos extras e termos</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-group-title">Campos extras no formulário</div>
                            <div class="mag-toggle-row">
                                <div class="mag-toggle-row__text">
                                    <div class="mag-toggle-row__label">Motivo da consulta</div>
                                    <div class="mag-toggle-row__hint">Texto livre opcional pro paciente.</div>
                                </div>
                                <ToggleSwitch v-model="cfg.triagem_motivo" />
                            </div>
                            <div class="mag-toggle-row">
                                <div class="mag-toggle-row__text">
                                    <div class="mag-toggle-row__label">Como nos conheceu?</div>
                                    <div class="mag-toggle-row__hint">Origem (indicação, redes sociais, busca…).</div>
                                </div>
                                <ToggleSwitch v-model="cfg.triagem_como_conheceu" />
                            </div>

                            <div class="mag-divider" />

                            <div class="mag-group-title">Segurança & LGPD</div>
                            <div class="mag-toggle-row">
                                <div class="mag-toggle-row__text">
                                    <div class="mag-toggle-row__label">Verificação de e-mail</div>
                                    <div class="mag-toggle-row__hint">Paciente confirma o e-mail antes de finalizar.</div>
                                </div>
                                <ToggleSwitch v-model="cfg.verificacao_email" />
                            </div>
                            <div class="mag-toggle-row">
                                <div class="mag-toggle-row__text">
                                    <div class="mag-toggle-row__label">Aceite obrigatório de termos</div>
                                    <div class="mag-toggle-row__hint">Checkbox de LGPD antes de finalizar.</div>
                                </div>
                                <ToggleSwitch v-model="cfg.exigir_aceite_lgpd" />
                            </div>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'triagem'"
                                    @click="saveCard('triagem')"
                                >
                                    <i :class="savingCard === 'triagem' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar triagem</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ── Textos da Jornada ── -->
                    <div id="mag-sec-textos" class="mag-w mag-w--full">
                        <div class="mag-w__head">
                            <div class="mag-w__icon mag-w__icon--pink"><i class="pi pi-file-edit" /></div>
                            <div class="mag-w__title">
                                <div class="mag-w__title-text">Textos da Jornada</div>
                                <div class="mag-w__sub">Mensagens exibidas ao paciente</div>
                            </div>
                        </div>
                        <div class="mag-w__body">
                            <div class="mag-field">
                                <label class="mag-label">Mensagem de boas-vindas</label>
                                <span class="mag-hint">Aparece após o paciente informar o nome.</span>
                                <JoditTextEditor
                                    v-model="cfg.mensagem_boas_vindas"
                                    :min-height="100"
                                />
                            </div>

                            <div class="mag-divider" />

                            <div class="mag-field">
                                <label class="mag-label">Como se preparar para a sessão</label>
                                <span class="mag-hint">Aparece na confirmação. Dicas, instruções, etc.</span>
                                <JoditTextEditor
                                    v-model="cfg.texto_como_se_preparar"
                                    :min-height="140"
                                />
                            </div>

                            <template v-if="cfg.exigir_aceite_lgpd">
                                <div class="mag-divider" />
                                <div class="mag-field">
                                    <label class="mag-label">Termos de uso / Política de privacidade</label>
                                    <span class="mag-hint">Aparece no checkbox de aceite.</span>
                                    <JoditTextEditor
                                        v-model="cfg.texto_termos_lgpd"
                                        :min-height="140"
                                    />
                                </div>
                            </template>

                            <div class="mag-card-actions">
                                <button
                                    class="mag-btn mag-btn--primary"
                                    :disabled="savingCard === 'textos'"
                                    @click="saveCard('textos')"
                                >
                                    <i :class="savingCard === 'textos' ? 'pi pi-spin pi-spinner' : 'pi pi-check'" />
                                    <span>Salvar textos</span>
                                </button>
                            </div>
                        </div>
                    </div>
                </template>
            </div>
        </div>
    </section>

    <!-- ── Card de Pré-visualização (Teleport). O target alterna conforme o
         viewport: topo do main (mobile) / sidebar (mid-desktop) / painel
         flutuante fora do fake dialog (wide-desktop). -->
    <Teleport :to="previewTarget">
        <div class="mag-w mag-w--side mag-w--preview">
            <div class="mag-w__head">
                <div class="mag-w__icon"><i class="pi pi-mobile" /></div>
                <div class="mag-w__title">
                    <div class="mag-w__title-text">Pré-visualização</div>
                    <div class="mag-w__sub">Como aparece no celular</div>
                </div>
            </div>
            <div class="mag-w__body">
                <AgendadorPreview :cfg="cfg" />
            </div>
        </div>
    </Teleport>
</template>

<style scoped>
/* ═══════ Page chrome ═══════ */
.mag-page {
    position: absolute;
    inset: 6px 6px calc(var(--m-dock-h, 76px) + 6px) var(--m-config-aside-left, 6px);
    z-index: 40;
    display: flex;
    flex-direction: column;
    background: var(--m-bg-medium);
    backdrop-filter: blur(32px) saturate(160%);
    -webkit-backdrop-filter: blur(32px) saturate(160%);
    border: 1px solid var(--m-border);
    border-radius: 18px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
    overflow: hidden;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    color: var(--m-text);
    animation: mag-page-enter 240ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
@keyframes mag-page-enter {
    from { opacity: 0; transform: scale(0.985); }
    to   { opacity: 1; transform: scale(1); }
}

.mag-page__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--m-border);
    flex-shrink: 0;
    gap: 10px;
}
.mag-page__title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1rem;
    font-weight: 700;
    color: var(--m-text);
    flex-wrap: wrap;
}
.mag-page__title-icon { color: var(--p-primary-color); font-size: 1.05rem; }
.mag-page__pro { font-size: 0.66rem !important; }
.mag-page__actions { display: flex; align-items: center; gap: 6px; }

.mag-close {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--m-border);
    color: var(--m-text-muted);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}
.mag-close:hover { background: var(--m-bg-soft-hover); color: var(--m-text); }
.mag-menu-btn {
    display: none;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 8px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    flex-shrink: 0;
}
.mag-menu-btn:hover { background: var(--m-bg-soft-hover); }

.mag-subheader {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 18px;
    background: var(--m-bg-soft);
    border-bottom: 1px solid var(--m-border);
    color: var(--m-text-muted);
    font-size: 0.78rem;
    flex-shrink: 0;
}
.mag-subheader__icon {
    color: var(--p-primary-color);
    font-size: 0.85rem;
    margin-top: 2px;
    flex-shrink: 0;
}

/* ═══════ Body 2-col ═══════ */
.mag-body {
    flex: 1;
    min-height: 0;
    display: flex;
    overflow: hidden;
}
.mag-side {
    width: 360px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--m-bg-soft);
    border-right: 1px solid var(--m-border);
    overflow: hidden;
}
.mag-side__scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mag-side__scroll::-webkit-scrollbar { width: 5px; }
.mag-side__scroll::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}

/* Botao "Configuracoes" no topo da .mag-side. Click alterna entre
   cards (default) e lista de configs (estado is-open: vira "Voltar"). */
.mag-cfg-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% - 24px);
    margin: 12px 12px 0;
    padding: 10px 12px;
    background: var(--m-bg-medium);
    border: 1px solid var(--m-border);
    border-radius: 9px;
    color: var(--m-text);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    text-align: left;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
    flex-shrink: 0;
}
.mag-cfg-btn:hover {
    background: var(--m-bg-soft-hover);
    border-color: var(--m-border-strong);
}
.mag-cfg-btn.is-open {
    background: color-mix(in srgb, var(--p-primary-color) 14%, transparent);
    border-color: color-mix(in srgb, var(--p-primary-color) 38%, transparent);
    color: var(--p-primary-color);
}
.mag-cfg-btn > i:first-child {
    color: var(--p-primary-color);
    font-size: 0.92rem;
}
.mag-cfg-btn > span { flex: 1; }
.mag-cfg-btn__chev {
    color: var(--m-text-muted);
    font-size: 0.7rem;
}
.mag-side__scroll--cfg {
    padding: 8px;
    gap: 0;
}

.mag-main {
    flex: 1;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mag-main::-webkit-scrollbar { width: 5px; }
.mag-main::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}

/* Desktop (>=1024): cards empilhados verticalmente (1-col), cada um
   com altura propria do conteudo. O grid 2-col anterior forcava cells
   na mesma row a igualarem altura — com align-self: start cards menores
   ficavam no topo do cell e o espaco vazio embaixo dava aparencia de
   "encavalado". 1-col com max-width centralizado eh mais legivel em
   telas largas e respeita "100% do conteudo interno" pedido pelo user.
   .mag-main ja eh display:flex flex-direction:column gap:12px no base —
   so adiciona limites de largura aqui. */
@media (min-width: 1024px) {
    /* Fake dialog: largura adaptativa, alinhada a esquerda (apos o
       config-aside global). Espelha o pattern de MelissaNegocio:
       - 1024–1012px : full-width (right: 6px) — overlap minimo
       - 1012–2012px : width = 1000px fixo (right cresce com viewport)
       - >= 2012px   : width = ~50% do viewport (right: 50%)
       Necessario pra ter espaco a direita pro painel flutuante do preview. */
    .mag-page {
        right: max(6px, min(50%, calc(100% - 1006px)));
    }
    .mag-main {
        max-width: 1100px;
        margin: 0 auto;
        width: 100%;
    }
    .mag-main > .mag-w {
        height: auto;
        flex-shrink: 0;
    }
}

/* ═══════ Card-base ═══════ */
.mag-w {
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    display: flex;
    flex-direction: column;
}
.mag-w--side {
    background: var(--m-bg-medium);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
}
.mag-w__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--m-border);
}
.mag-w__icon {
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    border-radius: 9px;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--p-primary-color) 15%, transparent);
    color: var(--p-primary-color);
}
.mag-w__icon > i { font-size: 0.95rem; }
.mag-w__icon--purple { background: color-mix(in srgb, #a855f7 15%, transparent); color: #a855f7; }
.mag-w__icon--blue   { background: color-mix(in srgb, #3b82f6 15%, transparent); color: #3b82f6; }
.mag-w__icon--cyan   { background: color-mix(in srgb, #06b6d4 15%, transparent); color: #06b6d4; }
.mag-w__icon--green  { background: color-mix(in srgb, #10b981 15%, transparent); color: #10b981; }
.mag-w__icon--orange { background: color-mix(in srgb, #f97316 15%, transparent); color: #f97316; }
.mag-w__icon--pink   { background: color-mix(in srgb, #ec4899 15%, transparent); color: #ec4899; }
.mag-w__title { flex: 1; min-width: 0; }
.mag-w__title-text {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--m-text);
    line-height: 1.2;
}
.mag-w__sub {
    font-size: 0.74rem;
    color: var(--m-text-muted);
    margin-top: 2px;
    line-height: 1.3;
}
.mag-w__body {
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* ═══════ Sidebar: Status ═══════ */
.mag-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 9px;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
}
.mag-toggle-row__text { flex: 1; min-width: 0; }
.mag-toggle-row__label {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--m-text);
}
.mag-toggle-row__hint {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    margin-top: 2px;
    line-height: 1.3;
}

.mag-link-loading {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--m-text-muted);
    font-size: 0.78rem;
}
.mag-link-label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
}
.mag-link-row {
    display: flex;
    gap: 4px;
    align-items: stretch;
}
.mag-link-input {
    flex: 1;
    min-width: 0;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    color: var(--m-text);
    padding: 7px 10px;
    border-radius: 7px;
    font-size: 0.72rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    outline: none;
}
.mag-link-input:focus {
    border-color: var(--p-primary-color);
}

.mag-slug {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 8px;
    border-top: 1px solid var(--m-border);
}
.mag-slug__label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
}
.mag-slug__row {
    display: flex;
    align-items: stretch;
    border: 1px solid var(--m-border);
    border-radius: 7px;
    overflow: hidden;
    background: var(--m-bg-soft);
}
.mag-slug__prefix {
    padding: 7px 10px;
    background: var(--m-bg-medium);
    color: var(--m-text-muted);
    font-size: 0.72rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    border-right: 1px solid var(--m-border);
}
.mag-slug__input {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: none;
    color: var(--m-text);
    padding: 7px 10px;
    font-size: 0.78rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    outline: none;
}

.mag-upgrade {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 9px;
    background: rgba(245, 158, 11, 0.10);
    border: 1px dashed rgba(245, 158, 11, 0.40);
    color: var(--m-text-muted);
    font-size: 0.74rem;
    line-height: 1.4;
}
.mag-upgrade > i {
    color: rgb(245, 158, 11);
    font-size: 0.95rem;
    margin-top: 2px;
}

.mag-empty-link {
    padding: 10px 12px;
    border-radius: 9px;
    background: var(--m-bg-soft);
    border: 1px dashed var(--m-border);
    color: var(--m-text-muted);
    font-size: 0.78rem;
    text-align: center;
}

/* ═══════ Sidebar: Resumos ═══════ */
.mag-summary-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    color: var(--m-text);
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.mag-summary-item:hover {
    background: var(--m-bg-soft-hover);
    border-color: var(--m-border-strong);
}
.mag-summary-item__icon {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border-radius: 8px;
    flex-shrink: 0;
}
.mag-summary-item__icon > i { font-size: 0.85rem; }
.mag-summary-item__text { flex: 1; min-width: 0; }
.mag-summary-item__label {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--m-text);
}
.mag-summary-item__resumo {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mag-summary-item__chev {
    color: var(--m-text-muted);
    font-size: 0.7rem;
    flex-shrink: 0;
    opacity: 0.5;
}

/* ═══════ Buttons ═══════ */
.mag-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 8px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    font-family: inherit;
    transition: background-color 120ms ease, opacity 120ms ease;
}
.mag-btn:hover { background: var(--m-bg-soft-hover); }
.mag-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.mag-btn--primary {
    background: var(--p-primary-color);
    border-color: var(--p-primary-color);
    color: var(--p-primary-contrast-color, #fff);
}
.mag-btn--primary:hover {
    background: color-mix(in srgb, var(--p-primary-color) 88%, black);
}
.mag-btn--full { width: 100%; }
.mag-btn--sm { padding: 6px 10px; font-size: 0.78rem; }

.mag-icon-btn {
    width: 36px;
    display: grid;
    place-items: center;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    border-radius: 7px;
    color: var(--m-text-muted);
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color 120ms ease, color 120ms ease;
}
.mag-icon-btn:hover {
    background: var(--m-bg-soft-hover);
    color: var(--m-text);
}

.mag-card-actions {
    display: flex;
    justify-content: flex-end;
    padding-top: 4px;
    border-top: 1px solid var(--m-border);
    margin-top: 4px;
}

/* ═══════ Form ═══════ */
.mag-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    /* flex-shrink: 0 — em parent flex-col (.mag-w__body), garante que
       fields nao colapsem. Originalmente adicionado pro PrimeVue Editor
       (Quill) que media altura via JS e shrunk quando flex pai nao tinha
       altura definida. Mantido apos troca pra Jodit por consistencia
       (form fields nunca devem shrink em layout vertical). */
    flex-shrink: 0;
}
.mag-label {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--m-text);
}
.mag-label__opt {
    font-weight: 400;
    color: var(--m-text-muted);
    opacity: 0.7;
}
.mag-hint {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    line-height: 1.3;
}
.mag-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
}
.mag-divider {
    height: 1px;
    background: var(--m-border);
    margin: 4px 0;
}
.mag-group-title {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
}

/* Color picker */
.mag-color {
    display: flex;
    align-items: center;
    gap: 8px;
}
.mag-color__input {
    flex: 1;
    min-width: 0;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.mag-color__swatch {
    width: 36px;
    height: 36px;
    border-radius: 7px;
    border: 1px solid var(--m-border);
    flex-shrink: 0;
}

/* ═══════ Uploads ═══════ */
.mag-uploads {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}
@media (min-width: 700px) {
    .mag-uploads { grid-template-columns: repeat(3, 1fr); }
}
.mag-upload {
    border: 1px solid var(--m-border);
    border-radius: 9px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.mag-upload__head {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 10px;
    background: var(--m-bg-medium);
    border-bottom: 1px solid var(--m-border);
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--m-text);
}
.mag-upload__head > i { font-size: 0.78rem; opacity: 0.6; }
.mag-upload__body {
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mag-upload__hint {
    font-size: 0.68rem;
    color: var(--m-text-muted);
    opacity: 0.7;
}
.mag-upload__preview {
    display: flex;
    justify-content: center;
}
.mag-upload__img {
    max-width: 100%;
    height: 56px;
    border-radius: 6px;
    border: 1px solid var(--m-border);
    object-fit: cover;
}
.mag-upload__img--circle {
    width: 56px;
    height: 56px;
    border-radius: 50%;
}
.mag-upload__zone {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px;
    border: 1.5px dashed var(--m-border);
    border-radius: 7px;
    background: var(--m-bg-soft);
    color: var(--m-text-muted);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.74rem;
    font-weight: 600;
    transition: border-color 120ms ease, background-color 120ms ease;
}
.mag-upload__zone:hover {
    border-color: var(--p-primary-color);
    background: color-mix(in srgb, var(--p-primary-color) 6%, transparent);
}

/* ═══════ Radio cards ═══════ */
.mag-radio-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mag-radio {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 9px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: border-color 120ms ease, background-color 120ms ease;
}
.mag-radio:hover { border-color: var(--m-border-strong); }
.mag-radio.is-active {
    border-color: var(--p-primary-color);
    background: color-mix(in srgb, var(--p-primary-color) 6%, transparent);
}
.mag-radio__label {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--m-text);
}
.mag-radio__desc {
    font-size: 0.72rem;
    color: var(--m-text-muted);
    margin-top: 2px;
    line-height: 1.3;
}

.mag-radio--mode { gap: 12px; }
.mag-radio__icon {
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    border-radius: 9px;
    background: var(--m-bg-medium);
    color: var(--m-text-muted);
    flex-shrink: 0;
}
.mag-radio__icon.is-active {
    background: color-mix(in srgb, var(--p-primary-color) 18%, transparent);
    color: var(--p-primary-color);
}
.mag-radio__icon > i { font-size: 1rem; }
.mag-radio__text { flex: 1; min-width: 0; }
.mag-radio__check {
    color: var(--p-primary-color);
    flex-shrink: 0;
}

/* ═══════ Chips (tipos de agendamento) ═══════ */
.mag-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.mag-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    transition: all 120ms ease;
}
.mag-chip:hover { border-color: var(--m-border-strong); }
.mag-chip.is-active {
    background: var(--p-primary-color);
    border-color: var(--p-primary-color);
    color: var(--p-primary-contrast-color, #fff);
}
.mag-chip > i { font-size: 0.7rem; }

/* ═══════ Methods (pagar na hora) ═══════ */
.mag-methods {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.mag-method {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    cursor: pointer;
    font-size: 0.85rem;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.mag-method:hover { background: var(--m-bg-soft-hover); }
.mag-method.is-active {
    border-color: var(--p-primary-color);
    background: color-mix(in srgb, var(--p-primary-color) 6%, transparent);
}
.mag-method.is-disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.mag-method > i {
    color: var(--m-text-muted);
    font-size: 0.92rem;
}
.mag-method__label { flex: 1; font-weight: 600; }
.mag-method__tag { font-size: 0.66rem !important; }

.mag-warn {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 9px;
    background: rgba(245, 158, 11, 0.10);
    border: 1px solid rgba(245, 158, 11, 0.30);
    color: rgb(180, 83, 9);
    font-size: 0.78rem;
    line-height: 1.4;
}
.mag-warn > i { font-size: 0.92rem; margin-top: 2px; flex-shrink: 0; }

/* PrimeVue Editor (Quill) trocado por JoditTextEditor — Jodit traz
   CSS proprio (jodit/es2021/jodit.min.css importado no componente)
   e suporta dark/light via theme prop. Sem override scoped aqui. */

/* ═══════ Mobile drawer ═══════ */
.mag-mobile-drawer {
    position: fixed;
    top: 0; left: 0;
    height: 100vh;
    height: 100dvh;
    width: min(380px, 90vw);
    z-index: 80;
    background: var(--m-bg-medium);
    backdrop-filter: blur(28px) saturate(160%);
    -webkit-backdrop-filter: blur(28px) saturate(160%);
    border-right: 1px solid var(--m-border);
    transform: translateX(-100%);
    transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
    color: var(--m-text);
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    display: flex;
    flex-direction: column;
}
.mag-mobile-drawer.is-open { transform: translateX(0); }
.mag-mobile-drawer__scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mag-mobile-drawer__scroll::-webkit-scrollbar { width: 5px; }
.mag-mobile-drawer__scroll::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}
/* No mobile a .mag-side e teleportada pra dentro do drawer scroll. */
.mag-mobile-drawer__scroll .mag-side {
    width: 100%;
    border-right: none;
}

.mag-mobile-drawer__backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 79;
}
.mag-drawer-fade-enter-active,
.mag-drawer-fade-leave-active { transition: opacity 200ms ease; }
.mag-drawer-fade-enter-from,
.mag-drawer-fade-leave-to { opacity: 0; }

/* ═══════ Mobile (<1024px) ═══════ */
@media (max-width: 1023px) {
    .mag-body { flex-direction: column; padding: 0; }
    .mag-body > .mag-side { display: none; }
    .mag-main { width: 100%; padding: 8px; }
    .mag-main .mag-w {
        height: auto;
        flex: 0 0 auto;
        align-self: stretch;
    }
    .mag-grid-2 { grid-template-columns: 1fr; }
    .mag-page__title > span:first-of-type { display: none; }
    .mag-page__title-icon { display: none; }
    .mag-menu-btn--mobile-only { display: inline-flex; }
}

/* ═══════ Painel flutuante do Preview (wide-desktop >= 1340px) ═══════
   Vive FORA do fake dialog, ancorado a sua right edge + 14px gap.
   Largura fica em 320px pra acomodar o phone-frame (260px + bordas + padding).
   Glass igual ao fake dialog: fundo, blur, borda, radius, sombra. */
.mag-floating-preview {
    display: none; /* default: oculto. Wide-desktop ativa via @media abaixo. */
    position: absolute;
    top: 6px;
    /* height segue o conteudo (sem bottom). max-height limita ao mesmo
       espaco do fake dialog pra forcar scroll se ficar muito alto. */
    max-height: calc(100% - var(--m-dock-h, 76px) - 12px);
    width: 320px;
    z-index: 39; /* abaixo do mag-page (40) — nao concorre por foco */
    overflow-y: auto;
    overflow-x: hidden;
    /* Sem padding aqui: o card .mag-w--preview interno controla o espaco
       e seu __head fica flush com o topo, alinhando com o head do fake dialog. */
    padding: 0;
    background: var(--m-bg-medium);
    backdrop-filter: blur(32px) saturate(160%);
    -webkit-backdrop-filter: blur(32px) saturate(160%);
    border: 1px solid var(--m-border);
    border-radius: 18px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
    color: var(--m-text);
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mag-floating-preview::-webkit-scrollbar { width: 5px; }
.mag-floating-preview::-webkit-scrollbar-thumb { background: var(--m-border-strong); border-radius: 3px; }

/* Placeholders do preview na sidebar/main: nao introduzem wrapper visivel.
   Os filhos teleportados se posicionam como flex items diretos do parent
   (mag-side scroll ou mag-main), herdando o mesmo gap dos outros cards. */
.mag-sidebar-preview-target,
.mag-main-preview-target { display: contents; }

/* Esconde target da sidebar em mobile (preview vai pro main) e em
   wide-desktop (vai pro floating) */
@media (max-width: 1023px) {
    .mag-sidebar-preview-target { display: none; }
}

/* Esconde target do main em desktop (>=1024px) — preview vai pra
   sidebar/floating */
@media (min-width: 1024px) {
    .mag-main-preview-target { display: none; }
}

/* Dentro do painel flutuante, o card de preview perde o "card-em-card":
   sem fundo/borda/sombra propria (o glass do painel ja faz esse papel). */
.mag-floating-preview > .mag-w--preview {
    background: transparent;
    border: none;
    box-shadow: none;
    border-radius: 0;
}
.mag-floating-preview > .mag-w--preview > .mag-w__head {
    border-bottom: 1px solid var(--m-border);
    padding: 14px 18px;
}
.mag-floating-preview > .mag-w--preview > .mag-w__body {
    padding: 14px 18px;
}

/* Wide-desktop: floating ativo, ancorado a right edge do .mag-page + 14px gap.
   .mag-page tem `right: max(6px, min(50%, calc(100% - 1006px)))`, entao seu
   right edge esta a `100% - max(...)` do parent-left. O preview comeca 14px
   apos isso. 1340px e o piso onde page (1006) + gap (14) + preview (320) +
   margem (caso) cabem confortavelmente. */
@media (min-width: 1340px) {
    .mag-floating-preview {
        display: block;
        left: calc(100% - max(6px, min(50%, calc(100% - 1006px))) + 14px);
    }
    /* Placeholder da sidebar some — preview foi pro painel flutuante */
    .mag-sidebar-preview-target { display: none; }
}
</style>
