/* ============================================================================
   sisga-global.css  —  Hoja de estilos GLOBAL de SISGA (overrides propios)
   ----------------------------------------------------------------------------
   Este es el archivo CANÓNICO para cualquier ajuste de estilo global de SISGA
   que deba aplicar a TODA la aplicación (CSHTML/MVC y ASPX/Web Forms).

   Reglas:
   - Se carga con un <link> DESPUÉS de "Content/modernize/css/styles.css"
     (el CSS del template Modernize, de terceros) para ganar la cascada.
   - NUNCA se edita styles.css directamente: es de terceros y minificado, y se
     perdería al regenerar el template. Los overrides van aquí.
   - Enlazado en TODOS los layouts/masters que cargan Modernize:
     Master/Generales|Material|SinMenu.Master y los layouts de Views/Shared/*
     (más Views/Autenticacion/Index.cshtml).
   - Para un nuevo ajuste global, agregarlo aquí con un comentario de sección.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   Contraste de bordes de campos (accesibilidad — usuarios 55+)
   El template Modernize pinta los bordes casi invisibles sobre blanco
   (.form-control/.form-select = #dfe5ef ~1.3:1). Se suben a #8a94a6 (~3:1)
   para cumplir WCAG 1.4.11. Solo controles de formulario; NO cards ni tablas.
   :focus e is-valid/invalid conservan su color (mayor especificidad en Modernize).
   ---------------------------------------------------------------------------- */
.form-control,
.form-select,
.form-check-input,
.input-group-text {
    border-color: #8a94a6;
}

    /* Deshabilitados / solo-lectura: visibles pero algo más tenues */
    .form-control:disabled,
    .form-control[readonly],
    .form-select:disabled {
        border-color: #b4bcca;
    }

/* ----------------------------------------------------------------------------
   Dropdowns sin flecha (affordance de lista desplegable)
   ----------------------------------------------------------------------------
   Modernize aplica `appearance: none` a `.form-control`, lo que borra la flecha
   NATIVA del <select>, pero solo repone una flecha propia en `.form-select`.
   Resultado: todo `<select class="form-control">` —el patrón dominante en la app,
   tanto en Razor (Html.DropDownList) como en `asp:DropDownList`— se ve idéntico a
   una caja de texto: el usuario no tiene ninguna señal de que puede desplegarlo.
   Se repone la misma flecha de Bootstrap 5 para que el control se lea como lista.

   Exclusiones deliberadas:
   - `[multiple]` y `[size]` renderizan como listbox (varias filas visibles): ahí
     la flecha es falsa porque no hay nada que desplegar.
   - `.select2-hidden-accessible` es el <select> original que Select2 oculta y
     sustituye por su propio widget; pintarlo no se ve y solo suma trabajo.
   ---------------------------------------------------------------------------- */
select.form-control:not([multiple]):not([size]):not(.select2-hidden-accessible),
.body-wrapper .container-fluid select:not(.form-select):not([multiple]):not([size]):not(.select2-hidden-accessible),
select.TituloCombo:not([multiple]):not([size]) {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 16px 12px;
    padding-right: 2.25rem;
}

