feat(ui): modernize home dashboard and welcome experience close #72 #73
276
docs/stories/Story-72-Modernizacion-Home-PhronCare.md
Normal file
276
docs/stories/Story-72-Modernizacion-Home-PhronCare.md
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
# PhronCare — Story #72: Modernización de la Página de Inicio
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
|
||||||
|
Modernizar la página principal posterior al login para reemplazar el contenido demo actual por una Home profesional, moderna y visualmente atractiva, alineada con el resto de PhronCare.
|
||||||
|
|
||||||
|
La nueva Home debe funcionar como punto de entrada al sistema y ofrecer una visión rápida de los módulos principales.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contexto funcional
|
||||||
|
|
||||||
|
Actualmente la página principal del BackOffice muestra contenido de demostración utilizado durante el desarrollo inicial.
|
||||||
|
|
||||||
|
El contenido existente no representa información funcional del producto y genera una percepción poco profesional para usuarios finales.
|
||||||
|
|
||||||
|
PhronCare ya cuenta con múltiples módulos funcionales:
|
||||||
|
|
||||||
|
- Pacientes
|
||||||
|
- Presupuestos
|
||||||
|
- Ventas
|
||||||
|
- Remitos
|
||||||
|
- Sales Documents
|
||||||
|
- Stock
|
||||||
|
- Tickets
|
||||||
|
- Configuración
|
||||||
|
|
||||||
|
La Home debe evolucionar hacia un dashboard de bienvenida que sirva como punto de navegación principal.
|
||||||
|
|
||||||
|
Esta Story se enfoca exclusivamente en la capa UI.
|
||||||
|
|
||||||
|
No debe incorporar métricas reales ni nuevas integraciones.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alcance
|
||||||
|
|
||||||
|
Analizar la implementación actual de la Home.
|
||||||
|
|
||||||
|
Identificar archivos involucrados.
|
||||||
|
|
||||||
|
Reemplazar el contenido demo actual por un dashboard institucional.
|
||||||
|
|
||||||
|
Implementar:
|
||||||
|
|
||||||
|
### 1. Hero de bienvenida
|
||||||
|
|
||||||
|
Bloque superior con:
|
||||||
|
|
||||||
|
- nombre del sistema
|
||||||
|
- mensaje de bienvenida
|
||||||
|
- descripción breve
|
||||||
|
|
||||||
|
Ejemplo:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Bienvenido a PhronCare
|
||||||
|
|
||||||
|
Gestión integral para empresas de internación domiciliaria,
|
||||||
|
ortopedia y prestaciones médicas.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Accesos rápidos
|
||||||
|
|
||||||
|
Mostrar tarjetas de navegación hacia módulos principales.
|
||||||
|
|
||||||
|
- Pacientes
|
||||||
|
- Presupuestos
|
||||||
|
- Ventas
|
||||||
|
- Remitos
|
||||||
|
- Sales Documents
|
||||||
|
- Stock
|
||||||
|
- Tickets
|
||||||
|
|
||||||
|
Cada tarjeta debe permitir navegación directa.
|
||||||
|
|
||||||
|
### 3. Tarjetas resumen
|
||||||
|
|
||||||
|
Agregar sección de KPIs visuales mock.
|
||||||
|
|
||||||
|
Ejemplos:
|
||||||
|
|
||||||
|
- Presupuestos Activos
|
||||||
|
- Remitos Emitidos
|
||||||
|
- Facturas Pendientes
|
||||||
|
- Tickets Abiertos
|
||||||
|
|
||||||
|
Valores estáticos temporales.
|
||||||
|
|
||||||
|
No consumir API.
|
||||||
|
|
||||||
|
No generar endpoints.
|
||||||
|
|
||||||
|
### 4. Actividad reciente
|
||||||
|
|
||||||
|
Agregar listado visual de actividad simulada.
|
||||||
|
|
||||||
|
Ejemplo:
|
||||||
|
|
||||||
|
- Presupuesto aprobado
|
||||||
|
- Remito emitido
|
||||||
|
- Factura generada
|
||||||
|
- Ticket cerrado
|
||||||
|
|
||||||
|
Contenido mock.
|
||||||
|
|
||||||
|
### 5. Responsive
|
||||||
|
|
||||||
|
La Home debe visualizarse correctamente en:
|
||||||
|
|
||||||
|
- Desktop
|
||||||
|
- Tablet
|
||||||
|
- Notebook
|
||||||
|
|
||||||
|
Utilizar Bootstrap existente.
|
||||||
|
|
||||||
|
### 6. Compatibilidad visual
|
||||||
|
|
||||||
|
Mantener compatibilidad con:
|
||||||
|
|
||||||
|
- tema claro
|
||||||
|
- tema oscuro
|
||||||
|
|
||||||
|
No romper estilos existentes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fuera de alcance
|
||||||
|
|
||||||
|
No modificar:
|
||||||
|
|
||||||
|
- Data
|
||||||
|
- Models
|
||||||
|
- Domain
|
||||||
|
- Core
|
||||||
|
- API
|
||||||
|
- Base de datos
|
||||||
|
- Stored Procedures
|
||||||
|
- Repositorios
|
||||||
|
- DTOs
|
||||||
|
- Endpoints
|
||||||
|
- Swagger
|
||||||
|
- Autenticación
|
||||||
|
- Permisos
|
||||||
|
|
||||||
|
No incorporar:
|
||||||
|
|
||||||
|
- métricas reales
|
||||||
|
- integraciones externas
|
||||||
|
- reportes
|
||||||
|
- charts dinámicos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Criterios de aceptación
|
||||||
|
|
||||||
|
- La página principal deja de mostrar contenido demo.
|
||||||
|
- Existe una sección institucional de bienvenida.
|
||||||
|
- Existen accesos rápidos a módulos principales.
|
||||||
|
- Existen tarjetas resumen visuales.
|
||||||
|
- Existe sección de actividad reciente mock.
|
||||||
|
- La página es responsive.
|
||||||
|
- Funciona correctamente en modo claro y oscuro.
|
||||||
|
- No se generan cambios fuera de UI.
|
||||||
|
- El proyecto compila correctamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decisiones de diseño
|
||||||
|
|
||||||
|
### Dashboard estático inicial
|
||||||
|
|
||||||
|
La Home funcionará inicialmente como dashboard visual.
|
||||||
|
|
||||||
|
Las métricas serán simuladas.
|
||||||
|
|
||||||
|
Esto evita dependencias innecesarias con API y permite evolucionar posteriormente hacia métricas reales.
|
||||||
|
|
||||||
|
### Navegación rápida
|
||||||
|
|
||||||
|
La Home debe priorizar velocidad de acceso a funcionalidades frecuentes.
|
||||||
|
|
||||||
|
No reemplaza menús laterales existentes.
|
||||||
|
|
||||||
|
Los complementa.
|
||||||
|
|
||||||
|
### Implementación exclusivamente UI
|
||||||
|
|
||||||
|
Toda la Story queda limitada a:
|
||||||
|
|
||||||
|
```text
|
||||||
|
UI (Blazor)
|
||||||
|
```
|
||||||
|
|
||||||
|
Sin impacto en capas inferiores.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wireframe funcional esperado
|
||||||
|
|
||||||
|
```text
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| Bienvenido a PhronCare |
|
||||||
|
| Gestión integral de prestaciones médicas |
|
||||||
|
+--------------------------------------------------+
|
||||||
|
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
| Pacientes | Ventas | Stock | Tickets |
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
| Presup. | Remitos | Facturas | Config |
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
| 128 | 42 | 15 | 6 |
|
||||||
|
| Presup. | Remitos | Facturas | Tickets |
|
||||||
|
+-----------+-----------+-----------+-------------+
|
||||||
|
|
||||||
|
Actividad reciente
|
||||||
|
|
||||||
|
• Presupuesto aprobado
|
||||||
|
• Remito emitido
|
||||||
|
• Factura generada
|
||||||
|
• Ticket cerrado
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entregable esperado
|
||||||
|
|
||||||
|
Archivos potencialmente involucrados:
|
||||||
|
|
||||||
|
- phronCare.UIBlazor/Pages/Index.razor
|
||||||
|
- phronCare.UIBlazor/wwwroot/css/app.css
|
||||||
|
|
||||||
|
Pueden agregarse componentes UI auxiliares si Codex considera necesario reutilizar patrones existentes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Branch sugerida
|
||||||
|
|
||||||
|
```text
|
||||||
|
feature/leandro/72-home-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit sugerido
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat(ui): modernize home dashboard and welcome experience close #72
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Instrucción para Codex
|
||||||
|
|
||||||
|
```text
|
||||||
|
Analizar primero el repositorio completo.
|
||||||
|
|
||||||
|
Identificar cómo está implementada actualmente la Home.
|
||||||
|
|
||||||
|
Reutilizar componentes, estilos y patrones ya existentes.
|
||||||
|
|
||||||
|
No generar APIs.
|
||||||
|
No generar Core.
|
||||||
|
No generar Domain.
|
||||||
|
No generar Models.
|
||||||
|
|
||||||
|
Limitar todos los cambios a UI.
|
||||||
|
|
||||||
|
Implementar la Home descrita en esta Story.
|
||||||
|
|
||||||
|
Generar patch final validado mediante compilación exitosa.
|
||||||
|
```
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<div class="@($"{NavMenuCssClass} nav-scrollable bg-dark text-white")" @onclick="ToggleNavMenu" style="padding-top:4px;">
|
<div class="@($"{NavMenuCssClass} nav-scrollable bg-dark text-white")" @onclick="ToggleNavMenu" style="padding-top:4px;">
|
||||||
<nav class="flex-column text-center">
|
<nav class="flex-column text-center">
|
||||||
<div class="nav-item px-2 py-0">
|
<div class="nav-item px-2 py-0">
|
||||||
<NavLink class="nav-link text-white d-flex align-items-center gap-2 py-0 px-2" href="/DashboardPanel" Match="NavLinkMatch.All" activeClass="bg-secondary text-white">
|
<NavLink class="nav-link text-white d-flex align-items-center gap-2 py-0 px-2" href="/" Match="NavLinkMatch.All" activeClass="bg-secondary text-white">
|
||||||
<span class="oi oi-home" aria-hidden="true"></span>
|
<span class="oi oi-home" aria-hidden="true"></span>
|
||||||
@if (!navMenuService.Minimized)
|
@if (!navMenuService.Minimized)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,50 +1,135 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
@using phronCare.UIBlazor.Pages.Authorization
|
@using phronCare.UIBlazor.Pages.Authorization
|
||||||
|
@inject NavigationManager Navigation
|
||||||
|
|
||||||
<PageTitle>PhronCare</PageTitle>
|
<PageTitle>PhronCare</PageTitle>
|
||||||
|
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
<h1>Hola, usuario!</h1>
|
<section class="home-dashboard">
|
||||||
Bievenido a PhronCare.
|
<div class="home-hero">
|
||||||
Estamos en etapa de desarrollo.-
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<ul class="fa-ul">
|
|
||||||
<li><span class="fa-li"><i class="fa-solid fa-check-square"></i></span>List icons can</li>
|
|
||||||
<li><span class="fa-li"><i class="fa-solid fa-check-square"></i></span>be used to</li>
|
|
||||||
<li><span class="fa-li"><i class="fa-solid fa-spinner fa-pulse"></i></span>replace bullets</li>
|
|
||||||
<li><span class="fa-li"><i class="fa-regular fa-square"></i></span>in lists</li>
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
<div>
|
<div>
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-arrow-left fa-fw" title="Back"></i></span>
|
<span class="home-eyebrow">BackOffice operativo</span>
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-arrow-right fa-fw" title="Forward"></i></span>
|
<h1>Bienvenido a PhronCare</h1>
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-arrows-rotate fa-fw" title="Refresh"></i></span>
|
<p>
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-house fa-fw" title="Home"></i></span>
|
Gestion integral para empresas de internacion domiciliaria,
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-info fa-fw" title="Info"></i></span>
|
ortopedia y prestaciones medicas.
|
||||||
<span style="border: 1px solid silver; border-radius: 0.25em; padding: 0.5em;"><i class="fa-solid fa-download fa-fw" title="Download"></i></span>
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="home-hero-status" aria-label="Estado general">
|
||||||
|
<span class="home-status-dot"></span>
|
||||||
|
Plataforma operativa
|
||||||
</div>
|
</div>
|
||||||
<br />
|
|
||||||
<div class="fa-3x">
|
|
||||||
<i class="fa-solid fa-sync fa-spin"></i>
|
|
||||||
<i class="fa-solid fa-circle-notch fa-spin"></i>
|
|
||||||
<i class="fa-solid fa-cog fa-spin"></i>
|
|
||||||
<i class="fa-solid fa-cog fa-spin fa-spin-reverse"></i>
|
|
||||||
<i class="fa-solid fa-spinner fa-spin-pulse"></i>
|
|
||||||
<i class="fa-solid fa-spinner fa-spin-pulse fa-spin-reverse"></i>
|
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
|
||||||
|
|
||||||
|
<div class="home-section-header">
|
||||||
|
<h2>Accesos rapidos</h2>
|
||||||
|
<span>Modulos principales</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="quick-access-grid">
|
||||||
|
@foreach (var item in QuickAccessItems)
|
||||||
|
{
|
||||||
|
<button type="button" class="quick-access-card" @onclick="() => NavigateTo(item.Url)">
|
||||||
|
<span class="quick-access-icon @item.AccentClass">
|
||||||
|
<i class="@item.Icon" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span class="quick-access-content">
|
||||||
|
<strong>@item.Title</strong>
|
||||||
|
<small>@item.Description</small>
|
||||||
|
</span>
|
||||||
|
<i class="fas fa-chevron-right quick-access-arrow" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="home-content-grid">
|
||||||
|
<section>
|
||||||
|
<div class="home-section-header">
|
||||||
|
<h2>Resumen operativo</h2>
|
||||||
|
<span>Valores temporales</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="kpi-grid">
|
||||||
|
@foreach (var item in SummaryItems)
|
||||||
|
{
|
||||||
|
<div class="kpi-card">
|
||||||
|
<div class="kpi-icon @item.AccentClass">
|
||||||
|
<i class="@item.Icon" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>@item.Value</strong>
|
||||||
|
<span>@item.Title</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="home-section-header">
|
||||||
|
<h2>Actividad reciente</h2>
|
||||||
|
<span>Simulada</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="activity-list">
|
||||||
|
@foreach (var item in RecentActivity)
|
||||||
|
{
|
||||||
|
<div class="activity-item">
|
||||||
|
<span class="activity-icon @item.AccentClass">
|
||||||
|
<i class="@item.Icon" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<strong>@item.Title</strong>
|
||||||
|
<small>@item.Description</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</Authorized>
|
</Authorized>
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
<LoginPage />
|
<LoginPage />
|
||||||
</NotAuthorized>
|
</NotAuthorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
public bool state;
|
private readonly List<QuickAccessItem> QuickAccessItems =
|
||||||
private void OnChangeToggleSwitchState(bool value)
|
[
|
||||||
|
new("Pacientes", "Gestion de pacientes y datos asistenciales.", "/sales/patients", "fas fa-user-injured", "accent-blue"),
|
||||||
|
new("Presupuestos", "Consulta y seguimiento de presupuestos.", "/quotes/dashboard", "fas fa-file-invoice-dollar", "accent-green"),
|
||||||
|
new("Ventas", "Clientes, productos y circuito comercial.", "/sales/customers", "fas fa-briefcase", "accent-indigo"),
|
||||||
|
new("Remitos", "Emision y control de remitos.", "/deliverynotes", "fas fa-truck", "accent-orange"),
|
||||||
|
new("Sales Documents", "Documentos comerciales y facturacion.", "/salesdocuments", "fas fa-receipt", "accent-teal"),
|
||||||
|
new("Stock", "Productos medicos y trazabilidad.", "/stock/products", "fas fa-boxes-stacked", "accent-violet"),
|
||||||
|
new("Tickets", "Alta y seguimiento de tickets.", "/dashboardpanel", "fas fa-ticket-alt", "accent-red")
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly List<SummaryItem> SummaryItems =
|
||||||
|
[
|
||||||
|
new("Presupuestos Activos", "128", "fas fa-file-signature", "accent-green"),
|
||||||
|
new("Remitos Emitidos", "42", "fas fa-truck-fast", "accent-orange"),
|
||||||
|
new("Facturas Pendientes", "15", "fas fa-file-invoice", "accent-teal"),
|
||||||
|
new("Tickets Abiertos", "6", "fas fa-headset", "accent-red")
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly List<ActivityItem> RecentActivity =
|
||||||
|
[
|
||||||
|
new("Presupuesto aprobado", "Hace 12 minutos", "fas fa-check-circle", "accent-green"),
|
||||||
|
new("Remito emitido", "Hace 38 minutos", "fas fa-truck", "accent-orange"),
|
||||||
|
new("Factura generada", "Hoy, 10:45", "fas fa-receipt", "accent-teal"),
|
||||||
|
new("Ticket cerrado", "Hoy, 09:20", "fas fa-circle-check", "accent-red")
|
||||||
|
];
|
||||||
|
|
||||||
|
private void NavigateTo(string url)
|
||||||
{
|
{
|
||||||
state = value;
|
Navigation.NavigateTo(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed record QuickAccessItem(string Title, string Description, string Url, string Icon, string AccentClass);
|
||||||
|
private sealed record SummaryItem(string Title, string Value, string Icon, string AccentClass);
|
||||||
|
private sealed record ActivityItem(string Title, string Description, string Icon, string AccentClass);
|
||||||
}
|
}
|
||||||
318
phronCare.UIBlazor/Pages/Index.razor.css
Normal file
318
phronCare.UIBlazor/Pages/Index.razor.css
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
.home-dashboard {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero {
|
||||||
|
align-items: flex-start;
|
||||||
|
background: var(--background-highlight);
|
||||||
|
border: 1px solid var(--background-highlight-light);
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-eyebrow {
|
||||||
|
color: var(--link-color);
|
||||||
|
display: block;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0;
|
||||||
|
margin-bottom: 0.45rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero h1 {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero p {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
margin: 0.75rem 0 0;
|
||||||
|
max-width: 760px;
|
||||||
|
opacity: 0.78;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero-status {
|
||||||
|
align-items: center;
|
||||||
|
background: var(--background);
|
||||||
|
border: 1px solid var(--background-highlight-light);
|
||||||
|
border-radius: 999px;
|
||||||
|
color: var(--text-background);
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.45rem 0.75rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-status-dot {
|
||||||
|
background: #16a085;
|
||||||
|
border-radius: 999px;
|
||||||
|
box-shadow: 0 0 0 4px rgba(22, 160, 133, 0.14);
|
||||||
|
height: 0.6rem;
|
||||||
|
width: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-section-header {
|
||||||
|
align-items: baseline;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-section-header h2 {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-section-header span {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
opacity: 0.62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.9rem;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-card {
|
||||||
|
align-items: center;
|
||||||
|
background: var(--background-highlight);
|
||||||
|
border: 1px solid var(--background-highlight-light);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: var(--text-background);
|
||||||
|
cursor: pointer;
|
||||||
|
display: grid;
|
||||||
|
gap: 0.75rem;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
min-height: 86px;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-card:hover,
|
||||||
|
.quick-access-card:focus {
|
||||||
|
border-color: var(--link-color);
|
||||||
|
box-shadow: 0 0.35rem 1rem rgba(0, 0, 0, 0.12);
|
||||||
|
outline: none;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-icon,
|
||||||
|
.kpi-icon,
|
||||||
|
.activity-icon {
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #fff;
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-icon {
|
||||||
|
font-size: 1rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-content strong {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-content small {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 0.78rem;
|
||||||
|
line-height: 1.35;
|
||||||
|
opacity: 0.66;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-arrow {
|
||||||
|
color: var(--text-background);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.48;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-content-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.5rem;
|
||||||
|
grid-template-columns: minmax(0, 1.3fr) minmax(280px, 0.7fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-content-grid section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.9rem;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-card,
|
||||||
|
.activity-list {
|
||||||
|
background: var(--background-highlight);
|
||||||
|
border: 1px solid var(--background-highlight-light);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-card {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.9rem;
|
||||||
|
min-height: 92px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-icon {
|
||||||
|
font-size: 1rem;
|
||||||
|
height: 2.65rem;
|
||||||
|
width: 2.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-card strong {
|
||||||
|
color: var(--text-background);
|
||||||
|
display: block;
|
||||||
|
font-size: 1.75rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-card span {
|
||||||
|
color: var(--text-background);
|
||||||
|
display: block;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-top: 0.35rem;
|
||||||
|
opacity: 0.68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.85rem;
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 0.95rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item + .activity-item {
|
||||||
|
border-top: 1px solid var(--background-highlight-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-icon {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
height: 2.25rem;
|
||||||
|
width: 2.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item strong {
|
||||||
|
color: var(--text-background);
|
||||||
|
display: block;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-item small {
|
||||||
|
color: var(--text-background);
|
||||||
|
display: block;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
margin-top: 0.18rem;
|
||||||
|
opacity: 0.62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-blue {
|
||||||
|
background: #2473a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-green {
|
||||||
|
background: #138f77;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-indigo {
|
||||||
|
background: #34495e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-orange {
|
||||||
|
background: #da8c10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-teal {
|
||||||
|
background: #2c8f9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-violet {
|
||||||
|
background: #7f3d9b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent-red {
|
||||||
|
background: #cf4435;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1199.98px) {
|
||||||
|
.quick-access-grid {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.home-content-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-access-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767.98px) {
|
||||||
|
.home-hero {
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero h1 {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero-status {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-grid,
|
||||||
|
.quick-access-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user