/* ===========================================================================
   gEdu · solo ajustes propios. El shell (aside/Main_Wrapper/Word_wrap/header/
   footer), el modo oscuro y los componentes los aporta iGemas.css (de gInm).
   Replicamos la estructura HTML de gInm y dejamos que su hoja la estilice.
   El color de marca queda en una variable para cambiarlo en un solo lugar.
   =========================================================================== */

:root {
    --gedu-acento: #F6BE00;            /* color de marca (amarillo dorado tipo lápiz Mongol) */
    --gedu-logo: #F6BE00;              /* color del logo en el sidebar */
}

/* Logo SVG recoloreable (hereda el color del contenedor vía currentColor).
   Se centra con flex para que no se "salga" del cuadro del sidebar. */
.app-logo {
    color: var(--gedu-logo);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 84px;
}
.logo-gedu { height: 64px; width: auto; display: block; }
/* Acento de marca sobre el verde por defecto de iGemas, donde aplique.
   Se definen las VARIABLES de Bootstrap, no solo background/color: `.btn:hover` aplica
   `background-color: var(--bs-btn-hover-bg)` y, si nadie la define, el botón se quedaba
   TRANSPARENTE justo al ir a hacerle clic (12-ago, visto en el "Ingresar" del login).
   Fijando las variables, hover/focus/active/disabled quedan resueltos de una vez. */
.btn-acento {
    --bs-btn-bg: var(--gedu-acento);
    --bs-btn-border-color: var(--gedu-acento);
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: var(--gedu-acento);
    --bs-btn-hover-border-color: var(--gedu-acento);
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: var(--gedu-acento);
    --bs-btn-active-border-color: var(--gedu-acento);
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-disabled-bg: var(--gedu-acento);
    --bs-btn-disabled-border-color: var(--gedu-acento);
    --bs-btn-disabled-color: #1a1a1a;
    background: var(--gedu-acento);
    border-color: var(--gedu-acento);
    color: #1a1a1a;
}
/* El oscurecido queda como respuesta al hover (ahora sobre un fondo que sí existe). */
.btn-acento:hover, .btn-acento:focus { filter: brightness(.95); color: #1a1a1a; }

/* Cuando no hay sesión no se muestra el aside: el contenido ocupa todo. */
body.SinMenu #Main_Wrapper { width: 100% !important; float: none !important; }

/* Un respiro entre el icono y su texto en el menú lateral (venían pegados).
   En el riel contraído no aplica: allí el icono va solo y centrado. */
aside #MainMenuLst > li a i,
aside #MainMenuLst > li button i { margin-right: .55rem; }

/* Contraer el menú en ESCRITORIO (clic en el botón del header → body.NoMenu).
   El aside NO desaparece: queda como un RIEL delgado con solo los iconos, así
   siempre se ve dónde está cada módulo. Un clic en un grupo re-expande el menú
   (el JS quita NoMenu y Bootstrap abre ese grupo con el mismo clic). */
@media (min-width: 768px) {
    body.NoMenu aside { width: 64px; }
    body.NoMenu #Main_Wrapper { width: calc(100vw - 94px); }

    /* Solo iconos: fuera textos, submenús, chevron y logo. */
    body.NoMenu aside span,
    body.NoMenu aside .app-logo,
    body.NoMenu aside #MainMenuLst .collapse,
    body.NoMenu aside #MainMenuLst .collapsing { display: none !important; }
    /* Excepción: el envoltorio del icono de Notificaciones (con su badge) sí se ve. */
    body.NoMenu aside #MainMenuLst .icono-notif,
    body.NoMenu aside #MainMenuLst .icono-notif .badge { display: inline-block !important; }
    body.NoMenu ul#MainMenuLst li button.btn-toggle::before { content: none; }

    /* !important: los últimos ítems (Notificaciones, Ajustes, Salir) traen la
       clase .text-start de Bootstrap, que también es !important y sin esto
       dejaba sus iconos pegados al borde mientras el resto centraba.
       "Salir" cuelga de un <form>, por eso no basta con el hijo directo. */
    body.NoMenu aside #MainMenuLst > li a,
    body.NoMenu aside #MainMenuLst > li button {
        text-align: center !important;
        width: 100%;
    }
    body.NoMenu aside #MainMenuLst > li a i,
    body.NoMenu aside #MainMenuLst > li button i { margin: 0; }

    /* Sin el logo arriba, la lista aprovecha el alto completo del riel. */
    body.NoMenu #MainMenuLst { height: calc(100% - 20px); }
}

/* ── Avisos del sistema: Gemi te lo dice (12-ago, Valeria) ───────────────────
   Gemi va SUELTO, sin caja de color detrás, y el mensaje sale en un globo de
   diálogo que apunta hacia él. La línea de color del pie se consume sola: se ve
   cuánto le queda al aviso. Los errores no llevan línea — no se van solos. */
#geduAvisos {
    position: fixed;
    /* 20-ago (Valeria, diseño gCon): esquina INFERIOR DERECHA (issue #40 sigue en
       pie), globo arriba y Gemi asomando debajo, más grande. Sigue siendo toast:
       no bloquea nada. */
    /* 17-sep (Valeria): sube lo justo para NO tapar la línea del pie («gEdu · Sistema de
       gestión escolar»), que vive en esa misma esquina. */
    bottom: 2.75rem;
    right: 1rem;
    z-index: 1080;              /* por encima de los modales de Bootstrap (1055) */
    display: grid;
    gap: .65rem;
    justify-items: end;
    align-content: end;         /* los avisos se apilan hacia ARRIBA desde la esquina */
    max-width: min(30rem, calc(100vw - 2rem));
    pointer-events: none;       /* el hueco entre avisos no roba clics a la página */
}
#geduAvisos > * { pointer-events: auto; }

/* Globo ARRIBA, Gemi DEBAJO (calcado de gCon): columna centrada. */
.gemi-aviso {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* 21-sep: un texto sin espacios (una ruta «C:\inetpub\…», una URL) no se parte solo:
       ensanchaba el globo más allá del borde de la pantalla y se llevaba la ✕ con él — el
       aviso de error, que no se cierra solo, quedaba imposible de quitar. El aviso no pasa
       del ancho de su columna y el texto se parte donde haga falta. */
    max-width: 100%;
    min-width: 0;
    overflow-wrap: anywhere;
    animation: gemiEntra .3s cubic-bezier(.22, 1, .36, 1) both;
}
.gemi-sale { animation: gemiSale .25s ease-in forwards; }

.gemi-cara {
    width: 84px;
    height: 84px;
    object-fit: contain;
    object-position: top;
    flex: 0 0 auto;
    margin-top: 2px;            /* pegadito a la colita del globo */
    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .25));
}

.gemi-globo {
    position: relative;
    max-width: 100%;
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
    border-radius: 14px;
    padding: .75rem 2.1rem .85rem 1rem;
    box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
    font-size: .95rem;
    cursor: pointer;
}
/* La colita del globo, apuntando hacia abajo, a Gemi. */
.gemi-globo::before {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -6.5px;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    background: var(--bs-body-bg);
    border-right: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color);
    transform: rotate(45deg);
}

.gemi-titulo {
    display: block;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    margin-bottom: .05rem;
}
.gemi-texto { display: block; }

/* El botón de acción: hacer algo desde el propio aviso (ver el recibo, ir a la
   bandeja) en vez de tener que buscarlo en la pantalla. */
.gemi-accion {
    display: inline-block;
    margin-top: .45rem;
    font-weight: 600;
    font-size: .85rem;
    text-decoration: none;
    color: inherit;
    border: 1px solid currentColor;
    border-radius: 7px;
    padding: .2rem .65rem;
}
.gemi-accion:hover { background: rgba(127, 127, 127, .14); color: inherit; }

.gemi-cerrar {
    position: absolute;
    top: .2rem;
    right: .35rem;
    background: transparent;
    border: 0;
    color: var(--bs-secondary-color);
    font-size: 1.15rem;
    line-height: 1;
    padding: .1rem .25rem;
    cursor: pointer;
}
.gemi-cerrar:hover { color: var(--bs-body-color); }

/* Línea de tiempo: arranca completa y se consume hasta que el aviso se va. */
.gemi-barra {
    position: absolute;
    /* Sin overflow:hidden en el globo (recortaría la colita): la línea se mete
       unos px para respetar las esquinas redondeadas. */
    left: 8px;
    right: 8px;
    bottom: 0;
    height: 3px;
    border-radius: 3px;
    transform-origin: left;
    animation: gemiCorre linear forwards;
}

