<!--
|--------------------------------------------------------------------------
| Agência PSI — Cadastro externo de paciente (v2 · HomeCards DNA)
|--------------------------------------------------------------------------
| Redesenho disruptivo: multi-step flow (4 etapas), título com gradiente,
| números decorativos gigantes, DM Sans, fundo vivo (noise + lines + spots).
| Toda a lógica original foi preservada: fetch de invite info, ViaCEP,
| honeypot, captcha condicional, validação, submit, LGPD, mock DEV.
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, reactive, ref, onMounted, onBeforeUnmount, watch } from 'vue';
import { useRoute } from 'vue-router';

import InputMask from 'primevue/inputmask';
import Textarea from 'primevue/textarea';
import Checkbox from 'primevue/checkbox';
import Dialog from 'primevue/dialog';
import Select from 'primevue/select';

import { useToast } from 'primevue/usetoast';
import { supabase } from '@/lib/supabase/client';
import { digitsOnly, isValidEmail, toISODate, generateCPF, fmtCPF } from '@/utils/validators';
import MathCaptchaChallenge from '@/components/security/MathCaptchaChallenge.vue';
import { useLayout } from '@/layout/composables/layout';

const route = useRoute();
const toast = useToast();
const isDev = import.meta.env.DEV;

// Tema claro/escuro (sem persistência — só no tempo-de-vida desta página)
const { layoutConfig, isDarkTheme, toggleDarkMode } = useLayout();
const _initialDark = ref(false);

function forceLightSilent() {
    if (isDarkTheme.value) {
        document.documentElement.classList.remove('app-dark');
        layoutConfig.darkTheme = false;
    }
}
function restoreThemeSilent() {
    const want = _initialDark.value;
    if (isDarkTheme.value !== want) {
        document.documentElement.classList.toggle('app-dark', want);
        layoutConfig.darkTheme = want;
    }
}

// ----------------------------------------------------------------
// Token
// ----------------------------------------------------------------
const token = computed(() => String(route.query.t || '').trim());
const TOKEN_RX = /^[0-9a-f]{32}$|^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const tokenOk = computed(() => TOKEN_RX.test(token.value));

// ----------------------------------------------------------------
// Flags
// ----------------------------------------------------------------
const honeypot = ref('');
const captchaRequired = ref(false);
const captchaId = ref('');
const captchaAnswer = ref(null);
const salvando = ref(false);
const sucesso = ref(false);
const policyOpen = ref(false);

// ----------------------------------------------------------------
// Hero / Invite info
// ----------------------------------------------------------------
const inviteInfo = ref(null);
const loadingInfo = ref(false);
const heroAvatarFailed = ref(false);
const heroLogoFailed = ref(false);

const WORK_DESCRIPTION_LABEL = {
    psicologo_clinico: 'Psicólogo(a) Clínico(a)',
    psicanalista: 'Psicanalista',
    psiquiatra: 'Psiquiatra',
    psicoterapeuta: 'Psicoterapeuta',
    neuropsicologo: 'Neuropsicólogo(a)',
    psicologo_organizacional: 'Psicólogo(a) Organizacional',
    psicologo_escolar: 'Psicólogo(a) Escolar',
    psicologo_hospitalar: 'Psicólogo(a) Hospitalar',
    coach_mentor: 'Coach / Mentor(a)',
    terapeuta_holistico: 'Terapeuta Holístico(a)',
    outro: 'Profissional da saúde mental'
};

const heroTherapist = computed(() => inviteInfo.value?.therapist || null);
const heroClinic = computed(() => inviteInfo.value?.clinic || null);
const heroDisplayName = computed(() => heroTherapist.value?.display_name || 'Profissional');
const heroFirstName = computed(() => String(heroDisplayName.value || '').trim().split(/\s+/)[0] || '');
const heroLastName = computed(() => String(heroDisplayName.value || '').trim().split(/\s+/).slice(1).join(' '));
const heroAvatar = computed(() => (!heroAvatarFailed.value ? heroTherapist.value?.avatar_url || '' : ''));
const heroClinicLogo = computed(() => (!heroLogoFailed.value ? heroClinic.value?.logo_url || '' : ''));
const heroWorkLabel = computed(() => {
    const key = heroTherapist.value?.work_description;
    if (!key) return '';
    return WORK_DESCRIPTION_LABEL[key] || 'Profissional da saúde mental';
});
const heroInitials = computed(() => {
    const parts = String(heroDisplayName.value || '').trim().split(/\s+/).filter(Boolean);
    if (!parts.length) return '·';
    if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
    return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
});
const hasBothLogos = computed(() => !!(heroAvatar.value && heroClinicLogo.value));

