.app-shell {
    display: flex;
    min-height: 100vh;
    background: rgb(var(--canvas-rgb));
    color: rgb(var(--ink-rgb));
}

body.unauth {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Centrado por márgenes automáticos y no por `justify-content: center`.
       Centrar reparte el desbordamiento a los dos lados por igual, y entonces
       lo que se sale por arriba no se puede alcanzar: no hay scroll hacia
       negativo. Entrar mide 684 px con sus dos campos, su enlace y el bloque
       de credenciales de demostración, así que en una ventana de 664 px su
       título quedaba a 44 px del borde —debajo de la barra del logotipo, que
       ocupa los primeros 84— y no había forma de subir a leerlo. Un margen
       automático centra igual cuando cabe, y cuando no cabe se apoya en el
       borde de arriba y desborda solo por abajo, que es hacia donde sí se
       puede rodar. */
    min-height: 100vh;
    background: rgb(var(--canvas-rgb));
}
body.unauth main {
    display: flex;
    align-items: center;
    justify-content: center;
    /* La barra con el logotipo y el tema va absoluta sobre el borde de arriba:
       cuando el contenido se apoya ahí, hay que dejarle su sitio. */
    margin-block: auto;
    padding: 84px 16px 24px;
    width: 100%;
}

body.auth {
    padding-left: 260px;
}

/* content wrapper */
.content-wrapper { width: 100%; }
body.unauth .content-wrapper {
    width: auto;
    max-width: 960px;
    margin: 0 auto;
}

aside.sidebar {
    width: 260px;
    min-height: 100vh;
    background: rgb(var(--surface-rgb));
    border-right: 1px solid rgb(var(--line-rgb));
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
}

/* ── La barra lateral ────────────────────────────────────────────────────
   Tres piezas de arriba abajo: la marca, el menú (que es lo único que hace
   scroll) y el pie con la identidad. Antes eran cinco bloques y el usuario
   iba arriba, bajo el logo. */

.sidebar-marca {
    padding: 20px 16px;
    flex-shrink: 0;
}
.sidebar-marca a { display: block; }

/* El menú hace scroll cuando no cabe, en vez de recortarse.

   La barra es `position: fixed` con `inset: 0 auto 0 0`, así que su altura es
   la de la ventana y no puede crecer. El menú es `flex: 1`, pero un hijo de
   flex tiene `min-height: auto` por defecto: se niega a encogerse por debajo
   de su contenido, desborda, y lo que sobra queda tapado por el pie. Con el
   rol líder eran nueve entradas y "Ajustes" se veía cortado por la mitad.

   `min-height: 0` deja que el menú se encoja y `overflow-y: auto` le da la
   barra de desplazamiento. */
.sidebar-nav {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* El rótulo de cada grupo. No es un enlace: solo dice de qué van los de
   debajo. */
/* Lo de la cuenta va debajo, separado por una línea y no por un rótulo.
   Los rótulos "Workspace" y "Cuenta" no están en ninguna captura: el menú es
   una lista, y dos palabras de más en un menú de seis entradas pesan más que
   lo que aclaran. La línea dice lo mismo sin ocupar un renglón. */
.sidebar-corte {
    border: 0;
    border-top: 1px solid rgb(var(--line-rgb));
    margin: 14px 8px;
}

.sidebar .sidebar-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: var(--radius-md);
    font-size: 14px;
    color: rgb(var(--ink-muted-rgb));
    transition: background 0.15s, color 0.15s;
}
.sidebar .sidebar-link:hover {
    background: rgb(var(--surface-2-rgb));
    color: rgb(var(--ink-rgb));
}
/* La entrada activa: pastilla turquesa y el icono del color de la marca. Antes
   activa y hover eran idénticas, así que al pasar el ratón por encima parecía
   que la sección había cambiado. */
.sidebar .sidebar-link.active {
    background: rgb(var(--brand-tint-rgb));
    color: rgb(var(--brand-text-rgb));
    font-weight: 500;
}
.sidebar .sidebar-link.active .icono { color: rgb(var(--brand-text-rgb)); }

.sidebar-pie {
    flex-shrink: 0;
    border-top: 1px solid rgb(var(--line-rgb));
    padding: 12px;
}

.sidebar-usuario {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 4px;
    min-width: 0;
}
.su-avatar {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 50%;
    background: rgb(var(--brand-rgb));
    color: rgb(var(--brand-on-rgb));
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 13px;
}
/* Crece para empujar el atajo a Preferencias contra el borde derecho de la
   caja, que es donde lo pide el diseño. `min-width: 0` es lo que permite que
   un nombre largo se recorte con puntos suspensivos en vez de estirar la
   caja: sin él, un hijo de flex se niega a bajar de su ancho de contenido. */
.su-texto { flex: 1; min-width: 0; }
.su-nombre {
    font-size: 13.5px;
    font-weight: 600;
    color: rgb(var(--ink-rgb));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.su-rol {
    font-size: 11.5px;
    color: rgb(var(--ink-subtle-rgb));
}

/* El atajo a Preferencias, en la misma caja que quién eres y con qué rol. */
.su-preferencias {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-md);
    color: rgb(var(--ink-subtle-rgb));
    transition: background 0.15s, color 0.15s;
}
.su-preferencias:hover {
    background: rgb(var(--surface-2-rgb));
    color: rgb(var(--ink-rgb));
}

