/* =============================================================================
   te.componentes.css — las piezas que se repiten en MAS DE UNA pantalla.
   =============================================================================

   Se carga despues de te.tokens.css y te.base.css, y antes de las hojas de
   pantalla. La diferencia con las otras dos, para no acabar metiendo aqui de
   todo:

        te.tokens.css      el vocabulario: variables, y nada mas
        te.base.css        los elementos HTML de serie: body, input, table...
        te.componentes.css una pieza CON NOMBRE que sale en dos sitios o mas
        <hoja de pantalla> lo que solo pasa en una pantalla

   ⚠️ LA PRUEBA PARA ENTRAR AQUI: que la pieza este YA en dos sitios. No "va a
      estar". Si solo se usa en una pantalla, va en la hoja de esa pantalla, y el
      dia que aparezca la segunda copia se sube aqui y se borran las dos.

   ========================================================================== */

/* ── Boton de la cabecera ────────────────────────────────────────────────────
   El sol/luna y el de vista movil, en el login y en la cabecera de la
   aplicacion. Estaba escrito en styleLogin.css, o sea que la cabecera de la
   aplicacion no lo tenia: por eso no salia el boton de modo claro/oscuro una vez
   dentro. Es la pieza que estrena este fichero.

   Los iconos van dibujados EN LINEA y con currentColor: asi cambian de color
   solos con el modo, sin dos ficheros .svg que mantener ni un guion que cambie
   el src. El de vista movil era un SVG blanco y en modo claro no se veia. */
.btnCabecera {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: none;
    border-radius: var(--te-radio);
    color: var(--te-texto-suave);
    cursor: pointer;
    opacity: .8;
    transition: color .15s ease, background-color .15s ease, opacity .15s ease;
}

.btnCabecera:hover {
    color: var(--te-texto);
    background-color: var(--te-superficie);
    opacity: 1;
}

.btnCabecera:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--te-acento-foco);
}

/* El boton de tema lleva DENTRO los dos iconos, sol y luna, y te.tema.js ensena
   el que toca con el atributo [hidden]. Se hace asi -y no cambiando el trazado
   del SVG desde el guion- para que el icono correcto salga ya en el primer
   pintado, sin parpadeo, igual que el color del tema. */
.btnCabecera [hidden] {
    display: none;
}

/* ── Icono de accion ─────────────────────────────────────────────────────────
   El de la barra de mantenimiento y el de la cabecera. El trazado sale de
   clases/IconosSvg.cs; aqui esta TODO lo que se ve: color, tamano y hover.

   Antes cada icono eran TRES ficheros -normal, _over y _des- y dos atributos
   onmouseover/onmouseout que cambiaban el src. Cuarenta y ocho ficheros para
   dieciseis botones, y una peticion al servidor la primera vez que pasabas el
   raton por encima. Ahora el hover es una linea de CSS.

   ⚠️ El color sale de currentColor, y por eso no hay que tocar nada al cambiar de
      modo: los PNG eran blancos con transparencia y en modo claro NO SE VEIAN. */
.iconoTE {
    /* El tamaño lo pone la CLASE, no el atributo width= de cada <svg>. Asi
       "armonizar los iconos" es cambiar un numero, y no repasar cada llamada a
       IconosSvg.Svg(). Medido en la 1004 (Productos): 14 iconos a 20 y 4 a 19,
       que es la diferencia justa para que se note sin saber por que. */
    width: var(--te-tam-icono);
    height: var(--te-tam-icono);
    color: var(--te-texto-suave);
    cursor: pointer;
    vertical-align: middle;
    transition: color .15s ease;
}

.iconoTE:hover {
    color: var(--te-acento);
}

/* Apagado: ni color de aviso ni icono distinto, solo se aparta. Sustituye a los
   ficheros _des.png, que eran una tercera copia de cada dibujo. */
.iconoTE.desactivado {
    color: var(--te-borde);
    cursor: default;
    pointer-events: none;
}
/* Con contenido: las notas de la barra cuando la ficha TIENE notas o adjuntos. Era el notas_full.png, que
   desde que la barra es SVG no se ponía nunca (showInfoAttachFileForm, TouchExpress_Ajax.js). */
.iconoTE.conContenido {
    color: var(--te-acento);
}
/* Informativo: un icono que acompana a un dato y no hace nada al pulsarlo -el recuento
   de registros de la barra-. Sin mano ni hover, para que no prometa un clic. */
.iconoTE.informativo {
    cursor: default;
    pointer-events: none;
}

/* El separador entre botones de la barra. Era un PNG de 10x50 px repetido
   diecisiete veces: al lado de un icono de 20 px se veia enorme, y ademas era
   una imagen fija que en modo claro no cambiaba. */
.sepBarra {
    display: inline-block;
    width: 1px;
    height: 18px;
    margin: 0 var(--te-hueco-xs);
    background-color: var(--te-borde);
    vertical-align: middle;
}

/* El boton de mostrar menu nace oculto: lo ensena showMenu()/hideMenu() con jQuery,
   que escribe display en linea y por tanto gana a esta clase. Antes era un
   style="display:none" pegado a la etiqueta; ahora que el icono lo pinta
   IconosSvg.Svg() el estado inicial tiene que venir por clase. */
.ocultoInicial {
    display: none;
}

/* Los iconos NO se encogen. Van dentro de contenedores flex -la cabecera y la barra-
   y sin esto flex los aplasta cuando no caben: salian a 10 px de ancho por 19 de
   alto, o sea deformados, en vez de simplemente no caber. */
