/* ==========================================================================
   OKENTRA IoT Portal — sistema visual
   Paleta y tipografía tomadas del sitio institucional okentra.com:
   violeta #573CE6, carbón #26262F, verde #1F9D6B, navy #0B1345, Manrope.
   ========================================================================== */

/* Manrope servida desde el propio portal: la instalación del cliente puede no
   tener salida a internet (§16), así que no se depende de Google Fonts. */
@font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('/static/fonts/manrope-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                   U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                   U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('/static/fonts/manrope-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Marca */
    --brand-violet: #664BFF;
    --brand-violet-strong: #7A63FF;
    --brand-violet-light: #A786FA;
    --brand-violet-soft: #F0EDFF;
    --brand-navy: #081345;

    /* Superficies */
    --bg-main: #F5F6FA;
    --bg-card: #FFFFFF;
    --bg-subtle: #F5F6FA;
    --bg-hover: #F0EDFF;
    --bg-input: #FFFFFF;

    /* Texto */
    --text-primary: #26262F;
    --text-secondary: #6B7080;
    --text-muted: #9CA1B0;

    /* Estados (§21: verde OK, amarillo preventivo, rojo crítico, gris offline) */
    --accent-blue: #573CE6;
    --accent-green: #1F9D6B;
    --accent-warning: #B26A00;
    --accent-danger: #D13A3A;
    --accent-offline: #7C8499;

    --green-soft: #E4F5ED;
    --warning-soft: #FDF0DC;
    --danger-soft: #FCEAEA;
    --offline-soft: #EDEFF3;

    --brand-violet-pale: #C7BCFF;

    --border-color: #E6E6F0;
    /* Sombras y radios calcados del sitio institucional */
    --shadow-sm: 0 1px 2px rgba(8, 19, 69, 0.06);
    --shadow-md: 0 1px 3px rgba(8, 19, 69, 0.08), 0 1px 2px rgba(8, 19, 69, 0.05);
    --shadow-lg: 0 30px 70px rgba(8, 19, 69, 0.14), 0 2px 8px rgba(8, 19, 69, 0.06);
    --radius: 14px;
    --radius-lg: 28px;
    /* Gradiente característico de la marca */
    --gradient-brand: linear-gradient(120deg, #664BFF 0%, #081345 100%);
}

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    background-color: var(--bg-main);
    color: var(--text-primary);
    display: flex;
    min-height: 100vh;
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* El atributo `hidden` se apoya en `display: none` de la hoja del navegador, que
   pierde frente a cualquier regla de autor. Sin esto, `.card { display: flex }`
   deja visibles los diez pasos del asistente a la vez. */
[hidden] {
    display: none !important;
}

/* --------------------------------------------------------------- *
 * Navegación
 * --------------------------------------------------------------- */

.sidebar {
    width: 244px;
    flex-shrink: 0;
    background-color: var(--bg-card);
    border-right: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    padding: 1.75rem 0.9rem 1.25rem;
    /* Fijo en la pantalla y con scroll propio: sin esto, una lista larga de
       tarjetas empujaba a toda la página hacia abajo y se llevaba el menú
       (y el botón de cerrar sesión) fuera de vista con ella. */
    height: 100vh;
    position: sticky;
    top: 0;
    overflow-y: auto;
}

.sidebar .brand {
    padding: 0 0.6rem;
    margin-bottom: 2rem;
}

.sidebar .brand img {
    width: 100%;
    max-width: 168px;
    height: auto;
    display: block;
}

.nav-menu {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.62rem 0.85rem;
    color: var(--text-secondary);
    text-decoration: none;
    border-radius: 8px;
    font-size: 0.925rem;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-link:hover {
    background-color: var(--bg-hover);
    color: var(--text-primary);
}

.nav-link.active {
    background-color: var(--brand-violet-soft);
    color: var(--brand-violet);
    font-weight: 600;
}

.nav-icon {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    box-sizing: content-box;
    padding: 5px;
    border-radius: 9px;
    color: var(--brand-violet);
    background: var(--brand-violet-soft);
    opacity: 0.85;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-link.active .nav-icon {
    background: var(--brand-violet);
    color: #fff;
    opacity: 1;
}

.sidebar-footer {
    margin-top: auto;
    padding: 1.1rem 0.6rem 0;
    border-top: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.user-box { display: flex; flex-direction: column; gap: 0.1rem; }
.user-name { font-weight: 600; font-size: 0.9rem; color: var(--text-primary); }
.user-role { color: var(--text-muted); font-size: 0.78rem; text-transform: capitalize; }

/* El nombre de usuario lleva a "Mi cuenta": mismo lugar de siempre, ahora clicable */
.user-box-link {
    text-decoration: none;
    padding: 0.4rem 0.5rem;
    margin: -0.4rem -0.5rem;
    border-radius: 8px;
    transition: background-color 0.15s ease;
}
.user-box-link:hover { background-color: var(--bg-hover); }

.menu-toggle {
    display: none;
    position: fixed;
    top: 0.9rem;
    left: 0.9rem;
    z-index: 30;
    background: var(--bg-card);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    box-shadow: var(--shadow-sm);
    font-size: 1.1rem;
    padding: 0.4rem 0.7rem;
    cursor: pointer;
}

.main-content {
    flex: 1;
    padding: 2rem 2.25rem;
    overflow-y: auto;
    min-width: 0;
}

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.75rem;
}

.header h1 {
    font-size: 1.55rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--brand-navy);
}

/* --------------------------------------------------------------- *
 * Banda resumen con el gradiente de marca
 * --------------------------------------------------------------- */

.hero {
    position: relative;
    overflow: hidden;
    background: var(--gradient-brand);
    border-radius: var(--radius-lg);
    padding: 1.6rem 1.9rem;
    margin-bottom: 1.5rem;
    color: #FFFFFF;
    box-shadow: var(--shadow-lg);
}

/* Halo radial, el mismo recurso que usa el sitio institucional */
.hero::after {
    content: "";
    position: absolute;
    top: -60%;
    right: -10%;
    width: 460px;
    height: 460px;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0) 70%);
    pointer-events: none;
}