/* El relleno del contenido se decide aquí y no en la plantilla. Antes eran
   dos: 24px de este bloque más las `p-8` del envoltorio de dentro, 56px en
   total, que dejaban el contenido flotando lejos de la barra lateral. */
main.content {
    flex: 1;
    margin-left: 0;
    padding: 32px 40px 48px;
    width: 100%;
}

.stat-card {
    background: linear-gradient(135deg, rgb(var(--surface-rgb)) 0%, rgb(var(--brand-rgb) / 0.08) 100%);
    border: var(--border-width) solid rgb(var(--line-rgb));
    border-radius: var(--radius-md);
    padding: 20px;
}

.modal {
    position: fixed;
    inset: 0;
    background: rgb(var(--overlay-rgb) / 0.8);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: 20px;
}
.modal-content {
    background: rgb(var(--surface-rgb));
    border: var(--border-width) solid rgb(var(--line-rgb));
    border-radius: var(--radius-lg);
    max-width: 900px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: var(--shadow-soft);
}

/* El interruptor. Su caja del panel lateral (`.theme-switch`) se fue con él:
   ahora vive dentro de una tarjeta de Ajustes, que ya pone el fondo y el
   borde. */
.switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
}
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background-color: rgb(var(--ink-subtle-rgb));
    transition: 0.3s;
    border-radius: 999px;
}
.slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.3s;
    border-radius: 50%;
    box-shadow: 0 2px 6px rgb(var(--ink-rgb) / 0.25);
}
input:checked + .slider {
    background-color: rgb(var(--brand-strong-rgb));
}
input:checked + .slider:before {
    transform: translateX(20px);
}

/* ══════════════════════════════════════════════════════════════════════
   El armazón del reporte de una sesión (capturas reporte-01 a reporte-05).

   No es el de la aplicación. Aquí no se navega: se lee una cosa de principio
   a fin, y es larga. La barra de arriba cruza entera —la salida a la
   izquierda, qué estás leyendo en medio, y a la derecha las dos cosas que se
   hacen con un reporte terminado— y debajo van el índice y el reporte.
   ══════════════════════════════════════════════════════════════════════ */

body.reporte {
    padding-left: 0;
    padding-top: 68px;
}

.reporte-barra {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 40;
    height: 68px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 0 28px;
    background: rgb(var(--surface-rgb));
    border-bottom: var(--border-width) solid rgb(var(--line-rgb));
}

.rb-izquierda {
    display: flex;
    align-items: center;
    gap: 18px;
    min-width: 0;
}

.rb-texto { min-width: 0; }