/* Tema oscuro: la flecha #343a40 desaparece sobre fondo oscuro */
[data-bs-theme="dark"] select.form-control:not([multiple]):not([size]):not(.select2-hidden-accessible),
[data-bs-theme="dark"] .body-wrapper .container-fluid select:not(.form-select):not([multiple]):not([size]):not(.select2-hidden-accessible),
[data-bs-theme="dark"] select.TituloCombo:not([multiple]):not([size]) {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Deshabilitado: la flecha también se atenúa, si no el control parece activo */
select.form-control:disabled,
.body-wrapper .container-fluid select:disabled {
    opacity: 1; /* Modernize no la baja; el color del borde ya comunica el estado */
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* ----------------------------------------------------------------------------
   .btn-default y .hidden — clases de Bootstrap 3 que BS5 eliminó
   ----------------------------------------------------------------------------
   `.btn-default` sigue vivo en 434 vistas: es, de lejos, el botón secundario más
   usado de la aplicación. Bootstrap 5 no lo define, así que sin un equivalente
   esos botones quedan como un `.btn` pelado: sin fondo ni borde, prácticamente
   invisibles sobre la tarjeta blanca.

   Existía un parche, pero SOLO dentro de dos layouts (_MasterGeneral y
   Generales.Master). Las pantallas servidas por Material.Master,
   _LayoutEstudiante, _LayoutProfesores o _MasterAdmisiones se quedaban sin él.
   Al ser una regla global, su sitio es esta hoja: así cubre a todos los layouts.

   Se corrige además su aspecto. El parche los pintaba gris oscuro sólido, lo que
   le daba a cada acción secundaria el peso visual de una acción principal. En
   Bootstrap 3 `.btn-default` era el botón BLANCO con borde gris —el secundario
   neutro—, y ese es el papel que cumple en estas vistas. Se reconstruye con esa
   intención, usando las variables del tema para que respete claro y oscuro.
   ---------------------------------------------------------------------------- */
.hidden {
    display: none !important;
}

/* `.img-circle` y `.img-rounded` son de Bootstrap 3 y BS5 no las define: las fotos de
   estudiantes y terceros salían CUADRADAS. Medido: 33 vistas solo en el portal del
   padre/estudiante. Se mapean a su equivalente de BS5 en vez de editar cada vista. */
.img-circle {
    border-radius: 50%;
}

.img-rounded {
    border-radius: var(--bs-border-radius, 0.375rem);
}

/* `.badge` a secas es un patrón de Bootstrap 3 (`<span class="badge">N</span>`) que
   sigue vivo en las vistas heredadas (p. ej. el contador de tickets de la Vista 360
   de restaurante). En BS5 `.badge` solo define el texto en blanco y el fondo lo
   ponen `bg-*` / `text-bg-*`: sin ellas el número queda blanco sobre blanco,
   invisible. Se repone el gris secundario SOLO cuando no hay clase de fondo. */
.badge:not([class*="bg-"]):not([class*="text-bg-"]) {
    background-color: var(--bs-secondary, #6c757d);
}

/* `.btn-default` recupera su papel de SECUNDARIO NEUTRO (decisión aprobada, R-01).
   El template Modernize la define como `.btn-default{background-color:var(--bs-primary)}`,
   con lo que se veía IDÉNTICA a `.btn-primary`: en una pantalla con «Guardar» y
   «Cancelar» ambos salían azules y no se distinguía la acción principal.

   Se declaran los colores directamente, no con `var(--bs-btn-*)`: la regla del tema
   es una declaración directa y las variables no le ganan (ese fue el fallo del
   intento anterior, documentado en §7.11 del inventario 025). Esta hoja se carga
   DESPUÉS de `styles.css` en todos los layouts, así que a igual especificidad gana.

   Se excluyen las variantes de color explícitas (`btn-primary`, `btn-danger`…): hay
   vistas que escriben `class="btn btn-default btn-primary"`, y ahí manda la de color. */
.btn-default:not(.btn-primary):not(.btn-secondary):not(.btn-success):not(.btn-danger):not(.btn-warning):not(.btn-info):not(.btn-light):not(.btn-dark) {
    background-color: var(--bs-body-bg, #fff);
    border-color: var(--bs-border-color, #dee2e6);
    color: var(--bs-body-color, #2a3547);
}

.btn-default:not(.btn-primary):not(.btn-secondary):not(.btn-success):not(.btn-danger):not(.btn-warning):not(.btn-info):not(.btn-light):not(.btn-dark):hover,
.btn-default:not(.btn-primary):not(.btn-secondary):not(.btn-success):not(.btn-danger):not(.btn-warning):not(.btn-info):not(.btn-light):not(.btn-dark):focus {
    background-color: var(--bs-secondary-bg, #f2f6fa);
    border-color: var(--bs-border-color, #dee2e6);
    color: var(--bs-body-color, #2a3547);
}

/* Las vistas que escriben `btn-default` SIN la clase base `btn` se quedan sin la
   caja del botón (relleno, borde, radio): el tema solo les da el color de fondo.
   Se les completa la caja, conservando el color que ya pone el tema. */
.btn-default:not(.btn) {
    display: inline-block;
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
    line-height: 1.5;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    user-select: none;
    border: 1px solid transparent;
    border-radius: var(--bs-border-radius);
}

/* ----------------------------------------------------------------------------
   R-01 · Botones de acción dentro de las tablas de datos
   ----------------------------------------------------------------------------
   Cada fila llevaba tres botones SÓLIDOS y saturados (Editar, Ver, Eliminar).
   Repetidos en 40 filas saturan la pantalla, y un «Eliminar» en rojo sólido en
   cada fila le da a la acción destructiva el peso de la acción principal.

   Medido: 1.070 botones de color dentro de celdas. De ellos **1.053 están en
   tablas marcadas como tabla de datos** (`table`, `dataTable`, `TablaGenerica`,
   `display`, `datatable`) y solo 17 en tablas de maquetación. Por eso la regla se
   acota a esas clases: una tabla sin clase puede ser maquetación heredada, donde
   un botón sí puede ser la acción principal de la pantalla.

   Se resuelve en CSS y no vista por vista: son 440 vistas. Al pasar el ratón
   recuperan el color sólido, que mantiene la señal de acción y el contraste.

   REVISIÓN: el estado de reposo era `transparent` + el color de marca como texto.
   Con la paleta pastel de Modernize eso da un rótulo de 1.9:1 sobre blanco
   (#13deb9 en `btn-success`, #49beff en `btn-secondary`): se reportó que «los
   botones parecen deshabilitados», y en las pantallas donde el botón de fila ES
   la acción principal —los periodos P1…P5 de calificaciones cualitativas— el
   usuario no sabía que podía pulsarlos.

   Se conserva la intención de R-01 (nada de sólidos saturados repetidos 40 veces)
   pero el reposo pasa a ser una PASTILLA legible: fondo teñido, borde de marca y
   rótulo en el tono oscuro de la misma familia. El sólido sigue reservado al hover.
   ---------------------------------------------------------------------------- */

/* Tonos oscuros de la paleta Modernize (55% de sombra sobre el color de marca).
   El tema declara `--bs-*-text-emphasis`, pero con el literal SCSS
   `shade-color(#13deb9, 60%)` SIN resolver, así que no se puede usar. */
:root {
    --sisga-primary-emphasis: #2a3d73;
    --sisga-secondary-emphasis: #215673;
    --sisga-success-emphasis: #086453;
    --sisga-danger-emphasis: #713e30;
    --sisga-warning-emphasis: #734e0e;
    --sisga-info-emphasis: #254673;
}

.table td .btn-primary,
.table td .btn-secondary,
.table td .btn-success,
.table td .btn-danger,
.table td .btn-warning,
.table td .btn-info,
.dataTable td .btn-primary,
.dataTable td .btn-secondary,
.dataTable td .btn-success,
.dataTable td .btn-danger,
.dataTable td .btn-warning,
.dataTable td .btn-info,
.TablaGenerica td .btn-primary,
.TablaGenerica td .btn-secondary,
.TablaGenerica td .btn-success,
.TablaGenerica td .btn-danger,
.TablaGenerica td .btn-warning,
.TablaGenerica td .btn-info {
    background-image: none;
}

.table td .btn-primary,
.dataTable td .btn-primary,
.TablaGenerica td .btn-primary {
    background-color: var(--bs-primary-bg-subtle, #eef2ff);
    color: var(--sisga-primary-emphasis);
    border-color: var(--bs-primary);
}

.table td .btn-secondary,
.dataTable td .btn-secondary,
.TablaGenerica td .btn-secondary {
    background-color: var(--bs-secondary-bg-subtle, #eef8ff);
    color: var(--sisga-secondary-emphasis);
    border-color: var(--bs-secondary);
}

.table td .btn-success,
.dataTable td .btn-success,
.TablaGenerica td .btn-success {
    background-color: var(--bs-success-bg-subtle, #e6fffa);
    color: var(--sisga-success-emphasis);
    border-color: var(--bs-success);
}

.table td .btn-danger,
.dataTable td .btn-danger,
.TablaGenerica td .btn-danger {
    background-color: var(--bs-danger-bg-subtle, #fbf2ef);
    color: var(--sisga-danger-emphasis);
    border-color: var(--bs-danger);
}

.table td .btn-warning,
.dataTable td .btn-warning,
.TablaGenerica td .btn-warning {
    background-color: var(--bs-warning-bg-subtle, #fef5e5);
    color: var(--sisga-warning-emphasis);
    border-color: var(--bs-warning);
}

.table td .btn-info,
.dataTable td .btn-info,
.TablaGenerica td .btn-info {
    background-color: var(--bs-info-bg-subtle, #ebf3fe);
    color: var(--sisga-info-emphasis);
    border-color: var(--bs-info);
}

/* Al pasar el ratón o al enfocar recuperan el sólido: la acción sigue siendo
   evidente y el texto vuelve a tener contraste sobre el color. */
.table td .btn-primary:hover, .table td .btn-primary:focus,
.dataTable td .btn-primary:hover, .dataTable td .btn-primary:focus,
.TablaGenerica td .btn-primary:hover, .TablaGenerica td .btn-primary:focus {
    background-color: var(--bs-primary);
    color: #fff;
}

.table td .btn-secondary:hover, .table td .btn-secondary:focus,
.dataTable td .btn-secondary:hover, .dataTable td .btn-secondary:focus,
.TablaGenerica td .btn-secondary:hover, .TablaGenerica td .btn-secondary:focus {
    background-color: var(--bs-secondary);
    color: #fff;
}

.table td .btn-success:hover, .table td .btn-success:focus,
.dataTable td .btn-success:hover, .dataTable td .btn-success:focus,
.TablaGenerica td .btn-success:hover, .TablaGenerica td .btn-success:focus {
    background-color: var(--bs-success);
    color: #fff;
}

.table td .btn-danger:hover, .table td .btn-danger:focus,
.dataTable td .btn-danger:hover, .dataTable td .btn-danger:focus,
.TablaGenerica td .btn-danger:hover, .TablaGenerica td .btn-danger:focus {
    background-color: var(--bs-danger);
    color: #fff;
}

.table td .btn-warning:hover, .table td .btn-warning:focus,
.dataTable td .btn-warning:hover, .dataTable td .btn-warning:focus,
.TablaGenerica td .btn-warning:hover, .TablaGenerica td .btn-warning:focus {
    background-color: var(--bs-warning);
    color: #fff;
}

.table td .btn-info:hover, .table td .btn-info:focus,
.dataTable td .btn-info:hover, .dataTable td .btn-info:focus,
.TablaGenerica td .btn-info:hover, .TablaGenerica td .btn-info:focus {
    background-color: var(--bs-info);
    color: #fff;
}

/* ----------------------------------------------------------------------------
   R-03 · Enlaces de acción de las páginas Web Forms
   ----------------------------------------------------------------------------
   En las pantallas ASPX las acciones son `<asp:LinkButton>` / `<asp:HyperLink>` con
   clases heredadas —`TituloVinculo`, `EdicionDataGrid`, `EliminarDataGrid`…—, no
   botones. Medido: **597 enlaces** sin clase `btn`, y sus rótulos son acciones sin
   ambigüedad: «Añadir», «Ingresar», «Modificar», «Editar», «Actualizar», «Eliminar»,
   «Cancelar», «Volver».

   Las hojas que les daban estilo (`EstiloPrincipal.css`, `EstiloDataGrid.css`) ya solo
   se cargan en `Emergentes/` y en cuatro páginas sueltas: en el resto de la aplicación
   esas acciones se ven como texto subrayado, inconsistente con los botones del resto.

   Se resuelve aquí y no tag por tag: son cientos de etiquetas repartidas por todo el
   módulo Web Forms, y el marcado que las genera no cambia. Se usa la misma apariencia
   discreta que R-01 dio a los botones de fila.
   ---------------------------------------------------------------------------- */
a.TituloVinculo,
a.TituloEmergente,
a.VinculoDataGrid,
a.VinculoDatagrid,
a.EdicionDataGrid,
a.EliminarDataGrid,
a.TituloEliminar {
    display: inline-block;
    padding: 0.25rem 0.5rem;
    margin: 0.125rem;
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.5;
    text-align: center;
    text-decoration: none;
    vertical-align: middle;
    white-space: nowrap;
    cursor: pointer;
    background-color: transparent;
    border: 1px solid;
    border-radius: var(--bs-border-radius, 0.25rem);
}

a.TituloVinculo,
a.TituloVinculo:link,
a.TituloVinculo:visited {
    color: var(--bs-primary);
    border-color: var(--bs-primary);
}

a.TituloEmergente, a.TituloEmergente:link, a.TituloEmergente:visited,
a.EdicionDataGrid, a.EdicionDataGrid:link, a.EdicionDataGrid:visited {
    color: var(--bs-secondary);
    border-color: var(--bs-border-color, #dee2e6);
}

/* `VinculoDataGrid` es SIEMPRE el mismo papel en las 54 pantallas Web Forms que lo
   usan: el dato de la fila —el nombre del docente, del tercero, del estudiante—
   convertido en el enlace que abre ese registro. Es la acción principal de la
   grilla, y no había nada que lo dijera: `--bs-secondary` es #49beff, 2.1:1 sobre
   blanco, así que el nombre se leía como texto normal («¿dónde hay que dar clic?»).
   Se le da el color primario y peso medio: se lee como enlace sin gritar. */
a.VinculoDataGrid, a.VinculoDataGrid:link, a.VinculoDataGrid:visited,
a.VinculoDatagrid, a.VinculoDatagrid:link, a.VinculoDatagrid:visited {
    color: var(--sisga-primary-emphasis, #2a3d73);
    border-color: var(--bs-border-color, #dee2e6);
    font-weight: 500;
}

a.EliminarDataGrid, a.EliminarDataGrid:link, a.EliminarDataGrid:visited,
a.TituloEliminar, a.TituloEliminar:link, a.TituloEliminar:visited {
    color: var(--bs-danger);
    border-color: var(--bs-danger);
}

a.TituloVinculo:hover, a.TituloVinculo:focus {
    background-color: var(--bs-primary);
    color: #fff;
    text-decoration: none;
}

a.TituloEmergente:hover, a.TituloEmergente:focus,
a.EdicionDataGrid:hover, a.EdicionDataGrid:focus {
    background-color: var(--bs-secondary-bg, #f2f6fa);
    color: var(--bs-body-color);
    text-decoration: none;
}

/* Al apuntarlo se subraya: es la señal universal de «esto es un enlace». */
a.VinculoDataGrid:hover, a.VinculoDataGrid:focus,
a.VinculoDatagrid:hover, a.VinculoDatagrid:focus {
    background-color: var(--bs-primary-bg-subtle, #eef2ff);
    border-color: var(--bs-primary);
    color: var(--sisga-primary-emphasis, #2a3d73);
    text-decoration: underline;
}

a.EliminarDataGrid:hover, a.EliminarDataGrid:focus,
a.TituloEliminar:hover, a.TituloEliminar:focus {
    background-color: var(--bs-danger);
    color: #fff;
    text-decoration: none;
}

/* Los enlaces que llevan una imagen dentro (iconos heredados) no deben recibir la caja
   del botón: la imagen ya es el control. */
a.TituloVinculo:has(img),
a.TituloEmergente:has(img) {
    padding: 0;
    border: 0;
    background: none;
}

/* ----------------------------------------------------------------------------
   Breadcrumb con eslabón vacío
   ----------------------------------------------------------------------------
   `Controles/Titulo.ascx` siempre renderiza `lblTituloSecundario`, aunque la
   página no le asigne texto. BS5 dibuja el separador con `::before` sobre el
   ítem SIGUIENTE, así que un ítem vacío se ve como una viñeta suelta colgando
   detrás de "Inicio" (visible en Principal/Inicio.aspx). Ocultar el ítem oculta
   también su separador, que es justo lo que se busca.
   ---------------------------------------------------------------------------- */
.breadcrumb .breadcrumb-item:empty {
    display: none;
}

/* ----------------------------------------------------------------------------
   Formularios heredados: .form-group, .control-label y .help-block
   ----------------------------------------------------------------------------
   Bootstrap 5 eliminó estas tres clases, y siguen en decenas de vistas. Sin
   ellas los formularios pierden TODO su ritmo vertical: las etiquetas quedan
   pegadas a su campo y los campos pegados entre sí, en un bloque compacto y
   difícil de leer. Se les devuelve el espaciado y la jerarquía mínimos.

   La etiqueta se declara `display:block` para que quede ARRIBA del campo, que
   es la convención de formularios del proyecto (nunca etiquetas flotantes).
   ---------------------------------------------------------------------------- */
.form-group {
    margin-bottom: 1rem;
}

.control-label {
    display: block;
    margin-bottom: 0.35rem;
    font-weight: 500;
}

.help-block {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
    color: var(--bs-secondary-color, #6c757d);
}

/* ----------------------------------------------------------------------------
   .panel — la "tarjeta" de Bootstrap 3, todavía en 35 vistas
   ----------------------------------------------------------------------------
   BS5 la sustituyó por `.card`. Sin equivalente, un `.panel` se ve como texto
   suelto sobre el fondo: sin recuadro, sin separación y sin encabezado
   distinguible. Se reconstruye con la apariencia de una card del tema.
   Antes existía una regla para `.panel.panel-default`, pero solo dentro de
   Generales.Master (páginas ASPX) y aplicaba el relleno al panel entero, con lo
   que se sumaba al del `.panel-body`.
   ---------------------------------------------------------------------------- */
/* IMPORTANTE: se estilizan solo los paneles REALES (los que declaran una variante),
   nunca `.panel` a secas. En el repositorio hay 684 `class="panel "` sueltos que no
   envuelven un panel: son un contenedor vacío alrededor del enlace al manual de ayuda.
   Darles recuadro dibujaría 684 cajas vacías por toda la aplicación. */
.panel.panel-default,
.panel.panel-info,
.panel.panel-warning,
.panel.panel-primary,
.panel.panel-success,
.panel.panel-danger {
    margin-bottom: 1rem;
    background-color: var(--bs-card-bg, #fff);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
}

.panel-heading {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--bs-border-color);
    font-weight: 600;
}

.panel-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

.panel-body {
    padding: 1rem;
}

.panel-footer {
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--bs-border-color);
    background-color: var(--bs-secondary-bg, #f8f9fa);
}

/* ----------------------------------------------------------------------------
   Botones permanentemente "pulsados": la clase `active` heredada de Bootstrap 3
   ----------------------------------------------------------------------------
   2.543 botones repartidos en 1.176 archivos se escriben así:

       class="btn btn-primary active btn-sm"

   En Bootstrap 3 esa `active` era inocua en un botón normal. En Bootstrap 5
   significa PULSADO: aplica `--bs-btn-active-bg`, un tono más oscuro que el
   normal. Resultado: casi todos los botones de la aplicación se dibujan como si
   estuvieran presionados, y el usuario nunca ve el color de reposo del botón.

   NO se corrige desde aquí. Intentarlo con CSS obliga a reponer el color normal
   a mano (`background-color: var(--bs-btn-bg)`), y eso falla justamente en los
   botones cuyo color NO viene de las variables sino de una declaración directa
   del tema —como `.btn-default`, que Modernize pinta con `var(--bs-primary)`—:
   esos quedaban transparentes o de otro color que sus gemelos sin `active`.

   La corrección vive en `Scripts/sisga-bs5-compat.js`, que RETIRA la clase
   sobrante del DOM. Sin la clase, cada botón recupera su aspecto normal sea cual
   sea la regla que lo pinta, sin que este archivo tenga que adivinarlo. Allí se
   respetan los sitios donde `active` sí quiere decir "seleccionado": grupos de
   botones, barras de herramientas, pestañas y toggles.
   ---------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------------
   Botones que llevan la clase del icono en el propio botón
   ----------------------------------------------------------------------------
   167 botones de la aplicación se escriben así:

       @Html.ActionLink("Detalles", "Details", …, new { @class = "btn btn-info ti ti-list-details" })

   `Html.ActionLink` no admite HTML dentro, así que el icono no puede ir en un
   `<i>` hijo y se cuela como clase del propio botón. Dos consecuencias visibles:

   1. `.ti` declara `font-family: tabler-icons !important` sobre TODO el elemento,
      de modo que la ETIQUETA del botón se dibuja con la tipografía de iconos.
      Las letras latinas no existen en esa fuente, así que el navegador recurre a
      su fuente por defecto y el rótulo queda con otra tipografía que el resto.
   2. El glifo lo pinta `::before` pegado al texto, sin ningún espacio: se leía
      literalmente «≡Detalles».

   Se devuelve la tipografía normal al botón y se deja la de iconos solo donde
   corresponde —el pseudo-elemento—, con una separación. Así se corrigen los 167
   de una vez, sin tocar ninguna vista.
   ---------------------------------------------------------------------------- */
.btn.ti,
.btn .ti {
    font-family: inherit !important;
}

.btn.ti::before,
.btn .ti::before {
    font-family: tabler-icons !important;
}

/* Solo cuando el glifo y el rótulo comparten elemento hace falta separarlos */
.btn.ti::before {
    margin-right: 0.35rem;
}

/* ----------------------------------------------------------------------------
   Enlace al manual de ayuda
   ----------------------------------------------------------------------------
   Aparece en más de 100 pantallas como un icono suelto flotando sobre el
   contenido, sin ninguna caja que lo identifique como algo pulsable. Se le da
   apariencia de botón pequeño para que se lea como una acción, sin tener que
   editar cada vista. El icono ya lleva `title="Manual de ayuda"`.
   ---------------------------------------------------------------------------- */
a[href*="/saga/documentacion"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    color: var(--bs-secondary-color, #6c757d);
    text-decoration: none;
    background-color: var(--bs-body-bg);
}

a[href*="/saga/documentacion"]:hover {
    background-color: var(--bs-secondary-bg, #eef2f7);
    color: var(--bs-body-color);
}

/* ----------------------------------------------------------------------------
   Menú lateral: los rótulos largos se cortaban en seco
   ----------------------------------------------------------------------------
   Modernize declara `white-space: nowrap` en `.sidebar-link` y el `.left-sidebar`
   tiene ancho fijo (270px) con el scroll horizontal de SimpleBar deshabilitado.
   Resultado: opciones como "Notificacion Alerta Estudiante" o "Registro
   Actividades de Apoyo" quedaban truncadas SIN puntos suspensivos, o sea
   ilegibles y sin señal de que faltaba texto. Se permite que envuelvan a varias
   líneas, que es la única salida con un ancho fijo.
   Aplica a los 6 sidebars del sistema (MVC y ASPX) porque todos usan #sidebarnav.
   ---------------------------------------------------------------------------- */
#sidebarnav .sidebar-link {
    white-space: normal;
    /* Con 2+ líneas el icono debe quedar junto a la PRIMERA, no centrado en el bloque */
    align-items: flex-start;
}

/* El icono va como <i> directo o envuelto en <span> según el sidebar: se cubren ambos */
#sidebarnav .sidebar-link > *:not(.hide-menu) {
    flex-shrink: 0;
    line-height: 25px; /* misma altura de línea del enlace: alinea icono y primera línea */
}

#sidebarnav .sidebar-link .hide-menu,
#sidebarnav .nav-small-cap .hide-menu {
    white-space: normal;
    overflow-wrap: anywhere; /* corta un rótulo de una sola palabra antes que desbordar */
    line-height: 1.3;
}

/* En modo minimizado (mini-sidebar) el rótulo se oculta: no debe envolver ni empujar */
[data-sidebartype="mini-sidebar"] #sidebarnav .sidebar-link {
    align-items: center;
}

/* ----------------------------------------------------------------------------
   asp:RadioButton / asp:CheckBox con CssClass → recuadro fantasma en la etiqueta
   ----------------------------------------------------------------------------
   ASP.NET, cuando un asp:RadioButton/asp:CheckBox tiene CssClass Y Text, aplica
   la clase a un <span> WRAPPER que envuelve el <input> y su <label> —NO al
   <input>—. Si esa clase es form-check-input, el SPAN hereda el recuadro de
   control BS5 (borde 1.25px + fondo + tamaño fijo), pensado para el <input>. Con
   el borde de contraste de arriba (#8a94a6) el recuadro se vuelve visible como un
   cuadro alrededor del texto de la etiqueta. Se neutraliza el box del wrapper; el
   control real es el <input> nativo interno, al que se le da el color de marca.
   IMPORTANTE: el selector `span.form-check-input` SOLO afecta a los <span> wrapper
   de ASP.NET; los <input class="form-check-input"> reales (MVC/Razor o asp sin
   Text) NO se tocan y conservan su apariencia BS5.
   ---------------------------------------------------------------------------- */
span.form-check-input {
    border: 0 !important;
    background: none !important;
    width: auto !important;
    height: auto !important;
    padding: 0;
    vertical-align: baseline;
}

    span.form-check-input > input[type="radio"],
    span.form-check-input > input[type="checkbox"] {
        accent-color: var(--bs-primary);
    }

/* ----------------------------------------------------------------------------
   Select2 dentro de modales Bootstrap 5
   ----------------------------------------------------------------------------
   Select2 renderiza el dropdown en body con z-index ~1051; los modales SISGA
   usan ~2100. Sin dropdownParent (inyectado por sisga-select2-modal.js) el
   listado queda detrás. Estas reglas son red de seguridad.
   ---------------------------------------------------------------------------- */
#myModal,
#myModalList,
#myModalCargando,
#ssgaLupaModal {
    z-index: 2100 !important;
}

/* Modal lupa ASPX debe vivir en body; reforzar por encima del backdrop */
body > #ssgaLupaModal,
#ssgaLupaModal.show {
    z-index: 2100 !important;
    pointer-events: auto !important;
}

#ssgaLupaModal .modal-dialog,
#ssgaLupaModal .modal-content,
#ssgaLupaModal .modal-body,
#ssgaLupaModal iframe {
    pointer-events: auto !important;
}

.modal-backdrop {
    z-index: 2090 !important;
}

.modal-backdrop.show {
    z-index: 2090 !important;
}

/*
 * Definitivo: CUALQUIER modal visible por encima del backdrop (2090).
 * Cubre #myModal, #ssgaLupaModal, #exampleModal y modales propios de vista.
 * El guardian JS (sisga-bs5-compat) además mueve el nodo a <body>.
 */
body > .modal,
.modal.show {
    z-index: 2100 !important;
    pointer-events: auto !important;
}

body > .modal .modal-dialog,
body > .modal .modal-content,
.modal.show .modal-dialog,
.modal.show .modal-content {
    pointer-events: auto !important;
}

#myModal .select2-container,
#myModalList .select2-container {
    z-index: 2110 !important;
}

#myModal .select2-dropdown,
#myModalList .select2-dropdown {
    z-index: 2120 !important;
}
/* Dropdown aún anexado a body (fallback si no hubo dropdownParent) */
body > .select2-container,
.select2-container--open {
    z-index: 2200 !important;
}

.select2-dropdown {
    z-index: 2200 !important;
}

/* ----------------------------------------------------------------------------
   Lupas span.dialog-window (buscador municipio) — área clicable global
   ---------------------------------------------------------------------------- */
span.dialog-window.ti,
.input-group-text:has(> span.dialog-window),
.input-group-text.dialog-window-hit {
    cursor: pointer !important;
    pointer-events: auto !important;
}

span.dialog-window.ti {
    display: inline-block;
    min-width: 1.25rem;
    min-height: 1.25rem;
    line-height: 1.25rem;
}

/* ----------------------------------------------------------------------------
   Modal de municipios (Localidades) — layout horizontal (label | select | texto | +)
   ---------------------------------------------------------------------------- */
#myModal .modal-header.bg-primary .modal-title,
#myModal .modal-header.bg-primary h5 {
    color: #fff;
}

.localidades-modal-form .form-label {
    color: #2a3547;
}

.localidades-modal-form .form-select,
.localidades-modal-form .form-control {
    width: 100%;
}

.localidades-modal-form .select2-container {
    width: 100% !important;
}
/* Fallback si algún parcial aún usa form-horizontal BS3 dentro del modal */
#contenidoModal .form-horizontal > .form-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

#contenidoModal .form-horizontal .control-label {
    flex: 0 0 140px;
    max-width: 140px;
    text-align: left !important;
    margin-bottom: 0;
    font-weight: 600;
}

#contenidoModal .form-horizontal .form-group > .col-md-2,
#contenidoModal .form-horizontal .form-group > .col-md-3,
#contenidoModal .form-horizontal .form-group > .col-md-1 {
    float: none;
    width: auto;
    flex: 1 1 auto;
    padding: 0;
}

#contenidoModal .form-horizontal select.form-control,
#contenidoModal .form-horizontal .form-control {
    width: 100% !important;
    max-width: 280px;
}

#myModal .modal-footer {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
}

/* ── Alertas ────────────────────────────────────────────────────────────────
   Modernize define `.alert-light` con el mismo color de texto que de fondo
   (#f6f9fc sobre #f6f9fc): el mensaje queda invisible. Se le devuelve el color
   de texto del cuerpo y un borde para que se distinga del fondo de la página. */
.alert-light {
    color: var(--bs-body-color);
    border-color: var(--bs-border-color);
}

/* ── DataTables ─────────────────────────────────────────────────────────────
   El selector de cantidad de registros se dimensiona por su contenido y la
   flecha del form-select termina encima del número. Se le da ancho suficiente
   y se separan los controles del encabezado/pie de la tabla. */
.dataTables_wrapper .dataTables_length select {
    width: auto;
    min-width: 5rem;
    display: inline-block;
}

.dataTables_wrapper .dataTables_filter input {
    width: auto;
    min-width: 14rem;
    display: inline-block;
    margin-left: 0.5rem;
}

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter {
    margin-bottom: 0.75rem;
}

.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
    margin-top: 0.75rem;
}
/* ---------------------------------------------------------------------
   Spinner con Tabler Icons.
   Sustituye a los antiguos 'fa fa-spinner fa-spin' de Font Awesome
   (libreria retirada): el icono pasa a ti-loader-2 y esta clase aporta
   el giro que antes daba fa-spin.
   --------------------------------------------------------------------- */
.ti-spin {
    display: inline-block;
    animation: sisga-spin 1s linear infinite;
}

@keyframes sisga-spin {
    to { transform: rotate(360deg); }
}

/* ---------------------------------------------------------------------
   Casillas de seleccion .chkseleccion (43 vistas de seleccion multiple).
   Su marcado trae un aro ti-circle sin significado (el shim lo retira) y
   el estado solo se comunicaba por el color del boton. Aqui el icono pasa
   a la metafora de casilla: cuadro vacio en reposo y cuadro con check
   cuando la fila queda seleccionada (el JS de esas vistas alterna
   btn-default <-> btn-success).
   --------------------------------------------------------------------- */
.chkseleccion .ti::before {
    content: "\eb2c"; /* ti-square */
}

.chkseleccion.btn-success .ti::before {
    content: "\eb28"; /* ti-square-check */
}

/* ---------------------------------------------------------------------
   Fila seleccionada de DataTables: el estilo por defecto pinta la fila
   de azul solido con texto blanco (las pantallas de seleccion multiple
   la usan para marcar estado). Se suaviza a un tinte del color primario
   conservando el color del texto, para que una tabla con muchas filas
   seleccionadas no quede como un bloque azul.
   --------------------------------------------------------------------- */
table.dataTable tbody tr.selected,
table.dataTable > tbody > tr.selected > * {
    box-shadow: inset 0 0 0 9999px rgba(93, 135, 255, 0.14) !important;
    color: inherit !important;
}

/* ----------------------------------------------------------------------------
   Select2: la flecha se dibujaba FUERA del campo
   ----------------------------------------------------------------------------
   El template Modernize trae su propio tema de Select2 y pisa dos declaraciones
   del plugin:

       body .select2-container { display: inline; }
       body .select2-container--classic ... __arrow,
       body .select2-container--default  ... __arrow { top:-2px; right:20px; width:auto; }

   La flecha se posiciona en absoluto contra .select2-container. Al bajar el
   contenedor de inline-block a inline, su caja deja de ser la del campo y pasa a
   ser la caja de LINEA, que arranca en el renglon de la ETIQUETA; con top:-2px
   encima, la flecha quedaba dibujada sobre la etiqueta, fuera del control, y
   width:auto la dejaba con 0px de ancho.

   Se reponen los valores del plugin. Las reglas empiezan por body, igual que las
   de Modernize, para igualar especificidad: esta hoja se carga DESPUES de
   styles.css en todos los layouts, asi que a igual especificidad gana. La flecha
   se estira a height:100% en vez de los 26px del plugin porque el alto del control
   lo fija el tema (40px); el cursor va centrado dentro de esa caja.

   Se toca solo el tema --default, que es el que usa la aplicacion. El --classic
   dibuja su flecha como un recuadro aparte, con fondo y borde propios, y no se ha
   verificado ninguna pantalla que lo use.
   ---------------------------------------------------------------------------- */
body .select2-container {
    display: inline-block;
}

body .select2-container--default .select2-selection--single .select2-selection__arrow {
    top: 0;
    right: 0;
    width: 2rem;
    height: 100%;
}

/* ----------------------------------------------------------------------------
   Toggle NO/SI (checkboxpicker): la etiqueta debe quedar ARRIBA
   ----------------------------------------------------------------------------
   checkboxpicker oculta el <input type="checkbox"> original y le inserta detras
   un .btn-group con los dos botones. Ese grupo es inline-flex y .form-label de
   Bootstrap 5 no declara display, asi que ambos caian en el MISMO renglon:
   "Permitir Generar PIN [NO][SI]".

   Antes no se notaba por un defecto: como no existia regla para .hidden (clase de
   Bootstrap 3 que BS5 no define), el checkbox seguia visible y, al ser un
   .form-control de ancho completo, empujaba el toggle al renglon siguiente. Al
   reponer .hidden desaparecio ese empujon y con el la maquetacion correcta.

   Se declara el grupo como flex (elemento de bloque) para que baje de renglon, y
   se le limita el ancho al de su contenido: si no, ocuparia toda la fila y los dos
   botones saldrian estirados. El selector describe la estructura exacta que genera
   el plugin, asi que no alcanza a ningun otro .btn-group de la aplicacion.
   ---------------------------------------------------------------------------- */
input[type="checkbox"].hidden + .btn-group {
    display: flex;
    width: fit-content;
}


/* ============================================================================
   Menu de modulos en pantallas pequenas
   ----------------------------------------------------------------------------
   Hasta 991 px el menu de modulos llevaba `d-none` y desaparecia por completo.
   El hamburguesa abre el menu lateral del modulo ACTUAL, asi que en un telefono
   no habia forma de pasar de DOCENTE a ACADEMICO o a INFORMES: el usuario
   quedaba atrapado en el modulo por el que entro.

   Ahora baja a una segunda fila con el icono arriba y el ROTULO DEBAJO en letra
   pequena: la version solo-iconos resulto criptica (el usuario no sabia que
   modulo era cual y las pestanas no llevan tooltip). Si las siete no caben, la
   fila se desliza horizontalmente; los margenes auto de la primera y la ultima
   la centran cuando si caben. Con desbordamiento, space-around RECORTA el
   arranque de la fila y las primeras pestanas quedan inalcanzables: por eso
   flex-start + margenes auto, y no space-around como antes.
   Por encima de 992 px esta regla no aplica y el escritorio queda igual.

   DOS COSAS QUE HAY QUE ANULAR A LA FUERZA, las dos vienen de Bootstrap:

     1. `flex-direction`. `.navbar-expand-lg` pone las `.navbar-nav` en COLUMNA
        por debajo del breakpoint. Sin `row`, los modulos salen apilados uno
        debajo de otro y ocupan la pantalla entera: fue el defecto que se vio en
        un telefono real la primera vez.
     2. `flex-shrink`. Como item flexible, `width: 100%` no impide que se encoja
        -medido en navegador, quedaba en 43 px-. `flex: 0 0 100%` es lo que le
        garantiza la fila entera.
   ============================================================================ */
@media (max-width: 991.98px) {
    /* La barra no envuelve por defecto (flex-wrap: nowrap), asi que sin esto el menu de
       modulos se queda en la misma fila que el hamburguesa y los iconos de utilidad, y en
       un telefono estrecho todo se aprieta. Con wrap, baja limpio a su propia linea. */
    .topbar .navbar { flex-wrap: wrap; }

    .topbar .module-nav {
        order: 10;                        /* despues del hamburguesa, del nombre y de los puntos */
        flex: 0 0 100%;
        width: 100%;
        max-width: 100%;
        flex-direction: row !important;   /* (1) navbar-expand-lg las apila en columna */
        flex-wrap: nowrap;
        justify-content: flex-start;
        align-items: center;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        margin-left: 0 !important;
        padding: .15rem 0;
        border-top: 1px solid rgba(0, 0, 0, .075);
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .topbar .module-nav::-webkit-scrollbar { display: none; }

    .topbar .module-nav .nav-item { flex: 0 0 auto; }

    /* Centrado sin recorte: si el contenido cabe, los margenes auto centran la
       fila; si desborda, colapsan a 0 y el scroll alcanza ambos extremos. */
    .topbar .module-nav .nav-item:first-child { margin-left: auto; }
    .topbar .module-nav .nav-item:last-child { margin-right: auto; }

    /* Icono arriba, rotulo debajo. El texto es el mismo del escritorio (ya
       estaba en el DOM, oculto): aqui solo se apila en columna y se reduce.
       El modulo activo conserva su subrayado (border-bottom de la pestana). */
    .topbar .module-nav .nav-link {
        display: flex;
        flex-direction: column;
        align-items: center;
        font-size: .62rem !important;
        line-height: 1.2;
        letter-spacing: .02em;
        padding: .3rem .55rem !important;
        white-space: nowrap;
    }

    .topbar .module-nav .nav-link .ti {
        font-size: 1.25rem;
        margin-right: 0 !important;
    }
}


/* ============================================================================
   Portada de novedades  (Principal/Inicio.aspx)
   ----------------------------------------------------------------------------
   Era la unica pantalla que seguia sin ser responsive. La causa no es el layout:
   es el contenido. Las novedades traen anchos FIJOS en pixeles -siete imagenes
   entre 500 y 900 px, y dos videos de YouTube a 700 y 560- que en un telefono de
   390 px desbordan y estiran la pagina entera.

   Se arregla con una regla y no atributo por atributo porque casi todo ese
   contenido se emite desde `Response.Write` en el code-behind y se reescribe cada
   vez que se publica una novedad: corregir los nueve de hoy no evitaria el
   decimo de manana.

   `aspect-ratio` conserva la proporcion de los videos al encogerlos. Donde no
   este soportado, `max-width` por si solo ya impide el desbordamiento -el video
   queda con banda negra, pero la pagina no se rompe-.
   ============================================================================ */
#iniciTabContent img,
#iniciTabContent iframe,
#iniciTabContent video,
#iniciTabContent table {
    max-width: 100%;
}

#iniciTabContent img {
    height: auto;
}

#iniciTabContent iframe {
    width: 100%;
    aspect-ratio: 16 / 9;
    height: auto;
}


/* ============================================================================
   Coach marks del menu (guia de primer uso en pantallas pequenas)
   ----------------------------------------------------------------------------
   En resoluciones pequenas el menu lateral arranca oculto y varios usuarios no
   descubren el hamburguesa ni la barra de modulos. sisga-coachmark.js (bundle
   ~/modernize/js) anade estas clases SOLO si el usuario no ha usado nunca el
   menu (claves sisga_coach_* en localStorage) y las retira al primer toque.

   Las animaciones viven dentro de media queries con los MISMOS breakpoints que
   comprueba el JS: 1299.98px es donde el template Modernize esconde el sidebar
   (styles.css) y 991.98px donde las pestanas de modulos bajan a su fila. Por
   encima el coach no tiene sentido (sidebar visible / pestanas con rotulo) y
   asi el JS no necesita vigilar cambios de tamano de la ventana.
   ============================================================================ */

/* Fuera del breakpoint (ventana agrandada tras cargar) el globo no se ve. */
.sisga-coach-globo { display: none; }

@media (max-width: 1299.98px) {
    /* El <li> circular del hamburguesa: ancla del globo y del anillo. */
    .sisga-coach-ancla { position: relative; }

    .sisga-coach-pulso::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        border-radius: 50%;
        pointer-events: none;
        animation: sisga-coach-onda 2s ease-out infinite;
    }

    .sisga-coach-globo {
        display: block;
        position: absolute;
        top: calc(100% + 12px);
        left: -4px;
        z-index: 100;  /* sobre el topbar (9) y el sidebar (99) */
        border: 0;
        border-radius: .5rem;
        padding: .45rem .8rem;
        background: #5d87ff;  /* primario de Modernize */
        color: #fff;
        font-size: .8rem;
        white-space: nowrap;
        box-shadow: 0 4px 12px rgba(0, 0, 0, .25);
        animation: sisga-coach-flota 1.8s ease-in-out infinite;
    }

    /* Flecha del globo apuntando al hamburguesa. */
    .sisga-coach-globo::before {
        content: "";
        position: absolute;
        bottom: 100%;
        left: 16px;
        border: 7px solid transparent;
        border-bottom-color: #5d87ff;
    }
}

@media (max-width: 991.98px) {
    /* La barra de modulos "respira" unas cuantas veces para llamar la vista.
       No es infinita: si el usuario la ignora, dejar el latido permanente
       convertiria la guia en ruido. Reaparece en la siguiente pagina hasta
       que toque una pestana. */
    .sisga-coach-modulos {
        animation: sisga-coach-brillo 2.2s ease-in-out 6;
    }

    .sisga-coach-modulos .nav-link .ti {
        animation: sisga-coach-late 2.2s ease-in-out 6;
    }
}

@keyframes sisga-coach-onda {
    0%   { box-shadow: 0 0 0 0 rgba(93, 135, 255, .65); }
    70%  { box-shadow: 0 0 0 14px rgba(93, 135, 255, 0); }
    100% { box-shadow: 0 0 0 0 rgba(93, 135, 255, 0); }
}

@keyframes sisga-coach-flota {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(5px); }
}

@keyframes sisga-coach-brillo {
    0%, 100% { background-color: transparent; }
    50%      { background-color: rgba(93, 135, 255, .12); }
}

@keyframes sisga-coach-late {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.18); }
}

/* Con animaciones reducidas la guia queda estatica: el globo con su texto
   cumple la funcion sin movimiento. */
@media (prefers-reduced-motion: reduce) {
    .sisga-coach-pulso::after,
    .sisga-coach-globo,
    .sisga-coach-modulos,
    .sisga-coach-modulos .nav-link .ti {
        animation: none;
    }
}

/* ============================================
   TEXTO DE USUARIO MULTILINEA
   Conserva los saltos de linea de textos escritos por el usuario
   (tareas y observaciones del aula) sin usar Html.Raw, y fuerza
   alineacion izquierda dentro de contenedores centrados.
   ============================================ */
.texto-preservado {
    white-space: pre-wrap;
    overflow-wrap: break-word;
    text-align: left;
}