function _normalizeUrl(u) {
    const s = String(u || '').trim();
    if (!s) return '';
    if (/^https?:\/\//i.test(s)) return s;
    return `https://${s}`;
}
function _instagramUrl(handle) {
    const s = String(handle || '').trim().replace(/^@/, '');
    if (!s) return '';
    if (/^https?:\/\//i.test(s)) return s;
    return `https://instagram.com/${s}`;
}
function _firstSocialFromClinic(socials) {
    if (!Array.isArray(socials)) return null;
    for (const item of socials) {
        if (!item) continue;
        if (typeof item === 'string' && item.trim()) return { label: 'Rede social', href: _normalizeUrl(item), icon: 'pi pi-globe', external: true };
        if (typeof item === 'object') {
            const url = item.url || item.link || item.handle;
            const kind = String(item.platform || item.type || item.network || '').toLowerCase();
            if (!url) continue;
            const href = kind.includes('instagram') ? _instagramUrl(url) : _normalizeUrl(url);
            const icon = kind.includes('instagram') ? 'pi pi-instagram'
                       : kind.includes('facebook')  ? 'pi pi-facebook'
                       : kind.includes('youtube')   ? 'pi pi-youtube'
                       : kind.includes('linkedin')  ? 'pi pi-linkedin'
                       : 'pi pi-globe';
            return { label: item.platform || 'Rede social', href, icon, external: true };
        }
    }
    return null;
}

const heroContactChips = computed(() => {
    const chips = [];
    const t = heroTherapist.value || {};
    const c = heroClinic.value || {};
    const parts = [c.street, c.number].filter(Boolean).join(', ');
    const cityUf = [c.city, c.state].filter(Boolean).join(' · ');
    const addr = [parts, c.neighborhood, cityUf].filter(Boolean).join(' — ');
    if (addr) chips.push({ label: addr, href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(addr)}`, icon: 'pi pi-map-marker', external: true });
    const phone = c.phone || t.phone;
    if (phone) {
        const d = String(phone).replace(/\D/g, '');
        chips.push({ label: phone, href: d ? `tel:+${d.startsWith('55') ? d : '55' + d}` : `tel:${phone}`, icon: 'pi pi-phone', external: false });
    }
    if (c.email) chips.push({ label: c.email, href: `mailto:${c.email}`, icon: 'pi pi-envelope', external: false });
    const site = c.site || t.site_url;
    if (site) chips.push({ label: 'Site', href: _normalizeUrl(site), icon: 'pi pi-globe', external: true });
    if (t.instagram) {
        const handle = String(t.instagram).replace(/^@/, '').replace(/^https?:\/\/(www\.)?instagram\.com\//i, '').replace(/\/$/, '');
        chips.push({ label: `@${handle}`, href: _instagramUrl(t.instagram), icon: 'pi pi-instagram', external: true });
    } else {
        const social = _firstSocialFromClinic(c.social);
        if (social) chips.push(social);
    }
    return chips;
});

async function fetchInviteInfo() {
    if (!tokenOk.value) return;
    loadingInfo.value = true;
    try {
        const { data, error } = await supabase.functions.invoke('get-intake-invite-info', { body: { token: token.value } });
        if (error) return;
        if (data?.ok && data.info) inviteInfo.value = data.info;
    } catch { /* silencioso */ } finally {
        loadingInfo.value = false;
    }
}

// Autosave de progresso (8.4) — backend marca status='in_progress' e, se
// paciente abandonar, job cron cria lead no CRM.
// Debounce pra não spammar: salva 1.5s após parar de digitar em campos chave.
let _progressTimer = null;
const progressDebounceMs = 1500;
function scheduleProgressSave() {
    if (!tokenOk.value || sucesso.value) return;
    if (_progressTimer) clearTimeout(_progressTimer);
    _progressTimer = setTimeout(savePartialProgress, progressDebounceMs);
}

async function savePartialProgress() {
    if (!tokenOk.value || sucesso.value) return;
    const nome = String(form.nome_completo || '').trim();
    const tel = digitsOnly(form.telefone || '');
    // Só salva se já tem mínimo pra contato (nome OU telefone)
    if (!nome && !tel) return;
    try {
        await supabase.functions.invoke('save-intake-progress', {
            body: {
                token: token.value,
                nome_completo: nome || undefined,
                telefone: tel || undefined,
                email_principal: String(form.email_principal || '').trim() || undefined,
                onde_nos_conheceu: String(form.onde_nos_conheceu || '').trim() || undefined
            }
        });
    } catch { /* silencioso — autosave não é crítico */ }
}

// O watch que dispara `scheduleProgressSave` foi movido pra depois da
// declaração de `form` (linha ~319) — referência aqui violava TDZ.

// ----------------------------------------------------------------
// Helpers
// ----------------------------------------------------------------
function cleanStr(v) { const s = String(v ?? '').trim(); return s ? s : null; }
function randInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
function pick(arr) { return arr[randInt(0, arr.length - 1)]; }
function maybe(p = 0.5) { return Math.random() < p; }
function pad2(n) { return String(n).padStart(2, '0'); }

function randomDateDDMMYYYY(minAge = 18, maxAge = 65) {
    const now = new Date();
    const age = randInt(minAge, maxAge);
    const year = now.getFullYear() - age;
    return `${pad2(randInt(1, 28))}-${pad2(randInt(1, 12))}-${year}`;
}
function randomPhoneBR() {
    return `(${randInt(11, 99)}) ${randInt(90000, 99999)}-${randInt(1000, 9999)}`;
}
function generateCPFFormatted() { return fmtCPF(generateCPF()); }
function generateRG() {
    const base = Array.from({ length: 8 }, () => randInt(0, 9));
    let sum = 0;
    for (let i = 0; i < 8; i++) sum += base[i] * (9 - i);
    const mod = sum % 11;
    let dv = 11 - mod;
    if (dv === 10) dv = 'X'; else if (dv === 11) dv = 0;
    return [...base, dv].join('').replace(/^(\d{2})(\d{3})(\d{3})([\dX])$/, '$1.$2.$3-$4');
}
function randomEmailFromName(name) {
    const slug = String(name || 'paciente').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().replace(/[^a-z0-9]+/g, '.').replace(/(^\.)|(\.$)/g, '');
    return `${slug}.${randInt(10, 999)}@email.com`;
}

// ----------------------------------------------------------------
// CEP
// ----------------------------------------------------------------
const cepLoading = ref(false);
const addressLocked = computed(() => salvando.value || cepLoading.value);

async function fetchCep(cepRaw) {
    const cep = String(cepRaw || '').replace(/\D/g, '');
    if (cep.length !== 8) return null;
    const res = await fetch(`https://viacep.com.br/ws/${cep}/json/`, { headers: { Accept: 'application/json' } });
    if (!res.ok) return null;
    const data = await res.json();
    if (!data || data.erro) return null;
    return data;
}
async function onCepBlur() {
    if (cepLoading.value) return;
    const cepDigits = String(form.cep || '').replace(/\D/g, '');
    if (cepDigits.length !== 8) return;
    cepLoading.value = true;
    try {
        const d = await fetchCep(form.cep);
        if (!d) { toast.add({ severity: 'warn', summary: 'CEP', detail: 'CEP não encontrado.', life: 2500 }); return; }
        form.cidade = d.localidade || form.cidade;
        form.estado = d.uf || form.estado;
        form.bairro = d.bairro || form.bairro;
        form.endereco = d.logradouro || form.endereco;
        if (!form.complemento) form.complemento = d.complemento || '';
        toast.add({ severity: 'success', summary: 'CEP', detail: 'Endereço preenchido automaticamente.', life: 1800 });
    } catch {
        toast.add({ severity: 'error', summary: 'CEP', detail: 'Falha ao consultar o ViaCEP.', life: 2500 });
    } finally {
        cepLoading.value = false;
    }
}

// ----------------------------------------------------------------
// Options
// ----------------------------------------------------------------
const GENDER_OPTIONS = [
    { label: 'Masculino', value: 'male' },
    { label: 'Feminino', value: 'female' },
    { label: 'Não-binário', value: 'non_binary' },
    { label: 'Outro', value: 'other' },
    { label: 'Prefiro não informar', value: 'na' }
];
const MARITAL_OPTIONS = [
    { label: 'Solteiro(a)', value: 'single' },
    { label: 'Casado(a)', value: 'married' },
    { label: 'Divorciado(a)', value: 'divorced' },
    { label: 'Viúvo(a)', value: 'widowed' },
    { label: 'Prefiro não informar', value: 'na' }
];

// ----------------------------------------------------------------
// Form
// ----------------------------------------------------------------
function resetForm() {
    return {
        nome_completo: '', email_principal: '', telefone: '',
        cep: '', pais: 'Brasil', cidade: '', estado: 'SP',
        endereco: '', numero: '', bairro: '', complemento: '',
        data_nascimento: '', naturalidade: '', genero: '', estado_civil: '',
        onde_nos_conheceu: '', encaminhado_por: '', observacoes: '',
        nacionalidade: '', email_alternativo: '', telefone_alternativo: '',
        cpf: '', rg: '', escolaridade: '', profissao: '',
        nome_parente: '', grau_parentesco: '', telefone_parente: '',
        nome_responsavel: '', telefone_responsavel: '', cpf_responsavel: '',
        observacao_responsavel: '', cobranca_no_responsavel: false
    };
}
const form = reactive(resetForm());
const consent = ref(false);

// Autosave de progresso: precisa de `form` declarado antes (TDZ).
watch(
    () => [form.nome_completo, form.telefone, form.email_principal, form.onde_nos_conheceu],
    scheduleProgressSave
);

const errors = reactive({
    nome_completo: '', email_principal: '', email_alternativo: '', telefone: '', consentimento: ''
});

function validate() {
    errors.nome_completo = '';
    errors.email_principal = '';
    errors.email_alternativo = '';
    errors.telefone = '';
    errors.consentimento = '';
    if (!String(form.nome_completo || '').trim()) errors.nome_completo = 'Informe seu nome completo';
    if (!isValidEmail(form.email_principal)) errors.email_principal = 'Informe um e-mail válido';
    if (cleanStr(form.email_alternativo) && !isValidEmail(form.email_alternativo)) errors.email_alternativo = 'E-mail alternativo inválido';
    if (!digitsOnly(form.telefone)) errors.telefone = 'Informe um telefone para contato';
    if (!consent.value) errors.consentimento = 'É necessário marcar o consentimento.';
    return !errors.nome_completo && !errors.email_principal && !errors.email_alternativo && !errors.telefone && !errors.consentimento;
}

// ----------------------------------------------------------------
// Progress
// ----------------------------------------------------------------
const progressPct = computed(() => {
    const checks = [!!cleanStr(form.nome_completo), !!digitsOnly(form.telefone), isValidEmail(form.email_principal), !!cleanStr(form.data_nascimento), !!cleanStr(form.cep), !!cleanStr(form.endereco), !!cleanStr(form.cidade), !!consent.value];
    const done = checks.filter(Boolean).length;
    return Math.round((done / checks.length) * 100);
});

// ----------------------------------------------------------------
// Steps (disruptive flow)
// ----------------------------------------------------------------
const STEPS = [
    { key: 'identity', short: 'Você',       titleA: 'Quem é',  titleB: 'você?',      desc: 'Começando com o essencial — nome, contato e como te chamar.',                      color: '#4ADE80', colorDim: 'rgba(74,222,128,0.1)',  colorBorder: 'rgba(74,222,128,0.28)' },
    { key: 'personal', short: 'Sobre você', titleA: 'Mais',    titleB: 'sobre você', desc: 'Dados pessoais e profissionais. Todos são opcionais — compartilhe o que quiser.',  color: '#60A5FA', colorDim: 'rgba(96,165,250,0.1)',  colorBorder: 'rgba(96,165,250,0.28)' },
    { key: 'address',  short: 'Endereço',   titleA: 'Onde te', titleB: 'encontrar',  desc: 'Digite o CEP e o resto preenche sozinho. Tudo aqui é opcional.',                    color: '#C084FC', colorDim: 'rgba(192,132,252,0.1)', colorBorder: 'rgba(192,132,252,0.28)' },
    { key: 'finalize', short: 'Finalizar',  titleA: 'Pra',     titleB: 'finalizar',  desc: 'Contatos de apoio, observações e seu consentimento. Depois é só enviar.',          color: '#A78BFA', colorDim: 'rgba(167,139,250,0.1)', colorBorder: 'rgba(167,139,250,0.28)' }
];

const currentStep = ref(0);
const farthestStep = ref(0);
const currentStepData = computed(() => STEPS[currentStep.value]);

function validateStep(idx) {
    if (idx === 0) {
        return !!String(form.nome_completo || '').trim()
            && isValidEmail(form.email_principal)
            && !!digitsOnly(form.telefone);
    }
    if (idx === 3) return consent.value === true;
    return true;
}
const canAdvance = computed(() => validateStep(currentStep.value));
const canSubmit = computed(() => validateStep(0) && validateStep(3));

function scrollTop() { window.scrollTo({ top: 0, behavior: 'smooth' }); }
function goNextStep() {
    if (!canAdvance.value) {
        if (currentStep.value === 0) validate();
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Preencha os campos obrigatórios.', life: 2000 });
        return;
    }
    if (currentStep.value < STEPS.length - 1) {
        currentStep.value += 1;
        if (currentStep.value > farthestStep.value) farthestStep.value = currentStep.value;
        scrollTop();
    }
}
function goPrevStep() {
    if (currentStep.value > 0) { currentStep.value -= 1; scrollTop(); }
}
function goToStep(i) {
    if (i > farthestStep.value) return;
    currentStep.value = i;
    scrollTop();
}

function preencherMock() {
    const firsts = ['Ana', 'Bruno', 'Carla', 'Daniel', 'Eduarda', 'Felipe', 'Giovana', 'Henrique', 'Isabela', 'João'];
    const lasts = ['Silva', 'Santos', 'Oliveira', 'Souza', 'Pereira', 'Lima', 'Ferreira', 'Almeida', 'Costa'];
    const cities = ['São Carlos', 'Ribeirão Preto', 'Campinas', 'São Paulo'];
    const neighborhoods = ['Centro', 'Jardim Paulista', 'Vila Prado', 'Santa Felícia'];
    const streets = ['Rua das Flores', 'Av. Brasil', 'Rua XV de Novembro', 'Av. São Carlos'];

    const nome = `${pick(firsts)} ${pick(lasts)} ${pick(lasts)}`;
    const cidade = pick(cities);

    form.nome_completo = nome;
    form.data_nascimento = randomDateDDMMYYYY(18, 70);
    form.naturalidade = cidade;
    form.genero = pick(GENDER_OPTIONS).value;
    form.estado_civil = pick(MARITAL_OPTIONS).value;
    form.email_principal = randomEmailFromName(nome);
    form.email_alternativo = maybe(0.35) ? `alt.${randInt(10, 999)}@gmail.com` : '';
    form.telefone = randomPhoneBR();
    form.telefone_alternativo = maybe(0.35) ? randomPhoneBR() : '';
    form.cpf = generateCPFFormatted();
    form.rg = generateRG();
    form.observacoes = 'Cadastro via link externo.';
    form.onde_nos_conheceu = pick(['Instagram', 'Google', 'Indicação', 'Site']);
    form.encaminhado_por = maybe(0.45) ? `${pick(firsts)} ${pick(lasts)}` : '';
    form.pais = 'Brasil';
    form.cep = '13561-260';
    form.cidade = cidade;
    form.estado = 'SP';
    form.endereco = pick(streets);
    form.numero = String(randInt(10, 9999));
    form.bairro = pick(neighborhoods);
    form.complemento = maybe(0.3) ? `Apto ${randInt(10, 999)}` : '';
    form.escolaridade = pick(['Ensino Médio', 'Superior completo', 'Pós-graduação']);
    form.profissao = pick(['Estudante', 'Professora', 'Desenvolvedor', 'Enfermeira']);
    form.nacionalidade = 'Brasileira';

    consent.value = true;
    farthestStep.value = STEPS.length - 1;
    currentStep.value = STEPS.length - 1;
    toast.add({ severity: 'info', summary: 'Exemplo', detail: 'Campos preenchidos.', life: 1800 });
}

// ----------------------------------------------------------------
// Enviar
// ----------------------------------------------------------------
async function enviar() {
    if (!tokenOk.value || sucesso.value) return;

    const ok = validate();
    if (!ok) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Revise os campos obrigatórios.', life: 2200 });
        if (errors.nome_completo || errors.email_principal || errors.telefone) currentStep.value = 0;
        else if (errors.consentimento) currentStep.value = STEPS.length - 1;
        return;
    }

    const isoBirth = toISODate(form.data_nascimento);
    if (cleanStr(form.data_nascimento) && !isoBirth) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Data de nascimento inválida (use DD-MM-AAAA).', life: 2500 });
        currentStep.value = 0;
        return;
    }

    salvando.value = true;
    try {
        const truncate = (v, n) => { const s = cleanStr(v); return s ? String(s).slice(0, n) : null; };
        const payload = {
            nome_completo: truncate(form.nome_completo, 200),
            email_principal: cleanStr(form.email_principal)?.toLowerCase().slice(0, 120) || null,
            telefone: digitsOnly(form.telefone),
            email_alternativo: cleanStr(form.email_alternativo)?.toLowerCase().slice(0, 120) || null,
            telefone_alternativo: digitsOnly(form.telefone_alternativo) || null,
            cpf: digitsOnly(form.cpf),
            rg: truncate(form.rg, 20),
            cep: digitsOnly(form.cep),
            pais: truncate(form.pais, 60) || 'Brasil',
            cidade: truncate(form.cidade, 120),
            estado: truncate(form.estado, 2) || 'SP',
            endereco: truncate(form.endereco, 200),
            numero: truncate(form.numero, 20),
            bairro: truncate(form.bairro, 120),
            complemento: truncate(form.complemento, 120),
            data_nascimento: isoBirth || null,
            naturalidade: truncate(form.naturalidade, 120),
            genero: cleanStr(form.genero),
            estado_civil: cleanStr(form.estado_civil),
            profissao: truncate(form.profissao, 120),
            escolaridade: truncate(form.escolaridade, 120),
            nacionalidade: truncate(form.nacionalidade, 80),
            onde_nos_conheceu: truncate(form.onde_nos_conheceu, 80),
            encaminhado_por: truncate(form.encaminhado_por, 120),
            observacoes: truncate(form.observacoes, 2000),
            consent: !!consent.value
        };
        Object.keys(payload).forEach((k) => { if (payload[k] === undefined) delete payload[k]; });

        const clientInfo = typeof navigator !== 'undefined' && navigator.userAgent
            ? String(navigator.userAgent).slice(0, 500) : null;

        if (captchaRequired.value && (!captchaId.value || captchaAnswer.value == null)) {
            toast.add({ severity: 'warn', summary: 'Verificação', detail: 'Responda a pergunta de verificação antes de enviar.', life: 3000 });
            salvando.value = false;
            return;
        }

        const { data, error } = await supabase.functions.invoke('submit-patient-intake', {
            body: {
                token: token.value,
                payload,
                website: honeypot.value,
                captcha_id: captchaId.value || null,
                captcha_answer: captchaAnswer.value,
                client_info: clientInfo
            }
        });

        let errBody = null;
        if (error?.context?.json) { try { errBody = await error.context.json(); } catch { /* sem body */ } }
        else if (error?.context && typeof error.context.text === 'function') {
            try { const t = await error.context.text(); if (t) { try { errBody = JSON.parse(t); } catch { errBody = { message: t }; } } } catch { /* sem body */ }
        }
        const errCode = String(errBody?.error || data?.error || '');

        if (/captcha-required/i.test(errCode)) {
            captchaRequired.value = true; captchaId.value = ''; captchaAnswer.value = null;
            toast.add({ severity: 'warn', summary: 'Verificação extra', detail: 'Por segurança, responda a pergunta abaixo.', life: 3500 });
            currentStep.value = STEPS.length - 1;
            salvando.value = false;
            return;
        }
        if (/captcha-wrong/i.test(errCode)) {
            captchaId.value = ''; captchaAnswer.value = null;
            toast.add({ severity: 'warn', summary: 'Verificação', detail: 'Resposta incorreta. Tente novamente.', life: 3500 });
            salvando.value = false;
            return;
        }
        if (/rate-limited/i.test(errCode)) {
            const retryAfter = errBody?.retry_after_seconds || data?.retry_after_seconds;
            const after = retryAfter ? Math.ceil(retryAfter / 60) : null;
            toast.add({ severity: 'warn', summary: 'Muitas tentativas', detail: after ? `Tente novamente em ${after} min.` : 'Tente novamente mais tarde.', life: 6000 });
            salvando.value = false;
            return;
        }

        // A partir daqui: sem código conhecido → loga e surfa detalhe real no toast.
        if (error || data?.error) {
            // eslint-disable-next-line no-console
            console.error('[submit-patient-intake] falhou', { errCode, errBody, rawError: error, data });
            const srvMsg = errBody?.message || data?.message;
            const detail = srvMsg
                ? srvMsg
                : (errCode ? `Erro do servidor: ${errCode}` : (error?.message || 'Falha ao enviar.'));
            throw new Error(detail);
        }

        sucesso.value = true;
        toast.add({ severity: 'success', summary: 'Enviado', detail: 'Cadastro enviado com sucesso.', life: 2500 });
    } catch (err) {
        toast.add({ severity: 'error', summary: 'Falha ao enviar', detail: err?.message || 'Não foi possível enviar. Verifique o link e tente novamente.', life: 4500 });
    } finally {
        salvando.value = false;
    }
}

watch(() => form.cep, (newVal, oldVal) => {
    const d = String(newVal || '').replace(/\D/g, '');
    const prev = String(oldVal || '').replace(/\D/g, '');
    if (d.length === 8 && d !== prev) onCepBlur();
});

onMounted(() => {
    _initialDark.value = isDarkTheme.value;
    forceLightSilent();
    fetchInviteInfo();
});

onBeforeUnmount(() => { restoreThemeSilent(); });
</script>

<template>
    <Toast />
    <div class="cpe-root" :class="{ 'is-dark': isDarkTheme }">
        <!-- BG -->
        <div class="cpe-bg" aria-hidden="true">
            <div class="cpe-bg__noise" />
            <div class="cpe-bg__line cpe-bg__line--1" />
            <div class="cpe-bg__line cpe-bg__line--2" />
            <div class="cpe-bg__line cpe-bg__line--3" />
            <div class="cpe-bg__spot cpe-bg__spot--a" />
            <div class="cpe-bg__spot cpe-bg__spot--b" />
        </div>

        <div class="cpe-wrap">
            <!-- NAV -->
            <nav class="cpe-nav">
                <div class="cpe-nav__brand">
                    <span class="cpe-nav__logo">Ψ</span>
                    <span class="cpe-nav__name">Agência PSI</span>
                </div>
                <div class="cpe-nav__right">
                    <span class="cpe-nav__chip" :class="tokenOk ? 'cpe-nav__chip--ok' : 'cpe-nav__chip--err'">
                        <i :class="tokenOk ? 'pi pi-check' : 'pi pi-times'" />
                        {{ tokenOk ? 'Link verificado' : 'Link inválido' }}
                    </span>
                    <button
                        type="button"
                        class="cpe-nav__theme"
                        :aria-label="isDarkTheme ? 'Mudar para modo claro' : 'Mudar para modo escuro'"
                        :title="isDarkTheme ? 'Modo claro' : 'Modo escuro'"
                        @click="toggleDarkMode"
                    >
                        <i :class="['pi', isDarkTheme ? 'pi-sun' : 'pi-moon']" />
                    </button>
                </div>
            </nav>

            <!-- ERROR -->
            <section v-if="!tokenOk" class="cpe-state cpe-state--error">
                <div class="cpe-state__eyebrow">Atenção</div>
                <h1 class="cpe-state__title">
                    <span>Este link</span>
                    <span class="cpe-accent">não é válido</span>
                </h1>
                <p class="cpe-state__sub">Verifique se você copiou a URL completa. Se o problema persistir, peça um novo link ao seu terapeuta.</p>
            </section>

            <!-- SUCCESS -->
            <section v-else-if="sucesso" class="cpe-state cpe-state--success">
                <div class="cpe-state__icon"><i class="pi pi-check" /></div>
                <div class="cpe-state__eyebrow">Tudo certo</div>
                <h1 class="cpe-state__title">
                    <span>Cadastro</span>
                    <span class="cpe-accent">enviado</span>
                </h1>
                <p class="cpe-state__sub">
                    {{ heroFirstName ? heroFirstName + ' recebeu suas informações e entrará em contato em breve.' : 'Seus dados foram enviados com sucesso.' }}
                    Você pode fechar esta página.
                </p>
            </section>

            <!-- FLOW -->
            <template v-else>
                <!-- Hero: loading -->
                <header v-if="loadingInfo && !inviteInfo" class="cpe-hero cpe-hero--loading">
                    <div class="cpe-hero__skel">
                        <div class="cpe-hero__skel-avatar" />
                        <div class="cpe-hero__skel-lines">
                            <div class="cpe-hero__skel-line" style="width: 32%" />
                            <div class="cpe-hero__skel-line" style="width: 68%" />
                            <div class="cpe-hero__skel-line" style="width: 50%" />
                        </div>
                    </div>
                </header>

                <!-- Hero: loaded -->
                <header v-else-if="inviteInfo" class="cpe-hero">
                    <div class="cpe-hero__eyebrow">Você foi convidado(a) por</div>
                    <div class="cpe-hero__identity">
                        <div class="cpe-hero__avatar-wrap">
                            <img
                                v-if="heroAvatar"
                                :src="heroAvatar"
                                :alt="heroDisplayName"
                                class="cpe-hero__avatar"
                                @error="heroAvatarFailed = true"
                            />
                            <div v-else class="cpe-hero__avatar cpe-hero__avatar--initials">{{ heroInitials }}</div>
                            <div v-if="hasBothLogos" class="cpe-hero__logo-badge" :title="heroClinic?.name || ''">
                                <img :src="heroClinicLogo" alt="" @error="heroLogoFailed = true" />
                            </div>
                        </div>
                        <div class="cpe-hero__content">
                            <div v-if="heroClinic?.name" class="cpe-hero__clinic">{{ heroClinic.name }}</div>
                            <h1 class="cpe-hero__title">
                                <span>{{ heroFirstName }}</span>
                                <span v-if="heroLastName" class="cpe-accent">{{ heroLastName }}</span>
                            </h1>
                            <div v-if="heroWorkLabel" class="cpe-hero__work">{{ heroWorkLabel }}</div>
                            <p v-if="heroTherapist?.bio" class="cpe-hero__bio">{{ heroTherapist.bio }}</p>
                            <div v-if="heroContactChips.length" class="cpe-hero__contacts">
                                <a
                                    v-for="chip in heroContactChips"
                                    :key="chip.icon + chip.label"
                                    :href="chip.href"
                                    :target="chip.external ? '_blank' : '_self'"
                                    :rel="chip.external ? 'noopener noreferrer' : undefined"
                                    class="cpe-hero__contact"
                                >
                                    <i :class="chip.icon" />
                                    <span>{{ chip.label }}</span>
                                </a>
                            </div>
                        </div>
                    </div>
                </header>

                <!-- Hero: fallback -->
                <header v-else class="cpe-hero cpe-hero--bare">
                    <div class="cpe-hero__eyebrow">Pré-cadastro</div>
                    <h1 class="cpe-hero__title">
                        <span>Vamos nos</span>
                        <span class="cpe-accent">conhecer</span>
                    </h1>
                    <p class="cpe-hero__bio cpe-hero__bio--standalone">Preencha seus dados no seu tempo. Leva poucos minutos.</p>
                </header>

                <!-- STEPPER -->
                <div class="cpe-stepper">
                    <template v-for="(step, i) in STEPS" :key="step.key">
                        <button
                            type="button"
                            class="cpe-stepper__item"
                            :class="{
                                'is-active': currentStep === i,
                                'is-done': currentStep > i,
                                'is-locked': i > farthestStep
                            }"
                            :disabled="i > farthestStep"
                            :style="{ '--c': step.color, '--c-dim': step.colorDim, '--c-border': step.colorBorder }"
                            @click="goToStep(i)"
                        >
                            <span class="cpe-stepper__num">{{ pad2(i + 1) }}</span>
                            <span class="cpe-stepper__label">{{ step.short }}</span>
                            <i v-if="currentStep > i" class="cpe-stepper__check pi pi-check" />
                        </button>
                        <span v-if="i < STEPS.length - 1" class="cpe-stepper__line" :class="{ 'is-done': currentStep > i }" />
                    </template>
                </div>

                <!-- STEP CARD -->
                <article
                    class="cpe-card"
                    :style="{
                        '--c': currentStepData.color,
                        '--c-dim': currentStepData.colorDim,
                        '--c-border': currentStepData.colorBorder
                    }"
                >
                    <div class="cpe-card__num" aria-hidden="true">{{ pad2(currentStep + 1) }}</div>
                    <div class="cpe-card__shine" aria-hidden="true" />

                    <div class="cpe-card__head">
                        <span class="cpe-card__tag">Etapa {{ currentStep + 1 }} de {{ STEPS.length }}</span>
                        <span class="cpe-card__progress-txt">{{ progressPct }}%</span>
                    </div>

                    <div class="cpe-card__body">
                        <h2 class="cpe-card__title">
                            <span>{{ currentStepData.titleA }}</span>
                            <span class="cpe-accent">{{ currentStepData.titleB }}</span>
                        </h2>
                        <p class="cpe-card__desc">{{ currentStepData.desc }}</p>

                        <!-- STEP 0 -->
                        <div v-if="currentStep === 0" class="cpe-fields">
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_nome">Nome completo <span class="cpe-req">*</span></label>
                                <InputText id="f_nome" v-model="form.nome_completo" placeholder="Como você se chama?" class="cpe-input" :disabled="salvando" />
                                <span v-if="errors.nome_completo" class="cpe-field__err">{{ errors.nome_completo }}</span>
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_email">E-mail principal <span class="cpe-req">*</span></label>
                                <InputText id="f_email" v-model="form.email_principal" placeholder="seu@email.com" class="cpe-input" :disabled="salvando" />
                                <span v-if="errors.email_principal" class="cpe-field__err">{{ errors.email_principal }}</span>
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_tel">Telefone / WhatsApp <span class="cpe-req">*</span></label>
                                <InputMask id="f_tel" v-model="form.telefone" mask="(99) 99999-9999" placeholder="(00) 00000-0000" class="cpe-input" :disabled="salvando" />
                                <span v-if="errors.telefone" class="cpe-field__err">{{ errors.telefone }}</span>
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_nasc">Data de nascimento</label>
                                <InputMask id="f_nasc" v-model="form.data_nascimento" mask="99-99-9999" placeholder="DD-MM-AAAA" class="cpe-input" :disabled="salvando" />
                            </div>
                        </div>

                        <!-- STEP 1 -->
                        <div v-else-if="currentStep === 1" class="cpe-fields">
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_cpf">CPF</label>
                                <InputMask id="f_cpf" v-model="form.cpf" mask="999.999.999-99" placeholder="000.000.000-00" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_rg">RG</label>
                                <InputMask id="f_rg" v-model="form.rg" mask="99.999.999-9" placeholder="00.000.000-0" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_genero">Gênero</label>
                                <Select id="f_genero" v-model="form.genero" :options="GENDER_OPTIONS" optionLabel="label" optionValue="value" placeholder="Selecione" showClear class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_civil">Estado civil</label>
                                <Select id="f_civil" v-model="form.estado_civil" :options="MARITAL_OPTIONS" optionLabel="label" optionValue="value" placeholder="Selecione" showClear class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_nacional">Nacionalidade</label>
                                <InputText id="f_nacional" v-model="form.nacionalidade" placeholder="Brasileira" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_natural">Naturalidade (onde nasceu)</label>
                                <InputText id="f_natural" v-model="form.naturalidade" placeholder="Cidade de nascimento" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_escola">Escolaridade</label>
                                <InputText id="f_escola" v-model="form.escolaridade" placeholder="Ex: Superior completo" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_profi">Profissão</label>
                                <InputText id="f_profi" v-model="form.profissao" placeholder="Sua profissão" class="cpe-input" :disabled="salvando" />
                            </div>
                        </div>

                        <!-- STEP 2 -->
                        <div v-else-if="currentStep === 2" class="cpe-fields">
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_cep">CEP</label>
                                <InputMask id="f_cep" v-model="form.cep" mask="99999-999" placeholder="00000-000" class="cpe-input" :disabled="salvando" @blur="onCepBlur" @keyup.enter="onCepBlur" />
                                <span v-if="cepLoading" class="cpe-field__hint">Consultando…</span>
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_pais">País</label>
                                <InputText id="f_pais" v-model="form.pais" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_cidade">Cidade</label>
                                <InputText id="f_cidade" v-model="form.cidade" class="cpe-input" :disabled="addressLocked" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_estado">Estado</label>
                                <InputText id="f_estado" v-model="form.estado" class="cpe-input" :disabled="addressLocked" />
                            </div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_end">Endereço</label>
                                <InputText id="f_end" v-model="form.endereco" placeholder="Rua, avenida…" class="cpe-input" :disabled="addressLocked" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_num">Número</label>
                                <InputText id="f_num" v-model="form.numero" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_bairro">Bairro</label>
                                <InputText id="f_bairro" v-model="form.bairro" class="cpe-input" :disabled="addressLocked" />
                            </div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_compl">Complemento</label>
                                <InputText id="f_compl" v-model="form.complemento" placeholder="Apto, bloco…" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_mailalt">E-mail alternativo</label>
                                <InputText id="f_mailalt" v-model="form.email_alternativo" placeholder="alternativo@email.com" class="cpe-input" :disabled="salvando" />
                                <span v-if="errors.email_alternativo" class="cpe-field__err">{{ errors.email_alternativo }}</span>
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_telalt">Telefone alternativo</label>
                                <InputMask id="f_telalt" v-model="form.telefone_alternativo" mask="(99) 99999?-9999" placeholder="(00) 00000-0000" class="cpe-input" :disabled="salvando" />
                            </div>
                        </div>

                        <!-- STEP 3 -->
                        <div v-else-if="currentStep === 3" class="cpe-fields">
                            <div class="cpe-fields__section">Contatos & origem</div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_onde">Como nos conheceu?</label>
                                <InputText id="f_onde" v-model="form.onde_nos_conheceu" placeholder="Instagram, Google, indicação…" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_encam">Encaminhado por</label>
                                <InputText id="f_encam" v-model="form.encaminhado_por" placeholder="Nome de quem te indicou" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_obs">Observações</label>
                                <Textarea id="f_obs" v-model="form.observacoes" rows="3" autoResize placeholder="Algo que queira compartilhar" class="cpe-input" :disabled="salvando" />
                            </div>

                            <div class="cpe-fields__section">Contato de apoio (opcional)</div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_par">Nome de um parente</label>
                                <InputText id="f_par" v-model="form.nome_parente" placeholder="Alguém próximo" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_gpar">Parentesco</label>
                                <InputText id="f_gpar" v-model="form.grau_parentesco" placeholder="Mãe, irmã, etc." class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_tpar">Telefone do parente</label>
                                <InputMask id="f_tpar" v-model="form.telefone_parente" mask="(99) 99999?-9999" placeholder="(00) 00000-0000" class="cpe-input" :disabled="salvando" />
                            </div>

                            <div class="cpe-fields__section">Responsável (se menor de idade)</div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_resp">Nome do responsável</label>
                                <InputText id="f_resp" v-model="form.nome_responsavel" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_cpfresp">CPF do responsável</label>
                                <InputMask id="f_cpfresp" v-model="form.cpf_responsavel" mask="999.999.999-99" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field">
                                <label class="cpe-field__label" for="f_telresp">Telefone do responsável</label>
                                <InputMask id="f_telresp" v-model="form.telefone_responsavel" mask="(99) 99999-9999" class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-field cpe-field--full">
                                <label class="cpe-field__label" for="f_obsresp">Observação do responsável</label>
                                <Textarea id="f_obsresp" v-model="form.observacao_responsavel" rows="2" autoResize class="cpe-input" :disabled="salvando" />
                            </div>
                            <div class="cpe-check cpe-check--alt cpe-field--full">
                                <Checkbox v-model="form.cobranca_no_responsavel" :binary="true" inputId="cobranca_responsavel" :disabled="salvando" />
                                <label for="cobranca_responsavel" class="cpe-check__label">
                                    <span class="cpe-check__title">Permitir cobranças no nome do responsável?</span>
                                    <span class="cpe-check__sub">O sistema poderá usar nome e CPF do responsável nas cobranças.</span>
                                </label>
                            </div>

                            <div class="cpe-fields__section cpe-fields__section--accent">Consentimento <span class="cpe-req">*</span></div>
                            <div class="cpe-check cpe-field--full">
                                <Checkbox v-model="consent" :binary="true" inputId="ext_consent" :disabled="salvando" />
                                <label for="ext_consent" class="cpe-check__label">
                                    <span class="cpe-check__title">Concordo em enviar meus dados para o terapeuta.</span>
                                    <span class="cpe-check__sub">
                                        Usados apenas para contato e organização do atendimento.
                                        <button type="button" class="cpe-link" @click="policyOpen = true">Ver política de privacidade</button>
                                    </span>
                                </label>
                            </div>
                            <div v-if="errors.consentimento" class="cpe-field__err cpe-field--full">
                                {{ errors.consentimento }}
                            </div>

                            <div v-if="captchaRequired" class="cpe-field--full">
                                <MathCaptchaChallenge v-model:id="captchaId" v-model:answer="captchaAnswer" />
                            </div>
                        </div>
                    </div>

                    <!-- Foot -->
                    <div class="cpe-card__foot">
                        <div class="cpe-card__progress">
                            <div class="cpe-card__progress-bar" :style="{ width: progressPct + '%' }" />
                        </div>
                        <div class="cpe-card__actions">
                            <button v-if="currentStep > 0" type="button" class="cpe-btn cpe-btn--ghost" :disabled="salvando" @click="goPrevStep">
                                <i class="pi pi-arrow-left" /> Voltar
                            </button>
                            <span class="cpe-card__actions-space" />
                            <button
                                v-if="currentStep < STEPS.length - 1"
                                type="button"
                                class="cpe-btn cpe-btn--primary"
                                :disabled="!canAdvance || salvando"
                                @click="goNextStep"
                            >
                                Continuar <i class="pi pi-arrow-right" />
                            </button>
                            <button
                                v-else
                                type="button"
                                class="cpe-btn cpe-btn--send"
                                :disabled="!canSubmit || salvando || (captchaRequired && (!captchaId || captchaAnswer == null))"
                                @click="enviar"
                            >
                                <i v-if="salvando" class="pi pi-spin pi-spinner" />
                                <i v-else class="pi pi-send" />
                                {{ salvando ? 'Enviando…' : 'Enviar cadastro' }}
                            </button>
                        </div>
                    </div>
                </article>

                <!-- Meta + DEV -->
                <div class="cpe-meta">
                    <span class="cpe-meta__item"><i class="pi pi-lock" /> Seus dados são usados apenas para contato.</span>
                    <button type="button" class="cpe-meta__link" @click="policyOpen = true">Política de privacidade</button>
                </div>

                <div v-if="isDev" class="cpe-dev">
                    <button type="button" class="cpe-btn cpe-btn--xs" @click="preencherMock">
                        <i class="pi pi-bolt" /> [DEV] Preencher exemplo
                    </button>
                </div>
            </template>

            <!-- FOOTER -->
            <footer class="cpe-footer">
                <span class="cpe-footer__psi">Ψ</span>
                Agência PSI · Tecnologia aplicada à escuta
            </footer>
        </div>

        <!-- Honeypot global (sempre no DOM, fora do step) -->
        <div class="cpe-hp" aria-hidden="true">
            <label for="ext_website">Não preencha este campo</label>
            <input id="ext_website" v-model="honeypot" type="text" tabindex="-1" autocomplete="off" />
        </div>

        <!-- LGPD Dialog -->
        <Dialog v-model:visible="policyOpen" modal header="Política de privacidade" :style="{ width: '92vw', maxWidth: '720px' }" :breakpoints="{ '640px': '96vw' }" :draggable="false" :dismissableMask="true">
            <div class="text-sm leading-relaxed text-[var(--text-color)] space-y-4">
                <section>
                    <h3 class="text-base font-semibold">Finalidade do tratamento</h3>
                    <p>Seus dados pessoais são coletados exclusivamente para viabilizar o contato do terapeuta com você e organizar o atendimento clínico. Não são usados para marketing, compartilhamento com terceiros ou perfilamento.</p>
                </section>
                <section>
                    <h3 class="text-base font-semibold">Dados coletados</h3>
                    <ul class="list-disc pl-5 space-y-1">
                        <li>Identificação: nome completo, CPF, RG (opcional), data de nascimento, gênero, estado civil, nacionalidade, naturalidade.</li>
                        <li>Contato: telefone(s), e-mail(s), endereço.</li>
                        <li>Contexto: profissão, escolaridade, parente/responsável, origem do contato, observações que você optar por fornecer.</li>
                    </ul>
                </section>
                <section>
                    <h3 class="text-base font-semibold">Base legal (LGPD)</h3>
                    <p>Tratamos seus dados com base no <b>consentimento</b> (Art. 7º, I da Lei 13.709/2018), e quando aplicável, execução de contrato de prestação de serviço terapêutico (Art. 7º, V).</p>
                </section>
                <section>
                    <h3 class="text-base font-semibold">Retenção</h3>
                    <p>Dados de pré-cadastro são mantidos pelo tempo necessário para a conversão em paciente (ou descarte, se não houver andamento). Após início do vínculo terapêutico, seguem as regras do prontuário clínico (Resolução CFP 001/2009: mín. 5 anos após último atendimento).</p>
                </section>
                <section>
                    <h3 class="text-base font-semibold">Seus direitos</h3>
                    <ul class="list-disc pl-5 space-y-1">
                        <li>Confirmação da existência de tratamento;</li>
                        <li>Acesso aos seus dados;</li>
                        <li>Correção de dados incompletos, inexatos ou desatualizados;</li>
                        <li>Anonimização, bloqueio ou eliminação de dados desnecessários;</li>
                        <li>Portabilidade dos dados;</li>
                        <li>Eliminação dos dados pessoais tratados com base no consentimento;</li>
                        <li>Revogação do consentimento.</li>
                    </ul>
                    <p class="mt-2">Para exercer qualquer desses direitos, entre em contato diretamente com o profissional que enviou este link.</p>
                </section>
                <section>
                    <h3 class="text-base font-semibold">Segurança</h3>
                    <p>Adotamos medidas técnicas (criptografia em trânsito, controle de acesso, registros de auditoria) e administrativas para proteger seus dados.</p>
                </section>
                <section class="text-xs text-[var(--text-color-secondary)]">
                    <p>Data da última revisão: 18/04/2026.</p>
                </section>
            </div>
            <template #footer>
                <Button label="Entendi" icon="pi pi-check" @click="policyOpen = false" />
            </template>
        </Dialog>
    </div>