.rb-titulo {
    margin: 0;
    font-family: var(--font-display);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: rgb(var(--ink-rgb));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rb-nota {
    margin: 2px 0 0;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: rgb(var(--ink-subtle-rgb));
}

.rb-acciones {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* Compartir despliega sus destinos debajo del botón. El desplegable es el
   mismo componente que el del "⋯" de una fila; lo único propio es que aquí
   cuelga de un botón con texto. */
.rb-menu { position: relative; flex-shrink: 0; }

.reporte-lado {
    position: fixed;
    top: 68px;
    bottom: 0;
    left: 0;
    width: 244px;
    padding: 26px 24px;
    display: flex;
    flex-direction: column;
    gap: 26px;
    overflow-y: auto;
    border-right: var(--border-width) solid rgb(var(--line-rgb));
    /* Blanca, como la barra lateral de la aplicación y como las tarjetas del
       reporte (capturas reporte-01 a reporte-05). Era del gris del lienzo, así
       que la pantalla salían tres tonos —columna gris, canal gris, tarjetas
       blancas— y la columna se leía como fondo y no como una de las dos
       partes. */
    background: rgb(var(--surface-rgb));
}

.rl-indice {
    display: grid;
    gap: 2px;
    /* Una línea entre la ficha del programa y el índice (capturas reporte-01).
       Con solo el hueco de 26 px, "Contraparte" y "En este reporte" se leían
       como una misma lista: son dos cosas distintas —de qué es este reporte, y
       qué hay dentro de él—. */
    padding-top: 24px;
    border-top: var(--border-width) solid rgb(var(--line-rgb));
}

.rl-indice a {
    padding: 6px 0;
    font-size: 13.5px;
    color: rgb(var(--ink-muted-rgb));
}
.rl-indice a:hover { color: rgb(var(--brand-text-rgb)); }

/* La ficha del programa: pares etiqueta/valor, el valor a la derecha. */
.rl-ficha { display: grid; gap: 5px; }

.rl-nombre {
    margin: 0 0 8px;
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.4;
    color: rgb(var(--ink-rgb));
}

.rl-par {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    font-size: 12.5px;
    color: rgb(var(--ink-muted-rgb));
}

.rl-par b {
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 500;
    color: rgb(var(--ink-rgb));
}

.rl-pie {
    margin-top: auto;
    padding-top: 18px;
    border-top: var(--border-width) solid rgb(var(--line-rgb));
    font-size: 11.5px;
    line-height: 1.5;
    color: rgb(var(--ink-subtle-rgb));
}

.reporte-main {
    /* `body.app-shell` es una fila flex, y aquí `main` es su único hijo en
       flujo —la barra de arriba y la columna van fijas—. Sin crecer medía lo
       que medía su contenido: 830 px de una ventana de 1440, así que el
       reporte se leía en una columna de 586 px pegada al índice y con media
       ventana vacía a la derecha. Creciendo hasta el ancho de la fila, el
       `margin: 0 auto` del envoltorio ya tiene hueco que repartir y el reporte
       queda centrado en el espacio que le deja el índice. */
    flex: 1;
    min-width: 0;
    min-height: calc(100vh - 68px);
    padding-left: 244px;
}

/* Un reporte compartido no lleva columna: quien lo abre no tiene programa ni
   más reportes que consultar. */
body.reporte.unauth .reporte-main { padding-left: 0; }

.reporte-wrapper {
    width: 100%;
    max-width: 900px;
    margin: 0 auto;
    padding: 28px 32px 56px;
}

/* Sin sitio para la columna, el índice desaparece: sobre 900 px de ancho el
   reporte ya ocupa todo, y un índice apretado contra el texto estorba más de
   lo que orienta. */
@media (max-width: 1100px) {
    .reporte-lado { display: none; }
    .reporte-main { padding-left: 0; }
}

/* La barra del reporte en móvil. Es fija y de 68 px de alto, con el título a
   la izquierda y los botones a la derecha; en 390 px de ancho no cabían en la
   misma línea y se montaban: la fecha y los minutos de la práctica quedaban
   escritos por encima de "Exportar a PDF".

   Deja de ser fija, se reparte en dos líneas y crece lo que necesite. El hueco
   de 68 px que el contenido dejaba debajo ya no hace falta: la barra ocupa su
   sitio. */
@media (max-width: 720px) {
    .reporte-barra {
        position: static;
        height: auto;
        padding: 10px 14px;
        gap: 10px;
        flex-wrap: wrap;
    }
    .rb-izquierda { gap: 12px; }
    .rb-acciones { flex-wrap: wrap; }
    .reporte-main { padding-top: 0; }

    /* Al repartirse en dos líneas, "Compartir" baja pegado al borde izquierdo.
       El menú cuelga de su lado derecho, así que ahí se salía 67 px por la
       izquierda y de cada destino se leía media palabra. Aquí cuelga del
       izquierdo, que es el lado que sobra. */
    .rb-menu .menu-desplegable {
        left: 0;
        right: auto;
    }
}


/* ══ Móvil ═══════════════════════════════════════════════════════════════
   La barra lateral son 260 px fijos y el contenido vive detrás de un
   `padding-left` del mismo tamaño. En un teléfono de 390 px eso deja 130 px
   para todo lo demás: no era que la aplicación se viera apretada, es que no
   cabía y todas las pantallas desbordaban hacia la derecha.

   Debajo de 900 px la barra se sale de la pantalla y se abre con el botón de
   la barra superior. El corte es 900 y no 768 porque a 800 px el contenido ya
   iba estrecho de más con la barra puesta.

   La barra superior solo existe aquí: en escritorio no hay nada que abrir. */

.barra-movil { display: none; }

@media (max-width: 900px) {
    .barra-movil {
        display: flex;
        align-items: center;
        gap: 12px;
        position: sticky;
        top: 0;
        z-index: 30;
        height: 56px;
        padding: 0 14px;
        background: rgb(var(--surface-rgb));
        border-bottom: 1px solid rgb(var(--line-rgb));
    }
    .bm-menu {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        /* 44 px es el mínimo con el que un dedo acierta sin ampliar. */
        width: 44px;
        height: 44px;
        margin-left: -10px;
        border-radius: var(--radius-md);
        color: rgb(var(--ink-rgb));
        background: transparent;
        border: 0;
    }
    .bm-menu:hover { background: rgb(var(--surface-2-rgb)); }

    body.auth { padding-left: 0; }

    /* El armazón deja de ser dos columnas: la barra ya no ocupa sitio. */
    body.app-shell { display: block; }

    aside.sidebar {
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        z-index: 60;
        box-shadow: var(--shadow-soft);
    }
    aside.sidebar.es-abierto { transform: translateX(0); }

    .panel-fondo {
        position: fixed;
        inset: 0;
        z-index: 50;
        background: rgb(var(--overlay-rgb) / 0.5);
    }
    .panel-fondo[hidden] { display: none; }

    /* El contenido respira menos por los lados: en 390 px, 32 px de margen a
       cada lado se comen una sexta parte de la línea. */
    main.content { padding: 16px 14px 40px; }
    .reporte-wrapper { padding: 20px 16px 40px; }
}

/* `hidden` es un atributo de HTML, no una clase: sin esto el fondo del panel
   se pinta también en escritorio, donde no hay panel que abrir. */
[hidden] { display: none !important; }
