Sistema de utility classes mobile — mobile.css (shell s60)
Contexto
En la sesión s60 (@Esquembri, 2026-05-13) se cerró una deuda técnica heredada de NEXT.md
pre-s60: “V1HomeVivo mobile refactor — 64 estilos inline”. Incluyendo las secciones nuevas
incorporadas en la misma sesión (Noticias, Salud sistema, FAB extendido), el total de estilos
inline eliminados fue 92 (81 en V1HomeVivo.tsx + 11 en BottomNav.tsx).
Estrategia
- Sin tocar
tools.css— los selectorescuaderno-mobile-*ydirections-mobile-*ya añadidos en commits previos de s60 permanecen intactos. - Nuevo archivo
src/styles/mobile.css(~440 LOC) con todas las utility classes declarativas para el shell mobile completo. - Importado desde
AppLayout.astroinmediatamente trastools.css.
Resultado cuantitativo
| Componente | Inline antes | Inline después | Reducción |
|---|---|---|---|
V1HomeVivo.tsx | 81 | 6 | 93 % |
BottomNav.tsx | 11 | 0 | 100 % |
| Total | 92 | 6 | 93 % |
Los 6 inline restantes en V1HomeVivo son CSS custom properties dinámicas legítimas —
valores que cambian por instancia y que las utility classes consumen vía var():
| CSS var | Dónde se aplica | Tipo de valor |
|---|---|---|
--avatar-bg | Avatar usuario / PersonChip | Gradiente generado por nombre |
--prio-color | TaskRow · punto de prioridad | Color semántico por prioridad |
--health-color | HealthCard | Color de estado global del sistema |
--row-color | Filas de sensor en salud | Color por estado de sensor |
--fab-bg / --fab-fg | Iconos FAB extendido | Color por acción rápida |
--quick-bg / --quick-fg | QuickCard accesos | Color de tema por shortcut |
Patrones canónicos extraídos
Shell raíz
.mobile-shell—min-height: 100dvh+padding-bottomconsafe-area-inset-bottom.
Cabecera sticky
.mobile-sticky-header—position: sticky; top: 0+backdrop-filter: blur(20px)+padding-topconsafe-area-inset-top..mobile-brand— logotipo CreaRack-SL:.mobile-brand-main(accent) +.mobile-brand-suffix(outlined rojo,WebkitTextStroke).
Indicadores de estado
.mobile-pill— base badge redondeado conbackdrop-filter..mobile-pill-ok/.mobile-pill-warn— variantes semánticas (verde / ámbar)..mobile-pill-dot— punto pulsante interior.
Avatar
.mobile-avatar— círculo 34 px, gradiente víavar(--avatar-bg).
Bloque de saludo
.mobile-greeting-block— padding20px 16px 8px..mobile-greeting-today— fecha, color muted..mobile-greeting-headline—font-size: 1.857rem; font-weight: 700; letter-spacing: -0.5..mobile-greeting-summary— resumen tareas/alertas.
Secciones
.mobile-section-label— cabecera de sección: título + CTA..mobile-section-title— texto uppercase, tracking 0.8, muted..mobile-section-cta— enlace “Ver todas”, color brand.
Contenedores de filas
.mobile-row-list— columna congap: 8px+ padding lateral..mobile-row-grid-2—grid-template-columns: 1fr 1fr; gap: 8px..mobile-row-row— fila horizontal congap: 10px.
Tarjetas
.mobile-card— card base conborder-radius: 12px,border, fondo--bg-raised..mobile-card-empty— estado vacío con borde punteado..mobile-card-loading— estado de carga con borde punteado.
Alerta banner
.mobile-alert-banner-wrap— padding envolvente..mobile-alert-banner— gradiente warning +backdrop-filter..mobile-alert-icon/.mobile-alert-body/.mobile-alert-label/.mobile-alert-message/.mobile-alert-actions/.mobile-alert-cta.
Tarea (TaskRow)
.mobile-task-row— card condata-donepara opacity 0.5 en completado..mobile-task-check— botón circular 22 px;data-checkedgestiona fondo/borde..mobile-task-body/.mobile-task-title— elipsis condata-donepara tachado..mobile-task-meta/.mobile-task-meta-prio/.mobile-task-meta-prio-dot..mobile-task-chevron—›separador derecho.
Persona (PersonChip)
.mobile-person-chip— tarjeta de miembro de equipo; consume--avatar-bgy--status-color..mobile-person-avatar-wrap/.mobile-person-avatar/.mobile-person-status-dot..mobile-person-name/.mobile-person-sub.
Noticia (NewsCard)
.mobile-news-card— enlace-tarjeta noticias..mobile-news-meta/.mobile-news-pin/.mobile-news-category/.mobile-news-date/.mobile-news-title.
Acceso rápido (QuickCard)
.mobile-quick-card— consume--quick-bgy--quick-fg..mobile-quick-icon/.mobile-quick-title/.mobile-quick-sub.
Salud del sistema (HealthCard)
.mobile-health-card— consume--health-color..mobile-health-summary/.mobile-health-dot/.mobile-health-summary-body/.mobile-health-status/.mobile-health-sub..mobile-health-rows/.mobile-health-row(consume--row-color) /.mobile-health-row-dot/.mobile-health-row-label/.mobile-health-row-value..mobile-health-actions/.mobile-health-btn.
Navegación inferior (BottomNav)
.mobile-nav— barra fija +backdrop-filter: blur(24px)+safe-area-inset-bottom..mobile-nav-item— contenedor flexflex: 1; position: relative..mobile-nav-link/.mobile-nav-button— ítem de navegación;data-activegestiona color accent vs muted..mobile-nav-icon/.mobile-nav-label..mobile-nav-dropup— menú emergente hacia arriba (200 px,blur+ shadow)..mobile-nav-dropup-divider/.mobile-nav-dropup-link(condata-active).
FAB (Floating Action Button)
.mobile-fab-wrap—position: fixed; bottom: calc(92px + env(safe-area-inset-bottom))..mobile-fab— botón circular 56 px,border-radius: 999, fondo brand + shadow..mobile-fab-menu— panel expandido conposition: absolute; bottom: 68px..mobile-fab-item/.mobile-fab-item-icon(consume--fab-bg/--fab-fg).
Convención data-* en lugar de clases condicionales
BottomNav abandonó el patrón color: showActive ? 'var(--accent)' : 'var(--fg-muted)' inline.
Ahora usa data-active={showActive} en el elemento DOM y las clases utility aplican el color
vía selector de atributo CSS:
.mobile-nav-link[data-active="true"] { color: var(--accent); }
.mobile-nav-link:not([data-active="true"]) { color: var(--fg-muted); }
El mismo patrón se aplica a .mobile-task-row[data-done], .mobile-task-check[data-checked],
.mobile-task-title[data-done].
Mejoras de accesibilidad incluidas
- Añadido
type="button"a botones sin tipo explícito (tarea y FAB). - FAB recibe
aria-expanded={showFab}para anunciar estado. BottomNaveliminó la constanteFIXED_BGacoplada al JS y la movió a CSS.
Archivos tocados
| Archivo | Cambio |
|---|---|
src/styles/mobile.css | Nuevo — ~440 LOC, utility classes del shell mobile completo |
src/components/variants/mobile/V1HomeVivo.tsx | Refactor — 81 → 6 inline (−93 %) |
src/components/shell/BottomNav.tsx | Refactor — 11 → 0 inline (−100 %) |
src/layouts/AppLayout.astro | Import de mobile.css tras tools.css |
Véase también
- [[crearack—conceptos—interfaz-general]]