</template>

<style scoped>
/* ══════════════════════════════════════════════════ */
/*  TOKENS (HomeCards DNA — claro default, escuro opt-in) */
/* ══════════════════════════════════════════════════ */
.cpe-root {
    /* CORES BASE — modo CLARO (padrão) */
    --bg: #fafafb;
    --surface: #ffffff;
    --surface-2: #f4f4f8;
    --border: rgba(10, 10, 20, 0.09);
    --border-2: rgba(10, 10, 20, 0.16);
    --text: #1a1a22;
    --muted: rgba(26, 26, 34, 0.62);
    --dim: rgba(26, 26, 34, 0.38);
    --overlay: rgba(10, 10, 20, 0.04);
    --overlay-2: rgba(10, 10, 20, 0.08);
    --line: rgba(10, 10, 20, 0.06);
    --btn-text: #0a0a0d;
    --noise-opacity: 0.35;
    --spot-a: rgba(124, 106, 247, 0.1);
    --spot-b: rgba(74, 222, 128, 0.08);
    --clinic-accent: #16a34a;
    --err-text: #b91c1c;
    --err-bg: rgba(244, 63, 94, 0.08);
    --err-border: rgba(244, 63, 94, 0.28);
    --num-opacity: 0.11;
    --scrim: rgba(255, 255, 255, 0.4);

    /* CORES FIXAS (iguais em ambos) */
    --primary: #7c6af7;
    --r: 14px;
    --r-lg: 24px;
    --r-xl: 32px;

    font-family: 'DM Sans', system-ui, -apple-system, sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    position: relative;
    overflow-x: hidden;
    transition: background 0.3s ease, color 0.3s ease;
}

