01El esqueleto
mobile-shell/index.tsx · mobile-top-bar.tsx · mobile-bottom-tabs.tsx · mobile-tab-items.tsLa web ya diseñó el shell móvil: top bar de 56 con wordmark, chip de ruta, campana y avatar; barra de 64 con cuatro pestañas y un FAB entre la segunda y la tercera; el <main> como único scroll. La app lo replica con safe areas de verdad —el notch arriba, el indicador de inicio abajo— y lo supera en dos sitios: el orbe y su muesca, y la campana que dice cuántas.
Top bar de 56 bajo la barra de estado
useSafeAreaInsets().topcomo padding real, no el--mobile-safe-area-topcondicional de la PWA. Fondo blanco al 72 % conexpo-blur(intensidad 20, saturate), líneaborder/40y la sombra del 4 % tintada a marino. Rejilla1fr auto 1fr: wordmark a la izquierda, chip centrado, campana y avatar a la derecha, todos de 44 de zona táctil.El wordmark es el mismo vector de la puerta
MogosWordmarkde MF-02 (cinco paths + punto) a 74 px, tinta marino. Un solo logo en todo el cliente: puertas, sidebar web, top bar. Toca y vuelve a/account.El chip de ruta: punto vivo, bandera, nombre corto
32 de alto, píldora, 10 px Geist medium. El punto de 6 lleva el ping de la web (escala 2,4 y fade, 1 s,
cubic-bezier(0,0,.2,1)) ensuccess-500del producto —la web usaemerald-500de Tailwind, que no está en la paleta— y la bandera deCountryFlag. «China» / «USA» porgetCorridorShortName; «Todas las rutas» con el globo y el punto apagado.La campana cuenta
La web muestra un punto marino y esconde la cifra en
sr-only. En el teléfono la cifra es lo útil: píldora marino de 16 con el número denotifications/unread-count, anillo blanco de 2. Marino y no rojo, por la misma razón que la web anotó: el azul es el idioma de esta zona; el rojo, de los errores. Polling de 60 s comouse-unread-count.Cuatro pestañas y un hueco de 64
MOBILE_TAB_ITEMStal cual: Inicio (activo solo en/accountexacto), Fletes, Almacén, Más. Icono 18 + etiqueta 10; inactivomuted-foreground, activobrand-700. Almacén leenav-feature-flags:comingSoon→ chip «Pronto» (brand-500, 8 px bold) y el tap abre el modal, nunca navega. Más lleva el puntoerror-500cuandosidebar-counts.pendingPayments > 0.La muesca
La barra no es un rectángulo: una máscara radial la muerde alrededor del orbe (radio 34 = 30 del orbe + 4 de aire) y un anillo de 71 dibuja el borde de la muesca con la misma línea de la barra. En RN:
react-native-svgcon unPathde la barra +BlurViewenmascarado (MaskedView). Es lo que hace que el orbe «se escape» de la barra sin el anillo blanco de 3 px de la web.Safe area abajo: 64 + 34
La barra mide 64; debajo, el inset del indicador de inicio (34 en iPhone con Face ID, 0 en Android con gestos de tres botones). El fondo de la barra cubre las dos alturas; las pestañas ocupan solo las 64 de arriba. En Android con barra de navegación de botones el shell la pinta del mismo blanco al 72 %.
Un solo scroll
<main>es el único contenedor que se mueve (ScrollView/FlashListpor pantalla concontentInsetinferior de 98 + 12). Top bar y tabs no viajan con el teclado:KeyboardAvoidingViewvive dentro del main, como eluseKeyboardInsetde la web.
Servicio de Almacenaje
Pronto podrás guardar tu mercancía en nuestros almacenes y pagar solo por el volumen que uses. Reserva, controla tu inventario y haz seguimiento desde un mismo lugar.
- Reserva espacio por CBMToma el espacio que necesitas en metros cúbicos.
- Gestiona tu inventarioRegistra y controla tus productos almacenados.
- Paga por lo que usasSolo pagas el volumen ocupado, sin costos fijos.
Tab activo con pop (escala 1 → 1,18 → 1 en 260 ms ease-spring + haptic light) y press a .95. Un Pressable que abre un modal (Almacén) se marca accessibilityRole="button" y accessibilityHint="Próximamente"; los otros tres son tab con selected. Las banderas salen de CountryFlag (SVG local), no del emoji del SO.
02El orbe que aterriza
mobile-fab.tsx · mobile-create-sheet.tsx · create-items.ts · use-profile-gate.tsLa firma visual de la app. La web tiene un disco de 48 en brand-700 con un anillo blanco; aurora-familia ya había decidido que el FAB móvil es una de las tres apariciones exactas de --grad-marca. El problema de un disco entero en degradado es que el + blanco cae sobre celeste-deep y lima y no contrasta. Solución: el núcleo es marino (el + blanco mide 15:1) y la aurora es el anillo de 5 px que lo rodea. Al tocar, el + gira a ×, el orbe vuela en diagonal y aterriza como roundel en la cabecera noche del sheet, que sube debajo. Una sola coreografía de 640 ms.
60 de orbe, 5 de aurora, 26 de +
El disco sube 22 px por encima de la barra y la muesca lo rodea con 4 px de aire. Anillo
--grad-marcaa 120°, núcleo marino con un brillo interior blanco al 18 %, sombra0 8px 22px rgba(2,27,84,.28)—la queaurora-familiadio al FAB, tintada a marino. El + va a trazo 2,5 (la web usa 2 sobre 20 px; a 26 px y sobre marino, 2 se ve fino).La coreografía · 640 ms, tres actos
0–160 press: escala .92 +
Haptics.impactAsync(Medium). 160–580 vuelo: el orbe viajatranslate(−147, −281)y escala a .66 conease-in-outmientras el + gira 45° conease-spring; el velo marino al 70 % entra en 260 y el sheet sube en 420ease-in-out(la curva de sheet de MF-01). 560–700 aterrizaje: el roundel aparece conpopde 160 y los ítems entran conrisey stagger de 40 ms. Cerrar es el camino inverso a 260.Cabecera noche, cuerpo de día
La cabecera es la banda noche de MF-01 (
--mogos-grad-rail+ glow celeste), la misma deDialogHeader tone="noche"y del modal Próximamente: la promesa la hace la marca. Asa blanca al 28 %, título Lemon Milk 16/600, descripción Poppins 12 enon-marino-soft. El radio del sheet es 20 —el del modal Próximamente— y no el 10 del resto de sheets: es la única superficie con permiso.«Nuevo» son tiles, «Otros» son filas
NEW_CREATE_ITEMScrea entidades: dos tiles con plate de 40 en celeste-soft (envío) y lima-soft (cotización), tinta marino, etiqueta Poppins 14/500.OTHER_CREATE_ITEMSson herramientas: filas de 44 con el platebrand-500/10de la web. Marca para lo que crea, producto para lo que ayuda. «Reservar storage» no aparece:create-items.tslo filtra pornav-feature-flags; cuando el flag cambie avisibleentra como tercer tile con plate celeste.El gate que la web móvil olvida
En web el sheet enlaza directo a
/account/create-shipment; la página/accountsí pasa poruseProfileGate. La app corrige la asimetría: los dos tiles llamanrequireCompleteProfile(() => router.push(…)). Con el perfil a medias, el sheet lo avisa antes (siguiente maqueta) y el tap abre elProfileGateModalcon el callback retenido: si el perfil se completa con el modal abierto, la navegación ocurre sola.Reduced motion
Con
useReducedMotion(): sin vuelo, sin giro, sin stagger. El velo y el sheet aparecen con fade de 80 ms y el roundel ya está. El orbe sigue siendo el orbe: la firma es la forma, no el movimiento.
?mid=380 para congelarla en ese milisegundo.Tira de fotogramas: cinco clones de la misma maqueta congelados con --at. La coreografía se escribe una vez y los fotogramas salen solos, como el splash de MF-02.
Sin envíos
No tienes envíos registrados todavía.
Sin envíos
No tienes envíos registrados todavía.
- Verificar teléfono
- Agregar dirección de envío
Con el perfil a medias el sheet no bloquea: avisa con la banda de IncompleteProfileBanner (warning-soft, tinta warning-deep 5,03:1) y deja tocar. El tap abre el ProfileGateModal de la web —plate primary/10, título Lemon Milk 24, lista de faltantes con warning-500, botones apilados— y guarda el destino: «Completar perfil» lleva a /complete-profile; al volver con el perfil completo, la app navega sola a donde se iba.
03La ruta
mobile-corridor-sheet.tsx · corridor-context.tsx · corridor-storage.ts · corridor-portal-welcome.tsx · corridors/statsEl corredor filtra toda la app: envíos, pagos, salidas. El chip del top bar abre el sheet de ruta con las mismas filas del CorridorSwitcher de escritorio —«Todas las rutas» y una por corredor con bandera, punto vivo y las cifras de corridors/stats— y la elección persiste en MMKV (el corridor-storage.ts de la web sobre localStorage). Al abrir la app con una ruta activa, el toast de bienvenida de CorridorPortalWelcome lo recuerda una vez por sesión.
Puedes cambiar la ruta cuando quieras desde el indicador en la parte superior.
Las filas del escritorio, a 44
Plate de 36 con la bandera (o el globo muted para «Todas»), nombre corto + punto vivo, meta en 12 muted con
metaShipmentsymetaInCustomsdecorridors/stats. Activa:bg-accent+ checkbrand-700. Elegir cierra el sheet e invalida las queries filtradas: envíos, pagos, salidas y los contadores.Persistencia y saneo
corridor-context.tsxhidrata desde MMKV al montar, sincroniza al cambiar y limpia sola si el corredor guardado ya no existe encorridors(desactivado). Sin sesión no hay corredor: el logout borra la clave.La bienvenida es un toast de Sileo
El texto de
corridor-portal-welcome.tsx(todavía sin i18n en web —deuda anotada) en la pastilla expandida de MF-01: bandera en el disco, título ensileo-info, descripción al 50 %. 5 s, resorte de 640 al entrar,sessionStorage→ un flag en memoria por arranque de la app.ConnectionPill, la versión mínima
La cantera (
mobile-client/components/network) la dibuja como píldora gris#1f2937con punto y «Reintentar». Aquí se redibuja con la pastilla Sileo de MF-01 para no tener dos toasts oscuros: punto rojo de 8, «Sin conexión», acción al 14 %. Detecta con NetInfo +/health; la resiliencia completa (cola, reintentos, estados por pantalla) es de MF-14.
04La campana y el centro
mobile-notifications-sheet.tsx · notification-item.tsx · notification-card.tsx · notification-icons.ts · /account/notificationsDos superficies, como en la web. La campana abre un sheet con las diez últimas y «Marcar todas»; «Ver todas las notificaciones» lleva a /account/notifications, el centro completo con la banda de día, las pestañas Todas / Sin leer / Leídas, los filtros de prioridad y tipo, y la lista —que en el teléfono no pagina: carga más al llegar al final. El icono y el plate de cada fila salen del mapa de los 38 tipos (notification-icons.ts): cinco categorías más las cuatro excepciones por tipo.
No tienes notificaciones
Cuando recibas notificaciones, aparecerán aquí
Sheet: la fila de 44 + 2 de canto
NotificationItemtal cual: plate 36 radio 14 con el color de categoría, título 14 (ink/500 sin leer · ink-soft/400 leída) + punto marino de 6, hora en 11 tabular, mensaje 13 a dos líneas, badge de tipo con el tono de prioridad. El estado no-leída es la barra de 2 px en el canto, marino (rojo si es HIGH/URGENT), nunca el fondo. Las acciones que en web salen al hover, en el teléfono salen al swipe (marcar leída a la derecha, borrar a la izquierda) —la píldora flotante de la maqueta es la que aparece durante el gesto.Cinco plates y cuatro excepciones
statusceleste-soft/marino ·paymentsuccess-soft/success-deep ·storagelima-soft/marino ·shippingmarino/celeste (la noche de la marca) ·systemwarning-soft/warning-deep.ACCOUNT_CREATED→ user-plus,PROFILE_COMPLETED→ circle-check (los dos con plate status),ANNOUNCEMENT_PUBLISHED→ megáfono,NEW_CATALOG→ libro. Es el mapa exacto denotification-icons.ts; los 38 tipos resuelven ahí.El centro: cards y carga infinita
NotificationCardradio 14, plate 48, título Geist 14/600, barra de 4 en el canto para las no leídas, punto con pulso, menú ⋯ (marcar leída · ver detalles · eliminar) como action sheet. La paginación «Anterior / Siguiente» de la web se convierte enFlashListcononEndReachedy el pie «Cargando más…»:notifications?page=n&limit=20es la misma API, consumida en cursor.Filtros en sheet, no en popover
Las pestañas Todas / Sin leer (con contador celeste) / Leídas son los
Tabspill de MF-01. Prioridad y Tipo son losSelectdel producto que en táctil abren un bottom sheet con sus opciones (MF-01 §5). Con un filtro activo aparece «Limpiar» y, si no hay resultados, el vacío con el plate celeste → lima de la web y el mismo CTA.Tocar navega al
actionUrl, mapeadoCada notificación trae la ruta web (
/account/my-shipments/123,/account/freights/…,/account/payments). La app la pasa por un mapa ruta web → ruta app (el mismo que MF-10 usará para el deep link del push) y marca leída al tocar. Los destinos que aún no existen (04, 06, 07) abren su tab con el detalle en cola.Marcar todas y los contadores
«Marcar todas» llama
notifications/mark-all-read, pone el contador de la campana en 0 al instante (optimistic) e invalidaunread-count. El polling de 60 s deuse-unread-countyuse-sidebar-countssigue igual que en web hasta que MF-10 traiga realtime.
05Más es una pantalla
/account/mas/page.tsx · user-avatar-menu.tsx · lib/i18n/config.ts · signOutDecisión de Fabrizio en este estudio: el cuarto tab navega a /account/mas, como hace un tab nativo, y el MobileMoreSheet de la web no se porta. Una sola superficie: cabecera con avatar, nombre y correo sobre la aurora de día; Cuenta, Accesos, Preferencias y Cerrar sesión. El tab queda activo, la ruta es deep-linkeable y el gesto atrás funciona. Idioma abre un sheet con los tres locales; cambiar uno cambia la app entera sin reiniciar (i18next.changeLanguage + expo-localization solo para el default).
Cuenta
Accesos
Preferencias
Cuenta
Accesos
Preferencias
Cabecera: aurora de día, no degradado brand
La web pinta
from-brand-500 to-brand-700con texto blanco: el azul de producto que la serie aurora está retirando. Aquí va la banda de día (celeste-soft → lima-soft, la que la web ya usa en/account/notifications) con avatar de 48, nombre Poppins 14/600 y correo 12 ink-soft, ambos en marino (14,57:1). Tocarla lleva a/account/profile.Las filas, agrupadas y con sus cifras
Tres grupos con cabecera versalita 11/600 muted y filas de 44: plate muted 36, etiqueta Poppins 14/500, chevron. Pagos lleva la píldora
error-500considebar-counts.pendingPayments; Cotizaciones, la cifra dependingServiceQuotesen meta; Idioma muestra el locale activo con su nombre, no su código.Lo que no está, a propósito
Recompensas y Tutoriales siguen ocultos por producto (2026-08-09, DECISIONS #12). Mi perfil no es una fila: es la cabecera. El correo del usuario vive solo aquí y en el menú de escritorio.
Idioma en sheet: es · en · zh
La página web de
/account/massolo alterna es ↔ zh; el sheet web y el menú de escritorio ofrecen los tres. La app ofrece los tres siempre: sheet claro de MF-01 con el nombre en su propia lengua (langen cada fila), el código en versalita y el checkbrand-700. Elegir cierra el sheet, llamachangeLanguagey persiste en MMKV; el copy de toda la app se re-renderiza sin reiniciar (DECISIONS #18).Cerrar sesión, sin confirmación
Como en web: la fila roja llama
supabase.auth.signOut(), borraexpo-secure-store, el corredor y la caché de queries, y reemplaza el stack por/login. El tab «Más» pierde su punto porque ya no hay contadores.Tab activo + pop
Al entrar, «Más» toma
brand-700con el pop de 260 ms y conserva el punto rojo si hay pagos pendientes: el punto es información, no una llamada al tab.
06El home, con sus tres widgets
(app)/account/page.tsx · my-shipments.tsx · pending-payments.tsx · departures-calendar.tsx · storage-pricing-dialog.tsx/account compone cuatro bloques y la app los replica en una columna: la banda de bienvenida (aurora de día, la que la web ya usa en el centro de notificaciones y que aurora-home pidió para el saludo), Mis envíos con los KPI-chips que filtran y el carrusel de cards, Pagos pendientes con el monto en display y «Pagar», y Próximas salidas con el calendario codificado por corredor. Todo filtrado por la ruta del chip. Pull-to-refresh nativo, skeletons que heredan la superficie y vacíos que invitan.
Sin envíos
No tienes envíos registrados todavía.
Sin pagos pendientes
No tienes pagos pendientes en este momento.
La bienvenida es la banda de día
PageFramepone hoy el título en Lemon Milk 24 marino sobrebg-secondary, sin banda;aurora-home(2026-08-07) decidió la banda y la web la estrenó en/account/notificationscomo.mogos-day-band. La app la lleva al saludo: celeste-soft → lima-soft con los dos glows a la deriva (26 s / 37 s), tinta marino (14,57:1 / 15,35:1). Título y subtítulo son los deaccount.dashboard.*, literales.«Crear envío» es el orbe
En web
showActionsOnMobilemete dos botones en la cabecera porque el teléfono no tenía otra forma de crear. La app sí: el orbe. La banda conserva solo «Ver tarifas» (secundario pequeño, abreStoragePricingDialog); «Crear envío» queda en el vacío de Mis envíos, donde sí es la siguiente acción. Los dos pasan porrequireCompleteProfile.KPI-chips que filtran
Verbatim de
kpi.tsx: radio 14, bordemogos-line, Poppins 14; activo borde marino + marino/5 + tinta marino. Tocar filtra el carrusel (inTransit/inWarehouse/readyForPickup) y volver a tocar quita el filtro. Las cifras salen de los mismos 100 pedidos deorders?perPage=100(deuda: pedir un agregado; MF-04 la hereda).ShipmentCard, 280 de ancho, en carrusel con snap
Fondo
gray-50, radio 14, barco/avión enbrand-500, corredor «friendly» + badge de estatus (ORDER_STATUS_VARIANTS), ETA en Lemon Milk 24 extralightbrand-700(o «Por confirmar» en tinta), tracking del proveedor como cifra protagonista, «Ver detalle» terciario al detalle de MF-04.FlashListhorizontal consnapToInterval296 y el degradado de la máscara al borde.Pagos pendientes: el monto manda
PendingPaymenttal cual: monto en display 24 extralight tabular + corredor, «Pagar» primario, y las cuatro filas deAttributeField(fecha límite solo si viene, código, referencia, estatus conBadgeerror / warning / default). «Pagar» abre el portal en WebView (DECISIONS #15, forma en MF-07). «Ver todos» →/account/payments.El calendario habla la paleta
Celdas de 46 con el número arriba y el barco/avión en marino (trazo 1,6) abajo; puntos por corredor: China
--rojo, USA marino (el celeste desaparecía sobre su propia celda —nota dedepartures-calendar.tsx:758); tintes rojo/10, marino/8 y el degradado de ambos al 12 %; hoy con el número en disco marino. Leyenda con los tres swatches. Con ruta activa, puntos y tintes se apagan porque ya no discriminan nada.El día abre un diálogo
Título «N salidas este día», una
DepartureCardpor salida (fondo rojo/10 o azul/10 según corredor, fechas en display, origen → destino, badge Abierto / Cierre próximo / Cerrado), elSelectde recordatorio (que en la web todavía no guarda nada) y «Cerrar» / «Guardar recordatorio». El recordatorio real llega con MF-10.Cargar, refrescar, vaciar
Skeleton: la banda ya conoce el nombre (viene de
users/mepersistido en MMKV), los widgets muestran su forma enaccentcon el pulso de 2 s. Pull-to-refresh:RefreshControlnativo en marino, invalidaorders,payments/me/pending,departuresy los contadores a la vez. Vacíos: losEmptypunteados de MF-01, uno por widget, y un solo CTA en toda la pantalla.
07Los tres avisos
incomplete-profile-banner.tsx · profile-gate-modal.tsx · coming-soon-feature-modal.tsx · use-banner-dismiss.tsLa web ya tiene los tres y la app los trae tal cual: el banner de perfil incompleto entre el top bar y el main (se cierra 24 h), el ProfileGateModal que retiene la acción (§02) y el modal Próximamente del tab Almacén (§01). Aquí, el banner sobre el home completo, con lo que empuja y lo que no.
El banner es parte del chrome, no del scroll
Va entre el top bar y el
<main>, como enmobile-shell/index.tsx:shrink-0, no viaja con el scroll ni con el teclado. Warning-soft, líneawarning/28, triángulo y textos enwarning-deep(5,03:1). Título con el porcentaje deuseProfileCompletion, descripción truncada con la lista de faltantes, «Completar →» en outline y la × que lo esconde 24 h (use-banner-dismisssobre MMKV).Los faltantes, con nombre
MISSING_LABELSdeprofile-gate-modal.tsx: verificar correo, verificar teléfono, cédula o pasaporte, dirección de envío. Los mismos cuatro pasos del stepper de/complete-profilede MF-02, al que llevan tanto el banner como el modal.El gate y el banner no compiten
El banner informa; el gate detiene. Si el banner está cerrado y el usuario toca «Nuevo envío», el gate aparece igual (lee
isComplete, no el dismiss). Si el perfil se completa en otra pantalla, los dos desaparecen solos: la queryusers/mese invalida al volver de/complete-profile.Próximamente, con la marca
El modal de Almacén (§01) es el de la web retintado en aurora: radio 20, cabecera noche con el wordmark blanco y su punto rojo, píldora lima con tinta marino (14,44:1), tres filas con plate celeste-soft, CTA
.mogos-ctaen píldora.coming-soon-contextlo abre porfeature key; hoy solo existestorage.Guardas de navegación
Sin sesión →
/login. Todo(app)protegido, incluidas/calculator,/catalog,/locationsy/suggestions, que en web quedan fuera del middleware. LosactionUrly deep links que apunten a una ruta protegida esperan la sesión y luego navegan.
08Lo que hay que escribir en Moti
Moti + Reanimated · escala de MF-01 · useReducedMotionCada coreografía de la pieza con su equivalente en nativo. La escala es la del estudio (80 / 160 / 260 / 420 / 640, ease-out, ease-in-out, ease-spring) que Fabrizio cerró en MF-01. Nada de aquí es obligatorio para usar la app: con «Reducir movimiento» activo todo se vuelve fade de 80 ms o nada.
| Momento | Qué se ve | Duración · curva | En nativo | Reduced motion |
|---|---|---|---|---|
| Press del orbe | escala .92 + haptic medium | 160 · ease-out | Pressable + withTiming; Haptics.impactAsync(Medium) | haptic sí, escala no |
| Vuelo del orbe | translate(−147, −281) · scale .66 · + → × | 420 · ease-in-out (giro: spring) | Animated.View absoluto en el root del shell; useSharedValue de progreso 0→1 que mueve orbe, velo y sheet a la vez | sin vuelo; el roundel ya está |
| Velo | marino al 70 % entra | 260 · ease-out | MotiView opacity sobre Modal transparent | fade 80 |
| Sheet sube / baja | translateY 100 % → 0 | 420 abre · 260 cierra · ease-in-out | la librería de sheet sale de la tabla comparativa de goal-phases (gorhom / true-sheet); la curva es esta | fade 80 |
| Aterrizaje | roundel pop + tiles rise con stagger 40 | 160 spring · 260 ease-out | MotiView con delay por índice | todo visible de entrada |
| Tab activo | icono 1 → 1,18 → 1 + color · haptic light | 260 · ease-spring | withSequence(withSpring) en el icono del tab | solo color |
| Ping del chip | disco de 6 escala 2,4 y fade, en bucle | 1000 · cubic-bezier(0,0,.2,1) | withRepeat(withTiming), −1; se detiene fuera de foco | punto fijo |
| Campana | al subir el contador: vaivén ±12° + el número hace pop | 640 · ease-spring | withSequence en rotateZ; se dispara cuando unread-count crece | solo el número |
| Banda de día | dos glows a la deriva | 26 s · 37 s · ease-in-out | withRepeat sobre translate + scale de dos View con blur; se pausa en background | banda estática |
| Skeleton | pulso | 2000 · cubic-bezier(.4,0,.6,1) | withRepeat opacity 1 ↔ .5 | fijo |
| Toast | cae con resorte | 640 · ease-spring | Sileo de MF-01 | fade 80 |
| Stack push | slide iOS · fade-through Android | nativo | react-native-screens, no se reimplementa | nativo |
Fuente de verdad de la escala: proposal/mogos-mobile-componentes.html §10 y packages/mobile-ui/src/theme/motion.ts (MF-01). Los 640 ms totales de la coreografía del orbe son 160 de press + 420 de vuelo + 60 de solape con el aterrizaje.
09Lo que queda decidido
docs/specs/2026-09-05-mobile-shell.md- Firma
Orbe: núcleo marino, aurora alrededor
Elegido por Fabrizio (2026-09-05) sobre el abanico radial y el cuadro marino con punto rojo. El disco entero en degradado se descartó al medir: el + blanco sobre celeste-deep da 2,2:1. Anillo de 5 px con
--grad-marca, núcleo marino, + blanco a 15:1. La muesca de la barra es parte de la firma. - Coreografía
El orbe aterriza en el sheet
Una sola coreografía de 640 ms: press, vuelo en diagonal con giro del +, aterrizaje como roundel en la cabecera noche. La cabecera noche es la banda de MF-01; el radio 20 del sheet de crear es el del modal Próximamente y es la única excepción al radio 10 de los sheets.
- Gate
Crear pasa por el perfil, también desde el sheet
La web móvil enlaza directo y solo
/accountgatea. La app aplicarequireCompleteProfilea los dos tiles y avisa dentro del sheet con la banda deIncompleteProfileBanner. El callback se retiene: completar el perfil termina la acción sola. - Más
Pantalla, no sheet
Elegido por Fabrizio (2026-09-05): el cuarto tab navega a
/account/mas.MobileMoreSheetno se porta. Cabecera en banda de día en lugar del degradado brand; Idioma abre un sheet con es · en · zh (la página web solo alternaba es ↔ zh). - Campana
Contador visible, en marino
La web esconde la cifra en
sr-onlyy muestra un punto. En el teléfono la píldora de 16 con el número es lo útil. Marino y no rojo, por la misma regla que la web anotó enmobile-top-bar.tsx. - Centro
Scroll infinito, no paginación
/account/notificationsconserva banda, tabs y filtros; «Anterior / Siguiente» se vuelveFlashList+onEndReachedsobre la misma API paginada. Las acciones por hover pasan a swipe en la fila y a action sheet en la card. - Home
La bienvenida es la banda de día
PageFrameweb no la tiene;aurora-homela pidió y la web ya la estrenó en el centro de notificaciones. La app la usa en el saludo y en la cabecera de Más. «Crear envío» sale de la cabecera porque ahora existe el orbe; «Ver tarifas» se queda. - Verde
success-500 del producto, no emerald de Tailwind
El punto vivo del chip y de las filas de ruta usa
emerald-500en web, un color fuera de la paleta del producto. La app usasuccess-500(#17b26a), que sí es token. Único cambio de color respecto a la web en toda la pieza; el resto de foráneos (red/blue del corridor-badge, blue-50 del aviso de tarifa) se replican y se anotan como deuda. - Sombras
Tintadas a marino, también el chrome
Top bar y tabs llevan en web sombras en
slate-900; aquí el mismo 4 % / 6 % sobre marino, y el orbe la sombra del FAB deaurora-familia. Cierra la decisión 4 de MF-01 para el shell. - Fletes
El tab existe; el contenido es de MF-06
La pantalla Fletes se dibuja con su sub-nav (Fletes / Mis envíos) y skeleton para fijar el estado activo del tab y la cabecera; lo que va dentro lo decide el design-studio de MF-06.
- Almacén
Flag de la web, modal de la web
nav-feature-flagsse lee igual:comingSoon→ chip «Pronto» y modal;hidden(Mi Locker) → no existe. «Reservar storage» entra al sheet de crear como tercer tile el día que el flag cambie (DECISIONS #6). - Red
ConnectionPill = pastilla Sileo
La píldora gris de la cantera se redibuja con el toast oscuro de MF-01 para no tener dos superficies negras. Versión mínima (NetInfo +
/health); la resiliencia completa es de MF-14. - Pregunta · Figma
¿Hay capturas del Home del Figma viejo?
El brief pedía pedirlas. En el repo no hay ninguna (
design/assets/fotossolo tiene el README). Esta pieza sigue a la web tal como está (DECISIONS #3). Si las capturas existen y traen algo que la web perdió, se revisa antes de goal-phases.
Las dos decisiones de este estudio —el orbe y Más como pantalla— las tomó Fabrizio en la sesión del 2026-09-05 con AskUserQuestion, una a una, sobre tres direcciones cada una. El resto son consecuencias de leer el código de apps/client y de las tres piezas anteriores.