CreaRack-SL

Sistema de utility classes mobile — mobile.css (shell s60)

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 selectores cuaderno-mobile-* y directions-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.astro inmediatamente tras tools.css.

Resultado cuantitativo

ComponenteInline antesInline despuésReducción
V1HomeVivo.tsx81693 %
BottomNav.tsx110100 %
Total92693 %

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 varDónde se aplicaTipo de valor
--avatar-bgAvatar usuario / PersonChipGradiente generado por nombre
--prio-colorTaskRow · punto de prioridadColor semántico por prioridad
--health-colorHealthCardColor de estado global del sistema
--row-colorFilas de sensor en saludColor por estado de sensor
--fab-bg / --fab-fgIconos FAB extendidoColor por acción rápida
--quick-bg / --quick-fgQuickCard accesosColor de tema por shortcut

Patrones canónicos extraídos

Shell raíz

  • .mobile-shell — min-height: 100dvh + padding-bottom con safe-area-inset-bottom.

Cabecera sticky

  • .mobile-sticky-header — position: sticky; top: 0 + backdrop-filter: blur(20px) + padding-top con safe-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 con backdrop-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ía var(--avatar-bg).

Bloque de saludo

  • .mobile-greeting-block — padding 20px 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 con gap: 8px + padding lateral.
  • .mobile-row-grid-2 — grid-template-columns: 1fr 1fr; gap: 8px.
  • .mobile-row-row — fila horizontal con gap: 10px.

Tarjetas

  • .mobile-card — card base con border-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 con data-done para opacity 0.5 en completado.
  • .mobile-task-check — botón circular 22 px; data-checked gestiona fondo/borde.
  • .mobile-task-body / .mobile-task-title — elipsis con data-done para 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-bg y --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-bg y --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.
  • .mobile-nav — barra fija + backdrop-filter: blur(24px) + safe-area-inset-bottom.
  • .mobile-nav-item — contenedor flex flex: 1; position: relative.
  • .mobile-nav-link / .mobile-nav-button — ítem de navegación; data-active gestiona 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 (con data-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 con position: 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.
  • BottomNav eliminó la constante FIXED_BG acoplada al JS y la movió a CSS.

Archivos tocados

ArchivoCambio
src/styles/mobile.cssNuevo — ~440 LOC, utility classes del shell mobile completo
src/components/variants/mobile/V1HomeVivo.tsxRefactor — 81 → 6 inline (−93 %)
src/components/shell/BottomNav.tsxRefactor — 11 → 0 inline (−100 %)
src/layouts/AppLayout.astroImport de mobile.css tras tools.css

Véase también

  • [[crearack—conceptos—interfaz-general]]