/* Versión blanca del logotipo sobre el gradiente. El manual pide respetar el
   área de protección: por eso queda arriba a la derecha, sin nada encima. */
.hero-logo {
    position: absolute;
    top: 1.5rem;
    right: 1.9rem;
    width: 118px;
    height: auto;
    opacity: 0.9;
}

.hero-title {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--brand-violet-pale);
    margin-bottom: 0.9rem;
}

.hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 2.2rem;
    position: relative;
}

.hero-stat { display: flex; flex-direction: column; gap: 0.1rem; }

.hero-stat b {
    font-size: 1.85rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.1;
}

.hero-stat span {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.7);
}

.hero-stat.is-alert b { color: #FFB4A8; }

/* --------------------------------------------------------------- *
 * Indicadores y avisos
 * --------------------------------------------------------------- */

.status-pill {
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    border: 1px solid transparent;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.status-pill::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}

.status-ok      { background: var(--green-soft);   color: var(--accent-green);   border-color: #C6E9DA; }
.status-error   { background: var(--danger-soft);  color: var(--accent-danger);  border-color: #F5CFCF; }
.status-demo    { background: var(--brand-violet-soft); color: var(--brand-violet); border-color: #D9CFFB; }
.status-unknown { background: var(--offline-soft); color: var(--accent-offline); border-color: var(--border-color); }

.toast {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    z-index: 50;
    max-width: 380px;
    padding: 0.85rem 1.15rem;
    border-radius: var(--radius);
    font-size: 0.88rem;
    box-shadow: var(--shadow-lg);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-left-width: 4px;
}

.toast-error   { border-left-color: var(--accent-danger); color: var(--accent-danger); }
.toast-success { border-left-color: var(--accent-green);  color: var(--accent-green); }
.toast-info    { border-left-color: var(--brand-violet);  color: var(--brand-violet); }

.empty-state {
    text-align: center;
    padding: 2.25rem 1.5rem;
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* --------------------------------------------------------------- *
 * Tarjetas
 * --------------------------------------------------------------- */

.grid-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1.15rem;
}

/* Agrupación por piso, al modo de las habitaciones de la consola del iHost */
.grupo + .grupo { margin-top: 1.9rem; }

.grupo-titulo {
    display: flex;
    align-items: baseline;
    gap: 0.7rem;
    margin-bottom: 0.85rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border-color);
}

.grupo-titulo > span:first-child {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--brand-navy);
    letter-spacing: -0.01em;
}

.grupo-conteo { font-size: 0.78rem; color: var(--text-muted); }

/* Arrastrar tarjetas entre pisos */
.card[data-device-id] { cursor: grab; }
.card[data-device-id]:active { cursor: grabbing; }

.card.arrastrando { opacity: 0.45; transform: scale(0.98); }

/* Tarjeta delante de la cual va a caer la que se arrastra: se corre un poco y
   muestra una guía violeta a su izquierda, como el hueco donde se va a insertar. */
.card.hueco {
    box-shadow: -6px 0 0 -2px var(--brand-violet);
    transform: translateX(5px);
    transition: transform 0.1s ease;
}

.grupo[data-floor] { border-radius: var(--radius); transition: background-color 0.15s ease; }

/* Aviso de configuración incompleta: ámbar, no rojo. No es un fallo del
   sistema, es algo que falta cargar, y el rojo está reservado a las alertas. */
.aviso {
    background: #FFF8E6;
    border: 1px solid #F5D08A;
    border-left: 3px solid #F5A524;
    border-radius: var(--radius);
    padding: 0.9rem 1.1rem;
    margin-bottom: 1.25rem;
    color: #7A5300;
    font-size: 0.875rem;
    line-height: 1.55;
}

.aviso a { color: #7A5300; font-weight: 600; }

/* Un piso sin sensores sigue en pantalla, atenuado, para poder soltar una
   tarjeta ahí y devolverla. Si desaparece, no hay forma de volver arrastrando. */
.grupo-vacio { opacity: 0.7; }

.piso-vacio {
    grid-column: 1 / -1;
    padding: 1.6rem;
    border: 2px dashed var(--border-color);
    border-radius: var(--radius);
    text-align: center;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.grupo.destino-activo {
    background-color: var(--brand-violet-soft);
    outline: 2px dashed var(--brand-violet);
    outline-offset: 6px;
}

/* --------------------------------------------------------------- *
 * Panel de detalle
 * --------------------------------------------------------------- */

.modal-fondo {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(8, 19, 69, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 3rem 1.5rem;
    overflow-y: auto;
    backdrop-filter: blur(2px);
}

.modal {
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 720px;
}

.modal-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.4rem 1.6rem;
    border-bottom: 1px solid var(--border-color);
}

.modal-cabecera h3 { font-size: 1.05rem; font-weight: 700; color: var(--brand-navy); }

.modal-cerrar {
    background: none;
    border: none;
    font-size: 1.1rem;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.2rem 0.45rem;
    border-radius: 8px;
    line-height: 1;
}

.modal-cerrar:hover { background: var(--bg-hover); color: var(--text-primary); }

.modal-cuerpo { padding: 1.5rem 1.6rem 1.8rem; }

/* Contenedor de gráfico sobre fondo violeta-marino. `buildLineChart` detecta
   esta clase en un ancestro del canvas y cambia grilla, ejes y leyenda a los
   tonos claros; las series usan la paleta oscura, que se fija con usarPaleta(). */
.chart-oscuro {
    background: linear-gradient(160deg, #10184A 0%, #0E1640 55%, #1B0F47 100%);
    border-radius: var(--radius);
    padding: 1.1rem 1rem 0.6rem;
}

.chart-oscuro .chart-titulo {
    color: rgba(255, 255, 255, 0.92);
    font-size: 0.95rem;
    font-weight: 600;
    margin: 0 0 0.2rem 0.3rem;
}

/* Tarjeta oscura que agrupa el valor grande y el gráfico, al estilo de la
   app móvil: un solo bloque violeta-marino en vez de número y gráfico
   sueltos sobre el fondo blanco del resto del panel. */
.detalle-hero-oscuro {
    background: linear-gradient(160deg, #10184A 0%, #0E1640 55%, #1B0F47 100%);
    border-radius: var(--radius);
    padding: 1.5rem 1.1rem 0.6rem;
    margin-bottom: 1.1rem;
}

.detalle-hero-oscuro .chart-titulo {
    color: rgba(255, 255, 255, 0.92);
    font-size: 0.9rem;
    font-weight: 600;
    margin: 0.4rem 0 0.2rem 0.3rem;
}

.detalle-hero { text-align: center; margin-bottom: 0.3rem; }

.detalle-valor {
    font-size: 3rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.8rem;
}

.detalle-hero .pill-row { justify-content: center; margin-top: 0.7rem; }

/* Las píldoras claras de siempre no se leen sobre este fondo oscuro: se
   pasan a vidrio esmerilado, blanco translúcido sobre violeta-marino. */
.detalle-hero-oscuro .pill,
.detalle-hero-oscuro .badge {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}

.periodo-selector {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 1.1rem;
    background: var(--bg-subtle);
    padding: 0.28rem;
    border-radius: 999px;
}

.periodo {
    flex: 1;
    padding: 0.42rem 0.7rem;
    border: none;
    background: none;
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
}

.periodo.activo {
    background: var(--brand-violet);
    color: #FFFFFF;
    box-shadow: var(--shadow-sm);
}

@media (max-width: 768px) {
    .modal-fondo { padding: 1rem; }
    .detalle-valor { font-size: 2.2rem; }
}

.card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 1.15rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.card > h3 {
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: -0.005em;
}

.card.span-2 { grid-column: span 2; }

.card-header { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
.card-header h3 { font-size: 0.9rem; font-weight: 600; letter-spacing: 0.01em; }

/* Tarjeta de sensor: barra de acento a la izquierda y magnitud en violeta.
   El color del estado lo lleva la insignia (§21); el violeta es la identidad. */
.card[data-status] {
    border-left: 3px solid var(--brand-violet);
}

.card[data-status="Preventiva"] { border-left-color: var(--accent-warning); }
.card[data-status="Crítica"]    { border-left-color: var(--accent-danger); }
.card[data-status="Offline"]    { border-left-color: var(--accent-offline); }

.card-temp {
    font-size: 2.1rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--brand-violet);
}

.card[data-status="Preventiva"] .card-temp { color: var(--accent-warning); }
.card[data-status="Crítica"]    .card-temp { color: var(--accent-danger); }
.card[data-status="Offline"]    .card-temp { color: var(--text-muted); }

.card-meta { color: var(--text-secondary); font-size: 0.82rem; }
.card-meta strong { color: var(--brand-violet); font-weight: 600; }

/* --------------------------------------------------------------- *
 * Iconos de dispositivo y pastillas de estado
 * --------------------------------------------------------------- */

.device-icon {
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 11px;
    background: var(--brand-violet-soft);
    color: var(--brand-violet);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.device-icon svg { width: 21px; height: 21px; }

.card[data-status="Preventiva"] .device-icon { background: var(--warning-soft); color: var(--accent-warning); }
.card[data-status="Crítica"]    .device-icon { background: var(--danger-soft);  color: var(--accent-danger); }
.card[data-status="Offline"]    .device-icon { background: var(--offline-soft); color: var(--accent-offline); }

.card-title { display: flex; align-items: center; gap: 0.65rem; min-width: 0; }
.card-title h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.card-clicable { cursor: pointer; transition: box-shadow 0.15s ease, transform 0.15s ease; }
.card-clicable:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.card-seleccionada {
    outline: 2px solid var(--brand-violet);
    outline-offset: -1px;
    background: var(--brand-violet-soft);
}

/* Marca de qué línea del gráfico le corresponde a esta tarjeta */
.punto-serie {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 0.4rem;
    flex-shrink: 0;
}

.pill-row { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }

/* Magnitudes con su icono, al estilo de la consola del iHost */
.medida {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.82rem;
    font-weight: 600;
}

.icono-medida { width: 14px; height: 14px; flex-shrink: 0; }
.medida-temp { color: var(--brand-violet); }
.medida-hum  { color: #1F6FD0; }

.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--bg-subtle);
    color: var(--text-secondary);
}

.pill-ok      { background: var(--green-soft);   color: var(--accent-green); }
.pill-warning { background: var(--warning-soft); color: var(--accent-warning); }
.pill-danger  { background: var(--danger-soft);  color: var(--accent-danger); }

/* Pila dibujada con CSS, al estilo del indicador del iHost */
.battery {
    position: relative;
    width: 20px;
    height: 10px;
    border: 1.5px solid currentColor;
    border-radius: 3px;
    padding: 1px;
}

.battery::after {
    content: "";
    position: absolute;
    right: -3.5px;
    top: 2.5px;
    width: 2px;
    height: 3px;
    background: currentColor;
    border-radius: 0 1px 1px 0;
}

.battery-fill { display: block; height: 100%; background: currentColor; border-radius: 1px; }

/* Empuja la acción al pie para que quede a la misma altura en todas las
   tarjetas de la fila, sin importar cuánto texto tenga cada una. */
.card-action {
    margin-top: auto;
    align-self: flex-start;
}

.stat-row {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    color: var(--text-muted);
    font-size: 0.78rem;
}

.stat-row b {
    color: var(--brand-violet);
    display: block;
    font-size: 1.05rem;
    font-weight: 700;
    margin-top: 0.1rem;
}

.badge {
    padding: 0.22rem 0.6rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.badge-ok      { background-color: var(--green-soft);   color: var(--accent-green); }
.badge-warning { background-color: var(--warning-soft); color: var(--accent-warning); }
.badge-danger  { background-color: var(--danger-soft);  color: var(--accent-danger); }
.badge-offline { background-color: var(--offline-soft); color: var(--accent-offline); }

.chart-box { position: relative; height: 320px; }

/* --------------------------------------------------------------- *
 * Controles
 * --------------------------------------------------------------- */

.btn {
    padding: 0.55rem 1.05rem;
    border-radius: 8px;
    border: 1px solid transparent;
    font-family: inherit;
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    background-color: var(--brand-violet);
    color: #FFFFFF;
    text-decoration: none;
    display: inline-block;
    transition: filter 0.15s ease, background-color 0.15s ease;
}

.btn:hover { filter: brightness(1.08); }
.btn:active { filter: brightness(0.95); }

.btn-secondary {
    background-color: var(--bg-card);
    color: var(--text-primary);
    border-color: var(--border-color);
    box-shadow: var(--shadow-sm);
}
.btn-secondary:hover { background-color: var(--bg-hover); filter: none; }

.btn-success { background-color: var(--accent-green); color: #FFFFFF; }
.btn-danger  { background-color: var(--bg-card); color: var(--accent-danger); border-color: #F5CFCF; }
.btn-danger:hover { background-color: var(--danger-soft); filter: none; }

.btn-block { width: 100%; }
.btn-sm { padding: 0.32rem 0.7rem; font-size: 0.78rem; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 0.9rem;
    margin-bottom: 1rem;
}

.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field label { color: var(--text-secondary); font-size: 0.8rem; font-weight: 500; }

.field input[type="text"], .field input[type="number"], .field input[type="password"],
.field input[type="email"], .field input[type="datetime-local"], .field select, .field textarea,
.table-custom input[type="text"], .table-custom input[type="number"], .table-custom select {
    padding: 0.5rem 0.7rem;
    border-radius: 8px;
    border: 1px solid var(--border-color);
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.875rem;
    font-family: inherit;
    width: 100%;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:focus, .field select:focus, .field textarea:focus,
.table-custom input:focus, .table-custom select:focus {
    outline: none;
    border-color: var(--brand-violet);
    box-shadow: 0 0 0 3px var(--brand-violet-soft);
}

.field input[type="checkbox"] { accent-color: var(--brand-violet); width: 16px; height: 16px; }

.field-inline { flex-direction: row; align-items: center; gap: 0.5rem; }
.field-inline label { color: var(--text-primary); font-size: 0.875rem; }

.toolbar { display: flex; gap: 0.65rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: 0.5rem; }

/* --------------------------------------------------------------- *
 * Tablas
 * --------------------------------------------------------------- */

.table-wrapper {
    overflow-x: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
}

.table-custom {
    width: 100%;
    border-collapse: collapse;
    background-color: var(--bg-card);
    font-size: 0.865rem;
}

.table-custom th, .table-custom td {
    padding: 0.7rem 0.9rem;
    text-align: left;
    border-bottom: 1px solid var(--border-color);
    white-space: nowrap;
}

.table-custom th {
    background-color: var(--bg-subtle);
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.table-custom tbody tr:last-child td { border-bottom: none; }
.table-custom tbody tr:hover { background-color: #FAFBFD; }

.table-custom code {
    font-family: Consolas, monospace;
    font-size: 0.9em;
    color: var(--text-secondary);
}

/* Modo identificar: la fila del sensor que acaba de reportar un valor distinto
   se resalta y se desvanece, para reconocerlo sin bajarlo de su ubicación. */
.table-custom tbody tr.fila-cambio {
    animation: destello 4s ease-out;
}

@keyframes destello {
    0%   { background-color: var(--brand-violet); }
    12%  { background-color: var(--brand-violet); }
    100% { background-color: transparent; }
}

.table-custom tbody tr.fila-cambio td {
    animation: destello-texto 4s ease-out;
}

@keyframes destello-texto {
    0%   { color: #FFFFFF; }
    12%  { color: #FFFFFF; }
    100% { color: inherit; }
}

/* --------------------------------------------------------------- *
 * Asistente
 * --------------------------------------------------------------- */

.wizard-steps { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 1.5rem; }

.wizard-step {
    width: 30px; height: 30px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 600;
}

.wizard-step.active {
    background: var(--brand-violet);
    color: #FFFFFF;
    border-color: var(--brand-violet);
}

.wizard-step.done {
    background: var(--green-soft);
    color: var(--accent-green);
    border-color: #C6E9DA;
}

.wizard-actions { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1.25rem; }

.hint { color: var(--text-secondary); font-size: 0.85rem; line-height: 1.6; }
.hint ol, .hint ul { margin: 0.5rem 0 0 1.15rem; }
.hint li { margin-bottom: 0.2rem; }
.hint code {
    background: var(--bg-subtle);
    padding: 0.08rem 0.35rem;
    border-radius: 4px;
    font-size: 0.85em;
    font-family: Consolas, monospace;
}

/* --------------------------------------------------------------- *
 * Responsive: notebook, tablet y celular (§21)
 * --------------------------------------------------------------- */

@media (max-width: 1024px) {
    .card.span-2 { grid-column: span 1; }
    .main-content { padding: 1.75rem 1.5rem; }
}

@media (max-width: 768px) {
    body { display: block; }

    .menu-toggle { display: block; }

    .sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        z-index: 25;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: var(--shadow-lg);
    }

    body.sidebar-open .sidebar { transform: translateX(0); }

    .main-content { padding: 4.25rem 1rem 2rem; }
    .header h1 { font-size: 1.25rem; }
    .grid-cards { grid-template-columns: 1fr; }
    .toolbar { flex-direction: column; align-items: stretch; }
    .toast { left: 1rem; right: 1rem; max-width: none; }
}
