/* ═══════════════════════════════════════════════════════════════════════════
   data21-forms.css · TEMA DATA21 2026 · FORMULARIOS
   ───────────────────────────────────────────────────────────────────────────
   QUÉ ES
   Reimplementa el aspecto de los campos de la maqueta aprobada
   (.superpowers/brainstorm/50266-1788770755/maqueta.html, bloque "DESPUÉS",
   líneas 161-174) sobre el marcado que el panel YA usa. El HTML de las 42
   vistas NO cambia. Se carga después de bootstrap.min.css, core.css,
   components.css y select2.css, así que gana por orden a igualdad de
   especificidad.

   QUÉ CUBRE (dueño único de estos selectores; ningún otro fichero del tema
   puede escribirlos)
     .form-horizontal .form-group          .control-label / .control-label.required
     .form-control:not(.select2-container) / :hover / :focus / ::placeholder
     textarea (form-control, inputCat, inputCatH, inputCat_desc, inputCat_spen)
     .form-control-material
     .checkbox + label::before/::after + .checkbox-primary + .checkbox-con-ayuda
     .radio + .radio-primary
     .input-group / .input-group-addon / .input-group-addon.bg-custom
     .help-block / span.font-11.text-muted
     .has-error / .has-success / .has-warning
     .select2-container / .select2-choice / .select2-drop / .select2-results
     .switchery

   QUÉ NO TOCA (frontera del contrato anti-solape)
     · Ningún .btn ni .btn-* (incluido "Click para agregar", que es .btn-info
       y lo pinta data21-components.css).
     · El buscador y el paginador del grid (.qsbox, select[name=qtype],
       .sDiv, .pDiv): son de data21-components.css aunque sean inputs.
     · .card-box, .page-title, .flexigrid, .modal, .nav-tabs, .topbar,
       .side-menu, utilidades de margen y padding (m- y p-).
     · label a secas: components.css:24 pone label{font-weight:normal} para las
       etiquetas sueltas fuera de .control-label. Se respeta, no se toca.

   USO DE !important (solo donde no hay alternativa; cada caso comentado):
     · .has-error .form-control  -> jquery.form-validator.js:358 escribe
       border-color inline en el input al fallar.
     · .input-group-addon.bg-custom -> core.css:507 lleva !important.
     · span.font-11 -> core.css:292 lleva font-size:11px !important.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   1 · RITMO DE FILA
   maqueta L162: .form-group{margin-bottom:24px}
   NO se tocan margin-left/margin-right: core.css:623 los pone a -10px y son
   los que casan con el gutter de 10px del grid (core.css:422-474). Cambiarlos
   descuadraría los 495 form-group del panel.
   ═══════════════════════════════════════════════════════════════════════════ */
.form-horizontal .form-group{
  margin-bottom:var(--d21-e5);
}


/* ═══════════════════════════════════════════════════════════════════════════
   2 · ETIQUETA A LA IZQUIERDA
   maqueta L163-164: .control-label{width:180px;text-align:left;font-weight:600;
   line-height:38px}

   DESVIACIÓN DELIBERADA: se cambia la alineación y la tipografía, NO el ancho.
   El label real es .col-md-2/.col-sm-2 (16,66% ~ 223px) y forzarle 180px fijos
   rompería los 58 form-group que llevan DOS pares label+campo en la misma fila
   (patrón col-*-2 + col-*-4 + col-*-2 + col-*-4). Se deja el ancho de rejilla.
   Efecto: el input arranca ~30px más a la derecha que en la maqueta.

   La @media es OBLIGATORIA: el text-align:right de hoy vive en
   bootstrap.min.css DENTRO de @media(min-width:768px) con especificidad 0,2,0.
   Fuera de la media query no habría nada que vencer y en móvil el label debe
   seguir apilado. Nuestro selector es 0,3,0 -> gana sin !important.

   El segundo selector cubre los ~55 form-group que varias vistas inyectan por
   JS fuera de un form.form-horizontal (clientes_organigrama*.php,
   clientes_alarmas.php, maquetador_modales.php...): mismo marcado
   label.col-sm-2.control-label, misma pinta.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width:768px){
  .form-horizontal .form-group > .control-label,
  .form-group > label.control-label{
    text-align:left;
    font-weight:600;
    font-size:var(--d21-txt-sm);
    color:var(--d21-texto);
    /* SEGUNDA DESVIACIÓN, VERIFICADA CON PLAYWRIGHT.
       La maqueta escribe line-height:38px para que la etiqueta quede a la misma
       altura que el campo. Con las etiquetas de la maqueta (una palabra) es
       correcto, pero el panel tiene etiquetas que ocupan varias líneas dentro
       de su col-*-2: medido en plantillas_tratamientos.php hay una de CINCO
       líneas, que con interlineado 38px se estira a 190px de alto y se lee
       como cinco frases sueltas.
       Se consigue el MISMO resultado visual con interlineado normal más un
       padding superior: 10px + 18,85px/2 = 19,4px, que es el centro óptico de
       un control de 38px (19px). Para las etiquetas de una línea —la inmensa
       mayoría— el resultado es idéntico al de la maqueta; las que se parten
       dejan de descolgarse. */
    line-height:1.45;
    padding-top:10px;
    padding-bottom:0;
    margin-bottom:0;
  }
}

