01La esquina que escucha
suggestions-fab.tsx · suggestions-widget.tsx · use-suggestions-unread.tsEl botón es el monograma sobre su aurora (--grad-hero), la misma voz que las puertas de auth. En la web móvil mide 48 px y descansa a la derecha, encima de la tab bar; la app re-deriva la altura para el shell de MF-03: la tab bar mide 98, así que el botón vive a 98 + 12 + safe-area del fondo, en su propia columna — el orbe de Crear (--grad-marca) vive dentro de la barra y nunca se tocan. Se monta una sola vez en el shell autenticado y flota sobre todas las tabs y stacks, solo con sesión iniciada. En reposo está quieto: sin halo, sin pulso, sin insignia. No pide nada.
Cuenta
Accesos
Ayuda
Preferencias
El monograma es el botón
48 px sobre
--grad-hero, bordergba(170,228,243,.35)y la sombra del widget web. El vector viene delogo-source: la «m» recolorea a blanco y el punto rojo no se toca. Sin label en móvil (el «Cuéntanos algo» del hover es de escritorio).Columna propia, plano propio
right: 14·bottom: tab bar (98) + 12 + safe-area. La web usa 74 sobre tabs de 62 — misma regla, shell distinto. El orbe de Crear queda centrado dentro de la barra: el pulgar sabe cuál es cuál sin pensarlo. El clearance de 88 px de la web lo cubre elpadding-bottomque las pantallas ya llevan.Con novedad: halo + insignia
El halo celeste respira 3.2 s (escala 1 → 1.26, se apaga al 70 %). La insignia es celeste con dígitos marino y borde blanco de 2 px, arriba a la derecha — nunca sobre el punto rojo. Más de 9 → «9+». Aria: «{{count}} novedades sin leer». Reduced motion: el halo no se pinta; la insignia queda.
Qué cuenta como novedad
countSuggestionNews: un cambio de estado (visto / anotada / lista) después del últimoopenedAt+ cada respuesta del equipo posterior.openedAtse guarda en MMKV (espejo demogos.suggestions.openedAt.{userId}) y se estampa al abrir el panel — con el corte capturado antes, para que los puntos no mueran al abrir.Siempre escuchando
El realtime se suscribe en la raíz del widget, no en el panel: el canal broadcast
suggestions-user-{id}(eventosuggestions-changed) invalida['suggestions']y la insignia se actualiza con el panel cerrado. En background el socket muere: se reconcilia con un refetch al volver a foreground (AppState).
«Enviar sugerencia» (Más › Accesos) y «Reportar problema» (Crear › Otros) existen desde MF-03 y en la web móvil llevan a la página /suggestions; Fabrizio decidió (2026-09-24) que en la app abren el panel del widget — la sección 03 lo detalla; la página legacy no se construye. El FAB es la puerta nueva y es global: no depende de ninguna fila. La web además llega por el ToolsGroup del top bar de escritorio, que en móvil no existe.
02El panel, a pantalla completa
suggestions-panel.tsx · crown · composer · thread-list · rating-card · status-lineA 390 el panel es pantalla completa, no una hoja a medias — una hoja al 70 % deja media app asomando y el teclado se come lo que queda. Arriba la corona: --grad-hero con dos brillos a la deriva (celeste 22 s, lima 31 s) y un saludo que se elige por prioridad: recién enviada («Gracias, {{nombre}}») > ventana de lanzamiento (activa hasta el 1 oct 2026) > default («¿Qué mejoramos?»). El cuerpo es lienzo blanco. La vista inicial la decide resolveInitialView: sin sugerencias → nueva; una → su hilo; dos o más → la lista «Historial». Se resuelve una vez — los refetch nunca te cambian de vista.
¡Estrenamos plataforma!
Gracias por confiar en Mogos. Si tienes algún comentario, oportunidad de mejora o sugerencia, escríbenos por aquí y con gusto te respondemos. Estamos para mejorar y es normal que al principio haya pequeños errores. ¡Gracias!
La corona saluda una sola cosa
Título 15/600 y cuerpo 12.5 en
--mogos-on-marino-soft, con la X (32 px) arriba a la derecha («Cerrar sugerencias»). El copy es el shippeado, no el de la proposal web vieja. «Recién enviada» gana mientras haya un mensaje en vuelo que no falló.Chips solo la primera vez
«Para empezar» aparece únicamente en la primera sugerencia de la vida y sin nada en vuelo. Cada chip (44 px, tile celeste de 26) entra en cascada — 50/130/210 ms — y al tocarlo prellena y enfoca: nunca clasifica ni envía.
El composer es una píldora
Hueso con borde
--lineen reposo; al teclear pasa a blanco con borde celeste-deep y anillorgba(95,185,216,.18). La letra va a 16 px para que iOS no haga zoom. Crece hasta 96 px; Enter envía. Validación: mínimo 10 («Cuéntanos un poco más…»), máximo 500. El botón (36, marino) se apaga a--papersin texto válido. La nota «Lo lee el equipo…» es de escritorio: aquí no va.Envío optimista
La burbuja aparece al instante con «Enviando…» y el
POST /suggestionssale detrás (conroutede la pantalla de origen). Si falla: «No se envió» + «Reintentar». Si el usuario cierra con un mensaje retenido,flush()lo envía al desmontar. La burbuja local muere cuando la fila del server aparece en/mine— y el panel salta a su hilo.No es modal
Sin backdrop ni focus trap en web; en la app es una pantalla presentada sobre el shell (se cierra con la X o el gesto de volver). El estado nace del botón: 640 ms
ease-outdesde la esquina inferior derecha, radio 50 % → 20. Reduced motion: aparece resuelta.
Gracias, Fabrizio
Ya está con el equipo. Cuando la vean, te lo digo acá.
La lista de envíos no me deja filtrar por fecha de llegada, y con siete cajas abiertas se me pierde cuál llega primero.
Enviada · 14:32Y en general, ¿cómo vamos?
¿Qué mejoramos?
Escríbelo como se te ocurra. Lo lee el equipo.
Me encantaría poder pagar en cuotas los envíos grandes.
Lista · ya está en la appYa puedes pagar en cuotas los envíos sobre 500 $. Lo activamos esta mañana: está en Pagos, al lado del monto.
¿Qué mejoramos?
Escríbelo como se te ocurra. Lo lee el equipo.
Ya puedes pagar en cuotas los envíos sobre 500 $. Lo activamos esta mañana: está en Pagos…
Lista · ya está en la appTú: ¿El almacén de Yiwu recibe los sábados?
Vista por el equipoLa lista de envíos no me deja filtrar por fecha de llegada, y con siete cajas abiertas…
Anotada para hacerlaLa fila muestra el último que habló: si fuiste tú, el preview lleva el prefijo «Tú:» en gris. La hora es hh:mm el mismo día y «12 sept» después. El punto celeste (8 px con aro rgba(170,228,243,.25)) marca la fila con novedades; se ordena por última actividad. El rating aparece solo tras el primer mensaje de la vida y una vez por sesión: retiene el envío («Enviando…») hasta que eliges o saltas, espera 1200 ms por si cambias, y viaja en el mismo POST. Estrellas en --mogos-warning-deep con pop de resorte — uno de los dos únicos resortes del widget; el otro es el tick de «Lista».
/suggestions/mine03Las puertas abren el panel
create-items.ts · mobile-create-sheet.tsx · mas.tsx · decidido 2026-09-24Decidido por Fabrizio (2026-09-24): «Enviar sugerencia» (Más › Accesos) y «Reportar problema» (Crear › Otros) abren el panel del widget — el sistema vivo, con respuestas del equipo desde Slack y la línea de estado — y no la página vieja. El formulario legacy /suggestions (rating obligatorio, escalas brand/gray) no se porta: en la app hay una sola voz para escuchar al cliente. El rating no se pierde — vive en el widget, tras el primer mensaje (sección 02).
Cuenta
Accesos
Ayuda
Preferencias
Dos filas, un panel
Ambas puertas navegan al panel del widget (vista según
resolveInitialView) y estampan su origen en elroutedelPOST /suggestions— «Reportar problema» llega como el Crear sheet, la fila de Más como Más — para que el equipo sepa desde dónde escribió el cliente.La página legacy no se construye
Sin formulario aparte, sin rating obligatorio, sin la nota de las 24-48 horas: el widget responde más rápido de lo que esa nota promete. La web conserva su página; la app tiene una sola voz.
Los textos no cambian
Las filas conservan sus claves y sus íconos de MF-03 («Enviar sugerencia», «Reportar problema»): cambia el destino, no el copy. El FAB sigue siendo la puerta global y no depende de ninguna fila.
04Anuncios: color por type, superficie por placement
announcement-provider · top-banner · announcement-modal · embed · floating · maintenanceUn AnnouncementProvider nativo con las reglas de la web: GET announcements/active (60 s de staleTime, sin polling — refresca al enfocar y al reconectar), un anuncio por superficie (el primero por displayOrder; descartar el primero revela el siguiente), y si hay un anuncio de mantenimiento, suprime todo lo demás. El registro no trae colores: el type decide el color y el placement la superficie. El «visto» se guarda en MMKV con scope de usuario (mogos.announcements.dismissed.{userId}) — decisión de Fabrizio 2026-09-24: mejor que la web, donde es por navegador y eterno.
Cuenta
Accesos
Ayuda
Preferencias
Nueva ruta aérea China–Caracas
Mira cómo funciona el nuevo corredor en 90 segundos.
Abre 500 ms después
El modal espera medio segundo tras montar la pantalla — que el shell respire antes de hablar. Velo
--mogos-marino/70, card blanca con radio 10, texto centrado en móvil, fade + zoom 95 %.El ancho lo decide el contenido… en escritorio
16:9 → 640 · 4:5 → 480 · 9:16 → 400. A 390 los tres convergen al ancho útil (pantalla − 16 por lado) y el alto manda:
max-h 92%con scroll interno para los reels altos.Dos cierres, un destino
La X de arriba y el «Cerrar» del pie hacen lo mismo, y cualquier cierre — botón, X, gesto — marca el anuncio como visto para ese usuario — el modal habla una sola vez. El footer es
col-reverse: el CTA (si el admin puso texto y URL) queda arriba, a ancho completo.El embed viaja en WebView
YouTube
/embed/{id}?rel=0, Instagram/p|/reel → /embed/, TikTokembed/v2, Vimeoplayer— detección por URL en el cliente, sin tokens. Archivo directo (.mp4/.webm/.ogg) →expo-video. Caja negra sin spinner, 6 s de timeout, y el riesgo del brief (IG/TikTok dentro de WebView móvil) se prueba en la F1 con los dos embeds reales.El título en display
DialogTitleusafont-family-display: Lemon Milk 24, centrado. La descripción es elcontentdel anuncio en 14/20 gris.
Así llegó el contenedor de agosto
Así llegó el contenedor de agosto
No pudimos mostrar el contenido aquí.
Ver en InstagramCuenta
Accesos
Ayuda
Preferencias
Debajo del header, scrollea con el contenido (el resto del Inicio va en esqueleto: es de MF-03 y no se redibuja). Tinte soft del type con el acento fuerte en el borde izquierdo, título en bold, texto, CTA como link y la X arriba a la derecha. Una a la vez — la más reciente —; cerrarla la despide para ese usuario. Nunca pisa la tab bar ni el FAB.
Mantenimiento programado
Estamos mejorando la plataforma. Volvemos en unos minutos; tus envíos siguen su curso.
Más información| Type | Etiqueta | Color (banners) | Contraste | Tarjeta en Inicio · soft + acento |
|---|---|---|---|---|
| URGENT | Urgente | bg-mogos-rojo #C9313C · texto blanco | AA | rojo-soft · acento rojo-deep |
| INFO | Informativo | bg-mogos-marino #021B54 · texto blanco | AAA | celeste-soft · acento marino |
| WARNING | Advertencia | bg-mogos-warning-deep #8A5A10 · texto blanco | AA (el base #B6791A da 3.71:1 y no llega) | warning-soft · acento warning-deep |
| SUCCESS | Exitoso | bg-mogos-success #2F7A4F · texto blanco | AA | success-soft · acento success-deep |
| MAINTENANCE | Mantenimiento | bg-mogos-marino-deep #01123A · texto blanco | AAA | paper · acento marino-deep |
El top banner muestra en móvil solo el título truncado (el content es de escritorio) más el CTA y la X; empuja el shell — el equivalente nativo del --top-banner-height que en web desplaza top bar y tabs, siempre bajo el status bar (safe-area). El FLOATING_BOTTOM no flota en móvil: es la tarjeta del Inicio. El modal y la pantalla de mantenimiento no usan el mapa de colores. Cuando el embed falla sin miniatura propia, el server scrapea el og:image (announcements/og-preview, allowlist de hosts, caché 6 h) y si tampoco hay, queda el peldaño 3: solo el botón «Ver en {Proveedor}». El provider pide hoy ALL+ANONYMOUS — el TODO web de pedir CLIENT se replica y queda anotado como deuda. El copy de todas estas superficies está hardcodeado en la web: la app lo lleva a claves i18n nuevas es/en/zh con el español literal.
05La ayuda se muda a Más
sidebar-help-button.tsx · lib/changelog.ts · use-changelog-state.ts · tools-discoveryEn la web la ayuda vive en un dropdown del sidebar de escritorio; ningún shell móvil la tiene. Del menú real se porta lo que existe y funciona: «Contactar soporte» (mailto:soporte@mogos.com — sin WhatsApp: no está en la ayuda web), «Enviar sugerencia» (ya está en Accesos desde MF-03) y «Novedades» (la lista del changelog, 3 entradas sin fechas, con su punto azul de no-visto). Quedan fuera, por paridad: «Buscar ayuda...» (deshabilitado), los atajos de teclado (no aplican), «Ver todo →» (muerto) y Tutoriales (oculto desde 26bf55375). La forma — una sección «Ayuda» en Más y las novedades en una hoja — quedó aprobada por Fabrizio (2026-09-24). MF-13 solo agrega la sección Ayuda — banda, Cuenta, Accesos, Preferencias, Cerrar sesión y versión quedan tal cual, en su orden. El spotlight de herramientas (ToolsDiscoveryOverlay) queda diferido, fuera del alcance de MF-13: es desktop-only en web y se retoma cuando exista su versión web móvil o Fabrizio lo pida. La versión ya está al fondo de Más desde MF-03.
Cuenta
Accesos
Ayuda
Preferencias
Accesos
Ayuda
Preferencias
Cuenta
Accesos
Ayuda
Preferencias
El punto azul de «Novedades» es el bg-blue-500 crudo de la web (deuda anotada): aparece cuando lastSeenChangelogId (MMKV, espejo de mogos.lastSeenChangelogId) no es la última entrada, y abrir la hoja lo apaga (markAsSeen), igual que abrir el dropdown. La hoja no agrega fechas ni cuerpos: la fuente (lib/changelog.ts) solo tiene título por entrada. El discovery queda diferido (decisión 2026-09-24): cuando entre, en una mega-fase posterior, replicará la mecánica web — dos compuertas (onboarding cerrado + flag toolsDiscoveryDismissed), un solo paso — con target y copy nuevos.
06Lo que hay que escribir en Moti
suggestions-widget.css · dialog.tsx · Moti + Reanimated · useReducedMotion| Pieza | Qué anima (ya existe en web) | Duración · easing | Reduced motion |
|---|---|---|---|
| Halo del FAB | escala 1 → 1.26 con fundido, en loop, solo con novedades | 3.2 s · ease-out | no se pinta (la insignia queda) |
| Nacimiento del panel | nace del botón: esquina inferior derecha, radio 50 % → 20, opacidad al 60 % | 640 ms · ease-out | aparece resuelta |
| Chips «Para empezar» | suben 8 px con fundido, en cascada | 420 ms · 50/130/210 | estado final |
| Estrella elegida | pop escala 0 → 1 — uno de los dos únicos resortes | 240 ms · spring | swap directo |
| Tick de «Lista» | el ícono cohete hace pop al llegar el estado — el otro resorte | 240 ms · spring | swap directo |
| Glows de la corona | celeste y lima derivan en alternancia | 22 s / 31 s · in-out | quietos |
| Composer | hueso → blanco + borde celeste-deep + anillo al teclear | 160 ms · ease-out | swap directo |
| Modal de anuncio | espera 500 ms tras montar; velo + card con fade y zoom 95 % (Dialog del sistema) | sistema (Dialog) | directo, misma espera |
| Banners (top · flotante) | sin animación propia en la web: aparecen resueltos — paridad | — | igual |
| Toasts Sileo (página vieja) | caen con resorte, como todas las MF anteriores | 640 ms · spring | directo |
«El movimiento es señal, no decoración»: los dos resortes significan algo bueno acaba de pasar. Todo lo demás confirma. Nada de esta tabla es nuevo — es el CSS shippeado del widget más el Dialog del sistema, portado a Moti con useReducedMotion.
07Lo cerrado y lo que decide Fabrizio
docs/specs/2026-09-24-mobile-sugerencias.md · HOLD hasta OK- Decidido · Fabrizio 2026-09-24
Las puertas abren el panel; la página no se porta
«Enviar sugerencia» (Más) y «Reportar problema» (Crear) abren el panel del widget — el sistema vivo con respuestas de Slack y estados — con el origen estampado en
route. El formulario legacy/suggestionsno se construye; el rating queda el del widget (opcional, tras el primer mensaje). Sección 03. - Decidido · Fabrizio 2026-09-24
FLOATING_BOTTOM = tarjeta inline en el Inicio
En móvil el banner no flota: es una tarjeta debajo del header del Inicio que scrollea con el contenido — nunca sobre la tab bar ni el FAB. Tinte soft del type con el acento fuerte en el borde izquierdo, título en bold, texto, CTA como link y X arriba a la derecha. Solo en Inicio, una a la vez (la más reciente); cerrarla la despide para ese usuario. Pares soft/deep de la marca, AA verificado (tabla en 04).
- Decidido · Fabrizio 2026-09-24
Ayuda en Más + novedades en hoja: aprobado
Tal cual la sección 05: «Contactar soporte» (mailto) y «Novedades» (hoja con el changelog + versión), con
markAsSeenal abrir. Fuera por paridad: búsqueda deshabilitada, atajos, «Ver todo →», WhatsApp. - Decidido · Fabrizio 2026-09-24
Discovery: diferido, fuera de MF-13
El
ToolsDiscoveryOverlayes desktop-only en web; su versión móvil no entra en esta mega-fase. Se retoma cuando la web tenga una o Fabrizio la pida; la mecánica (dos compuertas, un paso) queda inventariada en 05. - Cerrada · paridad
El panel es pantalla completa
A 390 la web lo hace
inset: 0: «no una hoja a medias». La app lo presenta sobre el shell con la corona bajo el status bar. La vista inicial la decideresolveInitialView(0 → nueva, 1 → hilo, 2+ → historial) y no cambia con los refetch. - Cerrada · paridad
La verdad es el código, no la proposal vieja
El widget shippeado derivó del diseño aprobado en agosto: hoy tiene la lista «Historial» («Tú:», «Nueva sugerencia»), el saludo largo de lanzamiento (hasta el 1 oct 2026), «No se envió» + «Reintentar» y el composer de respuesta. La maqueta sigue al código; el copy es el de
es.jsonliteral. - Cerrada · paridad
Estados por reacciones de Slack, REJECTED invisible
👀 → «Vista por el equipo» · ✅ → «Anotada para hacerla» · 🚀 → «Lista · ya está en la app» (el único estado con color) · 🗑️ → REJECTED, que el API filtra y el cliente jamás ve. Las respuestas del equipo llegan del hilo de Slack con
authorName. Realtime: canal broadcastsuggestions-user-{id}→ invalidación; en background se reconcilia al volver (riesgo del brief, cubierto con refetch enAppState). - Cerrada · paridad
Anuncios: type pinta, placement coloca
Cinco types → cinco colores de marca AA (tabla en 04, con su par soft para la tarjeta del Inicio); cuatro placements → cuatro superficies. El modal y mantenimiento no usan el mapa. Un anuncio por superficie; mantenimiento suprime el resto y no se cierra. Escalera de fallback: embed → card con miniatura (
bannerImageUrl??og-preview, caché 6 h) → «Ver en {Proveedor}». Sin polling:staleTime60 s + focus/reconnect. - Cerrada · paridad
Rating: una vez, reteniendo el envío
Solo tras el primer mensaje de la vida y una vez por sesión: el mensaje queda en «Enviando…» hasta elegir o saltar, espera 1200 ms por si cambias, y viaja en el mismo
POST /suggestions. En la página vieja el rating es obligatorio; en el widget, opcional. - Cerrada · adaptación declarada
localStorage → MMKV, con scope de usuario donde importa
mogos.announcements.dismissed.{userId}(visto de anuncios — por usuario, decisión 2026-09-24: en web es por navegador y eterno),mogos.suggestions.openedAt.{userId}(corte de no-leídos) ymogos.lastSeenChangelogId(novedades). La llave del discovery queda para cuando entre. Mismo shape que la web, sin expiración. - Cerrada · MF-12
Tutoriales siguen sin puerta
La web los quitó de la ayuda (
26bf55375) y del ToolsGroup; MF-12 los construyó ocultos tras deep link. MF-13 no abre la puerta: ni fila en Ayuda ni mención en el discovery. Cuando la web la reponga, la fila vuelve aquí. - Cerrada · reuso
Lo que ya existe
Shell y Más (MF-03), StackHeader (MF-04), hojas y toasts Sileo (MF-01),
PressScale, patrón WebView (MF-07), MMKV (MF-00). Es nuevo:SuggestionsFab,SuggestionsPanel(corona, composer, hilo, historial, rating),AnnouncementProvidernativo con top banner, modal,AnnouncementCarddel Inicio y mantenimiento, y la sección Ayuda de Más. - Deuda anotada
Lo que la web debe y la app no repite… o replica y anota
El provider nunca pide
targetAudience: CLIENT(TODO web — se replica para no divergir y queda anotado). Copy de anuncios hardcodeado sin i18n (la app lo lleva a claves nuevas). Dotsbg-blue-500fuera de tokens (se replican). «Ver todo →» muerto (se omite). El floating web sin safe-area no se hereda: en móvil es la tarjeta del Inicio..sug-clearancedefinido y sin uso. Dismiss de anuncios eterno y sin scope de usuario.og-previewpúblico con allowlist. - Testing
DoD en iPhone = Fabrizio
Enviar una sugerencia desde el widget → 👀 en Slack → «Vista por el equipo» sin refrescar. Publicar un anuncio con un reel desde el admin y verlo en banner y modal (embeds IG/TikTok en WebView: probar primero). Ver la tarjeta en el Inicio, cerrarla y que no vuelva. Activar mantenimiento y que la app quede bloqueada. Abrir Novedades desde Más. C9 automática:
expo export --platform web+ visual-qa a 390×844 contra estas 15 maquetas (DECISIONS #4/#24).