/* Cada tipo pinta su color en el título, el borde de la acción y la línea. */
.gemi-ok .gemi-titulo, .gemi-ok .gemi-accion { color: var(--bs-success); }
.gemi-ok .gemi-barra { background: var(--bs-success); }
.gemi-err .gemi-titulo, .gemi-err .gemi-accion { color: var(--bs-danger); }
.gemi-err .gemi-barra { background: var(--bs-danger); }
.gemi-warn .gemi-titulo, .gemi-warn .gemi-accion { color: #b8860b; }
.gemi-warn .gemi-barra { background: #b8860b; }
.gemi-info .gemi-titulo, .gemi-info .gemi-accion { color: var(--bs-primary); }
.gemi-info .gemi-barra { background: var(--bs-primary); }
body.dark-mode .gemi-warn .gemi-titulo,
body.dark-mode .gemi-warn .gemi-accion { color: #f0c14b; }
body.dark-mode .gemi-warn .gemi-barra { background: #f0c14b; }

/* El modal de confirmar con el mismo diseño: el contenido es el globo (colita
   hacia abajo) y Gemi asoma debajo, centrado. */
/* modal-dialog-centered es flex en FILA: sin esto, Gemi salía al costado
   del globo en vez de asomar debajo. */
.gemi-confirm-dialog { flex-direction: column; justify-content: center; }
.gemi-confirm { border-radius: 14px; }
.gemi-confirm::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -6.5px;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    background: var(--bs-modal-bg, var(--bs-body-bg));
    border-right: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color);
    transform: rotate(45deg);
}
/* 06-nov (Valeria, A11): la pregunta de una acción delicada (data-confirm) es una ADVERTENCIA:
   globo con borde y título amarillos, los mismos tonos del toast amarillo (.gemi-warn). */
.gemi-confirm.gemi-confirm-warn { border: 2px solid #b8860b; }
.gemi-confirm.gemi-confirm-warn::after { border-right: 2px solid #b8860b; border-bottom: 2px solid #b8860b; bottom: -7.5px; }
.gemi-confirm-warn .modal-title { color: #b8860b; }
body.dark-mode .gemi-confirm.gemi-confirm-warn { border-color: #f0c14b; }
body.dark-mode .gemi-confirm.gemi-confirm-warn::after { border-color: #f0c14b; }
body.dark-mode .gemi-confirm-warn .modal-title { color: #f0c14b; }
.gemi-confirm-cara {
    display: block;
    margin: 3px auto 0;
    width: 88px;
    height: 88px;
    object-fit: contain;
    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .3));
}

/* Entra subiendo desde la esquina (ahora vive abajo) y sale hundiéndose. */
@keyframes gemiEntra { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes gemiSale { to { opacity: 0; transform: translateY(12px); } }
@keyframes gemiCorre { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) {
    .gemi-aviso, .gemi-sale { animation: none; }
    .gemi-barra { animation: none; transform: scaleX(1); }
}

/* --- La X de cerrar de los modales en oscuro (13-ago, Jeffrey) -------------
   Se veía casi invisible por una DOBLE negación: iGemas.css pinta el aspa
   BLANCA en dark-mode, y encima Bootstrap 5.3 (data-bs-theme="dark") le aplica
   su filtro invert(1) — blanco invertido = negro, sobre fondo oscuro, y al 50%
   de opacidad por defecto. Se anula el filtro (el icono ya viene blanco) y se
   sube la opacidad. No se toca iGemas.css: es la identidad compartida con los
   sistemas hermanos. */
body.dark-mode .modal-header .btn-close {
    filter: none;          /* el aspa YA viene blanca de iGemas.css */
    opacity: 1;            /* 22-sep (#37): al .85 seguía tenue sobre el encabezado oscuro */
}
body.dark-mode .modal-header .btn-close:hover,
body.dark-mode .modal-header .btn-close:focus-visible { opacity: 1; background-color: rgba(255,255,255,.18); border-radius: .375rem; }
/* Las X de FUERA del encabezado (alertas descartables) no reciben el aspa blanca:
   ahí el filtro de Bootstrap sí hace falta y solo se sube la opacidad. */
body.dark-mode .alert .btn-close { opacity: .95; }
body.dark-mode .alert .btn-close:hover { opacity: 1; }

/* --- Botones de contorno gris en oscuro (13-ago, Jeffrey) -----------------
   Bootstrap deja .btn-outline-secondary clavado en #6c757d pase lo que pase
   con el tema: en oscuro eso es gris medio sobre gris oscuro — 3.3:1, por
   debajo del 4.5:1 que pide la norma para texto. Se veía "apagado" en Ajustes
   (Cobranzas, Académico) y en toda barra que los use. En oscuro el texto pasa
   al color del cuerpo y el borde al del tema; el gris queda solo de relleno al
   pasar el mouse. Va aquí y no en iGemas.css: iGemas.css es la identidad
   compartida con gPay/gInm/gCon y no se toca desde gEdu. */
body.dark-mode .btn-outline-secondary {
    --bs-btn-color: var(--bs-body-color);
    --bs-btn-border-color: var(--bs-border-color);
    --bs-btn-hover-color: var(--bs-body-color);
    --bs-btn-hover-bg: var(--bs-secondary-bg);
    --bs-btn-hover-border-color: var(--bs-secondary-color);
    --bs-btn-active-color: var(--bs-body-color);
    --bs-btn-active-bg: var(--bs-secondary-bg);
    --bs-btn-active-border-color: var(--bs-secondary-color);
}

/* --- Login: fondo de paisaje del día (lo demás lo pone iGemas.css) -------- */
#Login_Main_Wrapper {
    background-color: #1a1a1a;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Velo que garantiza el contraste del formulario (12-ago). La densidad la calcula
   site.js midiendo la luminancia de la foto: con una playa clarísima sube, con una
   noche estrellada casi no se nota. Es una sombra INTERIOR y no un pseudo-elemento
   a propósito: cae sobre el fondo pero por debajo del contenido, sin tocar el
   posicionamiento del logo ni de la caja (que ya son absolutos) ni robar clics. */
#Login_Main_Wrapper.con-velo {
    box-shadow: inset 0 0 0 100vmax rgba(0, 0, 0, var(--velo-login, .3));
}

/* --- Horario (rejilla): compartido por Academico/Horario y HorarioVersiones --- */
.horario-grid td, .horario-grid th { vertical-align: middle; }
/* 03-nov: 6.5rem por celda para que los 5 días quepan a 1366 px con el menú abierto (a 8.5rem el viernes quedaba oculto). */
.horario-celda { min-width: 6.5rem; height: 3.2rem; padding: .15rem; }
.horario-grid td, .horario-grid th { padding-block: .15rem; }
/* 03-nov (nuevo diseño): la × va en la esquina para que no le quite alto a la materia. */
.horario-grid .bloque { padding: .15rem .35rem; }
.horario-grid .bloque > .btn-quitar { position: absolute; top: 0; right: 2px; }
/* La lista de materias de Por sección: también es el selector de la materia a colocar. */
#cuadreLista .list-group-item { padding: .3rem .5rem; font-size: .82rem; }
#cuadreLista .list-group-item[role="button"]:hover { background: var(--bs-tertiary-bg); }
#cuadreLista .list-group-item.elegida { box-shadow: inset 3px 0 0 var(--bs-primary); background: var(--bs-tertiary-bg); font-weight: 600; }
.chip-color-mini.flex-none { flex: none; }
/* 03-nov: iGemas.css pone nowrap a todas las filas de tabla: un nombre largo de materia estiraba la columna y
   empujaba los demás días fuera de la caja. En la rejilla el texto se parte dentro de su celda. */
.horario-grid tr { white-space: normal; }
.horario-celda.vacia { background: var(--bs-tertiary-bg); }
.horario-recreo td { background: var(--bs-tertiary-bg); font-style: italic; }
.bloque { position: relative; height: 100%; display: flex; flex-direction: column; justify-content: center;
          border-radius: .4rem; padding: .3rem .4rem; background: var(--bs-tertiary-bg); }
/* Texto fijo oscuro: legible sobre los pasteles tanto en claro como en oscuro. */
.bloque-mat { font-weight: 600; font-size: .85rem; line-height: 1.1; color: #1f2937; }
.bloque-doc { font-size: .72rem; color: #4b5563; line-height: 1.1; margin-top: .1rem; }
.bloque-quitar { position: absolute; top: 2px; right: 4px; margin: 0; }
.btn-quitar { border: 0; background: transparent; color: var(--bs-danger); font-size: 1rem; line-height: 1; cursor: pointer; padding: 0 .15rem; }
.btn-colocar { border: 1px dashed var(--bs-border-color); background: transparent; color: var(--bs-secondary-color);
               width: 100%; height: 3.4rem; border-radius: .4rem; font-size: 1.1rem; cursor: pointer; }
.btn-colocar:hover { border-color: var(--gedu-acento, #f3b21b); color: var(--gedu-acento, #f3b21b); }

/* Paleta de materias (mismo color en rejilla y avatares del directorio). */
.mat-c0 { background: #dbeafe; } .mat-c1 { background: #dcfce7; }
.mat-c2 { background: #fde2e4; } .mat-c3 { background: #ede9fe; }
.mat-c4 { background: #fef9c3; } .mat-c5 { background: #ccfbf1; }
.mat-c6 { background: #ffedd5; } .mat-c7 { background: #e0e7ff; }
.mat-c8 { background: #fce7f3; } .mat-c9 { background: #ecfccb; }
.mat-c10 { background: #e0f2fe; } .mat-c11 { background: #e7e5e4; }
.bloque.mat-c8 { border-left: 3px solid #ec4899; } .bloque.mat-c9 { border-left: 3px solid #84cc16; }
.bloque.mat-c10 { border-left: 3px solid #0ea5e9; } .bloque.mat-c11 { border-left: 3px solid #78716c; }
/* Celda partida: texto oscuro sobre pastel también en modo oscuro (los fuertes lo cambian justo abajo). */
.simul-item { color: #1f2937; }
/* 03-nov (Valeria): 12 colores fuertes, primarios y secundarios. Los mismos de PaletaMaterias.Fondos. */
.mat-c12 { background: #d32f2f; } .mat-c13 { background: #1565c0; } .mat-c14 { background: #fbc02d; }
.mat-c15 { background: #2e7d32; } .mat-c16 { background: #fb8c00; } .mat-c17 { background: #6a1b9a; }
.mat-c18 { background: #00796b; } .mat-c19 { background: #00838f; } .mat-c20 { background: #c2185b; }
.mat-c21 { background: #c0ca33; } .mat-c22 { background: #6d4c41; } .mat-c23 { background: #455a64; }
/* Sobre los más oscuros el texto va en blanco (PaletaMaterias.TextoClaro). */
.mat-c12, .mat-c13, .mat-c15, .mat-c17, .mat-c18, .mat-c19, .mat-c20, .mat-c22, .mat-c23 { --texto-materia: #fff; color: #fff; }
.mat-c12 .bloque-mat, .mat-c13 .bloque-mat, .mat-c15 .bloque-mat, .mat-c17 .bloque-mat, .mat-c18 .bloque-mat, .mat-c19 .bloque-mat, .mat-c20 .bloque-mat, .mat-c22 .bloque-mat, .mat-c23 .bloque-mat,
.mat-c12 .bloque-doc, .mat-c13 .bloque-doc, .mat-c15 .bloque-doc, .mat-c17 .bloque-doc, .mat-c18 .bloque-doc, .mat-c19 .bloque-doc, .mat-c20 .bloque-doc, .mat-c22 .bloque-doc, .mat-c23 .bloque-doc,
.mat-c12 .btn-quitar, .mat-c13 .btn-quitar, .mat-c15 .btn-quitar, .mat-c17 .btn-quitar, .mat-c18 .btn-quitar, .mat-c19 .btn-quitar, .mat-c20 .btn-quitar, .mat-c22 .btn-quitar, .mat-c23 .btn-quitar,
.mini-bloque.mat-c12, .mini-bloque.mat-c13, .mini-bloque.mat-c15, .mini-bloque.mat-c17, .mini-bloque.mat-c18, .mini-bloque.mat-c19, .mini-bloque.mat-c20, .mini-bloque.mat-c22, .mini-bloque.mat-c23 { color: #fff; }
.mat-c14, .mat-c16, .mat-c21 { color: #1f2937; }
.bloque.mat-c12, .bloque.mat-c13, .bloque.mat-c14, .bloque.mat-c15, .bloque.mat-c16, .bloque.mat-c17,
.bloque.mat-c18, .bloque.mat-c19, .bloque.mat-c20, .bloque.mat-c21, .bloque.mat-c22, .bloque.mat-c23 { border-left: 3px solid rgba(0, 0, 0, .35); }
/* 03-nov: chips del color de la materia (modal) y su puntito en el listado. */
.chip-color { display: block; width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px solid rgba(0, 0, 0, .25); cursor: pointer; }
.btn-check:checked + label .chip-color,
.btn-check:focus-visible + label .chip-color { outline: 3px solid var(--bs-primary); outline-offset: 2px; }
.chip-color-mini { display: inline-block; width: .75rem; height: .75rem; border-radius: 50%; border: 1px solid rgba(0, 0, 0, .25); }
.bloque.mat-c0 { border-left: 3px solid #3b82f6; } .bloque.mat-c1 { border-left: 3px solid #22c55e; }
.bloque.mat-c2 { border-left: 3px solid #ef4444; } .bloque.mat-c3 { border-left: 3px solid #8b5cf6; }
.bloque.mat-c4 { border-left: 3px solid #eab308; } .bloque.mat-c5 { border-left: 3px solid #14b8a6; }
.bloque.mat-c6 { border-left: 3px solid #f97316; } .bloque.mat-c7 { border-left: 3px solid #6366f1; }

/* Avatar del directorio docente (iniciales sobre el color de su materia). */
.avatar-doc { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center;
              justify-content: center; font-weight: 600; color: #1f2937; flex: 0 0 auto; }

/* --- Horario · edición desde "Por docente" ---------------------------------- */
#gridDocWrap .celda-doc { min-width: 8.5rem; height: 4.2rem; padding: .25rem; vertical-align: middle; }
#gridDocWrap .celda-doc.vacia { background: var(--bs-tertiary-bg); }
#gridDocWrap .celda-doc.sel { outline: 2px dashed var(--gedu-acento); outline-offset: -3px; }
#gridDocWrap .celda-doc.bloqueada { cursor: not-allowed; opacity: .55;
    background: repeating-linear-gradient(45deg, #f1f3f5, #f1f3f5 6px, #e3e6ea 6px, #e3e6ea 12px); }
body.dark-mode #gridDocWrap .celda-doc.bloqueada {
    background: repeating-linear-gradient(45deg, #2b3035, #2b3035 6px, #3a4046 6px, #3a4046 12px); }
#gridDocWrap .celda-doc.advertida:not(.bloqueada) { box-shadow: inset 0 0 0 2px #ffca28; }
#gridDocWrap .bloque + .bloque { margin-top: 2px; }
#gridDocWrap .bloque.doc-choque { outline: 2px solid var(--bs-danger); outline-offset: 1px; }
#gridDocWrap .bloque.doc-aviso { box-shadow: inset 0 0 0 2px #ffca28; }
#gridDocWrap .bloque.doc-multi { outline: 2px dashed #e6a700; outline-offset: 1px; }
#gridDocWrap .tag-multi { display: inline-block; font-size: .62rem; font-weight: 800; color: #7a5b00;
    background: #ffecb3; border-radius: .25rem; padding: 0 .25rem; line-height: 1.3; margin-left: .25rem; }
#gridDocWrap .bloque-doc-mov[draggable="true"] { cursor: grab; }
#docPaleta .chip-doc { font-size: .8rem; }

/* --- Horario · vista global (rejillas compactas de todas las secciones) ----- */
.horario-mini { font-size: .72rem; }
.horario-mini .mini-celda { padding: 2px; min-width: 4.5rem; vertical-align: middle; }
.horario-mini .mini-vacia { background: var(--bs-tertiary-bg); }
.mini-bloque { border-radius: .25rem; padding: .1rem .25rem; line-height: 1.15; color: #1f2937;
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 9rem; }
.mini-bloque + .mini-bloque { margin-top: 2px; }
.mini-celda.mini-choque { outline: 2px solid var(--bs-danger); outline-offset: -2px; }
.mini-celda.mini-multi { outline: 2px dashed var(--bs-warning); outline-offset: -2px; }
.mini-bloque.mini-apagado { opacity: .25; }
.mini-bloque.mini-resaltado { box-shadow: 0 0 0 2px var(--gedu-acento); font-weight: 600; }
/* Etiqueta "M" de multigrado intencional (también se usa fuera de #gridB: vista por materia). */
.tag-multi { display: inline-block; font-size: .62rem; font-weight: 800; color: #7a5b00;
    background: #ffecb3; border-radius: .25rem; padding: 0 .25rem; line-height: 1.3; }
@media print {
    .horario-mini .mini-bloque, .horario-mini .mini-celda { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .mini-bloque.mini-apagado { opacity: 1; }
    .mini-bloque.mini-resaltado { box-shadow: none; }
}

/* Las celdas del layout de DataTables son columnas .col de Bootstrap: traen
   padding de gutter (12px por lado) que, sumado al del card-body, dejaba un
   hueco a los lados de la TABLA (se notaba a la derecha, junto al scrollbar).
   La tabla llena el card-body...  */
.dt-container .dt-layout-full { padding-left: 0; padding-right: 0; }

/* ...pero la barra de botones, el buscador, el "mostrando N de N" y la
   paginación SÍ llevan un respiro lateral: 0.5rem, el mismo padding que
   Bootstrap le da a las celdas, para que el primer botón quede alineado con el
   texto de la primera columna en vez de pegado al borde de la tarjeta. */
.dt-container .dt-layout-start,
.dt-container .dt-layout-end { padding-left: .5rem; padding-right: .5rem; }

/* CONVENCIÓN DE ALINEACIÓN EN TABLAS (28-jul):
     · Dinero  → a la derecha (.text-end): así los montos alinean por la coma y se
       comparan de un vistazo, como en cualquier estado de cuenta.
     · Conteos → CENTRADOS (.col-conteo): un "1" suelto pegado al borde derecho
       queda lejísimos de su encabezado y cuesta encontrarlo.
     · Texto   → a la izquierda (lo natural para leer).
   Usa .col-conteo en el th y en el td; centra también el encabezado.
   El selector va con table.dataTable delante a propósito: DataTables alinea sola a
   la derecha toda columna que detecta numérica (td.dt-type-numeric), y una regla
   suelta .col-conteo perdía por especificidad. */
.col-conteo,
table.dataTable th.col-conteo,
table.dataTable td.col-conteo { text-align: center; }

/* 06-oct (Valeria): las FECHAS también van centradas. DataTables pega a la derecha toda columna
   que reconoce como fecha (td.dt-type-date); con esta regla todas quedan centradas sin tocar cada
   página. Una fecha que se ordena por un número oculto (data-order="yyyyMMdd…") DataTables la toma
   por numérica, no por fecha: esa columna lleva .col-fecha en el th y en el td. */
/* 06-oct: pestañas que en el TELÉFONO se deslizan de lado en vez de apilarse en renglones (en
   Mi información del portal, tres pestañas ocupaban tres renglones). En pantallas grandes no
   cambia nada. Uso: class="nav nav-tabs … tabs-deslizables". */
@media (max-width: 575.98px) {
    .tabs-deslizables { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
    .tabs-deslizables::-webkit-scrollbar { display: none; }
    .tabs-deslizables .nav-link { white-space: nowrap; }
}

.col-fecha,
table.dataTable th.col-fecha,
table.dataTable td.col-fecha,
table.dataTable th.dt-type-date,
table.dataTable td.dt-type-date { text-align: center; }

/* 17-ago (Valeria): el "+" del expansor quedaba pegado al borde de la tarjeta. La
   columna de gInm mide 32px y el glifo va centrado, así que se ensancha a 52 para
   darle aire por ambos lados. El mismo número está en site.js (ancho del <th>), o
   la cabecera y el cuerpo se desalinean. */
.tabla-dt th.dtr-control,
.tabla-dt td.dtr-control { width: 52px; }
/* La celda del + está vacía (el signo es un ::before absoluto): cuando la tabla
   desborda su caja, el auto-layout la aplasta hasta el padding y el + queda pegado
   al borde (Gestión de cobro, 19-ago). El min-width la sostiene. */
.tabla-dt td.dtr-control { min-width: 52px; }

/* Columna de selección (checkbox) que site.js antepone a toda .tabla-dt. */
.tabla-dt th.dt-sel, .tabla-dt td.dt-sel { width: 34px; text-align: center; }
.tabla-dt .dt-sel .form-check-input { cursor: pointer; }

/* 13-ago (Jeffrey): la columna de marcar estaba SIEMPRE puesta, en todas las
   tablas del sistema, aunque casi nunca se use — una columna de ruido fija. Ahora
   nace apagada y solo aparece cuando el usuario entra en "Elegir filas" desde el
   menú de Imprimir/Exportar.
   14-ago: quien la apaga es DataTables (column().visible(false) en site.js), NO
   una regla display:none como antes. Escondiéndola por CSS la celda seguía siendo
   una columna para DataTables: le reservaba su ancho en el <colgroup> y sobraba
   una franja muerta a la derecha de la tabla. Los índices de columna no sufren:
   los filtros hablan por la API, y ahí una columna oculta conserva su índice. */

/* Recorrido intro.js: fijar colores propios para que el texto se lea siempre
   (en modo oscuro el dark-mode aclaraba el texto y quedaba casi invisible). */
.introjs-tooltip { background: #fff !important; color: #212529 !important; }
.introjs-tooltiptext, .introjs-tooltip-title { color: #212529 !important; }
.introjs-tooltip .introjs-button {
    color: #212529 !important; background: #f8f9fa !important;
    border-color: #ced4da !important; text-shadow: none !important;
}
.introjs-tooltip .introjs-button:hover { background: #e9ecef !important; }
.introjs-tooltip .introjs-disabled { color: #adb5bd !important; }
.introjs-bullets ul li a { background: #ced4da; }
.introjs-bullets ul li a.active { background: var(--gedu-acento, #0d6efd); }

/* --- Constructor de formularios de inscripción (Plantillas/Editor) ---------- */
.mini-w-0 { min-width: 0; }
.constructor-preview { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); }
.constructor-preview .card-body { overflow-y: auto; }
.campo-fila .campo-grip, .seccion-grip { cursor: grab; }
.campo-fila.arrastrando, .seccion-card.arrastrando { opacity: .5; }
.campo-fila.drop-destino { box-shadow: inset 0 3px 0 var(--gedu-acento); }
.campos-lista.drop-destino, .seccion-card.drop-destino > .card-header { outline: 2px dashed var(--gedu-acento); outline-offset: -2px; }
.seccion-card .seccion-titulo { max-width: 24rem; }
.tipo-chip { border-radius: 2rem; }

/* --- Impresión: oculta el shell (sidebar/header/footer) y lo marcado .no-print, ----
   deja solo el contenido (formularios, planillas, tablas). Útil para imprimir o
   "Guardar como PDF" desde el navegador. */
@media print {
    aside,
    #Main_Wrapper > header,
    #Info_wrap,
    footer,
    .no-print { display: none !important; }

    #Main_Wrapper { width: 100% !important; margin: 0 !important; float: none !important; }
    #Word_wrap { position: static !important; padding: 0 !important; }
    body { background: #fff !important; }

    /* La app usa overflow:hidden/auto para su layout de pantalla; al imprimir eso RECORTA el
       documento a una sola página. Aquí se libera todo para que salgan TODAS las páginas. */
    html, body { overflow: visible !important; height: auto !important; }
    #Word_wrap, #Inf_Wrap, #Main_Wrapper { overflow: visible !important; height: auto !important; max-height: none !important; }
    div.dt-container > .row.dt-layout-table { overflow: visible !important; max-height: none !important; }
    /* Misma razón: una tabla ancha vive en su caja con scroll para no salirse en pantalla,
       pero en papel esa caja cortaría las columnas de la derecha. En impresión se suelta. */
    .table-responsive { overflow: visible !important; }
    .tabla-dt > thead > tr > th { position: static !important; }  /* cabecera no fija al imprimir */

    /* Tarjetas planas y sin cortes feos al paginar. */
    .card { border: 1px solid #ccc !important; box-shadow: none !important; break-inside: avoid; }

    /* 25-sep (Valeria): el papel no lleva el MARCO de la pantalla. El contenedor del main
       (#Word_wrap) conservaba su sombra y bordes redondeados, y el documento salía como una
       imagen pegada en la hoja. Y un documento (aviso, recibo) va sin caja alrededor. */
    #Word_wrap, #Inf_Wrap, #Main_Wrapper { box-shadow: none !important; border: 0 !important; border-radius: 0 !important; }
    .card.card-documento { border: 0 !important; background: transparent !important; max-width: none !important; }
    .card.card-documento > .card-body { padding: 0 !important; }
    a[href]::after { content: ""; }  /* no anexar la URL a los enlaces */

    /* Barra de DataTables (botones, buscador, paginación, "mostrar N") fuera de la impresión. */
    .dt-buttons, .dt-search, .dt-length, .dt-info, .dt-paging,
    .dataTables_filter, .dataTables_length, .dataTables_info, .dataTables_paginate { display: none !important; }

    /* Columnas/acciones que no deben salir impresas (marcadas con .dt-action o .no-print). */
    th.dt-action, td.dt-action { display: none !important; }

    /* Filas hijas del +/- (detalle expandido): no se imprimen; la impresión queda plana. */
    tr.child { display: none !important; }

    /* Las tablas pueden partir por filas entre páginas sin cortar una fila a la mitad. */
    table.tabla-dt, .tabla-imprimible { width: 100% !important; }
    tr, td, th { break-inside: avoid; }
    thead { display: table-header-group; }   /* repite el encabezado en cada página */
}

/* 28-sep (Valeria, Gestión de cobro): en modo oscuro las etiquetas .text-bg-light salían BLANCAS
   y, con .text-muted encima (p. ej. la fecha de un recordatorio ya pasado), el texto gris claro
   sobre blanco no se leía. En oscuro pasan a un fondo oscuro suave; el texto: el del tema, o el
   gris del tema si la etiqueta es .text-muted (que ahí sí contrasta). Arregla las 63 de una vez. */
[data-bs-theme="dark"] .badge.text-bg-light { background-color: var(--bs-tertiary-bg) !important; }
[data-bs-theme="dark"] .badge.text-bg-light:not(.text-muted) { color: var(--bs-body-color) !important; }

/* #126 (28-sep): marca de agua del recibo ANULADO — gris, grande, en diagonal al centro, en
   pantalla y en papel. No bloquea clics (pointer-events) ni se sale del recibo (overflow). */
.marca-anulado {
    position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
}
.marca-anulado span {
    transform: rotate(-35deg); white-space: nowrap;
    font-size: 7rem; font-weight: 800; letter-spacing: .1em; color: rgba(128, 128, 128, .28);
}

/* 30-sep (Valeria): un modal marcado .modal-imprimible, si está ABIERTO, es lo que se imprime (la
   revisión de «Emitir cargos»). El modal vive dentro del main, así que no se puede ocultar a sus
   hermanos con display: se esconde TODO con visibility y se vuelve visible solo el modal, que pasa a
   estar arriba de la hoja. Además se sueltan sus altos fijos y sus cajas con scroll: en pantalla
   llenan la ventana; en papel cortarían la lista en la primera hoja. */
@media print {
    body:has(.modal-imprimible.show) * { visibility: hidden; }
    body:has(.modal-imprimible.show) .modal-imprimible.show,
    body:has(.modal-imprimible.show) .modal-imprimible.show * { visibility: visible; }
    body:has(.modal-imprimible.show) .modal-backdrop { display: none !important; }
    .modal-imprimible.show { position: absolute !important; top: 0 !important; left: 0 !important;
                             width: 100% !important; height: auto !important; overflow: visible !important; }
    .modal-imprimible .modal-dialog, .modal-imprimible .modal-content, .modal-imprimible .modal-body,
    .modal-imprimible .h-100, .modal-imprimible .flex-grow-1,
    .modal-imprimible .overflow-auto, .modal-imprimible .overflow-hidden {
        height: auto !important; max-height: none !important; overflow: visible !important;
        transform: none !important; margin: 0 !important; }
    .modal-imprimible .modal-header { display: none !important; }   /* el título va en el encabezado de impresión */
    .modal-imprimible .sticky-top { position: static !important; }
}

/* Encabezado de documento imprimible (logo/título de la planilla); oculto en pantalla. */
.solo-impresion { display: none; }
@media print { .solo-impresion { display: block; } }

/* 07-oct (jefe): el PAPEL siempre es claro, aunque el sistema esté en modo oscuro — quien arma una
   plantilla (el área del editor) o mira su vista previa tiene que ver lo que saldrá en la hoja.
   Cubre: documentos emitidos (.card-documento: trámite, recibo, aviso, solvencia), boletín, las
   vistas previas de plantillas (.hoja-papel) y el área de escritura de Jodit. Además de esto, cada
   contenedor lleva data-bs-theme="light" para que Bootstrap use sus colores claros adentro
   (text-muted, tablas, bordes). La regla oscura de iGemas.css pone en blanco títulos, etiquetas y
   hr: aquí vuelven al color del papel. */
.card-documento, .boletin-doc, .hoja-papel, .jodit-wysiwyg {
    background-color: #fff !important;
    color: #212529 !important;
}
body.dark-mode :is(.card-documento, .boletin-doc, .hoja-papel, .jodit-wysiwyg) :is(h1, h2, h3, h4, h5, h6, label, hr) {
    color: inherit !important;
}
/* iGemas.css también pinta oscuro todo .card-body y .list-group-item, y gris claro todo .text-muted. */
body.dark-mode :is(.card-documento, .boletin-doc, .hoja-papel) :is(.card-body, .list-group-item) {
    background-color: transparent;
    color: inherit;
}
body.dark-mode :is(.card-documento, .boletin-doc, .hoja-papel, .jodit-wysiwyg) .text-muted { color: #6c757d !important; }

/* 07-oct (jefe: «el cuadro no queda idéntico»): las tablas de un documento armado en Jodit salen
   como se ven en el editor, que le pinta borde a TODA celda; sin esto el editor mostraba el cuadro
   y la hoja impresa salía sin líneas. Una celda con su propio borde (style="border…") manda.
   15-oct (prueba con modelos de boletín): el borde va a TODA celda, sin el :not de antes. Con el :not, una
   celda que cambiaba UN lado («border-bottom:none») o solo el color (el «color de borde» de Jodit) perdía
   los cuatro bordes. No hace falta excluirlas: el style en línea de la celda ya le gana a esta regla. */
.doc-cuerpo table { border-collapse: collapse; max-width: 100%; }
.doc-cuerpo td, .doc-cuerpo th { border: 1px solid currentColor; }
.doc-cuerpo td:not([style*="border"]),
.doc-cuerpo th:not([style*="border"]) { padding: .4em; vertical-align: middle; }
/* 15-oct: iGemas.css pone «table tr { white-space: nowrap }» a TODA tabla (las de DataTables no deben partir
   renglones). En un documento, y en el editor donde se arma, el texto de una celda SÍ tiene que cortar línea:
   sin esto un indicador largo se salía de la hoja y empujaba las demás columnas. */
.doc-cuerpo tr, .jodit-wysiwyg tr { white-space: normal; }

/* Boletines: cada boletín en su propia hoja al imprimir en lote. */
@media print { .salto-pagina { page-break-before: always; } }

/* 14-oct (Valeria): el boletín IMPRESO en Arial. Con la letra de Windows (Segoe UI) algunas «l»
   salían más gruesas que otras en el papel / «Microsoft Print to PDF». Provisional: cuando exista
   el constructor de boletines, la letra la elige el colegio. */
@media print { .boletin-doc { font-family: Arial, Helvetica, sans-serif; } }

/* 15-oct: el boletín con la plantilla PROPIA del colegio. Sin esto el navegador no imprime los fondos de
   celda que el colegio pintó en Jodit (salvo que se marque «Gráficos de fondo» al imprimir). */
.boletin-plantilla { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

/* 15-oct (Valeria): el botón de la IA («Importar documento», primero en la barra de TODOS los editores Jodit) se
   distingue: degradado azul con la varita blanca de los demás botones de IA (la pone jodit-init.js). */
.jodit-toolbar-button_importarDocumento .jodit-toolbar-button__button {
    background: linear-gradient(to bottom, #6cb4ff 0%, #2f8cff 45%, #0b5ed7 100%) !important;
    border-radius: 6px !important;
}
.jodit-toolbar-button_importarDocumento .jodit-toolbar-button__button:hover { filter: brightness(1.1); }
.jodit-toolbar-button_importarDocumento .icono-ia { color: #fff; font-size: 16px; line-height: 1; }

/* 15-oct (Valeria): el salto de CARA de las plantillas (frente → dorso, el tríptico…): un div con
   page-break-before (el botón «Nueva cara» o el que se escribió a mano en un modelo). En el editor y en la vista
   previa se ve como una línea punteada con letrero; en el papel no se ve: solo hace que lo que sigue salga en la
   hoja siguiente (la de atrás, si se imprime a doble cara). Jodit le mete un <br> adentro: se esconde.
   Solo en pantalla: el visor de boletines (BoletinesImprimir) también es «vista-previa-caras» y se imprime. */
@media screen {
.jodit-wysiwyg div[style*="page-break-before"],
.vista-previa-caras div[style*="page-break-before"] {
    position: relative; height: 0; margin: 1.6rem 0; border-top: 2px dashed #6c757d;
}
.jodit-wysiwyg div[style*="page-break-before"] > *,
.vista-previa-caras div[style*="page-break-before"] > * { display: none; }
.jodit-wysiwyg div[style*="page-break-before"]::after,
.vista-previa-caras div[style*="page-break-before"]::after {
    content: "Cara trasera · hoja siguiente"; position: absolute; left: 50%; top: 0; transform: translate(-50%, -50%);
    background: #fff; padding: 0 .6rem; color: #6c757d;
    font: 600 8pt Arial, sans-serif; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
}
/* 15-oct (Valeria): los paneles del botón «Columnas» (y los del tríptico) son celdas SIN borde: en el editor se
   marcan con una línea punteada para ver dónde escribir; en la vista previa y en el papel no se ve. */
.jodit-wysiwyg td[style*="border:none"],
.jodit-wysiwyg td[style*="border: none"] { outline: 1px dashed #adb5bd; outline-offset: -1px; }
/* En la vista previa, si hay caras, la primera dice que es el frente. */
.vista-previa-caras .boletin-plantilla:has(div[style*="page-break-before"])::before {
    content: "Cara frontal"; display: block; text-align: center; margin-bottom: .8rem; color: #6c757d;
    font: 600 8pt Arial, sans-serif; letter-spacing: .05em; text-transform: uppercase;
}
}

/* Encabezado reutilizable de impresión (partial _EncabezadoImpresion): identifica la página y
   el filtro aplicado. Solo se ve al imprimir. */
.encabezado-impresion { margin-bottom: 1rem; padding-bottom: .5rem; border-bottom: 2px solid #000; }
.encabezado-impresion .ei-fila { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.encabezado-impresion .ei-app { font-size: .8rem; color: #444; letter-spacing: .02em; }
.encabezado-impresion .ei-titulo { font-size: 1.35rem; font-weight: 700; line-height: 1.15; }
.encabezado-impresion .ei-fecha { font-size: .8rem; color: #444; white-space: nowrap; }
.encabezado-impresion .ei-filtros { margin-top: .35rem; display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; font-size: .9rem; }
.encabezado-impresion .ei-filtro strong { font-weight: 600; }

/* Impresión del HORARIO: colores reales, sin marcas de edición (ámbar/rayado/botones). */
@media print {
    .horario-grid .bloque,
    .horario-grid .simul-item,
    .horario-grid .horario-celda { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    #gridB .celda-drag.advertida,
    #gridB .celda-drag.bloqueada,
    #gridB .celda-drag.sel { background: #fff !important; box-shadow: none !important; outline: none !important; }
    .btn-quitar, .btn-partir { display: none !important; }
    .horario-grid { font-size: .78rem; }
    /* 03-nov: en papel, la rejilla completa: sin el tope de alto ni el scroll de la pantalla. */
    .horario-caja { max-height: none !important; overflow: visible !important; }
    .horario-caja thead th, .horario-caja tr > :first-child { position: static !important; }
}

/* --- Picker visual de íconos (etapas del embudo de admisión) --- */
.icono-picker {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    max-height: 220px;
    overflow-y: auto;
    padding: .5rem;
    border: 1px solid var(--bs-border-color);
    border-radius: .5rem;
    background: var(--bs-tertiary-bg);
}
.icono-opt {
    width: 42px;
    height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    padding: 0;
}
.icono-opt.active {
    background: var(--gedu-acento, #0d6efd);
    border-color: var(--gedu-acento, #0d6efd);
    color: #fff;
}

/* --- Programador de mensajes (Campañas): tarjeta clara + panel oscuro de regla --- */
.auto-hero { display: flex; align-items: center; gap: 1rem; }
.auto-ico {
    width: 48px; height: 48px; border-radius: 50%;
    background: var(--gedu-acento); color: #1a1a1a;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.25rem;
    box-shadow: 0 .5rem 1rem rgba(246, 190, 0, .35);
}
.lbl-mini {
    font-size: .7rem; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: #98a2b3;
}
.panel-oscuro {
    background: #161b22; color: #e6e6e6;
    border-radius: .75rem; padding: 1.5rem;
    position: relative; overflow: hidden;
}
.panel-oscuro::after {
    /* resplandor de marca en la esquina, como el mockup */
    content: ""; position: absolute; top: -45px; right: -45px;
    width: 140px; height: 140px; border-radius: 50%;
    background: var(--gedu-acento); opacity: .18; filter: blur(30px);
    pointer-events: none;
}
.panel-oscuro .acento { color: var(--gedu-acento); }
.panel-oscuro .lbl-mini { color: #8b949e; }
.panel-oscuro .form-control { background: #21262d; border-color: #30363d; color: #fff; }
.panel-oscuro .form-control:focus {
    background: #21262d; color: #fff;
    border-color: var(--gedu-acento);
    box-shadow: 0 0 0 .2rem rgba(246, 190, 0, .25);
}
.panel-oscuro input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(1); }
/* Chips cuadrados de día de la semana (L M X J V S D) */
.chip-dia {
    width: 42px; height: 42px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: .55rem; background: #21262d; border: 1px solid #30363d;
    color: #c9d1d9; font-weight: 600; cursor: pointer;
    transition: background .15s, transform .1s;
}
.chip-dia:hover { background: #30363d; color: #fff; }
.btn-check:checked + .chip-dia {
    background: var(--gedu-acento); border-color: var(--gedu-acento);
    color: #1a1a1a; font-weight: 700;
}
/* Chips avanzados (día del mes / meses) dentro del panel: tema oscuro */
.panel-oscuro .btn-check + .btn { background: #21262d; border-color: #30363d; color: #c9d1d9; }
.panel-oscuro .btn-check + .btn:hover { background: #30363d; color: #fff; }
.panel-oscuro .btn-check:checked + .btn {
    background: var(--gedu-acento); border-color: var(--gedu-acento);
    color: #1a1a1a; font-weight: 700;
}
.fila-toggle {
    display: flex; align-items: center; gap: .75rem;
    background: #21262d; border: 1px solid #30363d;
    border-radius: .55rem; padding: .65rem .9rem;
    max-width: 420px;
}
.panel-oscuro .form-check-input { background-color: #30363d; border-color: #4b5563; }
.panel-oscuro .form-check-input:checked {
    background-color: var(--gedu-acento); border-color: var(--gedu-acento);
}
.panel-oscuro details summary { color: #8b949e; cursor: pointer; }
.panel-oscuro details summary:hover { color: #c9d1d9; }
/* Botón principal: amarillo de marca, plano (17-ago, Valeria: fuera el brillo/halo). */
.btn-automatizacion {
    background: var(--gedu-acento); color: #1a1a1a;
    font-weight: 700; border: none; border-radius: .75rem;
    padding: .7rem 1.5rem;
}
/* 08-oct: Bootstrap pone en hover/foco background-color: var(--bs-btn-hover-bg), que en un
   .btn sin variante es transparente, y le gana a la regla de arriba (más específica): el
   botón «Siguiente» de Campañas quedaba sin fondo al pasarle el mouse. */
.btn-automatizacion:hover, .btn-automatizacion:focus, .btn-automatizacion:active {
    background: var(--gedu-acento); filter: brightness(.95); color: #1a1a1a;
}

/* --- Constructor de Automatizaciones: stepper + chips de tipo + tablero --- */
.acento-texto { color: var(--gedu-acento); }
.paso-nav { display: flex; gap: .4rem; flex-wrap: wrap; }
.paso-punto {
    display: inline-flex; align-items: center; gap: .45rem;
    border: 1px solid var(--bs-border-color); background: var(--bs-body-bg);
    border-radius: 2rem; padding: .3rem .8rem .3rem .35rem;
    font-size: .82rem; color: var(--bs-secondary-color); cursor: pointer;
    transition: border-color .15s, color .15s;
}
.paso-punto .paso-num {
    width: 24px; height: 24px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--bs-tertiary-bg); font-weight: 700; font-size: .75rem;
}
.paso-punto.activo { border-color: var(--gedu-acento); color: var(--bs-body-color); font-weight: 600; }
.paso-punto.activo .paso-num { background: var(--gedu-acento); color: #1a1a1a; }
.paso-punto.hecho .paso-num { background: #d1e7dd; color: #0f5132; }
.chip-tipo { border-radius: 2rem; }
.chip-tipo.activo { background: var(--bs-primary); color: #fff; }
.stat-auto .card-body i { opacity: .85; }

/* --- Constructor de campaña en una página --- */
.badge-paso {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%; margin-right: .5rem;
    background: var(--gedu-acento); color: #1a1a1a; font-weight: 700; font-size: .78rem;
}
.resumen-sticky { position: sticky; top: 1rem; }

/* --- Centro de campañas estilo iGemas: filas coloreadas por estado --- */
#tablaCampanas tr.fila-activa > td { background: rgba(13, 110, 253, .05); }
#tablaCampanas tr.fila-pausada > td { background: rgba(220, 53, 69, .07); }
#chipsEstado .btn.activo { background: var(--bs-secondary); color: #fff; }

/* --- Centro F3: calendario mensual --- */
.cal-grid { table-layout: fixed; }
.cal-grid td { height: 92px; vertical-align: top; padding: .25rem .35rem; }
.cal-vacia { background: var(--bs-tertiary-bg); }
.cal-num { font-weight: 700; font-size: .8rem; margin-bottom: .15rem; }
.cal-hoy { box-shadow: inset 0 0 0 2px var(--gedu-acento); }
.cal-hoy .cal-num { color: var(--gedu-acento); filter: brightness(.8); }
.cal-evento {
    display: block; font-size: .7rem; line-height: 1.25; padding: .1rem .3rem;
    margin-bottom: .15rem; border-radius: .3rem; text-decoration: none;
    background: rgba(13, 110, 253, .1); color: var(--bs-body-color);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-evento:hover { background: rgba(13, 110, 253, .2); }

/* --- Modo oscuro: las cards de color (text-bg-*) conservan su fondo ---------- */
/* iGemas.css pinta todo .card-body de gris #1F2937 en oscuro; en las cards de
   resumen coloreadas (Morosidad, dashboards) eso tapa el rojo/ámbar. */
body.dark-mode .card[class*="text-bg-"] .card-body { background-color: transparent; }

/* --- Modales de configuración (patrón gPay): divisor entre columnas en desktop --- */
@media (min-width: 992px) {
    .border-start-lg { border-left: 1px solid var(--bs-border-color); }
}

/* Form que envuelve body+footer de un modal full-screen: conserva el flex del
   modal-content para que el body scrollee y el footer quede fijo abajo. */
.modal-form-flex { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.modal-form-flex .modal-body { overflow-y: auto; }


/* ======= NAVBAR calcado de gPay (05-ago): identico en todos los sistemas iGemas ======= */

/* --- Disparador de la paleta de comandos (Ctrl+K) ---
   No es un input de verdad: es un boton que lo aparenta, porque escribir pasa en el modal. */
.btn-paleta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 14rem;
  padding: 0.35rem 0.5rem 0.35rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  background-color: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.875rem;
  line-height: 1.5;
  transition: border-color .15s ease, background-color .15s ease;
}

.btn-paleta:hover {
  border-color: var(--bs-secondary-color);
  background-color: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

.btn-paleta:focus-visible {
  outline: 0;
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), .25);
}

.btn-paleta-txt { flex-grow: 1; text-align: left; }
.btn-paleta-kbd { display: inline-flex; gap: 0.15rem; }

.btn-paleta-kbd kbd {
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.25rem;
  background-color: var(--bs-body-bg);
  color: var(--bs-secondary-color);
  font-size: 0.7rem;
  line-height: 1.4;
}

/* Movil: sin teclado fisico el atajo sobra, asi que queda solo la lupa. */
@media (max-width: 767.98px) {
  .btn-paleta { min-width: 0; padding: 0.35rem 0.6rem; }
  .btn-paleta-txt,
  .btn-paleta-kbd { display: none; }
}

/* -- Perfil de usuario: avatar del navbar ------------------------------- */
/* Un solo juego de reglas para los dos tamanos: cambia el diametro y la tipografia escala. */
.perfil-avatar,
.perfil-avatar-lg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 50%;
    overflow: hidden;
    background: var(--bs-primary);
    color: var(--bs-white);
    font-weight: 700;
    line-height: 1;
    user-select: none;
}
.perfil-avatar img,
.perfil-avatar-lg img { width: 100%; height: 100%; object-fit: cover; }

.perfil-avatar { width: 2rem; height: 2rem; font-size: 0.8rem; }
.perfil-avatar-lg { width: 5rem; height: 5rem; font-size: 1.75rem; }

/* El boton del navbar no debe verse como boton: es el avatar y ya. */
.perfil-toggle { border: 0; background: none; padding: 0.125rem; line-height: 0; }
.perfil-toggle:focus-visible { outline: 0.125rem solid var(--bs-primary); outline-offset: 0.125rem; }
.perfil-toggle::after { display: none; }   /* fuera la flechita de Bootstrap */

.perfil-menu { min-width: 15rem; }
.perfil-menu .perfil-menu-head {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 1rem 0.75rem;
}
.perfil-menu .perfil-menu-nombre { font-weight: 600; line-height: 1.2; }
.perfil-menu .perfil-menu-sub {
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
    word-break: break-all;
}

/* -- Calculadora (teclado completo + conversion BCV) --------------------- */
/* position: fixed a proposito: flota sobre la pagina sin sacarte de lo que hacias. */
.calc-divisas {
    position: fixed;
    top: 3.75rem;
    right: 1rem;
    z-index: 1055;              /* por encima de los dropdowns de Bootstrap (1000) */
    width: 17.5rem;
    max-width: calc(100vw - 2rem);
    border-radius: 0.5rem;
    overflow: hidden;
    background: var(--bs-body-bg);
    border: 0.0625rem solid var(--bs-border-color);
    display: none;
}
.calc-divisas.abierta { display: block; }

.calc-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
    background: var(--bs-dark);
    color: var(--bs-light);
    font-weight: 600;
    font-size: 0.9rem;
}

/* La pantalla: tabular-nums para que los digitos no bailen al teclear. */
.calc-pantalla {
    padding: 0.75rem;
    text-align: right;
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    overflow-x: auto;
    white-space: nowrap;
}

.calc-monedas { display: flex; gap: 0.25rem; padding: 0 0.75rem 0.5rem; }
.calc-monedas button {
    flex: 1 1 0;
    padding: 0.25rem 0;
    border: 0.0625rem solid var(--bs-border-color);
    border-radius: 0.375rem;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    font-size: 0.8rem;
    font-weight: 600;
}
.calc-monedas button.activa { background: var(--bs-primary); border-color: var(--bs-primary); color: var(--bs-white); }

.calc-conv { padding: 0 0.75rem 0.5rem; }
.calc-out {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 0.1875rem 0;
    font-variant-numeric: tabular-nums;
}

/* El teclado: rejilla 4x5 de botones planos (este bloque no venia en el hilo de
   gPay; se escribio aqui siguiendo sus mismas convenciones rem + variables). */
.calc-teclado {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.25rem;
    padding: 0.5rem 0.75rem;
    border-top: 0.0625rem solid var(--bs-border-color);
}
.calc-teclado button {
    padding: 0.4rem 0;
    border: 0.0625rem solid var(--bs-border-color);
    border-radius: 0.375rem;
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    font-size: 1rem;
    font-variant-numeric: tabular-nums;
}
.calc-teclado button:hover { background: var(--bs-secondary-bg); }
.calc-teclado button.fn { background: var(--bs-tertiary-bg); color: var(--bs-secondary-color); }
.calc-teclado button.op { background: var(--bs-tertiary-bg); color: var(--bs-primary); font-weight: 600; }
.calc-teclado button.igual { background: var(--bs-primary); border-color: var(--bs-primary); color: var(--bs-white); font-weight: 600; }

.calc-tasas {
    padding: 0.375rem 0.75rem;
    border-top: 0.0625rem solid var(--bs-border-color);
    font-size: 0.7rem;
    color: var(--bs-secondary-color);
    text-align: center;
}

/* ═══ Tareas (todo.txt) — CSS CALCADO de gPay site.css L677-972 (b112cee), pasado
   por Jeffrey 11-ago. Solo variables Bootstrap: sirve en claro y oscuro. Se
   omitieron las secciones de avisos/política (sin backend en gEdu todavía). ═══ */
/* ── Tareas (todo.txt) ──────────────────────────────────────────────────────────────────────── */
.tarea {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    border: 0.0625rem solid var(--bs-border-color);
    border-radius: 0.5rem;
    background: var(--bs-body-bg);
    margin-bottom: 0.5rem;
}
.tarea:hover { border-color: var(--bs-primary); }
.tarea.hecha { opacity: 0.55; }
.tarea.hecha .tarea-texto { text-decoration: line-through; }
/* Solo un borde a la izquierda: teñir la fila entera de rojo grita demasiado en una lista larga. */
.tarea.vencida { border-left: 0.1875rem solid var(--bs-danger); }

.tarea-check {
    border: 0; background: none; padding: 0;
    font-size: 1.25rem; line-height: 1.2;
    color: var(--bs-secondary-color);
}
.tarea-check:hover { color: var(--bs-primary); }
.tarea.hecha .tarea-check { color: var(--bs-success); }

.tarea-cuerpo { flex: 1 1 auto; min-width: 0; }
.tarea-linea { display: flex; align-items: baseline; gap: 0.375rem; flex-wrap: wrap; }
.tarea-texto { word-break: break-word; }

/* Prioridad: A/B/C se distinguen por color, de D en adelante todas iguales — más matices
   no aportan y el usuario no los recuerda. */
.tarea-prio {
    flex: 0 0 auto;
    width: 1.25rem; height: 1.25rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 0.25rem;
    font-size: 0.7rem; font-weight: 700;
    background: var(--bs-secondary-bg); color: var(--bs-secondary-color);
}
.tarea-prio.prio-a { background: var(--bs-danger); color: var(--bs-white); }
.tarea-prio.prio-b { background: var(--bs-warning); color: var(--bs-dark); }
.tarea-prio.prio-c { background: var(--bs-info); color: var(--bs-dark); }

.tarea-meta { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.25rem; }
.chip {
    display: inline-flex; align-items: center;
    padding: 0.0625rem 0.4375rem;
    border-radius: 0.75rem;
    font-size: 0.7rem;
    background: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
    white-space: nowrap;
}
.chip-contexto { background: rgba(var(--bs-purple-rgb, 111, 66, 193), 0.15); color: var(--bs-purple); }
.chip-vencida  { background: rgba(var(--bs-danger-rgb), 0.15);  color: var(--bs-danger); font-weight: 600; }
.chip-hoy      { background: rgba(var(--bs-warning-rgb), 0.2);  color: var(--bs-warning-text-emphasis); font-weight: 600; }
.chip-rec      { background: rgba(var(--bs-success-rgb), 0.15); color: var(--bs-success); }

.tarea-acciones { display: flex; align-items: center; gap: 0.125rem; opacity: 0; }
.tarea:hover .tarea-acciones, .tarea:focus-within .tarea-acciones { opacity: 1; }
/* En táctil no hay hover: los botones tienen que estar siempre visibles. */
@media (hover: none) { .tarea-acciones { opacity: 1; } }

/* ── Modal de tareas: tres columnas (filtros · lista · detalles) ─────────────────────────────── */
.tareas-modal .modal-body { min-height: 74vh; }
.tareas-grid {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr) 18rem;
    min-height: 74vh;
}
/* Botón para desplegar los detalles. Solo existe en móvil: en escritorio son una columna fija. */
.tareas-mas { display: none; }

/* En móvil, una sola columna y en este orden: filtros (en fila), el botón de nueva tarea, el
   formulario si lo abres, y la lista. Antes se apilaban las dos barras enteras encima de la lista
   y había que pasar por ocho campos para llegar a lo que uno viene a ver. */
@media (max-width: 61.9375rem) {
    .tareas-grid {
        grid-template-columns: 1fr;
        /* Manda el alto del modal, que en móvil es de pantalla completa. */
        min-height: 0;
    }

    .tareas-grid .tareas-side {
        order: 0;
        flex-direction: row;
        align-items: center;
        overflow-x: auto;
        border-right: 0;
        border-bottom: 0.0625rem solid var(--bs-border-color);
        padding: 0.5rem;
    }
    /* La fila es la lista de filtros, no su contenedor: el botón de avisos va aparte, al final.
       El flex:0 0 auto es imprescindible — sin él la caja de filtros se encoge a cero y en la barra
       solo queda el botón de "Cuándo avisarme". */
    .tareas-side > div { display: flex; gap: 0.25rem; flex: 0 0 auto; }
    .tareas-side-item { width: auto; }
    .tareas-side-titulo { display: none; }

    .tareas-grid .tareas-mas {
        order: 1;
        display: flex;
        align-items: center;
        width: 100%;
        padding: 0.625rem 0.75rem;
        border: 0;
        border-bottom: 0.0625rem solid var(--bs-border-color);
        background: var(--bs-tertiary-bg);
        color: var(--bs-body-color);
        font-size: 0.9rem;
    }
    .tareas-grid.opciones-abiertas .tareas-mas .fa-chevron-down { transform: rotate(180deg); }

    .tareas-grid .tareas-nueva {
        order: 2;
        display: none;
        border-left: 0;
        border-bottom: 0.0625rem solid var(--bs-border-color);
    }
    .tareas-grid.opciones-abiertas .tareas-nueva { display: flex; }
    /* El botón que despliega ya dice "Nueva tarea"; repetirlo dentro sobra. */
    .tareas-nueva-titulo { display: none; }

    .tareas-grid .tareas-main { order: 3; min-height: 0; }
}

.tareas-side {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    padding: 0.75rem;
    border-right: 0.0625rem solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
}
.tareas-side-titulo {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin: 0.75rem 0 0.25rem 0.5rem;
}
.tareas-side-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.375rem 0.5rem;
    border: 0;
    border-radius: 0.375rem;
    background: none;
    color: var(--bs-body-color);
    font-size: 0.85rem;
    text-align: left;
    white-space: nowrap;
}
.tareas-side-item:hover { background: var(--bs-secondary-bg); }
.tareas-side-item.activo { background: var(--bs-primary); color: var(--bs-white); }
.tareas-side-item.activo .badge { background: rgba(255, 255, 255, 0.25) !important; }
.tareas-side-item > span:first-of-type { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.tareas-side-tag { font-family: var(--bs-font-monospace); font-size: 0.8rem; }

.tareas-main { display: flex; flex-direction: column; min-width: 0; }

/* Columna derecha: escribir una tarea, entera. El texto y sus campos son una sola acción, así que
   viven juntos; el centro se queda solo para mirar la lista. */
.tareas-nueva {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.75rem;
    overflow-y: auto;
    border-left: 0.0625rem solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
}
.tareas-nueva-titulo {
    font-size: 0.8rem;
    font-weight: 600;
    padding-bottom: 0.375rem;
    border-bottom: 0.0625rem solid var(--bs-border-color);
}
.tareas-nueva .campo { display: flex; flex-direction: column; gap: 0.125rem; }
.tareas-nueva textarea { resize: vertical; }
/* Pegado al fondo aunque el formulario sea corto: el botón de guardar, siempre en el mismo sitio. */
.tareas-nueva-pie {
    margin-top: auto;
    padding-top: 0.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* Chips editables: el input vive dentro de la caja y crece con lo que se escribe. */
.chips-input {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.375rem;
    min-height: 1.9375rem;
    border: 0.0625rem solid var(--bs-border-color);
    border-radius: 0.375rem;
    background: var(--bs-body-bg);
}
.chips-input input {
    flex: 1 1 4rem;
    min-width: 4rem;
    border: 0;
    outline: 0;
    background: none;
    color: inherit;
    font-size: 0.85rem;
}
.chips-input .chip button {
    border: 0; background: none; padding: 0 0 0 0.25rem;
    color: inherit; opacity: 0.6; line-height: 1;
}
.chips-input .chip button:hover { opacity: 1; }

.tareas-lista { flex: 1 1 auto; overflow-y: auto; padding: 0.75rem; }

.tareas-pie {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.625rem 0.75rem;
    border-top: 0.0625rem solid var(--bs-border-color);
}
.tareas-pie small { font-size: 0.7rem; }

/* Confirmación de borrado: capa dentro del modal de tareas, no un modal anidado. */
.tareas-confirmar {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.45);
}
.tareas-confirmar.d-none { display: none !important; }
.tareas-confirmar-caja {
    width: 22rem;
    max-width: 100%;
    padding: 1rem;
    border-radius: 0.5rem;
    background: var(--bs-body-bg);
    border: 0.0625rem solid var(--bs-border-color);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.25);
}
.tareas-confirmar-caja p { word-break: break-word; }


/* ═══ C2 (11-ago, Valeria): programación de campañas en CLARO + calendario espejo ═══
   El panel de repetición deja el tema oscuro (.panel-oscuro sigue vivo para el
   wizard de Automatización) y el mini calendario pinta los disparos del mes
   MIENTRAS se configura — feedback inmediato, cero sorpresas. */
.panel-claro {
    background: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: .75rem; padding: 1.25rem;
}
.panel-claro .lbl-mini { color: var(--bs-secondary-color); }
.panel-claro .chip-dia { background: var(--bs-body-bg); border-color: var(--bs-border-color); color: var(--bs-body-color); }
.panel-claro .chip-dia:hover { background: var(--bs-secondary-bg); color: var(--bs-body-color); }
.panel-claro .btn-check + .btn { background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); color: var(--bs-body-color); }
.panel-claro .btn-check + .btn:hover { background: var(--bs-secondary-bg); }
.panel-claro .btn-check:checked + .btn,
.panel-claro .btn-check:checked + .chip-dia {
    background: var(--gedu-acento); border-color: var(--gedu-acento);
    color: #1a1a1a; font-weight: 700;
}
.panel-claro hr { border-color: var(--bs-border-color) !important; opacity: 1; }
.panel-claro .text-secondary { color: var(--bs-secondary-color) !important; }

/* El calendario espejo: una rejilla mínima, los disparos en el amarillo de marca. */
.mini-cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; font-size: .72rem; text-align: center; }
.mini-cal span { padding: .25rem 0; border-radius: .3rem; }
.mini-cal .cal-cab { color: var(--bs-secondary-color); font-weight: 700; }
.mini-cal .cal-fuera { color: var(--bs-border-color); }
.mini-cal .cal-disparo { background: var(--gedu-acento); color: #1a1a1a; font-weight: 800; }
.mini-cal .cal-hoy { outline: 2px solid var(--bs-primary); outline-offset: -2px; }

/* Calendario de campañas clicable (11-ago, Valeria): al pasar por un día aparece un
   "+" fantasma y el clic abre el modal del día (programar ahí / ver / modificar). */
.cal-clicable { cursor: pointer; position: relative; }
.cal-clicable .cal-mas {
    position: absolute; right: .35rem; bottom: .2rem;
    opacity: 0; color: var(--bs-secondary-color);
    transition: opacity .15s; pointer-events: none;
}
.cal-clicable:hover .cal-mas { opacity: .65; }
.cal-clicable:hover { background: var(--bs-tertiary-bg); }
.cal-semana td { vertical-align: top; }

/* Vista SEMANA del calendario: las columnas llegan hasta el borde inferior de la
   pantalla aunque haya pocos disparos (11-ago, Valeria).
   Va con `td.` a propósito: `.cal-grid td` (el alto de 92px de la vista MES) es más
   específico que una clase suelta y dejaba la semana en 92px — el cuadro salía
   achatado en vez de llegar al final de la página (12-ago). */
.cal-grid td.cal-sem-dia { height: calc(100dvh - 22rem); min-height: 14rem; }
/* Vista DÍA: mismo alto de pantalla que la semana. */
.cal-dia-lleno { min-height: calc(100dvh - 22rem); }

/* Días que ya pasaron (12-ago, Valeria): no se puede programar en el pasado, así que
   la celda se ve apagada y no responde al clic. Lo que SÍ salió ese día se sigue
   leyendo — es historia, no se esconde. */
.cal-pasado {
    /* Rayado tenue: se distingue del día disponible incluso en modo oscuro, donde un
       simple cambio de fondo casi no se nota. */
    background: repeating-linear-gradient(45deg,
        transparent, transparent 6px,
        var(--bs-secondary-bg) 6px, var(--bs-secondary-bg) 12px);
    opacity: .5;
    cursor: default;
}
/* El "+" de "programar aquí" no existe en el pasado (la regla que lo escondía vivía
   en .cal-clicable, que estos días ya no llevan). */
.cal-pasado .cal-mas { display: none; }
.cal-pasado .cal-evento { pointer-events: auto; }  /* el disparo pasado aún se abre */

/* El "+" de "programar aquí" en la semana: más visible que en el mes (la celda es
   grande y vacía, y ahí el gesto no se adivina) y centrado en la columna. */
.cal-sem-dia .cal-mas {
    right: 50%; bottom: auto; top: 50%;
    transform: translate(50%, -50%);
    font-size: 1.5rem;
}
.cal-sem-dia:hover .cal-mas { opacity: .85; }

/* "Limpiar filtros" de la barra de tablas (19-ago, Valeria): cuando HAY filtro y se
   puede pulsar, se ve igual que sus vecinos (el .active de Bootstrap lo oscurecía);
   cuando NO hay nada que limpiar, en vez de lavarse con opacidad (se confundía con
   "activo") se ve unos tonos más oscuro que el resto de la barra. */
.btn-limpiar-sb.active,
.btn-limpiar-sb.active:focus {
    background-color: var(--bs-secondary);
    border-color: var(--bs-secondary);
}
.btn-limpiar-sb.disabled {
    opacity: 1;
    background-color: #495057;   /* gris 3 tonos más oscuro que #6c757d */
    border-color: #495057;
    color: rgba(255, 255, 255, .55);
}

/* --- Editor de campaña v2 (22-sep-2026, alternativa D: recetas + ajuste + asistente) ------
   Todo sobre variables de Bootstrap: el tema oscuro sale gratis. El acento es el de marca. */
.ed-campana .form-label { font-weight: 600; margin-bottom: .3rem; }
.ed-campana .form-text { margin-top: .25rem; }
/* Chips marcables (tipo, canal, destino, repetición): botón con borde; marcado = amarillo. */
.ed-campana .ed-chip { border: 1px solid var(--bs-border-color); background: var(--bs-tertiary-bg); color: var(--bs-body-color); border-radius: .55rem; }
.ed-campana .ed-chip:hover { background: var(--bs-secondary-bg); }
.ed-campana .btn-check:checked + .ed-chip, .ed-campana .ed-chip.activo { background: var(--gedu-acento); border-color: var(--gedu-acento); color: #1a1a1a; font-weight: 700; }
.ed-campana .ed-chip-grande { display: inline-flex; flex-direction: column; align-items: flex-start; text-align: left; min-width: 9rem; padding: .55rem .9rem; }
.ed-campana .ed-chip-grande small { font-weight: 500; color: var(--bs-secondary-color); }
.ed-campana .btn-check:checked + .ed-chip-grande small, .ed-campana .ed-chip-grande.activo small { color: #3d3100; }
/* Recetas: una tarjeta por campaña típica; toda la tarjeta es el botón. */
.ed-recetas { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; }
.ed-receta { display: grid; gap: .4rem; text-align: left; padding: 1.1rem; border-radius: .75rem; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); color: var(--bs-body-color); transition: border-color .15s, transform .15s, box-shadow .15s; }
.ed-receta:hover, .ed-receta:focus-visible { border-color: var(--gedu-acento); transform: translateY(-2px); box-shadow: 0 .35rem 1rem rgba(0,0,0,.12); }
.ed-receta-ico { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--gedu-acento); color: #1a1a1a; font-size: 1.2rem; }
/* Cabecera del ajuste y resumen lateral: la frase grande y los datos clave. */
.ed-cab { padding: 1rem 1.25rem; border: 1px solid var(--bs-border-color); border-radius: .75rem; background: var(--bs-tertiary-bg); }
.ed-frase { font-size: 1.25rem; font-weight: 700; line-height: 1.3; margin: 0 0 .75rem; }
.ed-frase-sm { font-size: 1rem; margin-bottom: .25rem; }
.ed-dato-grande { font-size: 2.2rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.ed-eti-marca { background: var(--gedu-acento); color: #1a1a1a; }
/* Dos columnas: lo editable a la izquierda, calendario + vista previa a la derecha. */
.ed-cols { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 1.1rem; align-items: start; margin-top: 1rem; }
/* 30-sep: una ranura cuyo bloque no muestra nada (el bloque oculto, o todo lo de adentro oculto:
   el selector de un público que no lo usa, los meses sin «morosas», las tarjetas con el árbol a la
   vista) no ocupa lugar: si no, cada una deja el hueco del vstack y el paso «Destinatarios» se pasaba. */
.ed-campana [data-slot]:has(> .ed-blk[hidden]),
.ed-campana [data-slot]:not(:has(> .ed-blk > :not([hidden]))) { display: none; }
@media (max-width: 1150px) { .ed-cols { grid-template-columns: minmax(0, 1fr); } }
.ed-cols.ed-cols-arriba { margin-top: 0; } /* Ajuste (30-sep): la cabecera va dentro de la columna izquierda */
/* Plegables: «Todos los detalles» y «Cómo se comporta». */
.ed-plegable > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .5rem; padding: .7rem .9rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .75rem; font-weight: 600; }
.ed-plegable > summary::-webkit-details-marker { display: none; }
.ed-plegable > summary:hover { background: var(--bs-secondary-bg); }
.ed-plegable[open] > summary { border-radius: .75rem .75rem 0 0; }
.ed-plegable-cuerpo { border: 1px solid var(--bs-border-color); border-top: 0; border-radius: 0 0 .75rem .75rem; padding: 1rem; }
/* Interruptores con su explicación al lado. */
.ed-switch { display: flex; gap: .75rem; align-items: flex-start; padding: .65rem .9rem; border: 1px solid var(--bs-border-color); border-radius: .55rem; background: var(--bs-tertiary-bg); cursor: pointer; margin: 0; }
/* Cuadritos: a quién le llega y a qué dato. */
.ed-cuadritos { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: .5rem; }
/* 23-sep (Valeria: «los cards de destinatarios están rotos»): se usaba min-w-0 (clase de
   Tailwind) y Bootstrap no la trae. Sin ella un hijo flex no se encoge y text-truncate no
   corta: el texto se salía de la tarjeta. Definida aquí sirve a todos los que la usan. */
.min-w-0 { min-width: 0 !important; }
.ed-cuadrito { overflow: hidden; }
.ed-cuadrito { display: flex; align-items: center; gap: .6rem; min-width: 0; padding: .5rem .7rem; border: 1px solid var(--bs-border-color); border-radius: .55rem; background: var(--bs-body-bg); }
.ed-cuadrito-mas { justify-content: center; border-style: dashed; color: var(--bs-secondary-color); font-size: .85rem; font-weight: 600; }
.ed-ini { width: 34px; height: 34px; border-radius: 50%; flex: none; display: grid; place-items: center; background: var(--bs-secondary-bg); font-size: .8rem; font-weight: 700; }
/* Vista previa del mensaje: correo como página, WhatsApp/SMS como burbuja; lo rellenado en amarillo. */
.ed-previa { border: 1px solid var(--bs-border-color); border-radius: .75rem; overflow: hidden; background: var(--bs-body-bg); }
.ed-previa-cab { display: flex; align-items: center; gap: .4rem; padding: .5rem .75rem; background: var(--bs-secondary-bg); border-bottom: 1px solid var(--bs-border-color); font-size: .85rem; font-weight: 600; }
.ed-previa-cuerpo { padding: .85rem 1rem; font-size: .9rem; line-height: 1.55; max-height: 22rem; overflow: auto; }
.ed-previa-cuerpo img { max-width: 100%; height: auto; }
.ed-burbuja { background: rgba(37, 211, 102, .15); border-radius: 12px 12px 12px 4px; padding: .7rem .85rem; white-space: pre-wrap; }
.ed-marcador { background: var(--gedu-acento); color: #1a1a1a; border-radius: 4px; padding: 0 .25rem; font-weight: 700; }
/* Pasos del asistente. */
.ed-pasos { display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; }
.ed-paso { display: inline-flex; align-items: center; gap: .5rem; font-size: .9rem; padding: .4rem .75rem; border-radius: 999px; background: none; border: 1px solid transparent; color: var(--bs-secondary-color); cursor: pointer; }
.ed-paso:hover { background: var(--bs-tertiary-bg); color: var(--bs-body-color); }
.ed-paso.activo { background: var(--bs-secondary-bg); color: var(--bs-body-color); font-weight: 700; }
.ed-paso-n { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--bs-secondary-bg); font-size: .8rem; font-weight: 700; }
.ed-paso.activo .ed-paso-n { background: var(--gedu-acento); color: #1a1a1a; }
.ed-paso.listo .ed-paso-n { background: var(--bs-success); color: #fff; }
.ed-paso-sep { width: 16px; height: 1px; background: var(--bs-border-color); }
/* Pie pegado al fondo del cuerpo del modal: el primario nunca sale de vista. */
.ed-pie { position: sticky; bottom: -1rem; z-index: 4; display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; padding: .85rem 1rem; margin: 1rem -1rem -1rem; border-top: 1px solid var(--bs-border-color); background: var(--bs-body-bg); }

/* --- Menús desplegables de la barra de tablas (embudo, columnas, exportar) (22-sep, #35) ---
   El panel del embudo crece con cada condición y con los selectores extra que se le
   inyectan; sin tope se salía por abajo de la pantalla. Tope al alto visible y scroll
   propio. */
div.dt-button-collection { max-height: 75vh; overflow-y: auto !important; }

/* ── Tom Select (#100, 23-sep): selección múltiple con chips ──────────────────
   El tema bootstrap5 trae colores fijos de fondo claro; aquí se pasan a las
   variables de Bootstrap para que siga al modo oscuro como el resto de campos. */
.ts-wrapper.form-select .ts-control,
.ts-wrapper .ts-control,
.ts-dropdown {
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    border-color: var(--bs-border-color);
}
.ts-wrapper .ts-control input { color: var(--bs-body-color); }
.ts-wrapper.multi .ts-control > .item {
    background: var(--bs-secondary-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
    border-radius: 1rem;
    padding: 1px 4px 1px 10px;
}
.ts-wrapper.plugin-remove_button .item .remove { border-left: 0; opacity: .7; }
.ts-wrapper.plugin-remove_button .item .remove:hover { opacity: 1; background: transparent; }
.ts-dropdown .active { background-color: var(--bs-primary-bg-subtle); color: var(--bs-body-color); }
.ts-dropdown .option, .ts-dropdown .no-results, .ts-dropdown .create { color: var(--bs-body-color); }
.ts-dropdown .ts-dropdown-content { max-height: 40vh; } /* mismo tope que select-buscable */

/* --- Vista ÁRBOL con casillas (29-sep, «Propuesta 2»; cobro dirigido) ------------------------
   Va montada en el modal a pantalla completa del cobro dirigido. Izquierda: el árbol, con su
   propio scroll; derecha: los datos del cobro y el panel con el total. Colores del tema. */
.cd-form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.cd-form > .modal-body { overflow: hidden; } /* scrollean el árbol y el panel, no el modal */
/* 29-sep: el cobro dirigido es una PESTAÑA. La caja nace altísima y data-llenar-alto la recorta a lo
   que queda del main: siempre el alto justo, aunque el árbol se despliegue (sin scroll de página ni hueco). */
.cd-tab { height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
.cd-tab .arbol-cuerpo { overflow: hidden; }
/* 29-sep: el botón solo icono de una tarjeta de cifras (Emisión automática).
   30-sep (Valeria): un poco más grande y el icono CENTRADO — cuadrado fijo y flex, en vez de un
   padding que dejaba el icono corrido. 2.25rem sigue cabiendo sin alargar la tarjeta. */
.tarjeta-botones .btn {
    width: 2.25rem; height: 2.25rem; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 1.05rem; line-height: 1;
}
.arbol-buscar { max-width: 22rem; }
.arbol-cuerpo {
    flex: 1; min-height: 0;
    display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(20rem, 1fr);
}
.arbol-izq { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--bs-border-color); }
.arbol-titulo { display: flex; align-items: baseline; gap: .5rem; padding: .75rem 1rem 0; }
.arbol-montaje { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.arbol-barra { display: flex; align-items: center; gap: .75rem; padding: .6rem 1rem .25rem; }
.arbol-ayuda { padding: 0 1rem .6rem; border-bottom: 1px solid var(--bs-border-color); }
.arbol-lista { flex: 1; min-height: 0; overflow: auto; padding: .5rem .75rem 1rem; }
.arbol-fila {
    display: flex; align-items: center; gap: .5rem; min-height: 2.25rem;
    padding: .15rem .5rem .15rem calc(.5rem + var(--prof, 0) * 1.6rem);
    border-radius: .375rem;
}
.arbol-fila:hover { background: var(--bs-tertiary-bg); }
.arbol-fila .form-check-input { width: 1.1rem; height: 1.1rem; flex: 0 0 auto; cursor: pointer; }
.arbol-fila .form-check-label { cursor: pointer; }
.arbol-fila small { margin-left: .25rem; }
.arbol-nivel { font-weight: 700; min-height: 2.6rem; }
.arbol-grado { font-weight: 600; }
.arbol-nivel.arbol-completa { background: var(--bs-primary-bg-subtle); } /* solo el nivel: con todo marcado no satura */
.arbol-flecha { width: 1.75rem; flex: 0 0 1.75rem; padding: 0; color: var(--bs-secondary-color); text-align: center; }
.arbol-panel {
    display: flex; flex-direction: column; gap: .75rem; min-height: 0; overflow: auto;
    padding: 1rem; background: var(--bs-tertiary-bg);
}
.arbol-total { font-size: 2rem; font-weight: 700; line-height: 1; }
/* 01-oct: Monto y Vence del cobro dirigido. auto-fit: van lado a lado si cada uno tiene sus 10.5rem (lo que
   pide una fecha con su calendario); si el panel es más angosto, se apilan. Mira el ancho del PANEL, no el
   de la ventana: por eso no es una columna de Bootstrap. */
.cd-monto-vence { display: grid; gap: .75rem 1rem; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); }
@media (max-width: 767.98px) {
    .arbol-cuerpo { grid-template-columns: 1fr; overflow: auto; }
    .arbol-izq { border-right: 0; min-height: 20rem; }
}
/* En el paso «Destinatarios» de las campañas (29-sep): el árbol va DENTRO del modal, en una caja
   de alto fijo (en un modal no hay «main» que llenar). 30-sep: solo el árbol, a todo lo ancho —el
   cuadro de totales repetía lo que ya dicen el resumen y la cabecera—; al pie, regla viva o lista fija. */
.ed-arbol {
    display: grid; grid-template-columns: minmax(0, 1fr);
    height: 22rem; margin-top: .75rem;
    border: 1px solid var(--bs-border-color); border-radius: .5rem; overflow: hidden;
}
.ed-arbol .arbol-izq { border-right: 0; }
.arbol-pie { padding: .45rem 1rem; border-top: 1px solid var(--bs-border-color); background: var(--bs-tertiary-bg); }
.ed-arbol .arbol-barra { flex-wrap: wrap; row-gap: .25rem; }
.ed-arbol .arbol-buscar { max-width: none; flex: 1 1 12rem; }
/* Cada fila en UNA línea: el detalle («6 grados · 25 estudiantes · todos») se recorta si no cabe. */
.ed-arbol .arbol-fila label { white-space: nowrap; }
.ed-arbol .arbol-fila small { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.ed-arbol .arbol-panel { padding: .75rem; gap: .5rem; }
.ed-arbol .arbol-total { font-size: 1.5rem; }
@media (max-width: 767.98px) { .ed-arbol { grid-template-columns: 1fr; height: auto; } }

/* 25-sep (Jeffrey «scroll en Horario»): la rejilla vive en una caja con scroll propio que llena
   el alto (data-llenar-alto); los días quedan fijos arriba al bajar por las franjas. */
.horario-caja thead th { position: sticky; top: 0; z-index: 3; background: var(--bs-body-bg); }
/* 03-nov: y la columna Hora queda fija al desplazar de lado, para no perder de vista a qué hora es cada clase. */
.horario-caja tr > :first-child { position: sticky; left: 0; z-index: 2; background: var(--bs-body-bg); }
.horario-caja thead tr > :first-child { z-index: 4; }

/* #110: los acordeones «Método de pago 1/2/3» de la caja con la cabecera azul de gCon. */
.accordion-gcon .accordion-button { background: #0b1a6e; color: #fff; font-size: 1.05rem; }
.accordion-gcon .accordion-button:not(.collapsed) { background: #0b1a6e; color: #fff; box-shadow: none; }
.accordion-gcon .accordion-button::after { filter: brightness(0) invert(1); }

/* 25-sep (Valeria): un formulario que debe ocupar TODO el main (sin hueco abajo aunque sea
   corto). Se marca la tarjeta con .llenar-main: el main se vuelve columna flexible y la
   tarjeta crece hasta el fondo; si no cabe, su .card-body desplaza por dentro. Solo en
   pantalla: al imprimir el main se suelta (regla de @media print de arriba). */
@media screen {
    #Inf_Wrap:has(> .llenar-main) { display: flex; flex-direction: column; }
    .llenar-main { flex: 1 1 auto; min-height: 0; }
    .llenar-main > .card-body { overflow-y: auto; }
    /* 29-sep (Valeria): una DataTable dentro de .llenar-main también llega al fondo: la caja
       de la tabla crece y el «Mostrando… / Sin registros» queda ABAJO, como en las listas
       largas (Usuarios), y no pegado a la tabla cuando hay pocas filas o ninguna. */
    .llenar-main > .card-body:has(> .dt-container) { display: flex; flex-direction: column; }
    .llenar-main > .card-body > .dt-container { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
    .llenar-main > .card-body > .dt-container > .dt-layout-table { flex: 1 1 auto; }
}
