diff --git a/Obsidian/Brain/log.md b/Obsidian/Brain/log.md
index 11d69be..060f773 100644
--- a/Obsidian/Brain/log.md
+++ b/Obsidian/Brain/log.md
@@ -49,3 +49,53 @@ Touched: none
## [2026-05-08 00:00] session | Melissa cfg-* nativas + temas + cronometro DB
Touched: none
+
+## [2026-05-08 09:30] session | Chrome+preview em 7 paginas Melissa (LinkExterno preview novo)
+Touched: none (sem mudanca de wiki - aplicacao do pattern existente)
+Detalhes: Aplicou o chrome `right: max(6px, min(50%, calc(100% - 1006px)))`
+em 6 paginas tabulares (CadastrosRecebidos .mcr / Recorrencias .mr / Grupos
+.mg / Tags .mt / Compromissos .mc / Medicos .mm) - so o tamanho de janela,
+sem preview, conforme pedido pelo user. Adicionou novo @media (min-width:
+1024px) ao final de cada arquivo (cada um nao tinha esse breakpoint ainda).
+
+MelissaLinkExterno (.ml) ganhou tratamento completo: chrome + sidebar
+restruturada (2-col com aside agora a ESQUERDA, antes era a direita) +
+mobile drawer pattern (Teleport pro #ml-mobile-drawer-target, transitions,
+backdrop, botao Menu mobile-only) + 3-way teleport do preview (mobile=topo
+do main / mid-desktop=bottom da sidebar / wide-desktop>=1340=floating glass).
+Sidebar agora com Como funciona + Boas praticas (movidos da .ml-side direita)
++ scroll proprio. Sem cfg toggle (nao havia necessidade conceitual).
+
+Componente novo: src/components/cadastro/CadastroExternoPreview.vue (~350L).
+Phone-frame 260px estilo AgendadorPreview replicando o CadastroPacienteExterno
+publico: nav (logo Psi + chip verificado), hero (avatar 38px + nome split
+firstName/lastName em accent + work_description label + clinic name), stepper
+4 dots (1 active), card etapa 1 (numero decorativo + tag "Etapa 1 de 4" +
+title "Sobre voce" + 3 input bars + CTA "Continuar"), powered by. Recebe
+:token prop e busca info do convite via mesma edge function que o publico
+(get-intake-invite-info), watch refetcha quando token rotaciona. Sem token
+ou sem dados, fallbacks pra "Profissional" + iniciais.
+
+ESLint: 0 errors da minha mudanca. 2 errors pre-existentes em
+MelissaRecorrencias.vue (totalDone unused L235, v-for/v-bind:key L584) -
+nao toquei aquelas linhas. Working tree: 9 arquivos modificados +
+src/components/cadastro/ (untracked). Nao commitado, nao testado em browser.
+
+## [2026-05-08 07:55] session | MelissaAgendador preview celular teleport 3-way
+Touched: none (aplicacao do padrao MelissaNegocio - sem mudanca de wiki)
+Detalhes: Replicou o padrao floating preview do MelissaNegocio em
+MelissaAgendador.vue (+145L). Importou AgendadorPreview (phone-frame ja
+existente do legacy ConfiguracoesAgendadorPage). Adicionou ref isWideDesktop
++ matchMedia('(min-width: 1340px)') + computed previewTarget com 3-way
+branching: mobile -> #mag-main-preview-target (topo do main, acima de tudo,
+DIFERENTE do MelissaNegocio que vai pro drawer); mid-desktop (1024-1339) ->
+#mag-sidebar-preview-target (dentro da sidebar apos Status/Resumos);
+wide-desktop (>=1340) -> #mag-floating-preview-target (painel flutuante glass
+fora do fake dialog, 320px de largura, ancorado a +14px do right edge da
+.mag-page). Adicionou regra `right: max(6px, min(50%, calc(100% - 1006px)))`
+em .mag-page no @media >=1024px (necessario pra abrir espaco a direita pro
+floating). CSS: .mag-floating-preview com glass igual ao fake dialog;
+placeholders com display:contents; hide rules por breakpoint. Card de preview
+usa mag-w--side e perde fundo/borda no floating (glass do painel ja faz papel).
+ESLint 0 errors. Working tree: src/auto-imports.d.ts (auto-gerado) +
+MelissaAgendador.vue. Nao commitado, nao testado em browser ainda.
diff --git a/src/components/cadastro/CadastroExternoPreview.vue b/src/components/cadastro/CadastroExternoPreview.vue
new file mode 100644
index 0000000..e1cd641
--- /dev/null
+++ b/src/components/cadastro/CadastroExternoPreview.vue
@@ -0,0 +1,476 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Ψ
+ Agência PSI
+
+
+
+
+
+
+
+
+
Você foi convidado(a) por
+
+
+
+
{{ initials }}
+
+
+
{{ clinic.name }}
+
+ {{ firstName }}
+ {{ lastName }}
+
+
{{ workLabel }}
+
+
+
+
+
+
+
+ 01
+
+
+
+ 02
+
+
+
+ 03
+
+
+
+ 04
+
+
+
+
+
+
01
+
+ Etapa 1 de 4
+ 25%
+
+
+
+ Sobre
+ você
+
+
Preencha seus dados básicos.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Powered by Agência Psi
+
+
+
+
+
diff --git a/src/layout/melissa/MelissaAgendador.vue b/src/layout/melissa/MelissaAgendador.vue
index 494a0bc..da82ddd 100644
--- a/src/layout/melissa/MelissaAgendador.vue
+++ b/src/layout/melissa/MelissaAgendador.vue
@@ -17,6 +17,7 @@
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 { useTenantStore } from '@/stores/tenantStore';
@@ -41,14 +42,27 @@ 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; }
@@ -533,6 +547,11 @@ onMounted(async () => {
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();
@@ -543,6 +562,10 @@ onBeforeUnmount(() => {
try { _mqMobile.removeEventListener('change', _onMqMobileChange); }
catch { _mqMobile.removeListener(_onMqMobileChange); }
}
+ if (_mqWide) {
+ try { _mqWide.removeEventListener('change', _onMqWideChange); }
+ catch { _mqWide.removeListener(_onMqWideChange); }
+ }
clearTimeout(_copyTimer);
});
@@ -574,6 +597,12 @@ const summaryItems = computed(() => [
/>
+
+
+
+
+
+