/* Modo ESCURO (opt-in via classe) */
.cpe-root.is-dark {
    --bg: #0d0d10;
    --surface: #131317;
    --surface-2: #191920;
    --border: rgba(255, 255, 255, 0.07);
    --border-2: rgba(255, 255, 255, 0.12);
    --text: #eeeef2;
    --muted: rgba(238, 238, 242, 0.55);
    --dim: rgba(238, 238, 242, 0.25);
    --overlay: rgba(255, 255, 255, 0.04);
    --overlay-2: rgba(255, 255, 255, 0.08);
    --line: rgba(255, 255, 255, 0.06);
    --btn-text: #0a0a0d;
    --noise-opacity: 0.6;
    --spot-a: rgba(124, 106, 247, 0.14);
    --spot-b: rgba(74, 222, 128, 0.09);
    --clinic-accent: #4ade80;
    --err-text: #fda4af;
    --err-bg: rgba(244, 63, 94, 0.08);
    --err-border: rgba(244, 63, 94, 0.2);
    --num-opacity: 0.06;
    --scrim: rgba(0, 0, 0, 0.2);
}

/* BG */
.cpe-bg { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.cpe-bg__noise {
    position: absolute; inset: 0; opacity: var(--noise-opacity);
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
    background-size: 256px 256px;
}
.cpe-bg__line { position: absolute; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, var(--line), transparent); }
.cpe-bg__line--1 { top: 220px; }
.cpe-bg__line--2 { top: 52%; }
.cpe-bg__line--3 { bottom: 200px; }
.cpe-bg__spot { position: absolute; border-radius: 50%; filter: blur(110px); }
.cpe-bg__spot--a { width: 720px; height: 720px; top: -220px; right: -220px; background: radial-gradient(circle, var(--spot-a), transparent 65%); animation: cpe-flt 22s ease-in-out infinite alternate; }
.cpe-bg__spot--b { width: 640px; height: 640px; bottom: -160px; left: -180px; background: radial-gradient(circle, var(--spot-b), transparent 65%); animation: cpe-flt 28s ease-in-out infinite alternate-reverse; }
@keyframes cpe-flt { from { transform: translate(0,0) scale(1); } to { transform: translate(40px,30px) scale(1.08); } }