/* Asterisco gratis: 30 labels ya llevan class="required" en el HTML
   (clientes_modales, clientes_perfil, plantillas_contratos, preguntas...) y hoy
   no pintan absolutamente nada: la clase no existe en ninguna hoja del panel. */
.control-label.required::after{
  content:" *";
  color:var(--d21-marca);
  font-weight:700;
}


/* ═══════════════════════════════════════════════════════════════════════════
   3 · ANCHO DEL CAMPO — EL ARREGLO PRINCIPAL DEL ENCARGO
   Medido en el panel: input de 1097px dentro de un col-sm-10 de 1117px.
   La maqueta (L165) lo corta a 520px.

   Se hace en DOS CAPAS para que nada dependa de :has():

   CAPA A · base, sin :has(), funciona en cualquier navegador.
   Limita el CONTROL, no la columna. En los 58 form-group de dos pares el
   col-md-4 mide 447px y el input 427px: el tope de 520 no les afecta, siguen
   exactamente igual. Ésa es la gracia de limitar el control y no la columna.
   ═══════════════════════════════════════════════════════════════════════════ */
.form-horizontal .form-group input.form-control:not(.select2-container),
.form-horizontal .form-group select.form-control:not(.select2-container),
.form-horizontal .form-group > .control-label + [class*="col-"] > .select2-container,
.form-horizontal .form-group > .control-label + [class*="col-"] > .input-group,
.form-horizontal .form-group .form-control-material{
  max-width:var(--d21-campo-max);
  width:100%;
}

/* Excepción de la capa A: el input que vive DENTRO de un .input-group no se
   limita él, se limita el grupo entero (última línea de la regla de arriba).
   Si no, el grupo mediría 520 + el ancho del addon y se saldría de los 540. */
.form-horizontal .form-group .input-group input.form-control,
.form-horizontal .form-group .input-group select.form-control{
  max-width:none;
}

/* EL EDITOR REDACTOR VA AL MISMO TOPE QUE LOS DEMÁS CAMPOS.
   Sin esto, en configuracion.php (y en blog, textoygal, condiciones,
   plantillas… toda vista con Redactor) los inputs quedaban en {x:520, w:520} y
   el editor en {x:520, w:1013}: mismo borde izquierdo y el derecho 493px más
   allá. Antes del rediseño los cuatro controles medían 1080 y sí alineaban, así
   que el recorte a 520px había roto una alineación que existía.
   El plugin monta <div class="redactor_box"> alrededor del <textarea> y le
   escribe el ancho por JS, de ahí el max-width en vez de width.
   NOTA: esto NO cambia la decisión sobre los <textarea> pelados del bloque 5
   (siguen al 100% de su columna, que es el .campo.ancho de la maqueta); aquí se
   trata el editor, que en el marcado ocupa el lugar de un campo normal. */
.form-horizontal .form-group .redactor_box,
.form-horizontal .form-group .redactor-box{
  max-width:var(--d21-campo-max);
  width:100%;
}