.iconoTE {
    flex: 0 0 auto;
}

/* ── La versión de catálogo de la base, en el pie ─────────────────────────────
   Dos estados y ninguno más: si la base está al día o por delante, es un dato y
   va como el resto del pie; si va por detrás, es lo único del pie que hay que
   mirar, y va en ámbar -el mismo que el aviso de "registro modificado", que es
   el color que esta interfaz usa para "esto pide atención"-.

   ⚠️ No es rojo a propósito. Una base por detrás del código NO es un error: es
      lo normal entre que el catálogo cambia y pasa el actualizador. Rojo diría
      "algo está roto" y haría que se dejara de mirar a los dos días. */
.versionBBDD {
    margin-left: var(--te-hueco-m);
    color: var(--te-texto-suave);
}

.versionBBDDAtrasada {
    margin-left: var(--te-hueco-m);
    color: var(--te-aviso);
    font-weight: var(--te-peso-fuerte);
}

/* ── LA ESPERA DE TODA LA WEB (te.espera.js, VisualizarModalProgress) ──────────────────────────
   José, 07/10/2026: la ruleta de la página de espera de las publicaciones, «para toda la web». La capa la crea la función
   (no hay HTML de la espera en ninguna página). Bloquea los clics AL INSTANTE, pero sólo se deja VER si la operación dura
   más de --te-espera-aviso: la animación, de duración cero y con retardo, mantiene la opacidad a 0 hasta entonces (como
   hacía el «Actualizando datos» de antes). Al quitarla (display:none) la animación se reinicia sola. */
.teEspera {
    position: fixed; inset: 0; z-index: 99999;
    display: none; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--te-fondo) 72%, transparent);
    /* Es un popover (para salir encima de un <dialog> modal): fuera lo que el navegador le pone a uno. */
    width: auto; height: auto; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; color: inherit; overflow: hidden;
}
.teEspera.activa { display: flex; animation: te-espera-aparece 0s linear var(--te-espera-aviso) both; }
@keyframes te-espera-aparece { from { opacity: 0; } to { opacity: 1; } }
.teEsperaCaja {
    display: flex; flex-direction: column; align-items: center; gap: 14px;
    padding: 26px 34px 22px; border-radius: 16px;
    background: var(--te-superficie); border: 1px solid var(--te-borde);
    box-shadow: 0 18px 50px -20px rgba(0, 0, 0, .5);
}
.teEsperaTexto { margin: 0; color: var(--te-texto-suave); font-size: .95rem; font-weight: 500; text-align: center; max-width: 30ch; }

/* La ruleta: la M en el centro, respirando; el arco con el degradado del logo, que gira y se estira; un anillo de
   puntos que gira despacio y un arco corto que gira al revés. La misma que Publicar/app_offline.htm. */