/* LAYOUT */
.cpe-wrap {
    position: relative; z-index: 1;
    max-width: 960px; margin: 0 auto;
    padding: 24px 20px 60px;
    display: flex; flex-direction: column; gap: 32px;
}

/* NAV */
.cpe-nav { display: flex; align-items: center; justify-content: space-between; animation: cpe-fadeUp 0.4s ease both; }
.cpe-nav__brand { display: flex; align-items: center; gap: 10px; }
.cpe-nav__logo { font-size: 1.5rem; font-weight: 700; color: var(--primary); line-height: 1; text-shadow: 0 0 20px rgba(124,106,247,0.5); }
.cpe-nav__name { font-size: 0.9rem; font-weight: 600; letter-spacing: -0.01em; opacity: 0.85; }
.cpe-nav__right { display: flex; align-items: center; gap: 10px; }
.cpe-nav__chip {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 0.7rem; font-weight: 600;
    padding: 5px 12px; border-radius: 100px;
    border: 1px solid var(--border); background: var(--overlay);
}
.cpe-nav__chip--ok { color: #16a34a; border-color: rgba(22,163,74,0.28); background: rgba(22,163,74,0.08); }
.cpe-root.is-dark .cpe-nav__chip--ok { color: #4ade80; border-color: rgba(74,222,128,0.25); background: rgba(74,222,128,0.08); }
.cpe-nav__chip--err { color: #dc2626; border-color: rgba(220,38,38,0.28); background: rgba(220,38,38,0.08); }
.cpe-root.is-dark .cpe-nav__chip--err { color: #f43f5e; border-color: rgba(244,63,94,0.25); background: rgba(244,63,94,0.08); }
.cpe-nav__chip i { font-size: 0.68rem; }

.cpe-nav__theme {
    display: inline-grid; place-items: center;
    width: 34px; height: 34px; border-radius: 10px;
    background: var(--overlay); border: 1px solid var(--border);
    color: var(--muted); cursor: pointer; font-size: 0.85rem;
    transition: all 0.18s cubic-bezier(0.22, 1, 0.36, 1);
}
.cpe-nav__theme:hover { background: var(--overlay-2); color: var(--text); border-color: var(--border-2); transform: translateY(-1px); }
.cpe-nav__theme:active { transform: translateY(0); }

/* ACCENT gradient */
.cpe-accent {
    color: transparent;
    background: linear-gradient(135deg, #a78bfa, #60a5fa 50%, #4ade80);
    -webkit-background-clip: text;
    background-clip: text;
}

/* HERO */
.cpe-hero { animation: cpe-fadeUp 0.5s ease both; }
.cpe-hero__eyebrow { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.16em; color: var(--primary); opacity: 0.75; margin-bottom: 14px; }
.cpe-hero__identity { display: flex; gap: 22px; align-items: flex-start; }
.cpe-hero__avatar-wrap { position: relative; flex: 0 0 auto; }
.cpe-hero__avatar { width: 96px; height: 96px; border-radius: 24px; object-fit: cover; border: 1px solid rgba(255,255,255,0.15); box-shadow: 0 12px 40px -12px rgba(124,106,247,0.4); display: grid; place-items: center; }
.cpe-hero__avatar--initials {
    font-size: 2rem; font-weight: 700; letter-spacing: -0.02em;
    background: linear-gradient(135deg, rgba(167,139,250,0.3), rgba(96,165,250,0.3), rgba(74,222,128,0.3));
    color: var(--text);
}
.cpe-hero__logo-badge { position: absolute; bottom: -6px; right: -6px; width: 36px; height: 36px; border-radius: 12px; border: 2px solid var(--bg); background: #fff; overflow: hidden; box-shadow: 0 6px 20px -6px rgba(0,0,0,0.5); }
.cpe-hero__logo-badge img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }
.cpe-hero__content { min-width: 0; flex: 1; }
.cpe-hero__clinic { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; color: var(--clinic-accent); opacity: 0.92; margin-bottom: 6px; }
.cpe-hero__title { display: flex; flex-wrap: wrap; gap: 0 14px; margin: 0; font-size: clamp(2rem, 4.5vw, 2.8rem); font-weight: 700; letter-spacing: -0.04em; line-height: 1.05; }
.cpe-hero__work { margin-top: 8px; font-size: 0.85rem; color: var(--muted); }
.cpe-hero__bio {
    margin: 12px 0 0; font-size: 0.88rem; line-height: 1.65; color: var(--muted); max-width: 560px;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.cpe-hero__bio--standalone { max-width: 480px; }
.cpe-hero__contacts { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px; }
.cpe-hero__contact {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 12px; border-radius: 100px;
    background: var(--overlay); border: 1px solid var(--border);
    color: var(--muted); font-size: 0.72rem; text-decoration: none;
    transition: all 0.15s; max-width: 320px;
}
.cpe-hero__contact:hover { background: var(--overlay-2); color: var(--text); border-color: var(--border-2); }
.cpe-hero__contact span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cpe-hero__contact i { font-size: 0.7rem; }
.cpe-hero__skel { display: flex; gap: 22px; align-items: flex-start; animation: cpe-pulse 1.4s ease-in-out infinite; }
.cpe-hero__skel-avatar { width: 96px; height: 96px; border-radius: 24px; background: var(--overlay-2); }
.cpe-hero__skel-lines { flex: 1; display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }
.cpe-hero__skel-line { height: 14px; background: var(--overlay-2); border-radius: 6px; }
@keyframes cpe-pulse { 0%,100%{opacity:.5;} 50%{opacity:1;} }

@media (max-width: 600px) {
    .cpe-hero__identity { flex-direction: column; gap: 16px; }
    .cpe-hero__avatar, .cpe-hero__skel-avatar { width: 80px; height: 80px; border-radius: 20px; }
}

/* STATE (error / success) */
.cpe-state {
    border: 1px solid var(--border); border-radius: var(--r-xl);
    background: var(--surface); padding: 48px 32px;
    text-align: center; animation: cpe-fadeUp 0.5s ease both;
}
.cpe-state__icon {
    width: 56px; height: 56px; border-radius: 16px; margin: 0 auto 16px;
    display: grid; place-items: center; font-size: 1.3rem;
    background: linear-gradient(135deg, rgba(74,222,128,0.2), rgba(96,165,250,0.2));
    border: 1px solid rgba(74,222,128,0.3); color: #4ade80;
}
.cpe-state__eyebrow { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.16em; margin-bottom: 12px; opacity: 0.7; }
.cpe-state--error .cpe-state__eyebrow { color: #f43f5e; }
.cpe-state--success .cpe-state__eyebrow { color: #4ade80; }
.cpe-state__title { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 14px; margin: 0 0 14px; font-size: clamp(2rem, 4.5vw, 2.8rem); font-weight: 700; letter-spacing: -0.04em; line-height: 1.1; }
.cpe-state__sub { margin: 0 auto; max-width: 480px; font-size: 0.92rem; line-height: 1.6; color: var(--muted); }

/* STEPPER */
.cpe-stepper { display: flex; align-items: center; gap: 4px; animation: cpe-fadeUp 0.5s ease both; }
.cpe-stepper__item {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 8px 16px; border-radius: 100px;
    background: var(--overlay); border: 1px solid var(--border);
    color: var(--muted); cursor: pointer;
    font-family: inherit; font-size: 0.78rem; font-weight: 500;
    transition: all 0.18s cubic-bezier(0.22, 1, 0.36, 1);
    flex-shrink: 0;
}
.cpe-stepper__item:hover:not(.is-locked):not(.is-active) { background: var(--overlay-2); color: var(--text); }
.cpe-stepper__item.is-active { background: var(--c-dim); border-color: var(--c-border); color: var(--c); }
.cpe-stepper__item.is-done { color: var(--c); border-color: var(--c-border); background: var(--overlay); }
.cpe-stepper__item.is-locked { opacity: 0.4; cursor: not-allowed; }
.cpe-stepper__num { font-size: 0.72rem; font-weight: 700; opacity: 0.75; }
.cpe-stepper__label { font-weight: 600; letter-spacing: -0.01em; }
.cpe-stepper__check { font-size: 0.72rem; }
.cpe-stepper__line { flex: 1; min-width: 10px; height: 1px; background: var(--border); transition: background 0.2s; }
.cpe-stepper__line.is-done { background: rgba(167,139,250,0.4); }
@media (max-width: 640px) {
    .cpe-stepper__label { display: none; }
    .cpe-stepper__item { padding: 6px 12px; }
    .cpe-stepper__line { flex: 1; min-width: 6px; }
}

/* STEP CARD */
.cpe-card {
    position: relative; overflow: hidden;
    border: 1px solid var(--border); border-radius: var(--r-xl);
    background: var(--surface);
    transition: border-color 0.22s ease;
    animation: cpe-fadeUp 0.45s ease both;
}
.cpe-card:hover { border-color: var(--c-border); }
.cpe-card__num {
    position: absolute; top: 24px; right: 32px;
    font-size: 7rem; font-weight: 900; letter-spacing: -0.08em; line-height: 0.85;
    color: var(--c); opacity: var(--num-opacity); pointer-events: none; user-select: none;
}
.cpe-card__shine {
    position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0.5;
    background: radial-gradient(ellipse at 15% 0%, var(--c-dim), transparent 60%);
}
.cpe-card__head { position: relative; display: flex; align-items: center; justify-content: space-between; padding: 24px 28px 0; }
.cpe-card__tag {
    display: inline-flex; align-items: center; padding: 4px 11px; border-radius: 100px;
    background: var(--c-dim); border: 1px solid var(--c-border);
    color: var(--c); font-size: 0.65rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.12em;
}
.cpe-card__progress-txt { font-size: 0.72rem; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.cpe-card__body { position: relative; padding: 24px 28px 28px; }
.cpe-card__title {
    display: flex; flex-wrap: wrap; gap: 0 14px; margin: 0 0 10px;
    font-size: clamp(1.6rem, 3.8vw, 2.4rem);
    font-weight: 700; letter-spacing: -0.04em; line-height: 1.05;
}
.cpe-card__desc { margin: 0 0 28px; font-size: 0.92rem; line-height: 1.6; color: var(--muted); max-width: 540px; }

/* FIELDS */
.cpe-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 640px) { .cpe-fields { grid-template-columns: 1fr; gap: 14px; } }
.cpe-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cpe-field--full { grid-column: 1 / -1; }
.cpe-field__label { font-size: 0.72rem; font-weight: 600; color: var(--muted); letter-spacing: 0.01em; }
.cpe-req { color: var(--c, var(--primary)); font-weight: 700; }
.cpe-field__err {
    font-size: 0.72rem; color: var(--err-text);
    padding: 6px 10px; border-radius: 8px;
    background: var(--err-bg); border: 1px solid var(--err-border);
}
.cpe-field__hint { font-size: 0.7rem; color: var(--muted); }

.cpe-fields__section {
    grid-column: 1 / -1;
    font-size: 0.66rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.16em;
    color: var(--dim); padding-top: 10px;
    border-top: 1px dashed var(--border);
    margin-top: 6px;
}
.cpe-fields__section:first-child { border-top: none; padding-top: 0; margin-top: 0; }
.cpe-fields__section--accent { color: var(--c); }

/* PrimeVue tweaks (escopo .cpe-input) */
.cpe-input {
    width: 100% !important;
    background: var(--surface-2) !important;
    border: 1px solid var(--border) !important;
    color: var(--text) !important;
    border-radius: var(--r) !important;
    padding: 12px 14px !important;
    font-size: 0.88rem !important;
    font-family: inherit !important;
    transition: all 0.18s !important;
}
.cpe-input:hover:not(:disabled) { border-color: var(--border-2) !important; }
.cpe-input:focus, .cpe-input:focus-visible, .cpe-input:focus-within {
    border-color: var(--c, var(--primary)) !important;
    outline: none !important;
    box-shadow: 0 0 0 3px var(--c-dim, rgba(124,106,247,0.18)) !important;
}
.cpe-input:disabled { opacity: 0.55; }
/* Select (wrapper div) */
.cpe-input:is(.p-select) {
    display: flex; align-items: center;
    padding: 0 !important; min-height: 46px;
}
.cpe-input :deep(.p-select-label) { padding: 12px 14px !important; font-size: 0.88rem !important; color: var(--text) !important; }
.cpe-input :deep(.p-select-dropdown) { color: var(--muted) !important; }
.cpe-input :deep(.p-select-clear-icon) { color: var(--muted) !important; }
/* Textarea */
.cpe-input:is(textarea) { min-height: 72px; resize: vertical; line-height: 1.55; }

/* Select overlay */
.cpe-root :deep(.p-select-overlay) {
    background: var(--surface) !important;
    border: 1px solid var(--border) !important;
    border-radius: var(--r) !important;
    color: var(--text) !important;
    box-shadow: 0 12px 40px -12px rgba(0, 0, 0, 0.2) !important;
}
.cpe-root :deep(.p-select-list) { padding: 6px !important; }
.cpe-root :deep(.p-select-option) {
    color: var(--text) !important;
    border-radius: 10px !important;
    padding: 10px 12px !important;
}
.cpe-root :deep(.p-select-option.p-focus),
.cpe-root :deep(.p-select-option:hover) { background: var(--overlay-2) !important; }

/* Checkbox */
.cpe-check {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 14px; border-radius: var(--r);
    background: var(--overlay); border: 1px solid var(--border);
    grid-column: 1 / -1;
}
.cpe-check--alt { background: transparent; border: 1px dashed var(--border); }
.cpe-check__label { cursor: pointer; font-size: 0.82rem; color: var(--text); line-height: 1.5; flex: 1; }
.cpe-check__title { display: block; font-weight: 600; }
.cpe-check__sub { display: block; margin-top: 4px; font-size: 0.76rem; color: var(--muted); }
.cpe-root :deep(.p-checkbox) { margin-top: 2px; }
.cpe-root :deep(.p-checkbox .p-checkbox-box) {
    background: var(--surface-2) !important;
    border-color: var(--border-2) !important;
    border-radius: 6px !important;
    width: 20px; height: 20px;
}
.cpe-root :deep(.p-checkbox.p-highlight .p-checkbox-box) {
    background: var(--c, var(--primary)) !important;
    border-color: var(--c, var(--primary)) !important;
}

.cpe-link {
    background: none; border: none; padding: 0;
    color: var(--c, var(--primary)); font-size: 0.76rem;
    cursor: pointer; text-decoration: underline; font-family: inherit;
}
.cpe-link:hover { filter: brightness(1.2); }

/* Honeypot */
.cpe-hp { position: absolute; left: -9999px; top: -9999px; }

/* CARD FOOT */
.cpe-card__foot {
    position: relative; border-top: 1px solid var(--border);
    padding: 18px 28px; display: flex; flex-direction: column; gap: 14px;
    background: var(--overlay);
}
.cpe-card__progress { position: relative; height: 3px; width: 100%; background: var(--overlay-2); border-radius: 100px; overflow: hidden; }
.cpe-card__progress-bar { height: 100%; border-radius: inherit; background: var(--c); transition: width 0.35s ease; }
.cpe-card__actions { display: flex; align-items: center; gap: 10px; }
.cpe-card__actions-space { flex: 1; }

/* BUTTONS */
.cpe-btn {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 11px 20px; border-radius: 12px;
    font-size: 0.85rem; font-weight: 600;
    cursor: pointer; border: none; white-space: nowrap;
    transition: all 0.18s cubic-bezier(0.22, 1, 0.36, 1);
    font-family: inherit;
}
.cpe-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.cpe-btn--primary {
    background: var(--c, var(--primary)); color: var(--btn-text);
    box-shadow: 0 10px 36px -14px var(--c, var(--primary));
}
.cpe-btn--primary:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.12); }
.cpe-btn--send {
    background: linear-gradient(135deg, #a78bfa, #60a5fa 50%, #4ade80);
    color: var(--btn-text);
    box-shadow: 0 14px 48px -14px rgba(124,106,247,0.6);
    padding: 11px 24px;
}
.cpe-btn--send:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.08); }
.cpe-btn--ghost {
    background: transparent; color: var(--muted);
    border: 1px solid var(--border);
}
.cpe-btn--ghost:hover:not(:disabled) { background: var(--overlay); color: var(--text); border-color: var(--border-2); }
.cpe-btn--xs {
    padding: 6px 12px; font-size: 0.72rem; border-radius: 8px;
    background: var(--overlay); color: var(--muted);
    border: 1px solid var(--border);
}
.cpe-btn--xs:hover:not(:disabled) { background: var(--overlay-2); color: var(--text); }

/* META / DEV / FOOTER */
.cpe-meta {
    display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
    font-size: 0.76rem; color: var(--muted);
}
.cpe-meta__item { display: inline-flex; align-items: center; gap: 7px; }
.cpe-meta__item i { opacity: 0.7; }
.cpe-meta__link {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--primary); font-size: 0.76rem; text-decoration: underline;
    font-family: inherit;
}
.cpe-meta__link:hover { filter: brightness(1.2); }

.cpe-dev { display: flex; justify-content: flex-end; padding-top: 4px; }

.cpe-footer {
    display: flex; align-items: center; justify-content: center;
    gap: 8px; padding-top: 16px;
    font-size: 0.72rem; color: var(--dim);
}
.cpe-footer__psi { font-weight: 700; color: var(--primary); opacity: 0.5; }

/* ANIMS */
@keyframes cpe-fadeUp {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Mobile specifics for card */
@media (max-width: 540px) {
    .cpe-card__head, .cpe-card__body, .cpe-card__foot { padding-left: 20px; padding-right: 20px; }
    .cpe-card__num { font-size: 5rem; top: 16px; right: 20px; }
    .cpe-card__actions { flex-direction: column-reverse; align-items: stretch; }
    .cpe-card__actions-space { display: none; }
    .cpe-btn { width: 100%; justify-content: center; }
}
</style>