/* ───────────────────────────────────────────────────────────────────────────
   CAPA B · progresiva, con :has(). Corta también la COLUMNA a 540px
   (520 + los 2x10px de padding de columna del gutter real medido, NO los 15px
   de Bootstrap) para que el help-block y el mensaje de error del validador
   terminen en la misma línea que el input, como en la captura aprobada.

   REGLA APARTE, nunca fusionada con otra: si el navegador no soporta :has()
   descarta esta regla entera y se queda la capa A. Degradación segura.

   El :not(:has(...)) es CRÍTICO: sin él, un col-sm-10 que contiene la rejilla
   de 222 "checkbox checkbox-primary col-sm-6" quedaría aplastado a 260px por
   casilla y las frases de los checkbox se romperían en ocho líneas.
   ─────────────────────────────────────────────────────────────────────────── */
.form-horizontal .form-group > .control-label + :is(.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12):has(> input.form-control, > select.form-control, > .input-group, > .select2-container, > .form-control-material):not(:has(.checkbox, .radio, .cal_impacto, table, textarea, .redactor-box, .redactor-editor, .dd, .dropzone, .table-responsive, .flexigrid, img)){
  max-width:var(--d21-campo-caja);
}


/* ═══════════════════════════════════════════════════════════════════════════
   4 · EL CONTROL
   maqueta L168-173.
   Hoy: core.css:584 -> height 40px, border #E3E3E3, radius 4px, padding 3px 7px,
   transition 300ms; :focus con border #AAAAAA y outline:0!important.

   ROMPEDOR EVITADO — el :not(.select2-container) NO ES OPCIONAL.
   select2 3.5.2 COPIA la clase form-control a su div contenedor: en el DOM real
   aparece <div class="select2-container form-control select2">. Sin el :not(),
   los 42 selects del panel reciben 38px de alto y 12px de padding POR FUERA del
   <a class="select2-choice"> y se descuadran todos.
   El alto real del select2 se pinta abajo, en el bloque 11.

   Y la transición baja de 300ms a .13s: la maqueta responde inmediata.
   ═══════════════════════════════════════════════════════════════════════════ */
.form-control:not(.select2-container){
  height:var(--d21-control-h);
  border:1px solid var(--d21-borde-fuerte);
  border-radius:var(--d21-r-s);
  background-color:var(--d21-superficie);
  color:var(--d21-texto);
  font-family:var(--d21-fuente);
  font-size:var(--d21-txt-campo);
  padding:0 var(--d21-e3);
  box-shadow:none;
  transition:border-color var(--d21-t),box-shadow var(--d21-t);
}
.form-control:not(.select2-container)::placeholder{
  color:var(--d21-texto-tenue);
  opacity:1;
}
.form-control:not(.select2-container)::-webkit-input-placeholder{
  color:var(--d21-texto-tenue);
}
.form-control:not(.select2-container):hover{
  border-color:var(--d21-texto-tenue);
}
.form-control:not(.select2-container):focus{
  border-color:var(--d21-marca);
  box-shadow:0 0 0 3px var(--d21-marca-halo);
  background-color:var(--d21-superficie);
  color:var(--d21-texto);
  outline:0;
}
.form-control:not(.select2-container)[disabled],
.form-control:not(.select2-container)[readonly]{
  background-color:var(--d21-superficie-2);
  color:var(--d21-texto-suave);
  cursor:not-allowed;
}

/* Los 19 <select data-toggle="select2"> que NUNCA se inicializan (no existe
   ningún init de [data-toggle=select2] en el proyecto; el único es
   $(".select2").select2() en assets/js/main.js:79) siguen siendo <select>
   nativos. Se les da el mismo aspecto que al input para que no desentonen.
   Se deja el triángulo nativo del sistema: no se añaden imágenes nuevas. */
select.form-control:not(.select2-container){
  height:var(--d21-control-h);
  padding:0 var(--d21-e3);
  border-radius:var(--d21-r-s);
  border-color:var(--d21-borde-fuerte);
  line-height:calc(var(--d21-control-h) - 2px);
}
/* Los <select multiple> llevan style="height:100px" inline
   (reglas_de_tasas.php:372 y :493) y el inline gana; esto sólo recoloca el
   padding para que la lista no quede pegada al borde. */
select.form-control:not(.select2-container)[multiple],
select.form-control:not(.select2-container)[size]{
  height:auto;
  padding:var(--d21-e2) var(--d21-e3);
  line-height:1.5;
}

/* input type=file con .form-control (importador.php:175,
   importador_encargados.php:175): 38px con padding 0 lo dejaría cortado. */
.form-control:not(.select2-container)[type="file"]{
  height:auto;
  padding:var(--d21-e2) var(--d21-e3);
  line-height:1.4;
}