.teRuleta { position: relative; display: inline-block; width: var(--te-ruleta, 112px); height: var(--te-ruleta, 112px); }
.teRuletaHalo { position: absolute; inset: 14%; border-radius: 50%; background: radial-gradient(circle, var(--te-acento-foco), transparent 70%); animation: te-ruleta-halo 3.2s ease-in-out infinite; }
.teRuletaSvg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.teRuletaSvg circle { fill: none; }
.teRuletaPista { stroke: var(--te-borde); stroke-width: 2; opacity: .8; }
.teRuletaPuntos { stroke: var(--te-acento); stroke-width: 3.2; stroke-linecap: round; stroke-dasharray: 0 15.92; opacity: .5; }
.teRuletaArco { stroke: url(#teRuletaDegradado); stroke-width: 6; stroke-linecap: round; stroke-dasharray: 1 566; animation: te-ruleta-estira 1.7s ease-in-out infinite; }
.teRuletaArco2 { stroke: var(--te-acento-vivo); stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 64 326; opacity: .75; }
.teRuletaGira, .teRuletaGiraLenta, .teRuletaGiraReves { transform-box: fill-box; transform-origin: center; }
.teRuletaGira { animation: te-ruleta-gira 2s linear infinite; }
.teRuletaGiraLenta { animation: te-ruleta-gira 26s linear infinite; }
.teRuletaGiraReves { animation: te-ruleta-gira 3.4s linear infinite reverse; }
.teRuletaM { position: absolute; left: 50%; top: 50%; width: 42%; height: auto; transform: translate(-50%, -50%);
             filter: drop-shadow(0 6px 16px rgba(79, 147, 184, .35)); animation: te-ruleta-respira 3.2s ease-in-out infinite; }
@keyframes te-ruleta-gira { to { transform: rotate(360deg); } }
@keyframes te-ruleta-estira {
    0%   { stroke-dasharray: 1 566;   stroke-dashoffset: 0; }
    50%  { stroke-dasharray: 280 566; stroke-dashoffset: -70; }
    100% { stroke-dasharray: 280 566; stroke-dashoffset: -565; }
}
@keyframes te-ruleta-respira { 50% { transform: translate(-50%, -50%) scale(.93); } }
@keyframes te-ruleta-halo { 50% { transform: scale(1.18); opacity: .6; } }
/* Los listados: el «Cargando…» de cada rejilla jqGrid (#load_<id>, y #lui_<id> encima de las filas) lleva la ruleta:
   te.espera.js le cambia el loadtext. jqGrid lo enseña con display:block y lo quita con display:none, así que vale el
   mismo retardo que la capa. Con la especificidad alta a propósito: ui.jqgrid.css y el tema de jQuery UI
   (.ui-widget-content .ui-state-active) se cargan después en algunas páginas. */
.ui-jqgrid div.loading.ui-state-active {
    left: 50%; top: 50%; transform: translate(-50%, -50%);
    margin: 0; padding: 14px 22px 12px; border-radius: 14px;
    border: 1px solid var(--te-borde) !important; background: var(--te-superficie) !important;
    color: var(--te-texto-suave) !important; font-weight: 500; font-size: .85rem;
    box-shadow: 0 12px 34px -16px rgba(0, 0, 0, .5);
    animation: te-espera-aparece 0s linear var(--te-espera-aviso) both;
}
.ui-jqgrid div.jqgrid-overlay {
    background: color-mix(in srgb, var(--te-fondo) 60%, transparent); opacity: 1;
    animation: te-espera-aparece 0s linear var(--te-espera-aviso) both;
}
/* La misma ruleta DENTRO de una lista o un panel (TE.esperaLista): en el sitio de lo que se carga, con el mismo retardo,
   y ocupando la fila entera si el sitio es una rejilla de cards. */
.teEsperaLista {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
    --te-ruleta: 64px; padding: 12px 0; grid-column: 1 / -1; flex: 1 1 100%;
    animation: te-espera-aparece 0s linear var(--te-espera-aviso) both;
}
.teEsperaLista .teEsperaTexto { font-size: .85rem; }
.ui-jqgrid div.loading .teEsperaLista { padding: 0; animation: none; }

@media (prefers-reduced-motion: reduce) {
    .teRuletaHalo, .teRuletaM, .teRuletaGiraLenta { animation: none; }
    .teRuletaGira { animation-duration: 6s; } .teRuletaGiraReves { animation-duration: 9s; }
    .teRuletaArco { animation: none; stroke-dasharray: 150 566; }
}

/* ── Dialogos de pregunta, informacion y aviso ─────────────────────────────────────────────────
   Components/_MessageQuestion, _MessageInformation, _MessageWarning y _MsgQstnCloneForm.
   No tenian NI UNA LINEA de estilo: se pintaban como un bloque mas, a todo el ancho, sin fondo y
   al pie de la pagina (el "+" de cargar inventariables de la 3007: 1231x112 px en y=761). Ahora son
   una ventana: velo sobre la pagina y tarjeta centrada. Lo usa tambien la lista de plantillas. */
.divModalMessage {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(0, 0, 0, .45);
}

.divModalMessageContent {
    width: min(460px, 100%);
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px 18px 14px;
    background: var(--te-superficie);
    color: var(--te-texto);
    border: 1px solid var(--te-borde);
    border-radius: var(--te-radio);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .35);
    box-sizing: border-box;
}

.divModalMessageHeader {
    display: flex;
    align-items: center;
    gap: 10px;
}

.imgModalMessage {
    width: 28px;
    height: 28px;
    flex: none;
    object-fit: contain;
}

.lblModalMessageTitle {
    font-size: var(--te-tam-mayor);
    font-weight: 600;
    color: var(--te-acento);
}

.divModalMessageBody {
    font-size: var(--te-tam-base);
    line-height: 1.45;
    overflow-y: auto;
}

.divModalMessageFooter {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* el separador de 20 px que traian del 4.8: el hueco ya lo pone el gap */
.divModalMessageFooter > div { display: none; }

.divModalMessageFooter button {
    min-width: 96px;
    height: 30px;
    padding: 0 14px;
    font-size: var(--te-tam-base);
    border: 1px solid var(--te-borde-fuerte);
    border-radius: var(--te-radio-corto);
    background: var(--te-superficie);
    color: var(--te-texto);
    cursor: pointer;
}

.divModalMessageFooter button:hover {
    border-color: var(--te-acento);
    color: var(--te-acento);
}

/* el ultimo boton es el que hace la accion ("Si", "Aceptar"); los secundarios lo dicen */
.divModalMessageFooter button:last-child:not(.te-secundario) {
    background: var(--te-acento);
    border-color: var(--te-acento);
    color: var(--te-sobre-acento);
}

.divModalMessageFooter button:focus-visible,
.teListaPlantillas button:focus-visible {
    outline: 2px solid var(--te-acento);
    outline-offset: 2px;
}

/* ── Lista de plantillas (boton "Cargar plantilla" de la barra de la rejilla) ─────────────────── */
.teListaPlantillasFiltro {
    width: 100%;
    height: 30px;
    margin-bottom: 8px;
    padding: 0 8px;
    box-sizing: border-box;
    font-size: var(--te-tam-base);
    border: 1px solid var(--te-borde-fuerte);
    border-radius: var(--te-radio-corto);
    background: var(--te-fondo);
    color: var(--te-texto);
}

.teListaPlantillas {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 50vh;
    overflow-y: auto;
    border: 1px solid var(--te-borde);
    border-radius: var(--te-radio-corto);
}

.teListaPlantillas li[hidden] { display: none; }

.teListaPlantillas button {
    width: 100%;
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    text-align: left;
    font-size: var(--te-tam-base);
    border: 0;
    border-bottom: 1px solid var(--te-borde);
    background: transparent;
    color: var(--te-texto);
    cursor: pointer;
}

.teListaPlantillas li:last-child button { border-bottom: 0; }

.teListaPlantillas button:hover { background: var(--te-acento-suave); }

.teListaPlantillasCodigo {
    color: var(--te-texto-suave);
    font-variant-numeric: tabular-nums;
}

/* ── Botón de texto y botón de sólo icono ─────────────────────────────────────────────────────
   La pieza estaba TRES veces con tres nombres: .apBoton (4051 Aprovisionamiento), .cwBoton / .cwBtnIcono
   (4034 y 4040, el editor de configuración) y la de la 4003 (Cambio de contraseña). José, 24/09/2026: «pasa
   la 4051 y la 4034 al botón común». Ahora es ésta y las otras se han borrado. Vale igual para <button>
   que para <a>.
   El alto es el de --te-alto-control («alto común de campos y botones»): un botón al lado de un campo
   queda a su altura. Las copias iban a 28, 30 y 34 px.

     .teBoton                 el de siempre: borde y fondo de superficie
     .teBoton.tePrimario      la acción principal, en el acento
     .teBoton.teSuave         secundario sin borde («Cancelar», «Formatear»)
     .teBotonIcono            sólo icono; .tePeligro se pone rojo al pasar (papelera)
     .teBotonIcono.hecho      copiar/pegar salió bien; .fallo, no. Con color, no con texto. */
.teBoton,
.teBoton:link,
.teBoton:visited {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--te-hueco-xs);
    height: var(--te-alto-control);
    padding: 0 var(--te-hueco-m);
    border: 1px solid var(--te-borde-fuerte);
    border-radius: var(--te-radio);
    background: var(--te-superficie);
    color: var(--te-texto);
    font: inherit;
    font-size: var(--te-tam-base);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.teBoton:hover:not(:disabled) { border-color: var(--te-acento); }
.teBoton:disabled { opacity: .5; cursor: default; }
.teBoton .iconoTE { color: currentColor; cursor: inherit; }
.teBoton.tePrimario { border-color: var(--te-acento); background: var(--te-acento); color: var(--te-sobre-acento); font-weight: var(--te-peso-fuerte); }
.teBoton.tePrimario:hover:not(:disabled) { border-color: var(--te-acento-vivo); background: var(--te-acento-vivo); }
.teBoton.teSuave { border-color: transparent; background: transparent; color: var(--te-texto-suave); }
.teBoton.teSuave:hover:not(:disabled) { border-color: transparent; background: var(--te-superficie-2); color: var(--te-texto); }
/* Un botón trabajando ya no lleva su rueda (.teBoton.cargando, hasta el 07/10/2026): se desactiva y la espera es la de
   toda la web, VisualizarModalProgress (te.espera.js). */

.teBotonIcono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: var(--te-radio-corto);
    background: transparent;
    color: var(--te-texto-suave);
    cursor: pointer;
}

.teBotonIcono:hover:not(:disabled) { background: var(--te-superficie-2); color: var(--te-texto); }
.teBotonIcono.tePeligro:hover:not(:disabled) { color: var(--te-error); }
.teBotonIcono:disabled { opacity: .45; cursor: default; }
/* Apagados por CLASE, no por atributo: hay JavaScript del 4.8 que enciende y apaga con add/removeClass('disabled')
   (el «Pegar» de los perfiles, _CorporateProfileGrid). */
:is(.teBoton, .teBotonIcono).disabled { opacity: .45; cursor: default; pointer-events: none; }
/* La barra de los perfiles corporativos (_CorporateProfileGrid, en 14 pantallas): copiar, pegar y su aviso. */
.cpfBarra { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
    .cpfBarra > span { color: var(--te-texto-suave); font-size: var(--te-tam-menor); }
.teBotonIcono .iconoTE { color: inherit; }
.teBotonIcono.hecho { color: var(--te-ok); background: var(--te-ok-fondo); }
.teBotonIcono.fallo { color: var(--te-aviso); background: var(--te-aviso-fondo); }

/* ── LA casilla: la pastilla, para TODA la web ───────────────────────────────────────────────────
   José, 27/09/2026: «en todos sitios: check tipo pastilla [...] TODAS, TODAS EN EL MISMO SITIO». Es la
   pastilla «Impuestos» de la 6078 (Ventas hotel). Había seis casillas distintas —la nativa, la de KUENKA,
   la de tres estados con imágenes, el DIV de las rejillas, la imagen del árbol corporativo y el
   interruptor del programador— y ahora hay ésta:

       <label class="teCasilla"><input type="checkbox" ...><span>Texto</span></label>

   NO SE ESCRIBE A MANO: la pintan Casilla.Html() / Casilla.TresEstados() (clases/Casilla.cs) y
   TE.casilla() (js/te.casilla.js), que dan el mismo marcado. Sigue siendo el <input> nativo, escondido
   dentro: tecla espacio, foco, lector de pantalla.

       apagada     borde y fondo de superficie; el hueco del icono se guarda para que no baile al pulsar
       encendida   borde, texto y marca en el acento, fondo suave            (input:checked)
       tercera     fondo gris y un guion: «ni sí ni no»                       (data-estado="2" o :indeterminate)
       sin texto   la pastilla del icono solo, para una celda de rejilla

   El icono sale del almacén por máscara (/icono/marcado.svg y /icono/menos.svg): el marcado no lleva SVG. */
.teCasilla {
    position: relative; display: inline-flex; align-items: center; gap: 6px; flex: none;
    white-space: nowrap; cursor: pointer; user-select: none; vertical-align: middle;
    border: 1px solid var(--te-borde); border-radius: 999px; padding: 4px 12px 4px 8px;
    background: var(--te-superficie); color: var(--te-texto); font: inherit; line-height: 1.25;
}
.teCasilla::before {
    content: ""; flex: none; width: 16px; height: 16px; background: currentColor; opacity: 0;
    -webkit-mask: url(../icono/marcado.svg) no-repeat center / contain;
    mask: url(../icono/marcado.svg) no-repeat center / contain;
}
.teCasilla:not(:has(> span)) { padding: 3px 7px; }
/* (!) Con el tipo delante: te.base.css pinta input[type="checkbox"] con la misma especificidad. La de
   RADIO (Casilla.Opcion, TE.casilla({radio})) es la misma pastilla: se elige una del grupo. */
.teCasilla > input:is([type="checkbox"], [type="radio"]) {
    position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none;
}
.teCasilla:not(:has(> input:disabled)):hover { border-color: var(--te-borde-fuerte); }
.teCasilla:has(> input:checked) { border-color: var(--te-acento); color: var(--te-acento); background: var(--te-acento-suave); }
.teCasilla:has(> input:checked)::before { opacity: 1; }
.teCasilla:has(> input[data-estado="2"]),
.teCasilla:has(> input:indeterminate) { border-color: var(--te-borde-fuerte); background: var(--te-superficie-2); }
.teCasilla:has(> input[data-estado="2"])::before,
.teCasilla:has(> input:indeterminate)::before {
    opacity: 1; -webkit-mask-image: url(../icono/menos.svg); mask-image: url(../icono/menos.svg);
}
/* «No activo» (CH_NOACTIVO) marcada: en ROJO, que se vea que el registro está retirado. José, 27/09/2026:
   «si sabes que la pastilla corresponde al campo CH_NOACTIVO podrías hacer que al marcarlo la tinta fuese
   roja». En las fichas la clase la pone el motor (el campo lo dice el XML); en una rejilla, su formatter. */
.teCasilla.teCasillaNoActivo:has(> input:checked) { border-color: var(--te-error); color: var(--te-error); background: var(--te-error-fondo); }
.teCasilla:has(> input:focus-visible) { outline: 2px solid var(--te-acento); outline-offset: 2px; }
.teCasilla:has(> input:disabled) { opacity: .5; cursor: default; }
/* SÓLO VER (clase teCasillaSoloVer): la casilla que ENSEÑA un dato que se decide en otro sitio, como la «Receta» de
   la 1004 (Productos), que se marca sola al guardar los ingredientes en la 1027. Va deshabilitada pero no desvaída:
   es un dato, no un control apagado, y marcada se pinta como cualquier marcada. José, 06/10/2026. */
.teCasilla.teCasillaSoloVer:has(> input:disabled) { opacity: 1; }
/* (!) El inline-flex de arriba gana al [hidden]{display:none} del navegador, que pesa menos: sin esto
   una pastilla con hidden NO se esconde (MONO2, 27/09/2026, en el diálogo de supervisar pedido). */
.teCasilla[hidden] { display: none; }
/* Un grupo de pastillas seguidas (las opciones de un radio, varias casillas en fila). */
.teCasillas { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* ── TODA rejilla jqGrid, SIN la cuadrícula del tema jQuery UI de 2010 ─────────────────────────────────────
   José, 24/09/2026, de la 4010 (Revisión de precios): «se ve feo y viejo, sobre todo los recuadros de la
   PUTA GRILLA» y «descuadrado»; «lo mismo en el 1004» (Productos); y viéndola hecha: «esta grilla es mucho
   más bonita que las otras, ¿no le podemos dar a las otras este aspecto?». Cada celda iba enmarcada, los
   títulos centrados encima de números alineados a la derecha y las casillas pegadas arriba. Ahora, en todas:
   una raya fina entre filas y ninguna entre columnas, el alto de fila de las fichas nuevas, las casillas en
   medio y los campos de las celdas sin marco hasta que se pasa o se escribe.
   La alineación de cada TÍTULO la pone el JavaScript, igual que la de su columna (jqGrid no lo hace):
   te.jquery.jqGridXml.js y la 1004. jqGrid se queda hasta 2027; esto es sólo su aspecto.
   ⚠️ LOS ANCHOS LOS CALCULA jqGrid y aquí NO se tocan: descuenta 5 px por celda (2 + 2 de relleno y 1 de borde,
      su «cellLayout»), así que el relleno se queda en 2 px y la caja en la de siempre. Con más relleno o con
      box-sizing: border-box las columnas estrechas pierden el dato (el IVA de las líneas de la 2001, 45 px:
      «13,00» salía «13,0»). Lo nuevo es sólo lo que se VE: bordes, cabecera, alto, resaltado. Una pantalla de
      columnas anchas puede dar más aire en su hoja, poniéndolo igual en th y td (la 4010). */
.ui-jqgrid {
    border: 1px solid var(--te-borde); border-radius: var(--te-radio);
    background: var(--te-superficie); overflow: hidden; font-family: var(--te-tipo);
}
.ui-jqgrid .ui-jqgrid-hdiv { background: var(--te-superficie-2); border: 0; border-bottom: 1px solid var(--te-borde); }
.ui-jqgrid .ui-jqgrid-htable th,
.ui-jqgrid .ui-jqgrid-btable td {
    border-left: 0; border-top: 0;
    border-right: 1px solid transparent;
}
.ui-jqgrid .ui-jqgrid-htable th {
    height: 32px; padding: 0 2px; text-align: left;
    background: transparent; background-image: none; border-bottom: 0;
    color: var(--te-texto-suave); font-size: var(--te-tam-menor); font-weight: var(--te-peso-fuerte);
}
.ui-jqgrid .ui-jqgrid-htable th div { height: auto; }
.ui-jqgrid .ui-jqgrid-htable th .ui-jqgrid-resize { background: transparent; }
.ui-jqgrid .ui-jqgrid-bdiv { background: var(--te-superficie); }
/* SIN RAYAS ENTRE FILAS, y la fila en la que se está, marcada. José, 28/09/2026, vistas pintadas HOY y SIN RAYAS
   sobre la 3002 (Notas de entrega), la 2001 (Facturas de venta) y la 1032 (Grupos de menú): «rejillas sin rayas
   horizontales, y que se vea la línea donde estamos».
   ⚠️ LA RAYA LA PINTAN DOS: la celda (aquí) y la FILA, con el «border: 1px solid» de ui.jqgrid.css:32, que va detrás
      de esta hoja. Quitando sólo la de la celda, la de la fila seguía saliendo. La regla de la fila lleva
      .ui-jqgrid-btable para pesar más que la suya. El borde se queda en 1 px TRANSPARENTE: así el alto de cada fila
      no cambia y jqGrid no descuadra nada.
   «Donde estamos» es la fila seleccionada (ui-state-highlight) o la que tiene el foco dentro (:focus-within: la
   que se está editando, o a la que se llega con Tab o las flechas). Lleva el tinte del acento y una barra del
   acento a la izquierda. Pasar el ratón por encima es otra cosa, sólo un gris, para que no se confundan. */
.ui-jqgrid .ui-jqgrid-btable tr.jqgrow td {
    height: 30px; padding: 0 2px; vertical-align: middle;
    background: transparent; color: var(--te-texto);
    border-bottom: 1px solid transparent;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ui-jqgrid .ui-jqgrid-btable tr.jqgrow { border-bottom-color: transparent; }
.ui-jqgrid tr.jqgrow { background: transparent; }
.ui-jqgrid tr.jqgrow:hover > td,
.ui-jqgrid tr.jqgrow.ui-state-hover > td { background: var(--te-superficie-2); }
.ui-jqgrid tr.jqgrow.ui-state-highlight,
.ui-jqgrid tr.jqgrow.ui-state-highlight > td,
.ui-jqgrid tr.jqgrow:focus-within > td {
    background: var(--te-acento-suave); background-image: none; border-color: transparent; color: var(--te-texto);
}
.ui-jqgrid tr.jqgrow.ui-state-highlight > td:first-child,
.ui-jqgrid tr.jqgrow:focus-within > td:first-child { box-shadow: inset 3px 0 0 var(--te-acento); }
.ui-jqgrid tr.jqgrow td input[type="checkbox"] {
    width: var(--te-tam-casilla); height: var(--te-tam-casilla); margin: 0; vertical-align: middle;
}
/* El campo de una fila en edición (jqGrid): ocupa la celda, con el borde del acento. */
.ui-jqgrid tr.jqgrow td input.editable {
    box-sizing: border-box; width: 100% !important; height: 26px; padding: 0 6px;
    border: 1px solid var(--te-acento); border-radius: var(--te-radio-corto);
    background: var(--te-fondo); color: var(--te-texto); font: inherit;
}
.ui-jqgrid tr.jqgrow td[style*="right"] input.editable { text-align: right; }
/* El campo que va SIEMPRE en la celda (formatterTextboxFieldGrid de la 1004, y los de compras: texto, fecha y
   desplegable): sin marco ni fondo, como texto, hasta que se pasa por encima o se escribe. Una columna de cuadros
   vacíos era justo «los recuadros». Y de ALTO, la fila menos 2 px arriba y abajo: José, 24/09/2026, con la 3002
   delante, «los TextBox de las líneas siguen siendo pequeños, tienen un margen de la línea pequeño y con color de
   fondo» (medían 21 px en una fila de 30).
   (!) Ni ancho, ni relleno, ni letra: hay columnas de 45 px -el IVA de las líneas de la 2001- con el dato DENTRO
       del campo, y con más relleno o la letra de la celda «13,00» salía «13,».
   (!) El «:not(#_)» NO es un error: sube la regla al peso de un id. La regla base de los campos (te.base.css)
       quiere ir con el peso más bajo, pero sus ocho :not([type=...]) le dan el de ocho clases, y así su fondo
       le ganaba a éste: en la fila seleccionada cada campo salía como una caja oscura. */
.ui-jqgrid tr.jqgrow td :is(input.tbFieldGrid, input.tbFieldDateGrid, select.ddlFieldGrid):not(#_) {
    height: 26px;
    border: 1px solid transparent; border-radius: var(--te-radio-corto);
    background: transparent; color: var(--te-texto);
}
.ui-jqgrid tr.jqgrow td :is(input.tbFieldGrid, input.tbFieldDateGrid, select.ddlFieldGrid):not(#_):hover { border-color: var(--te-borde-fuerte); }
.ui-jqgrid tr.jqgrow td :is(input.tbFieldGrid, input.tbFieldDateGrid, select.ddlFieldGrid):not(#_):focus {
    outline: none; border-color: var(--te-acento); background: var(--te-fondo); box-shadow: 0 0 0 3px var(--te-acento-foco);
}
/* El desplegable de una celda, del ancho de SU columna: styleMain.css lo fija en 80 px y va centrado, así que en
   una columna más estrecha asomaba sólo su mitad (el T.IVA de las líneas de la 3003, 70 px: «A 4%»). */
.ui-jqgrid tr.jqgrow td select.ddlFieldGrid { width: 100%; min-width: 0; max-width: 100%; }
/* El que no se puede escribir (las UxC de un formato en unidades): sin la caja gris de antes, pero se sigue
   notando, en letra suave y sin marco al pasar. (Un select siempre casa con :read-only: por eso va :disabled.) */
.ui-jqgrid tr.jqgrow td :is(input.tbFieldGrid, input.tbFieldDateGrid):not(#_):read-only,
.ui-jqgrid tr.jqgrow td select.ddlFieldGrid:not(#_):disabled { color: var(--te-texto-suave); border-color: transparent; }
/* Las celdas «de formulario» de compras (te.3001 a te.3016) y de los formateadores comunes (te.jquery.jqGrid.js):
   cada una lleva su campo, y el estilo v19 lo pega ARRIBA (.divCellGrid con align-items: flex-start y
   .divlblFieldGrid con 3 px de relleno arriba). Con la fila de 24 px no se notaba; con la de 30 el texto quedaba
   arriba y el importe más abajo, en su cajita. José, 24/09/2026, con la 3002 (Notas de entrega de compra)
   delante. Todo al medio, y lo que no se escribe (el importe, el alias) sin caja: lo distingue el color, como
   en la 4010. Las cajas con significado (pedido interno, error, azul, naranja) se quedan como estaban. */
.ui-jqgrid tr.jqgrow td .divCellGrid { align-items: center; }
.ui-jqgrid tr.jqgrow td .divlblFieldGrid { height: auto; padding-top: 0; }
.ui-jqgrid tr.jqgrow td input.lblFieldGrid { height: 26px; }

/* ── Los colores CON SIGNIFICADO de las celdas: UN SOLO SITIO ────────────────────────────────
   José, 27/09/2026: «colores de significado en rejillas: hacer regla general ÚNICA para modificar en un solo
   sitio». Hasta hoy cada color estaba escrito en cuatro hojas (styleMain.css, TEWebNewStyle.css,
   TouchExpressStyle.css y aquí), una regla por tipo de campo, y la regla base de los campos se comía el de los
   que se escriben (el verde del Punto verde no se veía).
   - QUÉ color lleva cada clase: los --te-rejilla-* de aquí abajo. Cambiar uno es cambiar UNA línea.
   - CÓMO se pinta: una regla por significado para TODOS los campos de celda (lblFieldGrid, divlblFieldGrid,
     tbFieldGrid, tbFieldDateGrid, ddlFieldGrid y las casillas y radios de celda).
   El color va en la LETRA, sin caja (José, 24/09/2026: las cajitas eran «recuadros» dentro de la rejilla). La
   única con caja es la de error, que tiene que saltar a la vista.
   Las clases y lo que marcan hoy:
     verde                 la columna «P.Verde» de compras (3001-3003) y las cajas de la 3007 (Inventarios)
     azul, violeta         las bolsas y las unidades de la 3007
     morado                las unidades por caja y por bolsa de la 3007
     naranja               los stocks (origen, destino, mínimo) de la 3006 (Traspasos) y la 3007
     gris, pedidoInterno   lo que se ve y no se escribe (el IVA de la 3003, el alias, el stock y la UxC de los
                           pedidos internos 3013-3016)
     blanco                nada: un campo normal
     fieldError            el dato no vale (setCellErrorGrid / setRowErrorGrid)
   (!) El «:is(.ui-jqgrid tr.jqgrow td, body)» no es adorno: dentro de una rejilla pesa lo bastante para ganar a
       las reglas de sus campos (sin marco ni fondo, más arriba), y fuera sigue valiendo. El «:not(#_)», lo de
       siempre: la regla base de los campos pesa como ocho clases. */
:root {
    --te-rejilla-verde: var(--te-ok);
    --te-rejilla-azul: var(--te-acento-vivo);
    --te-rejilla-morado: var(--te-acento-vivo);
    --te-rejilla-naranja: var(--te-aviso);
    --te-rejilla-solo-lectura: var(--te-texto-suave);
    --te-rejilla-error: var(--te-error);
    --te-rejilla-error-fondo: var(--te-error-fondo);
    /* Y los ESTADOS de una fila entera, en su fondo (tenue: el texto se tiene que seguir leyendo). */
    --te-rejilla-fila-cancelado: var(--te-error-fondo);        /* cgpedidocancelado: 3017 (Estados de pedido) */
    --te-rejilla-fila-finalizado: var(--te-ok-fondo);          /* cgpedidofinalizado: 3017 */
    --te-rejilla-fila-pedido-proveedor: var(--te-error-fondo); /* cgpedidopedidoprove: 3017, ya pedido al proveedor */
    --te-rejilla-fila-sin-acuerdo: var(--te-error-fondo);      /* cgproductosinacuerdo: 3019, producto sin acuerdo */
    --te-rejilla-fila-conteo-pendiente: var(--te-error-fondo); /* cgconteopendiente: 3007, línea sin «contado» */
    --te-rejilla-fila-no-activo: .5;                           /* cgnoactivo: CH_NOACTIVO, apagada «para que no
                                                                  estorbe» (José, 27/09/2026, la 1032). Opacidad,
                                                                  no color: apaga también iconos y casillas */
}
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid):is(.verde, .azul, .violeta, .morado, .naranja, .gris, .pedidoInterno, .blanco):not(#_) {
    border-color: transparent; background: transparent;
}
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid).verde:not(#_) { color: var(--te-rejilla-verde); }
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid):is(.azul, .violeta):not(#_) { color: var(--te-rejilla-azul); }
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid).morado:not(#_) { color: var(--te-rejilla-morado); }
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid).naranja:not(#_) { color: var(--te-rejilla-naranja); }
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid):is(.gris, .pedidoInterno):not(#_) { color: var(--te-rejilla-solo-lectura); }
:is(.ui-jqgrid tr.jqgrow td, body) :is(.lblFieldGrid, .divlblFieldGrid, .tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid, .divCellCheckboxGrid).fieldError:not(#_),
:is(.ui-jqgrid tr.jqgrow td, body) :is(.tbFieldGrid, .tbFieldDateGrid, .ddlFieldGrid).fieldError:is(:focus, :hover):not(#_) {
    border-color: var(--te-rejilla-error); background: var(--te-rejilla-error-fondo); color: var(--te-rejilla-error);
}
/* Los estados de fila: la 3017 y la 3019 ponen la clase en cada celda (setCell); la 3007, en la fila. */
.ui-jqgrid tr.jqgrow td.cgpedidocancelado { background: var(--te-rejilla-fila-cancelado); }
.ui-jqgrid tr.jqgrow td.cgpedidofinalizado { background: var(--te-rejilla-fila-finalizado); }
.ui-jqgrid tr.jqgrow td.cgpedidopedidoprove { background: var(--te-rejilla-fila-pedido-proveedor); }
.ui-jqgrid tr.jqgrow td.cgproductosinacuerdo { background: var(--te-rejilla-fila-sin-acuerdo); }
.ui-jqgrid tr.jqgrow.cgconteopendiente > td { background: var(--te-rejilla-fila-conteo-pendiente); }
.ui-jqgrid tr.jqgrow.cgnoactivo > td { opacity: var(--te-rejilla-fila-no-activo); }
/* Y en la lista de la izquierda de las fichas (BrowserQuickSearch): la puerta enseña también lo «no activo» de las tiendas
   del usuario para poder reactivarlo (José, 07/10/2026, opción b), y sale igual de apagado. */
.tmgrdRow.qsNoActivo, .teqsCard.qsNoActivo { opacity: var(--te-rejilla-fila-no-activo); }
.ui-jqgrid .ui-jqgrid-pager { background: transparent; border: 0; border-top: 1px solid var(--te-borde); }

/* ── La pareja código + nombre (Pages/Shared/_CodigoNombre.cshtml) ────────────────────────────
   José, 13/09/2026: «una dupla de código/nombre, donde sólo se despliega el nombre», y el código
   «se sigue viendo, pero no se teclea». El código, estrecho (su ancho lo pone la pantalla, en
   caracteres) y con aspecto de dato, no de caja para escribir; el nombre se lleva el resto. */
.teCodNom { display: flex; align-items: center; gap: 6px; min-width: 0; width: 100%; }
.teCodNomCod {
    flex: none; text-align: right; font-variant-numeric: tabular-nums;
    color: var(--te-texto-suave); background: var(--te-superficie-2); cursor: default;
}
.teCodNomNom { flex: 1; min-width: 0; position: relative; }
    /* (!) Tres clases, no dos: styleMain.css y ui.te.round_borders.css ponen .TextBoxForm.tbAutoComplete a
       calc(100% - 270px), y con la misma especificidad gana la hoja que carga después. En la 4010 cargaban
       después y el nombre de la tarifa se quedaba en 56 px (14/09/2026). */
    .teCodNomNom > .TextBoxForm, .teCodNom .teCodNomNom > .TextBoxForm.tbAutoComplete { width: 100%; box-sizing: border-box; }

/* ── Un obligatorio vacío, en rojo suave (marcarObligatoriosVacios, js/te.jquery.utils.js) ─────
   José, 03/10/2026: «al dar de alta se vería como en un rojito suave aquellos campos obligatorios no
   rellenados»; al verlo, el rojo «sale muy chillón», el fondo amarillo «sale muy mal» y: «pon solo el borde
   amarillo». El amarillo de aviso del tema (--te-aviso), sin tocar el fondo. Desde que se pinta la ficha, y se
   quita al rellenarlo; al guardar manda el borde rojo de .Must (styleMain.css), por eso :not(.Must).
   !important: varias hojas viejas ponen el borde de .TextBoxForm con más especificidad. */
.teObligatorioVacio:not(.Must) { border-color: var(--te-aviso) !important; }

/* ── Un precio nunca es negativo (js/te.precios.js) ───────────────────────────────────────────
   José, 25/09/2026. La casilla con clase tePrecio que intenta recibir un «-» se pone en rojo un
   momento. Sombra por dentro y no borde ni outline: no mueve nada y una celda de rejilla con
   overflow:hidden no la recorta. :not(#_) por lo de arriba: la regla base de los campos de rejilla
   pesa como ocho clases. */
.tePrecioMal:not(#_) { box-shadow: inset 0 0 0 2px var(--te-error); background: var(--te-error-fondo); }

/* ── «Pasan a precio variable» (js/te.precios.js, TE.preciosQueSePierden) ─────────────────────
   José, 28/09/2026. La lista de lo que pierde su precio fijo al guardar: el nombre a la izquierda y el
   precio que tenía a la derecha, con cifras alineadas. Con muchos, se desplaza por dentro. */
.tePreciosPerdidos { list-style: none; margin: 10px 0; padding: 0; max-height: 260px; overflow-y: auto; border-top: 1px solid var(--te-borde); }
.tePreciosPerdidos li { display: flex; justify-content: space-between; gap: 16px; padding: 5px 2px; border-bottom: 1px solid var(--te-borde); }
.tePreciosPerdidos li b { white-space: nowrap; font-variant-numeric: tabular-nums; }
.tePreciosPerdidos li.teMas { justify-content: flex-start; color: var(--te-texto-suave); }
