Documento del prototipo
Las reglas vigentes viven en diseno/sistema-diseno.md. Este archivo documenta lo que el código hace hoy, incluidos los literales Color(0x...) y dp que deben migrarse a tokens.
Tema y diseño¶
Sistema visual de IslaBox: colores, tipografía, formas, espaciados, fondos y decisiones de diseño.
Identidad visual (de los assets)¶
| Elemento | Descripción |
|---|---|
| Logo principal | Palmera (azul navy 0xFF001129) dentro de círculo azul con isla en rojo 0xFFBB0016 (paleta cubana) |
| Logo horizontal | Palmera + texto "isla" (navy) + "box" (rojo) |
| Logo isotipo-texto | Solo texto "isla" navy + "box" rojo |
| Imagen de éxito | Sello/badge con checkmark |
⚠️ Los 4 drawables referenciados en
IslaImages.ktno existen enres/drawable/. La app crashea al abrir Welcome, Success, y la top bar del dashboard.
Colores¶
Definidos en ui/theme/Color.kt. Paleta M3 completa con énfasis en el azul navy como primario y el rojo cubano como secundario.
Primary (azul navy)¶
| Token | Color | Uso |
|---|---|---|
Primary |
#001129 |
Botones primarios, texto destacado, íconos principales |
OnPrimary |
#FFFFFF |
Texto sobre Primary |
PrimaryContainer |
#0F2644 |
Containers navy (claro) |
OnPrimaryContainer |
#798EB1 |
Texto sobre containers |
InversePrimary |
#B2C7ED |
Primary invertido |
PrimaryFixed |
#D5E3FF |
|
PrimaryFixedDim |
#B2C7ED |
|
OnPrimaryFixed |
#031C39 |
|
OnPrimaryFixedVariant |
#334767 |
Secondary (rojo cubano)¶
| Token | Color | Uso |
|---|---|---|
Secondary |
#BB0016 |
Acentos, alertas, mensajes importantes |
OnSecondary |
#FFFFFF |
|
SecondaryContainer |
#E1272B |
Containers rojos (medio) |
OnSecondaryContainer |
#FFFBFF |
|
SecondaryFixed |
#FFDAD6 |
|
SecondaryFixedDim |
#FFB4AC |
|
OnSecondaryFixed |
#410003 |
|
OnSecondaryFixedVariant |
#93000E |
Tertiary (carbón)¶
| Token | Color | Uso |
|---|---|---|
Tertiary |
#0E1112 |
Texto casi-negro, íconos de soporte |
OnTertiary |
#FFFFFF |
|
TertiaryContainer |
#232627 |
Containers carbón |
OnTertiaryContainer |
#8B8D8E |
|
TertiaryFixed |
#E1E3E4 |
|
TertiaryFixedDim |
#C5C7C8 |
|
OnTertiaryFixed |
#191C1D |
|
OnTertiaryFixedVariant |
#454748 |
Error¶
| Token | Color |
|---|---|
Error |
#BA1A1A |
OnError |
#FFFFFF |
ErrorContainer |
#FFDAD6 |
OnErrorContainer |
#93000A |
Background y Surface¶
| Token | Color | Notas |
|---|---|---|
Background |
#F8F9FF |
Casi blanco, tinte azul muy sutil |
OnBackground |
#0B1C30 |
|
Surface |
#F8F9FF |
Igual a Background |
OnSurface |
#0B1C30 |
|
SurfaceVariant |
#D3E4FE |
Tonos azul claro |
OnSurfaceVariant |
#44474E |
|
SurfaceDim |
#CBDBF5 |
|
SurfaceBright |
#F8F9FF |
|
SurfaceContainerLowest |
#FFFFFF |
|
SurfaceContainerLow |
#EFF4FF |
|
SurfaceContainer |
#E5EEFF |
|
SurfaceContainerHigh |
#DCE9FF |
|
SurfaceContainerHighest |
#D3E4FE |
|
Outline |
#74777E |
|
OutlineVariant |
#C4C6CE |
|
InverseSurface |
#213145 |
|
InverseOnSurface |
#EAF1FF |
|
SurfaceTint |
#4B5F80 |
Otros colores hardcodeados (fuera de la paleta M3)¶
| Color | Hex | Uso |
|---|---|---|
| Navy | 0xFF001129 |
Mismo que Primary, usado directamente en componentes |
| Red | 0xFFBB0016 |
Mismo que Secondary |
| Blue soft | 0xFFE3F2FD (alpha 0.8) |
Burbuja de fondo LiquidGlass |
| Pink soft | 0xFFFCE4EC (alpha 0.7) |
Burbuja de fondo LiquidGlass |
| White | 0xFFFFFFFF |
Cards, surface variants |
| Gray light | Color.LightGray |
Bordes sutiles, íconos deshabilitados |
| Gray (semitransparent) | Color.LightGray.copy(alpha = 0.5f) |
Dividers |
| Pink accent | 0xFFE91E63 |
"EMPIEZA AQUÍ" en FeaturedGuideCard, badge "MIA", dot de notificación |
| Red custom | 0xFFD32F2F |
Botón "Cerrar Sesión" |
| Green success | 0xFF4CAF50 |
Status dot identificador activo |
| Red error dot | 0xFFE53935 |
Stat card "En Tránsito" |
| Gray dot | 0xFF9E9E9E |
Stat card "En Almacén" |
| Red damaged | 0xFFF44336 |
StorageControl cuando quedan ≤ 3 días |
| Yellow warning | 0xFFFFC107 |
StorageControl 4-10 días |
| Surface para inputs | Color(0xFFF1F4F9), Color(0xFFF0F4F8), Color(0xFFF0F0F5) |
Backgrounds de celdas, íconos |
Inconsistencias:
- Hay 3 grises diferentes para backgrounds: 0xFFF1F4F9, 0xFFF0F4F8, 0xFFF0F0F5. Unificar.
- Hay 2 rojos: 0xFFBB0016 (paleta), 0xFFD32F2F (Cerrar Sesión), 0xFFE91E63 (acentos rosa). Unificar o documentar cuándo usar cada uno.
Tipografía¶
Definida en ui/theme/Type.kt. Usa FontFamily.SansSerif (placeholder para "Inter").
val Inter = FontFamily.SansSerif // TODO: cargar Inter desde res/font
val Typography = Typography(
displayLarge = 48sp / 56sp / Bold / -0.02 sp
headlineLarge = 32sp / 40sp / Bold / -0.01 sp
headlineMedium = 24sp / 32sp / SemiBold
headlineSmall = 20sp / 28sp / SemiBold
bodyLarge = 18sp / 28sp / Normal
bodyMedium = 16sp / 24sp / Normal
bodySmall = 14sp / 20sp / Normal
labelLarge = 12sp / 16sp / Bold / +0.05 sp
labelMedium = 16sp / 24sp / SemiBold / +0.1 sp
)
Observaciones:
- ✅ Cobertura completa de los 9 estilos M3.
- ⚠️ labelMedium tiene fontSize = 16sp que es igual a bodyMedium. Esto es inusual (normalmente labelMedium es 12sp). Es probable que se use mal.
- ❌ Falta agregar la fuente Inter en res/font/ (el comentario dice "Por ahora usaremos FontFamily.SansSerif como base").
Shapes¶
val Shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp),
small = RoundedCornerShape(8.dp),
medium = RoundedCornerShape(12.dp),
large = RoundedCornerShape(16.dp),
extraLarge = RoundedCornerShape(24.dp)
)
Usos:
- small (8dp): OutlinedTextField, IslaPrimaryButton default
- medium (12dp): Algunos cards, dropdowns
- large (16dp): (definido pero no usado)
- extraLarge (24dp): (definido pero no usado)
💡 Los
IslaCardusanRoundedCornerShape(20.dp)hardcoded (no del theme). Considerar usarlargeoextraLarge.
Spacing¶
val Spacing = Spacing(
default = 0.dp,
xs = 4.dp,
base = 8.dp,
sm = 12.dp,
md = 16.dp, // Margen estándar
lg = 24.dp, // Separación entre secciones
xl = 48.dp, // Separación grande (top hero, fin de pantalla)
gutter = 16.dp, // Coincide con md
containerMax = 1200.dp // Para layouts web (no se usa en app)
)
val LocalSpacing = staticCompositionLocalOf { Spacing() }
Disponible vía:
val spacing = LocalSpacing.current
spacing.md // 16.dp
Observación: containerMax = 1200.dp no tiene sentido en una app móvil. Es residuo de un proyecto web.
Tema — IslaBoxTheme¶
@Composable
fun IslaBoxTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme // ⚠️ mismo esquema
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
val insetsController = WindowCompat.getInsetsController(window, view)
window.statusBarColor = android.graphics.Color.TRANSPARENT
window.navigationBarColor = android.graphics.Color.TRANSPARENT
val isLightBackground = true // ⚠️ HARDCODED
insetsController.isAppearanceLightStatusBars = isLightBackground
insetsController.isAppearanceLightNavigationBars = isLightBackground
}
}
CompositionLocalProvider(LocalSpacing provides Spacing()) {
MaterialTheme(colorScheme, Typography, Shapes, content)
}
}
Observaciones críticas:
DarkColorSchemeyLightColorSchemeson idénticos (mismas asignaciones token por token). No hay dark mode real.isLightBackground = truehardcoded: los iconos de status bar siempre serán oscuros. Si en el futuro se quiere dark mode, hay que cambiar esto a!darkTheme.- Edge-to-edge correctamente configurado:
statusBarColorynavigationBarColortransparentes. ✅ - Compose pinta todo: el tema XML (
Theme.IslaBoxMaterial 1) no se ve, así que da igual su configuración.
Fondos¶
DotGridBackground — auth screens¶
Patrón técnico minimalista:
- Fondo blanco
#FFFFFF - Cuadrícula de 64dp con líneas discontinuas (
dashPathEffect floatArrayOf(10f, 15f)) - Círculos de 3/4 decorativos (~12% de las intersecciones, posición aleatoria)
- Color:
outline.copy(alpha = 0.3f)(gris medio) - Animación de entrada: las líneas se "arman" desde los bordes (pares desde un lado, impares desde el otro) en 2.5s con
EaseOutQuart - Stroke 1.1px
Usado en: Welcome, Login, Register, ForgotPassword, VerificationCode, Success.
LiquidGlassBackground — pantallas principales¶
Patrón orgánico con gradientes radiales desenfocados:
- Fondo base
#F8F9FA - Círculo superior izquierdo 400dp en
0xFFE3F2FDalpha 0.8 → transparente (azul suave) - Círculo inferior derecho 450dp en
0xFFFCE4ECalpha 0.7 → transparente (rosa suave) - Blur de 100-120dp con
BlurredEdgeTreatment.Unbounded
Usado en: MainLayout (Dashboard, Reportes, Paquetes, Guía, Perfil), ReporteDetalle, Notifications.
Observación: este fondo es computacionalmente caro (blur grande en cada frame). Si se nota lag en devices低端, considerar: - Reducir tamaño de los círculos. - Reducir radio de blur. - Cachear el fondo como bitmap. - Hacerlo opcional.
Diseño "Transatlantic Precision"¶
El comentario en IslaButtons.kt menciona un sistema llamado "Transatlantic Precision" como guía. La filosofía parece ser:
- Limpio, sin sombras pesadas: border 1dp en lugar de elevación.
- Esquinas redondeadas pero marcadas: 20dp en cards.
- Acentos puntuales en rojo: solo para alertas y CTAs primarios.
- Espaciado generoso: 24dp entre secciones, 48dp al final de pantallas.
- Mobile-first: la mayoría de componentes asumen ancho 360-414dp.
Decisiones de diseño pendientes¶
| # | Decisión | Opciones | Estado |
|---|---|---|---|
| 1 | Dark mode real | (a) Implementar M3 dark, (b) Siempre light, (c) Auto según sistema | Sin definir |
| 2 | Fuente Inter | (a) Cargar Inter en res/font, (b) Usar otra similar, (c) Mantener SansSerif | Sin definir |
| 3 | Color único de rojo | Unificar BB0016 / D32F2F / E91E63 |
Sin definir |
| 4 | Color único de gris claro | Unificar F1F4F9 / F0F4F8 / F0F0F5 |
Sin definir |
| 5 | Forma de cards | RoundedCornerShape(20.dp) hardcoded vs Shapes.large (16dp) o extraLarge (24dp) |
Sin definir |
| 6 | Liquid Glass en todos los fondos | Hoy está en todas las pantallas principales | Sin definir |
| 7 | Bordes vs elevación | Hoy mayoría usa border 1dp sin elevación | Decidido: border |
| 8 | Tema XML | Mantener Material.Light.NoActionBar o migrar a Material 3 |
Sin definir |
| 9 | labelMedium fontSize |
16sp (actual, raro) o 12sp (estándar M3) | Sin definir |
| 10 | Status bar en dark mode | Hoy siempre claro; en dark debería ser oscuro | Pendiente al implementar dark |
Tareas de tema y diseño¶
| # | Tarea | Prioridad |
|---|---|---|
| 1 | Decidir sobre dark mode (y por lo menos eliminar el isLightBackground = true hardcoded) |
Media |
| 2 | Cargar fuente Inter en res/font/ (o dejar documentado que es SansSerif) |
Baja |
| 3 | Unificar la paleta de rojos (1 solo red o documentar cuándo usar cada uno) |
Media |
| 4 | Unificar la paleta de grises claros | Baja |
| 5 | Estandarizar RoundedCornerShape de los cards (usar Shapes.large o extraLarge) |
Baja |
| 6 | Evaluar performance de LiquidGlassBackground en devices低端 |
Media |
| 7 | Migrar themes.xml a Material 3 (Theme.Material3.DayNight.NoActionBar) |
Baja |
| 8 | Revisar labelMedium (16sp es inusual; debería ser 12sp) |
Baja |
| 9 | Eliminar colors.xml (legacy, no se usa) |
Baja |
| 10 | Eliminar containerMax = 1200.dp de Spacing (no aplica a móvil) |
Baja |