/* Se conservan las variantes de tamaño de Bootstrap que el panel usa de verdad
   (contabilidad.php:63 y :68 usan .input-sm en el rango de fechas). Sin estas
   dos reglas la base de 38px se las comería, porque es más específica. */
.form-control:not(.select2-container).input-sm{
  height:var(--d21-control-h-sm);
  padding:0 var(--d21-e2);
  font-size:var(--d21-txt-sm);
}
.form-control:not(.select2-container).input-lg{
  height:46px;
  padding:0 var(--d21-e4);
  font-size:16px;
}

/* Envoltorio de paises.php y provincias.php: es un div que rodea al select. */
.form-control-material{
  display:block;
}


/* ═══════════════════════════════════════════════════════════════════════════
   5 · TEXTAREAS
   Dos familias. La segunda (inputCat, inputCatH, inputCat_desc, inputCat_spen)
   es huérfana: verificado que hoy no tiene NI UNA regla de CSS que la estilice.
   Cuando el redactor arranca sobre ellas las oculta, así que esto es además la
   red de seguridad para cuando el editor no llega a inicializarse.

   Especificidad: la regla base del bloque 4 es 0,2,0, así que el selector del
   textarea con .form-control tiene que ser 0,2,1
   (textarea.form-control:not(...)) para poder devolverle height:auto. Escrito
   como "textarea.form-control" a secas (0,1,1) perdería y todos los textarea
   del panel medirían 38px de alto.

   Los textarea NO llevan max-width: se quedan al ancho de su columna. Es el
   equivalente al .campo.ancho de la maqueta (L166).
   ═══════════════════════════════════════════════════════════════════════════ */
.form-horizontal textarea,
textarea.form-control:not(.select2-container),
textarea.inputCat,
textarea.inputCatH,
textarea.inputCat_desc,
textarea.inputCat_spen,
.form-control-material textarea{
  width:100%;
  height:auto;
  min-height:90px;
  max-width:100%;
  border:1px solid var(--d21-borde-fuerte);
  border-radius:var(--d21-r-s);
  background-color:var(--d21-superficie);
  color:var(--d21-texto);
  font-family:var(--d21-fuente);
  font-size:var(--d21-txt-campo);
  padding:var(--d21-e2) var(--d21-e3);
  line-height:1.5;
  box-shadow:none;
  transition:border-color var(--d21-t),box-shadow var(--d21-t);
}
.form-horizontal textarea:focus,
textarea.form-control:not(.select2-container):focus,
textarea.inputCat:focus,
textarea.inputCatH:focus,
textarea.inputCat_desc:focus,
textarea.inputCat_spen:focus,
.form-control-material textarea:focus{
  border-color:var(--d21-marca);
  box-shadow:0 0 0 3px var(--d21-marca-halo);
  outline:0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   6 · CHECKBOX · 253 casos (247 de ellos .checkbox-primary)
   LA MAQUETA NO LOS DIBUJA: se derivan del sistema, no se inventan.

   Mecánica real (components.css:377-435): el input está a opacity:0 y en
   position:absolute; la casilla la pinta label::before (17px) y la marca va en
   label::after con FontAwesome \f00c.

   NO se cambia el margin-left:-20px del ::before ni el padding-left:20px del
   .checkbox: así la casilla queda alineada con la columna de los inputs.

   DECISIÓN: el marcado pasa de #5d9cec (azul de la plantilla, que NO está en la
   paleta declarada) a --d21-info #337ab7, que sí está en la paleta y es el azul
   del .chk del bloque "ANTES" de la maqueta (L75). NO se pinta de naranja: el
   naranja es acento de MARCA, no de estado.
   ═══════════════════════════════════════════════════════════════════════════ */
.checkbox label::before{
  width:18px;
  height:18px;
  border-radius:var(--d21-r-s);
  border:1px solid var(--d21-borde-fuerte);
  background-color:var(--d21-superficie);
  transition:background-color var(--d21-t),border-color var(--d21-t),box-shadow var(--d21-t);
}
.checkbox label::after{
  width:18px;
  height:18px;
  font-size:11px;
  line-height:16px;
  padding-left:4px;
  padding-top:1px;
  /* Los 253 checkbox del panel son .checkbox-primary y llevan la marca en
     blanco sobre la casilla azul (regla de abajo). Este color sólo se vería si
     algún día apareciera un .checkbox sin variante de color. */
  color:var(--d21-texto-inv);
}
.checkbox-primary input[type="checkbox"]:checked + label::before{
  background-color:var(--d21-info);
  border-color:var(--d21-info);
}
.checkbox-primary input[type="checkbox"]:checked + label::after{
  color:var(--d21-texto-inv);
}
/* components.css:385 ya mata el outline del foco con !important; aquí sólo se
   añade el anillo de marca, que es el foco visible de toda la app. */
.checkbox input[type="checkbox"]:focus + label::before{
  border-color:var(--d21-marca);
  box-shadow:0 0 0 3px var(--d21-marca-halo);
}
.checkbox input[type="checkbox"]:disabled + label::before{
  background-color:var(--d21-superficie-2);
  border-color:var(--d21-borde);
}
.checkbox label{
  color:var(--d21-texto);
  font-size:var(--d21-txt-sm);
  line-height:1.5;
}

/* Arreglo gratis del padding asimétrico de los 222
   "checkbox checkbox-primary col-sm-6": components.css:377 pone
   padding-left:20px, que pisa el padding-left:10px del grid, así que la casilla
   quedaba pegada al borde izquierdo mientras la derecha conservaba sus 10px.
   30px = 20 del checkbox + 10 del grid -> simétrico. */
.checkbox[class*="col-"]{
  padding-left:30px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   7 · RADIO · 31 casos. Mismo criterio que el checkbox.
   Los textos de estos radios son frases enteras (no etiquetas de una palabra),
   por eso el line-height:1.5 y la casilla algo mayor.

   components.css:591-598 pinta el punto de .radio-primary en #5d9cec con
   especificidad 0,2,3 y 0,3,3, por encima de ".radio label::after" (0,1,2):
   hay que repintar esas dos reglas explícitamente o el punto sigue azul claro.
   ═══════════════════════════════════════════════════════════════════════════ */
.radio label::before{
  width:18px;
  height:18px;
  border:1px solid var(--d21-borde-fuerte);
  background-color:var(--d21-superficie);
  transition:border-color var(--d21-t),box-shadow var(--d21-t);
}
.radio label::after{
  width:10px;
  height:10px;
  top:4px;
  left:4px;
  background-color:var(--d21-info);
}
.radio-primary input[type="radio"] + label::after,
.radio-primary input[type="radio"]:checked + label::after{
  background-color:var(--d21-info);
}
.radio-primary input[type="radio"]:checked + label::before{
  border-color:var(--d21-info);
}
.radio input[type="radio"]:focus + label::before{
  border-color:var(--d21-marca);
  box-shadow:0 0 0 3px var(--d21-marca-halo);
}
.radio label{
  color:var(--d21-texto);
  font-size:var(--d21-txt-sm);
  line-height:1.5;
}
.radio[class*="col-"]{
  padding-left:30px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   8 · .checkbox-con-ayuda · 75 usos ya colocados en el HTML y CERO CSS.
   Clase libre. Aparece en dos sitios a la vez dentro del mismo .checkbox:
     <label for="..." class="checkbox-con-ayuda">frase larga</label>
     <a class="fa fa-question-circle checkbox-con-ayuda" data-toggle="popover">
   Hoy el enlace cae a la línea siguiente porque el label es inline-block y
   ocupa todo el ancho. Con display:inline el interrogante queda pegado al final
   del texto, que es justo lo que se espera de un icono de ayuda.
   ═══════════════════════════════════════════════════════════════════════════ */
label.checkbox-con-ayuda{
  display:inline;
  margin-right:var(--d21-e1);
}
a.checkbox-con-ayuda{
  color:var(--d21-texto-tenue);
  font-size:13px;
  vertical-align:baseline;
  cursor:pointer;
  text-decoration:none;
  transition:color var(--d21-t);
}
a.checkbox-con-ayuda:hover,
a.checkbox-con-ayuda:focus{
  color:var(--d21-marca);
  text-decoration:none;
}


/* ═══════════════════════════════════════════════════════════════════════════
   9 · INPUT-GROUP · 47 casos, con DOS variantes incompatibles del MISMO campo
   de fecha conviviendo en el panel:
     a) <span class="input-group-addon"><i></i></span>            -> gris
     b) <span class="input-group-addon bg-custom b-0 text-white"> -> teal #5fbeaa
   Es el defecto que hace que el mismo campo se vea de dos maneras distintas
   según la pantalla. Se unifican en la variante gris con el icono en naranja.

   DECISIÓN: NO se pintan de naranja enteros. Serían 37 botones de calendario
   naranjas seguidos y el acento dejaría de acentuar.

   Los radios de esquina los sigue resolviendo bootstrap.min.css
   (.input-group-addon:first-child / :last-child, 0,2,0), que gana a nuestro
   border-radius plano (0,1,0). Las dos reglas de .form-control se escriben
   igualmente para dejar la intención explícita.
   ═══════════════════════════════════════════════════════════════════════════ */
.input-group-addon{
  border:1px solid var(--d21-borde-fuerte);
  border-radius:var(--d21-r-s);
  background-color:var(--d21-superficie-2);
  color:var(--d21-texto-suave);
  padding:0 var(--d21-e3);
  font-size:var(--d21-txt-campo);
}
.input-group .form-control:first-child{
  border-top-right-radius:0;
  border-bottom-right-radius:0;
}
.input-group .form-control:last-child{
  border-top-left-radius:0;
  border-bottom-left-radius:0;
}
/* !important OBLIGATORIO: core.css:507 declara .bg-custom{background-color:
   #5fbeaa !important} y core.css:306 declara .b-0{border:none !important}.
   Nuestro selector es 0,2,0 (más específico) pero contra un !important sólo
   gana otro !important. */
.input-group-addon.bg-custom{
  background-color:var(--d21-superficie-2) !important;
  border:1px solid var(--d21-borde-fuerte) !important;
}
.input-group-addon.bg-custom,
.input-group-addon.bg-custom i,
.input-group-addon.text-white,
.input-group-addon.text-white i{
  color:var(--d21-marca) !important;
}
/* El addon acompaña al campo cuando éste tiene el foco. */
.input-group:focus-within .input-group-addon{
  border-color:var(--d21-marca);
}


/* ═══════════════════════════════════════════════════════════════════════════
   10 · AYUDA Y ERROR
   maqueta L174: .help-block{color:var(--texto-tenue);font-size:12.5px;
   margin-top:8px}

   El MISMO texto de ayuda tiene dos marcados distintos en la misma vista:
     configuracion.php:322 -> <span class="help-block"><small>...</small></span>
     configuracion.php:339 -> <span class="font-11 text-muted">...</span>
   Hay que cubrir los dos o la mitad de las ayudas se queda como está.

   El mensaje de error del validador es
   <span class="help-block form-error"> (jquery.form-validator.js:472), colgado
   del PADRE DIRECTO del input (el div.col-md-10), que además recibe la clase
   .has-error. Por eso todas las reglas de estado llevan .has-error como
   ANCESTRO y no como clase del .form-group.
   ═══════════════════════════════════════════════════════════════════════════ */
.help-block,
.help-block small,
span.font-11.text-muted{
  color:var(--d21-texto-tenue);
  font-size:var(--d21-txt-mini);
  margin-top:var(--d21-e2);
  margin-bottom:0;
  display:block;
  line-height:1.45;
}
/* !important OBLIGATORIO: core.css:292 declara .font-11{font-size:11px
   !important}. Sólo se levanta el tamaño; el color ya lo gana por
   especificidad (0,2,1 contra el 0,1,0 de .text-muted). */
span.font-11.text-muted{
  font-size:var(--d21-txt-mini) !important;
}

/* --- error ------------------------------------------------------------- */
/* !important OBLIGATORIO: jquery.form-validator.js:358-359 hace
   $input.css("border-color", "#ee163b"), es decir escribe un estilo INLINE en
   el input. Un !important de hoja sí gana a un inline sin !important. Además
   ese #ee163b no es el rojo de la paleta. */
.has-error .form-control,
.has-error .form-control:focus,
.has-error .form-control:hover{
  border-color:var(--d21-peligro) !important;
  box-shadow:0 0 0 3px rgba(224,67,67,.14) !important;
}
.has-error .control-label,
.has-error > .control-label{
  color:var(--d21-peligro);
}
/* bootstrap pinta .has-error .help-block en #a94442 (0,2,0): el texto de ayuda
   normal que convive con un campo en error no debe volverse rojo, sólo el
   mensaje del validador. */
.has-error .help-block{
  color:var(--d21-texto-tenue);
}
.help-block.form-error,
.has-error .help-block.form-error{
  color:var(--d21-peligro);
  font-weight:500;
}
/* El select2 en error. Los 42 select2 del panel llevan la clase form-control
   copiada en el contenedor, así que la regla de arriba ya los pinta; ésta cubre
   el select2 múltiple de clientes_modales.php:2054, que NO la lleva. El borde
   va en el CONTENEDOR, no en el <a>: ver el aviso del bloque 11. */
.has-error .select2-container{
  border-color:var(--d21-peligro);
}

/* --- éxito y aviso ------------------------------------------------------ */
.has-success .form-control{
  border-color:var(--d21-exito);
  box-shadow:none;
}
.has-success .control-label{
  color:var(--d21-exito);
}
.has-warning .form-control{
  border-color:var(--d21-aviso-claro);
  box-shadow:none;
}
.has-warning .control-label{
  color:var(--d21-aviso);
}


/* ═══════════════════════════════════════════════════════════════════════════
   11 · SELECT2 3.5.2 · 42 selects convertidos

   AVISO — ESTE BLOQUE NO SIGUE EL PLAN AL PIE DE LA LETRA, Y ES A PROPÓSITO.
   El plan daba por hecho que el alto del select2 lo pinta el
   <a class="select2-choice"> (select2.css:28 lo deja en 26px con degradado y
   borde #aaa). VERIFICADO CON PLAYWRIGHT: en ESTE panel eso no es cierto.
   pages.css:201-209 aplana el <a> con SIETE !important:
       .select2-container .select2-choice{
         background-image:none!important; border:none!important;
         height:auto!important; padding:0!important; line-height:22px!important;
         background-color:transparent!important; box-shadow:none!important }
   Es decir: en el panel la caja visible del select2 NO es el <a>, es el <div
   class="select2-container form-control"> que lo envuelve, y el <a> es sólo el
   texto. Escribir height/padding/border sobre el <a> no pinta nada (medido: el
   <a> se queda en 22px de alto pase lo que pase) y para forzarlo harían falta
   siete !important más contra una hoja que el encargo prohíbe tocar.

   Por eso se estiliza el CONTENEDOR, que es la caja de verdad, y así el select2
   queda EXACTAMENTE igual que un input: 38px, borde --borde-fuerte, radio 6px y
   foco naranja. Cero !important. El texto queda centrado solo: 1px de borde +
   7px de padding + los 22px de línea que impone pages.css = 30px, más 7+1 por
   abajo = los 38px del control.

   El :not(.select2-container) de la regla base del bloque 4 sigue siendo
   imprescindible: sin él, core.css:584 le metería al contenedor 40px de alto y
   3px 7px de padding y la caja quedaría descuadrada.
   ═══════════════════════════════════════════════════════════════════════════ */
.select2-container:not(.select2-container-multi){
  height:var(--d21-control-h);
  padding:7px var(--d21-e3);
  border:1px solid var(--d21-borde-fuerte);
  border-radius:var(--d21-r-s);
  background-color:var(--d21-superficie);
  color:var(--d21-texto);
  font-size:var(--d21-txt-campo);
  box-shadow:none;
  transition:border-color var(--d21-t),box-shadow var(--d21-t);
}
.select2-container:not(.select2-container-multi):hover{
  border-color:var(--d21-texto-tenue);
}
.select2-container-active:not(.select2-container-multi),
.select2-dropdown-open:not(.select2-container-multi){
  border-color:var(--d21-marca);
  box-shadow:0 0 0 3px var(--d21-marca-halo);
  outline:0;
}
/* Los select2 deshabilitados (configuracion.php:250, condiciones.php:267,
   blog.php:476) se leían igual que uno activo porque pages.css deja el <a>
   transparente y anula el gris de select2.css. */
.select2-container.select2-container-disabled{
  background-color:var(--d21-superficie-2);
  color:var(--d21-texto-suave);
  cursor:not-allowed;
}
/* Del <a> sólo se toca lo que pages.css NO bloquea: color y tipografía.
   El alto, el borde, el fondo y el padding se pintan arriba, en el contenedor. */
.select2-container .select2-choice,
.select2-container .select2-choice > .select2-chosen{
  color:inherit;
  font-family:var(--d21-fuente);
  font-size:inherit;
  text-decoration:none;
}
/* La flecha la deja pages.css:210 en 14px, transparente y sin borde, con el
   sprite select2.png dentro del <b>. Se respeta: cambiarle el ancho desplaza el
   sprite, que está anclado a la izquierda de la caja. */

/* --- el desplegable ----------------------------------------------------- */
/* NOTA: pages.css:224 declara .select2-drop-active{border:1px solid #e3e3e3
   !important}, así que el color del borde del desplegable se queda en #e3e3e3
   en vez de en --d21-borde #e2e7ee. La diferencia es de un punto de gris y no
   compensa meter un !important para ganarla. El radio, la sombra y la
   separación sí se aplican. */
.select2-drop,
.select2-drop.select2-drop-active{
  /* El shorthand es necesario: select2.css:140 deja el desplegable con
     border:1px solid #aaa y border-top:0 para pegarlo al campo. Al separarlo
     4px hay que devolverle el borde superior y unificar el gris de los cuatro
     lados. */
  border:1px solid var(--d21-borde);
  border-radius:var(--d21-r-s);
  box-shadow:var(--d21-sombra-menu);
  margin-top:4px;
  padding-top:0;
  color:var(--d21-texto);
}
.select2-results{
  padding:var(--d21-e1) 0 var(--d21-e1) var(--d21-e1);
}
.select2-results .select2-result-label{
  padding:7px var(--d21-e3);
  border-radius:var(--d21-r-s);
  font-size:var(--d21-txt-campo);
}
/* pages.css:220 pinta la opción marcada en teal #5fbeaa, que es el acento VIEJO
   de la plantilla. Misma especificidad (0,2,0) y cargamos después: gana esto. */
.select2-results .select2-highlighted{
  background-color:var(--d21-marca-suave);
  color:var(--d21-marca-oscuro);
}
.select2-results li em{
  background-color:var(--d21-marca-suave);
}
.select2-results .select2-no-results,
.select2-results .select2-searching,
.select2-results .select2-ajax-error,
.select2-results .select2-selection-limit{
  background-color:var(--d21-superficie-2);
  color:var(--d21-texto-suave);
  font-size:var(--d21-txt-sm);
  padding:7px var(--d21-e3);
}
.select2-search input{
  border:1px solid var(--d21-borde-fuerte);
  border-radius:var(--d21-r-s);
  font-family:var(--d21-fuente);
  font-size:var(--d21-txt-campo);
  color:var(--d21-texto);
}
/* Variante múltiple: clientes_modales.php:2054 (select2 select2-multiple).
   Aquí la caja es .select2-choices (plural). pages.css:237 la deja con
   border:1px solid #E3E3E3 !important y border-radius:4px !important, así que
   el borde y el radio de la píldora exterior NO se pueden cambiar sin meter
   !important; sólo se moderniza el chip de cada elemento elegido, que pages.css
   sí deja libre. Es UNA sola instancia en todo el panel. */
.select2-container-multi .select2-choices .select2-search-choice{
  background:var(--d21-marca-suave);
  background-image:none;
  border-color:var(--d21-marca-borde);
  border-radius:var(--d21-r-pill);
  box-shadow:none;
  color:var(--d21-marca-oscuro);
  padding:3px 10px 3px 20px;
  font-size:var(--d21-txt-sm);
}


/* ═══════════════════════════════════════════════════════════════════════════
   12 · SWITCHERY · 1 sola instancia (calendario.php:27)
   NO se intenta cambiar su color por CSS: va en data-color="#81c868" y el
   plugin lo aplica como estilo INLINE. Se deja verde, que es lo aprobado.
   El box-shadow:none tampoco pisa nada: switchery.js escribe inline el
   box-shadow inset que RELLENA la pastilla — es su mecanismo de animación y
   debe seguir ganando. Aquí sólo se redondea y se afina el raíl.
   ═══════════════════════════════════════════════════════════════════════════ */
.switchery{
  border-radius:var(--d21-r-pill);
  border-color:var(--d21-borde-fuerte);
  box-shadow:none;
}


/* ═══════════════════════════════════════════════════════════════════════════
   13 · label a secas
   components.css:24 declara label{font-weight:normal} para las etiquetas
   sueltas que hay fuera de .control-label. Se mantiene tal cual: en este
   fichero NO se escribe ninguna regla sobre "label" sin clase.
   ═══════════════════════════════════════════════════════════════════════════ */
