/* ==========================================================================
   Panel operativo Bonchef — hoja de estilos
   ==========================================================================

   ⚠ AQUÍ NO HAY NI UN COLOR ESCRITO A MANO. Todos entran como `var(--bc-…)`
   desde `web/tema.py`, que los lee de `paleta.py`. Si en este fichero aparece
   un `#rrggbb`, es que alguien ha duplicado la paleta — y esa paleta está
   validada para daltonismo y contraste, así que una copia que se queda atrás
   deja de serlo sin que nadie se entere.

   EL CRITERIO
   -----------
   El panel se mira **todo el día y con prisa**: densidad alta, jerarquía clara
   y cero adorno que compita con los números. El color de estado (🟢🟡🔴) está
   reservado a los datos; la interfaz no lo usa para nada decorativo, o dejaría
   de significar algo.

   LO QUE CAMBIÓ EN EL REDISEÑO, Y POR QUÉ
   ---------------------------------------
   El aspecto anterior venía de Streamlit y arrastraba sus tres tics:

   1. **Todo era una caja.** Cifra, aviso, filtro, tabla y tarjeta llevaban el
      mismo fondo blanco, el mismo borde y la misma sombra sobre un fondo crema.
      Apiladas, ninguna pesaba más que otra: no había jerarquía, había una
      columna de rectángulos flotando. Ahora la jerarquía la hacen **el espacio
      y la tipografía**, y el borde queda para lo que de verdad es un contenedor.
   2. **Superficies sin contraste.** El fondo (#F3F1EA) y las tarjetas (#FCFCFB)
      se diferenciaban un 3 % de luminancia: el crema no separaba nada, solo
      envejecía la pantalla. Ahora el lienzo de trabajo es blanco y quien lleva
      el tono cálido es la lateral.
   3. **Sin escala.** Dieciséis tamaños de letra, seis radios y diez márgenes
      distintos elegidos uno a uno. Ahora hay una escala de cada cosa, arriba,
      y nada fuera de ella.

   Y la lateral es oscura por una razón que no es de gusto: **el logo es arte
   blanco sobre transparencia**. Antes se sostenía dentro de un recuadro con
   degradado —lo más anticuado de la pantalla— porque sobre crema no se veía.
   ========================================================================== */

/* --- La escala ------------------------------------------------------------
   Todo lo que se repite, una sola vez y aquí. Si un valor de más abajo no sale
   de esta lista, es que alguien lo ha elegido a ojo. */
:root {
  /* Tipografía. La cola de emoji es la parte que importa y la que se olvida:
     Barlow llega subseteada al alfabeto latino (`unicode-range`), así que
     ningún emoji entra por ahí, y sin fuente de emoji detrás el navegador cae
     en un respaldo del sistema que no es determinista — pintaba cuadrados en
     los símbolos recientes (🧊 🟡 🟢 🔻) y acertaba en los antiguos (🏠 🌳 👥).
     `Segoe UI Symbol` va aparte de `Segoe UI Emoji`: cubre `▸ ⓘ ↺ ✕ ⬇`, que no
     son emoji de color y viven en otra fuente. */
  --bc-emoji: 'Segoe UI Emoji', 'Segoe UI Symbol', 'Apple Color Emoji',
              'Noto Color Emoji';
  --bc-fuente: 'Barlow', 'Segoe UI', system-ui, -apple-system, sans-serif,
               var(--bc-emoji);
  /* Los titulares y las cifras grandes son donde MÁS falla: Barlow Condensed no
     pasa por 'Segoe UI' y caía directamente en Arial. */
  --bc-fuente-titular: 'Barlow Condensed', 'Arial Narrow', sans-serif,
                       var(--bc-emoji);
  /* Monoespaciada para los nombres de tabla y de columna que aparecen en los
     avisos (`cfg.ObjetivosKPI`). Sin cola de emoji a propósito: ahí nunca hay
     uno, y la que trae el sistema ya resuelve los símbolos. */
  --bc-fuente-mono: ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', Consolas,
                    monospace;

  --t-2xs: .6875rem;   /* 11px · etiquetas de columna y de cifra */
  --t-xs:  .75rem;     /* 12px · pies y metadatos */
  --t-sm:  .8125rem;   /* 13px · notas, celdas de tabla */
  --t-md:  .875rem;    /* 14px · controles y botones */
  --t-base: 1rem;      /* 15px · texto corrido */
  --t-lg:  1.125rem;   /* 17px · h3 */
  --t-xl:  1.375rem;   /* 21px · h2 */
  --t-2xl: 1.75rem;    /* 26px · h1 */
  --t-3xl: 2.5rem;     /* 40px · la cifra que encabeza una pantalla */

  /* Espaciado en múltiplos de 4. */
  --e-1: 4px;  --e-2: 8px;  --e-3: 12px; --e-4: 16px;
  --e-5: 20px; --e-6: 24px; --e-7: 32px; --e-8: 40px;

  /* Radios pequeños: los de 14-16 px eran la mitad del aspecto «app de
     maqueta». Un panel de datos se lee mejor con esquinas discretas. */
  --r-xs: 4px; --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-full: 999px;

  /* Dos elevaciones, y se usan casi en ningún sitio: la sombra sirve para
     decir «esto flota por encima» —un desplegable—, no para decorar una
     tarjeta que no flota. El negro de aquí no es un color de la paleta —es
     sombra, no tinta—, y por eso va literal: teñirlo de marrón convertiría la
     profundidad en suciedad. */
  --sombra-1: 0 1px 2px rgba(0, 0, 0, .05);
  --sombra-2: 0 10px 30px -10px rgba(0, 0, 0, .28);

  /* Un solo alto para todos los controles: sin esto, un `<select>` y un botón
     puestos en la misma fila no se alinean y la barra de filtros baila. */
  --alto-control: 34px;
  /* Derivado del oliva, no copiado: escrito como `rgba(129,115,80,…)`
     era una segunda copia de `--bc-oliva` esperando a quedarse atrás. */
  --foco: 0 0 0 3px color-mix(in srgb, var(--bc-oliva) 24%, transparent);

  --lateral: 248px;
}


/* --- Reinicio corto ------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

/* El navegador ya trae `[hidden] { display: none }`, pero con la especificidad
   más baja que existe: cualquier `.bc-loquesea { display: grid }` de esta hoja
   lo gana y el elemento oculto se sigue viendo. Como esconder algo lo hace solo
   el JavaScript de las pestañas, un fallo aquí sería «las pestañas no ocultan
   nada» y costaría entenderlo. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--bc-fuente);
  font-size: var(--t-base);
  line-height: 1.5;
  color: var(--bc-ink);
  background: var(--bc-lienzo);
  -webkit-font-smoothing: antialiased;
}


/* --- Tipografía ----------------------------------------------------------
   Los titulares ya no van en mayúsculas. «BALANCE OPERATIVO POR CENTRO DE
   NEGOCIO» en versales y con interletrado es más lento de leer —se pierde la
   silueta de la palabra, que es por donde se reconoce— y es la firma visual de
   una plantilla de 2012. */
h1, h2, h3, h4 {
  font-family: var(--bc-fuente-titular);
  color: var(--bc-ink);
  font-weight: 700;
  margin: 0 0 var(--e-2);
  line-height: 1.15;
}
h1 { font-size: var(--t-2xl); letter-spacing: -.01em; }
h2 { font-size: var(--t-xl); margin-top: var(--e-6); }
h3 { font-size: var(--t-lg); margin-top: var(--e-5); }
h4 { font-size: var(--t-md); }

/* El emoji del título, fuera del peso del titular. Es iconografía, no texto: a
   tamaño de h1 competía con el nombre de la pantalla en lugar de señalarlo. */
.bc-h1-icono {
  font-size: .78em;
  margin-right: .4em;
  opacity: .85;
}

p { margin: 0 0 var(--e-3); }

a { color: var(--bc-rojo-osc); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--bc-rojo);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

code {
  font-family: var(--bc-fuente-mono);
  font-size: .92em;
  background: var(--bc-papel);
  padding: .1em .35em;
  border-radius: var(--r-xs);
}

/* Los números se leen en columna, así que van con cifras tabulares: sin esto,
   un «1» ocupa menos que un «8» y las unidades dejan de alinearse. */
.num, td.num, .bc-kpi-val, .bc-hero-val { font-variant-numeric: tabular-nums; }


/* --- Estructura: lateral fija + lienzo ------------------------------------ */
.bc-shell { display: flex; min-height: 100vh; }

.bc-lateral {
  width: var(--lateral);
  flex: 0 0 var(--lateral);
  background: var(--bc-nav);
  color: var(--bc-nav-texto);
  padding: 0 0 var(--e-6);
  position: sticky;
  top: 0;
  height: 100vh;
  /* ⚠ Ojo con `overflow-x` aquí: por la especificación de CSS, en cuanto UN eje
     deja de ser `visible` el otro se calcula como `auto`. Así que este
     `overflow-y` ya hace que cualquier cosa que se salga por el lado saque una
     barra horizontal, y ponerle `overflow-x: hidden` para taparla recortaría de
     verdad. Lo que se arregla es el desbordamiento, no la barra. */
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--bc-nav-linea) transparent;
}

.bc-principal {
  flex: 1 1 auto;
  min-width: 0;            /* sin esto, una tabla ancha estira el flex y
                              rompe el layout en vez de hacer scroll */
  /* Sin relleno arriba: ese hueco lo pone la cabecera, que va pegada al borde
     para poder quedarse fija al desplazar. */
  padding: 0 var(--e-7) var(--e-8);
  max-width: 1680px;
}


/* --- Marca, en la lateral ------------------------------------------------
   El logo se apoya en la lateral, sin recuadro ni degradado: es arte blanco y
   este es su fondo. El bloque con gradiente que lo envolvía existía solo para
   darle un fondo oscuro sobre una lateral clara. */
.bc-marca {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-5) var(--e-5) var(--e-4);
}
/* 22 px, no 30. El logo es de 700×143, así que a 30 px de alto ocupa 147 px de
   ancho y «Panel operativo» se quedaba sin sitio dentro de la lateral. */
.bc-marca img { height: 22px; flex: 0 1 auto; min-width: 0; }
.bc-marca .bc-marca-txt {
  color: var(--bc-nav-texto-suave);
  font-family: var(--bc-fuente);
  font-weight: 600;
  font-size: var(--t-2xs);
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: .09em;
  min-width: 0;            /* un hijo de flex no baja de su ancho de contenido */
}


/* La píldora de origen, pegada a la marca: dice de qué base salen los datos y
   de qué día son, y es lo primero que hay que poder comprobar. */
.bc-marca-origen { padding: 0 var(--e-5) var(--e-2); }


/* --- Menú ---------------------------------------------------------------- */
.bc-menu { padding: var(--e-2) var(--e-3) 0; }
.bc-menu a {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-sm);
  color: var(--bc-nav-texto);
  font-size: var(--t-md);
  font-weight: 500;
  line-height: 1.3;
  margin-bottom: 2px;
  position: relative;
  transition: background .12s ease, color .12s ease;
}
.bc-menu a:hover { background: var(--bc-nav-alto); text-decoration: none; }
.bc-menu a.activa {
  background: var(--bc-nav-alto);
  color: var(--bc-nav-fuerte);
  font-weight: 600;
}
/* La marca de «estás aquí» es una barra roja, no solo el fondo: sobre oscuro,
   un cambio de fondo por sí solo es demasiado sutil para verlo de reojo. */
.bc-menu a.activa::before {
  content: '';
  position: absolute;
  left: 0; top: 20%; bottom: 20%;
  width: 3px;
  border-radius: var(--r-full);
  background: var(--bc-rojo);
}
.bc-menu .bc-icono {
  width: 1.3em;
  text-align: center;
  flex: 0 0 auto;
  font-size: .95em;
}

.bc-seccion-lateral {
  padding: var(--e-4) var(--e-5) var(--e-2);
  border-top: 1px solid var(--bc-nav-linea);
  margin-top: var(--e-4);
}
.bc-seccion-lateral h4 {
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--bc-nav-texto-suave);
  margin-bottom: var(--e-2);
  font-family: var(--bc-fuente);
  font-weight: 600;
}
/* Dentro de la lateral manda el contraste de la lateral: el gris de `.bc-pie`
   está calculado para fondo claro y sobre oscuro no se leería. */
.bc-lateral .bc-pie, .bc-lateral .bc-nota { color: var(--bc-nav-texto-suave); }
.bc-lateral .bc-dato { color: var(--bc-nav-fuerte); font-weight: 600; }
.bc-lateral a { color: var(--bc-nav-texto); }


/* --- Tipos de texto menor ------------------------------------------------ */
.bc-pie, .bc-nota {
  color: var(--bc-ink-suave);
  font-size: var(--t-sm);
  line-height: 1.5;
}
.bc-pie { font-size: var(--t-xs); }
.bc-nota { margin: var(--e-1) 0 var(--e-3); }

/* Un renglón de 1.600 px no se lee: al llegar al final, el ojo no encuentra el
   principio del siguiente. Entre 60 y 90 caracteres es el ancho cómodo, y estos
   párrafos son explicaciones largas —no datos—, así que se acotan. Las tablas y
   los gráficos NO: esos sí quieren todo el ancho. */
.bc-nota, .bc-ok, .bc-aviso, .bc-error, .bc-info { max-width: 92ch; }
.bc-pie { max-width: 108ch; }
/* Salvo dentro de algo que ya está acotado, donde volver a acotar descuadra. */
.bc-kpi .bc-pie, .bc-kpi-pie, .bc-hero-pie, .bc-filtros .bc-pie,
.bc-tabla-caja .bc-nota { max-width: none; }
/* …y salvo que la pantalla lo pida. Un aviso que va pegado a una tabla de 1.600
   px y se queda en 92ch no se lee como «la advertencia de esta tabla», se lee
   como un trozo suelto que alguien dejó ahí: la caja de color pierde la mitad de
   su trabajo, que es cubrir lo que está avisando. Se pide a mano y por caja —no
   se levanta el tope para todas— porque en un párrafo corrido el renglón largo
   sigue siendo peor. */
.bc-ok.es-ancha, .bc-aviso.es-ancha, .bc-error.es-ancha, .bc-info.es-ancha,
.bc-nota.es-ancha, .bc-pie.es-ancha { max-width: none; }


/* La píldora de contexto: el origen de los datos en la lateral y el periodo en
   la cabecera de cada pantalla. Discreta a propósito — dice de qué va lo que se
   está mirando, no es un botón. */
.bc-etiqueta {
  display: inline-block;
  background: var(--bc-papel);
  color: var(--bc-ink-suave);
  border: 1px solid var(--bc-linea);
  padding: 3px var(--e-3);
  border-radius: var(--r-full);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}
.bc-lateral .bc-etiqueta {
  background: var(--bc-nav-alto);
  border-color: var(--bc-nav-linea);
  color: var(--bc-nav-texto);
}
/* Datos inventados: tiene que verse a la primera y desde cualquier pantalla. */
.bc-etiqueta.es-aviso,
.bc-lateral .bc-etiqueta.es-aviso {
  background: var(--bc-critico);
  border-color: var(--bc-critico);
  color: var(--bc-nav-fuerte);
}


/* --- El punto de semáforo ------------------------------------------------
   Sustituye a 🟢🟡🔴 en la interfaz, y no por gusto: **el Segoe UI Emoji de
   Windows Server 2019 no tiene el círculo amarillo ni el verde**. Son de
   Unicode 12 (2019) y la fuente es anterior, así que salían como cuadrados
   vacíos — medido aquí mismo con un navegador: 🔴 se dibuja a 54,9 px y 🟡 y 🟢
   a 25,8, que es el ancho del carácter de reemplazo. Y el semáforo es el
   lenguaje de esta pantalla.

   Además es mejor diseño aunque la fuente los tuviera: el verde de un emoji es
   el que eligió el fabricante de la fuente, no `--bc-verde`, que está validado
   para daltonismo y contraste. Dibujando el punto, el color es EL de la paleta
   y es nítido a cualquier tamaño.

   ⚠ El color nunca va solo: al lado siempre hay texto que dice lo mismo
   («errores críticos», «al límite»). Por eso el punto es `aria-hidden`. */
.bc-punto {
  display: inline-block;
  width: .62em;
  height: .62em;
  border-radius: 50%;
  flex: 0 0 auto;
  /* Alineado con la mitad de la altura de la x, no con la línea base: así queda
     centrado con el texto en lugar de colgando de él. */
  vertical-align: .02em;
  margin-right: .12em;
}
.bc-punto.es-bien    { background: var(--bc-verde); }
.bc-punto.es-aviso   { background: var(--bc-ambar); }
.bc-punto.es-critico { background: var(--bc-critico); }
/* En una cifra grande el punto crece con ella y desequilibra: se acota. */
.bc-kpi-val .bc-punto { width: .5em; height: .5em; margin-right: .2em; }


/* --- Cabecera de pantalla ------------------------------------------------ */
/* Se queda arriba al desplazar. En una tabla de 400 filas, a los tres segundos
   de scroll ya no se sabe qué pantalla es ni qué periodo se está mirando: el
   nombre y la etiqueta del periodo se habían ido. Y es justo el dato que hay
   que tener delante para no leer un número del mes equivocado. */
.bc-cabecera {
  position: sticky;
  top: 0;
  /* Por encima de la tabla (sus `th` van a 2) y por debajo del desplegable de
     un filtro (20), que sí tiene que taparlo todo. */
  z-index: 10;
  background: var(--bc-lienzo);
  display: flex;
  align-items: flex-start;
  gap: var(--e-4);
  flex-wrap: wrap;
  padding: var(--e-6) 0 var(--e-4);
  margin-bottom: var(--e-5);
  border-bottom: 1px solid var(--bc-linea);
}
/* Una cabecera ANIDADA (el escandallo dentro de una pantalla) no se pega a
   nada: ya está dentro de algo que se desplaza. */
.bc-cabecera.es-interior { position: static; }
.bc-cabecera h1 { margin-bottom: var(--e-1); }
/* Un subtítulo de 140 caracteres a lo ancho de 1.680 px no se lee: el ojo
   pierde el renglón. 72 caracteres es el ancho de lectura cómodo. */
.bc-cabecera .bc-pie { max-width: 72ch; }
.bc-cabecera .bc-derecha {
  margin-left: auto;
  text-align: right;
  padding-top: var(--e-1);
}


/* --- Tarjetas de cifra ---------------------------------------------------
   Sin sombra y sin levantarse al pasar por encima: una cifra no se pulsa, y
   animarla al pasar el ratón sugiere que sí. Lo que las separa del lienzo es un
   filete, que es lo mínimo que hace falta. */
/* UNA franja, no N cajas sueltas. En 🏠 Inicio hay cuatro rejillas seguidas con
   trece tarjetas en total: con borde y radio cada una, eso son trece rectángulos
   flotando y ninguna jerarquía — que es exactamente el aspecto del que venimos.
   Agrupadas en una franja con filetes internos, cada rejilla se lee como UN
   bloque de resumen y se distingue del siguiente.

   El truco del filete: el hueco de la rejilla deja ver el fondo del contenedor,
   así que `gap: 1px` sobre un fondo de color de línea dibuja los separadores
   sin que ninguna celda tenga que llevar borde. Y como es un hueco y no un
   borde, al envolver a la línea siguiente el filete cae solo donde toca. */
.bc-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: 1px;
  background: var(--bc-linea);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-md);
  overflow: hidden;
  margin: var(--e-3) 0 var(--e-5);
}
.bc-kpi {
  background: var(--bc-lienzo);
  padding: var(--e-3) var(--e-4);
  min-width: 0;
}
/* Solo las que SON un enlace reaccionan. */
a.bc-kpi { display: block; color: inherit; }
a.bc-kpi:hover { background: var(--bc-papel); text-decoration: none; }
/* ⚠ Por DENTRO. La franja recorta con `overflow: hidden` para que el radio
   corte las celdas de las esquinas, y eso se comía el anillo de foco de las
   tarjetas que son enlace: con el teclado no se veía dónde estabas. */
a.bc-kpi:focus-visible { outline-offset: -3px; }
.bc-kpi-lbl {
  color: var(--bc-ink-suave);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--t-2xs);
  letter-spacing: .07em;
  margin-bottom: var(--e-1);
}
.bc-kpi-val {
  font-family: var(--bc-fuente-titular);
  font-weight: 700;
  font-size: 1.65rem;
  line-height: 1.1;
  letter-spacing: -.01em;
}
.bc-kpi-pie {
  color: var(--bc-ink-suave);
  font-size: var(--t-xs);
  margin-top: var(--e-1);
}

/* Tarjeta de cifra con estado. En 🏠 Inicio las tres primeras cuentan errores,
   avisos y procesos correctos, y llevan el color de lo que cuentan.
   ⚠ Es una VARIANTE y no `class="bc-kpi bc-error"`, que es como estaba: apilar
   dos componentes deja que se peleen por el fondo, el borde, el radio, el
   relleno, el margen y el tamaño de letra, y quien gana lo decide el orden de
   esta hoja — o sea, el azar. Dentro de una rejilla, además, el margen vertical
   de la caja de aviso descuadraba las tres respecto a cualquier otra fila. */
.bc-kpi.es-critico, .bc-kpi.es-aviso, .bc-kpi.es-bien { border-top: 3px solid; }
.bc-kpi.es-critico { background: var(--bc-rojo-fondo);  border-top-color: var(--bc-critico); }
.bc-kpi.es-aviso   { background: var(--bc-ambar-fondo); border-top-color: var(--bc-ambar); }
.bc-kpi.es-bien    { background: var(--bc-verde-fondo); border-top-color: var(--bc-verde); }
a.bc-kpi.es-critico:hover { background: var(--bc-rojo-fondo);  filter: brightness(.97); }
a.bc-kpi.es-aviso:hover   { background: var(--bc-ambar-fondo); filter: brightness(.97); }
a.bc-kpi.es-bien:hover    { background: var(--bc-verde-fondo); filter: brightness(.97); }
.bc-kpi.es-critico .bc-kpi-lbl, .bc-kpi.es-critico .bc-kpi-pie { color: var(--bc-rojo-texto); }
.bc-kpi.es-aviso .bc-kpi-lbl,  .bc-kpi.es-aviso .bc-kpi-pie  { color: var(--bc-ambar-texto); }
.bc-kpi.es-bien .bc-kpi-lbl,   .bc-kpi.es-bien .bc-kpi-pie   { color: var(--bc-verde-texto); }
.bc-kpi.es-critico { color: var(--bc-rojo-texto); }
.bc-kpi.es-aviso   { color: var(--bc-ambar-texto); }
.bc-kpi.es-bien    { color: var(--bc-verde-texto); }

/* La cifra que encabeza una pantalla. Existe porque siete tarjetas del mismo
   tamaño no son una jerarquía: obligan a leerlas todas para saber si el día va
   bien. Aquí va UNA —la que contesta esa pregunta— y el resto quedan detrás. */
.bc-hero {
  /* Blanca, no gris: sobre el lienzo blanco, un relleno gris hace que la cifra
     más importante de la pantalla parezca desactivada. Lo que la destaca es el
     tamaño y el filete de estado, no un fondo.

     Y en rejilla, no tres líneas apiladas: la cifra y su contexto comparten
     línea base, así que la caja mide la mitad de alto y el contexto se lee al
     lado del número en vez de debajo. */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "lbl lbl" "val pie";
  align-items: baseline;
  column-gap: var(--e-4);
  background: var(--bc-lienzo);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-lg);
  padding: var(--e-4) var(--e-5);
  margin-bottom: var(--e-5);
}
.bc-hero-lbl { grid-area: lbl; }
.bc-hero-val { grid-area: val; }
.bc-hero-pie { grid-area: pie; }
.bc-hero-lbl {
  color: var(--bc-ink-suave);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--t-2xs);
  letter-spacing: .07em;
}
.bc-hero-val {
  font-family: var(--bc-fuente-titular);
  font-weight: 700;
  font-size: var(--t-3xl);
  line-height: 1.05;
  letter-spacing: -.02em;
  margin-top: var(--e-1);
  /* Proporcionales a propósito: no tiene nada con lo que alinearse. */
  font-variant-numeric: normal;
  white-space: nowrap;
}
.bc-hero-pie {
  color: var(--bc-ink-suave);
  font-size: var(--t-sm);
}
/* El color va SIEMPRE acompañado de texto que dice lo mismo: parte de la gente
   no lo distingue, así que no puede ser el único portador del significado.
   A la izquierda y no arriba: en una tarjeta de 1.600 px el filete superior
   quedaba a medio metro del texto que lo explica. */
.bc-hero.es-bien    { border-left: 4px solid var(--bc-verde); }
.bc-hero.es-aviso   { border-left: 4px solid var(--bc-ambar); }
.bc-hero.es-critico { border-left: 4px solid var(--bc-critico); }


/* --- Ritmo de la pantalla ------------------------------------------------
   El contenido era una columna continua: cabecera, notas, filtros, pestañas,
   cifras, tabla y pies, todo al mismo nivel y con el mismo aire. Sin escalones,
   el ojo no encuentra dónde empieza cada cosa y la pantalla se lee como un
   volcado. Aquí está el único sitio donde se decide ese ritmo. */
section { display: block; }
section + section { margin-top: var(--e-7); }
section > h2:first-child, section > .bc-h2-plano { margin-top: 0; }

/* Los pies de página al final de una sección eran tres párrafos grises seguidos
   del mismo tamaño que las notas de arriba: la pantalla terminaba en una mancha.
   Se agrupan, se aprietan y se cuelgan de un filete, para que se lean como lo
   que son —anotaciones de lo de encima— y no como más texto. */
.bc-tabla-caja + .bc-pie,
.bc-tarjeta + .bc-pie,
.bc-ok + .bc-pie {
  margin-top: var(--e-3);
  padding-top: var(--e-3);
  border-top: 1px solid var(--bc-linea-tenue);
}
.bc-pie + .bc-pie {
  margin-top: calc(var(--e-2) * -1 + 2px);
  padding-top: 0;
  border-top: none;
}

/* Un bloque de cifras lleva su nombre encima, pegado: sin él, cuatro rejillas
   seguidas son cincuenta números sin decir de qué van. */
.bc-grupo-cifras {
  font-size: var(--t-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--bc-ink-suave);
  margin: var(--e-6) 0 var(--e-2);
  font-family: var(--bc-fuente);
}
.bc-grupo-cifras:first-child { margin-top: 0; }


/* --- Cajas de estado -----------------------------------------------------
   Planas: sin sombra y con el filete fino. Antes competían con las cifras
   porque llevaban el mismo relieve que ellas. */
.bc-ok, .bc-aviso, .bc-error, .bc-info {
  padding: var(--e-3) var(--e-4);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  border-left-width: 3px;
  margin: var(--e-3) 0;
  font-size: var(--t-sm);
}
.bc-ok    { background: var(--bc-verde-fondo); color: var(--bc-verde-texto); border-left-color: var(--bc-verde); }
.bc-aviso { background: var(--bc-ambar-fondo); color: var(--bc-ambar-texto); border-left-color: var(--bc-ambar); }
.bc-error { background: var(--bc-rojo-fondo);  color: var(--bc-rojo-texto);  border-left-color: var(--bc-critico); }
.bc-info  { background: var(--bc-papel); color: var(--bc-ink); border-color: var(--bc-linea); border-left-color: var(--bc-oliva); }
.bc-ok > :last-child, .bc-aviso > :last-child,
.bc-error > :last-child, .bc-info > :last-child { margin-bottom: 0; }
.bc-ok ul, .bc-aviso ul, .bc-error ul, .bc-info ul { margin: var(--e-2) 0 0; padding-left: var(--e-5); }

/* El sello con la hora del corte de stock que se está mirando. No es adorno: es
   lo que distingue «kilos de ahora mismo» de «foto de las 21:00 de anoche», y
   sin el recuadro se lee como una frase más. */
.foto-stock {
  display: inline-block;
  background: var(--bc-papel);
  border: 1px solid var(--bc-linea);
  border-left: 3px solid var(--bc-oliva);
  border-radius: var(--r-md);
  padding: var(--e-2) var(--e-4);
  margin: 0 0 var(--e-4);
  font-size: var(--t-sm);
  color: var(--bc-ink);
}
/* La antigüedad y la calidad del corte, en segundo plano: acompañan al dato
   principal —qué día y a qué hora— sin competir con él. */
.foto-stock span { color: var(--bc-ink-suave); }


/* Un pliegue CERRADO no necesita el relleno de una tarjeta abierta. Con él,
   la caja de «Datos reales» de cada pantalla ocupaba 56 px de alto para enseñar
   un renglón, y son 56 px por delante de la tabla, que es a lo que se viene. */
details.bc-tarjeta:not([open]) { padding: var(--e-2) var(--e-4); }

/* Título, nota y tabla son UNA cosa, no tres bloques sueltos: se aprietan entre
   sí para que se lean juntos y para no gastar media pantalla antes del dato. */
h2 + .bc-nota, .bc-grupo-cifras + .bc-nota { margin-top: calc(var(--e-1) * -1); }
.bc-nota + .bc-tabla-caja, h2 + .bc-tabla-caja { margin-top: var(--e-2); }


/* --- Tarjetas y paneles -------------------------------------------------- */
.bc-tarjeta {
  background: var(--bc-lienzo);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-md);
  padding: var(--e-4) var(--e-5);
  margin: var(--e-4) 0;
}
.bc-tarjeta > h2, .bc-tarjeta > h3 { margin-top: 0; }
.bc-tarjeta > :last-child { margin-bottom: 0; }


/* --- Tablas --------------------------------------------------------------
   La tabla es el producto de este panel, así que se le da el ancho y se le
   quita todo lo demás: sin líneas verticales y sin cebra —el ojo sigue la fila
   solo, y las rayas compiten con el color de los semáforos, que sí significa
   algo—, con la cabecera pegada arriba.

   ⚠ `max-height` NO es decorativa: sin ella las cabeceras `sticky` no funcionan
   en ninguna pantalla. Al declarar `overflow`, esta caja pasa a ser el
   contenedor de scroll de los `<th>`; si nunca se desplaza en vertical,
   `top: 0` los deja exactamente donde ya estaban. De paso, la barra horizontal
   deja de estar al final de una tabla de 400 filas —donde nadie la ve— y queda
   siempre a la vista. */
.bc-tabla-caja {
  overflow: auto;
  max-height: 75vh;
  /* Reserva el hueco de la barra para que aparecer o desaparecer no mueva las
     columnas al filtrar. */
  scrollbar-gutter: stable;
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-md);
  background: var(--bc-lienzo);
}
table.bc-tabla {
  width: 100%;
  /* `separate` y no `collapse`: con `collapse`, el borde inferior de una
     cabecera `sticky` pertenece a la tabla y no a la celda, así que al
     desplazar se queda arriba sin su línea y el dato parece pegado al título. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--t-sm);
}
table.bc-tabla th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bc-papel);
  color: var(--bc-ink-suave);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--t-2xs);
  letter-spacing: .06em;
  text-align: right;
  padding: var(--e-2) var(--e-3);
  border-bottom: 1px solid var(--bc-linea);
  white-space: nowrap;
  cursor: help;            /* la cabecera lleva la fórmula en su `title` */
}
table.bc-tabla th:first-child,
table.bc-tabla td:first-child { text-align: left; }
table.bc-tabla td {
  padding: var(--e-2) var(--e-3);
  text-align: right;
  border-bottom: 1px solid var(--bc-linea-tenue);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
table.bc-tabla tbody tr:last-child > td { border-bottom: none; }
table.bc-tabla tbody tr:hover > td { background: var(--bc-papel); }
table.bc-tabla tr.total > td {
  font-weight: 700;
  background: var(--bc-papel);
  border-top: 1px solid var(--bc-linea);
}

/* Jerarquía del árbol desplegable. El peso de la letra baja con el nivel: es lo
   que deja ver de un vistazo dónde está el corte entre agregado y detalle. */
table.bc-tabla td.lbl { font-weight: 600; }
table.bc-tabla .indent1 { padding-left: var(--e-6); font-weight: 500; }
table.bc-tabla .indent2 { padding-left: var(--e-8); font-weight: 400; }
table.bc-tabla .indent3 { padding-left: 56px; font-weight: 400; }
table.bc-tabla tr.lvl0 > td.lbl { font-weight: 700; }
/* Celda que en ESTE nivel no se enseña (`desde_nivel`, en componentes.py).
   Vacía del todo: un guión o un cero se leerían como un dato, y el
   hueco tiene que leerse como «aquí todavía no». */
table.bc-tabla td.muda { background: transparent; }

.bc-caret {
  display: inline-block;
  width: 1em;
  color: var(--bc-ink-tenue);
  transition: transform .15s ease;
}
tr.expanded > td > .bc-caret { transform: rotate(90deg); }
table.bc-tabla tr.desplegable { cursor: pointer; }
table.bc-tabla tr.destacada > td { box-shadow: inset 0 0 0 2px var(--bc-oliva); }

/* Los iconos de acción de cada fila (🔎 escandallo, 🌳 árbol). Se atenúan hasta
   que se pasa por su fila: en una tabla de 400 filas son 800 iconos siempre
   encendidos compitiendo con las cifras, que es lo que se ha venido a leer. */
.bc-accion {
  cursor: pointer;
  padding: 0 3px;
  opacity: .4;
  text-decoration: none;
  transition: opacity .12s ease;
}
tr:hover .bc-accion { opacity: .85; }
.bc-accion:hover, .bc-accion:focus-visible { opacity: 1; text-decoration: none; }
td.bc-acciones { text-align: left; white-space: nowrap; }


/* --- Formularios y botones ----------------------------------------------- */
label {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--bc-ink-suave);
  display: block;
  margin-bottom: var(--e-1);
}

input[type=text], input[type=password], input[type=date], input[type=number],
select, textarea {
  width: 100%;
  height: var(--alto-control);
  padding: 0 var(--e-3);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-sm);
  background: var(--bc-lienzo);
  color: var(--bc-ink);
  font-family: inherit;
  font-size: var(--t-md);
  transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { height: auto; padding: var(--e-2) var(--e-3); }
input:hover, select:hover { border-color: var(--bc-ink-tenue); }
/* Anillo de foco de verdad: el `outline` de antes iba con `offset: -1px`, o sea
   pintado por DENTRO del borde, y en un campo estrecho no se distinguía del
   borde normal. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--bc-oliva);
  box-shadow: var(--foco);
}
input[type=checkbox] { accent-color: var(--bc-oliva); }

.bc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  height: var(--alto-control);
  padding: 0 var(--e-4);
  border-radius: var(--r-sm);
  border: 1px solid var(--bc-linea);
  background: var(--bc-lienzo);
  color: var(--bc-ink);
  font-family: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.bc-btn:hover {
  background: var(--bc-papel);
  border-color: var(--bc-ink-tenue);
  text-decoration: none;
}
.bc-btn.es-principal {
  background: var(--bc-rojo);
  border-color: var(--bc-rojo);
  color: var(--bc-nav-fuerte);
}
.bc-btn.es-principal:hover {
  background: var(--bc-rojo-osc);
  border-color: var(--bc-rojo-osc);
}
.bc-btn.es-suave {
  border-color: transparent;
  background: transparent;
  color: var(--bc-ink-suave);
}
.bc-btn.es-suave:hover { background: var(--bc-papel); color: var(--bc-ink); }
/* En la lateral oscura el botón hereda otro juego de colores. */
.bc-lateral .bc-btn {
  background: var(--bc-nav-alto);
  border-color: var(--bc-nav-linea);
  color: var(--bc-nav-texto);
}
.bc-lateral .bc-btn:hover { background: var(--bc-nav-linea); color: var(--bc-nav-fuerte); }
.bc-lateral .bc-btn.es-suave { background: transparent; border-color: transparent; }
.bc-lateral .bc-btn.es-suave:hover { background: var(--bc-nav-alto); }
/* Los botones de la lateral ocupan su columna entera: en 248 px, dos
   botones a medio ancho no caben con su texto. */
.bc-btn.es-ancho { width: 100%; }
.bc-form-lateral { margin-bottom: var(--e-2); }
.bc-pie-sesion { margin-top: var(--e-3); }

/* Un control que está ahí para explicar por qué NO se puede hacer algo: se ve,
   dice su motivo en el `title`, y no se pulsa. Iba escrito como
   `style="opacity:.5;pointer-events:none"` en cuatro sitios. */
.bc-btn.es-inerte {
  opacity: .5;
  pointer-events: none;
  cursor: default;
}

/* Fila de un producto por debajo de su mínimo, en ⚙ Configuración. El color
   salía escrito a mano en la plantilla: era una copia del rojo de aviso. */
tr.es-bajo-minimo > td { background: var(--bc-rojo-fondo); color: var(--bc-rojo-texto); }
/* Fila con semáforo: el fondo lo pone el dato —son los colores del informe de
   Power BI, ver `dominio/semaforos.py`— y aquí solo se garantiza que el texto
   encima se siga leyendo. */
tr.es-semaforo > td { color: var(--bc-ink); }

/* Barra de filtros: una banda, no una tarjeta. Es una herramienta, y ponerle el
   mismo borde y la misma sombra que a una cifra la hacía pesar lo mismo que el
   dato que sirve para encontrar. */
.bc-filtros {
  display: flex;
  gap: var(--e-3);
  align-items: flex-end;
  flex-wrap: wrap;
  background: var(--bc-papel);
  border-radius: var(--r-md);
  padding: var(--e-3) var(--e-4);
  margin-bottom: var(--e-4);
}
/* Un control no se estira a lo ancho de la pantalla por tener sitio: un
   desplegable de 1.300 px con «Almacén» dentro no se lee mejor, se lee peor
   —el ojo tiene que recorrerlo entero para volver— y hace que la barra parezca
   un formulario en vez de una herramienta. Crecen, pero con tope. */
.bc-filtros > div { min-width: 150px; max-width: 320px; }
.bc-filtros .bc-crece { flex: 1 1 200px; max-width: 420px; }
/* El hueco sobrante se va a la derecha en vez de repartirse entre los campos. */
.bc-filtros::after { content: ""; flex: 10 1 0; }
/* …salvo que la barra se use para centrar algo, como la paginación de Stock. */
.bc-filtros[style*="center"]::after { display: none; }
/* Los controles dentro de la banda van sobre el lienzo, no sobre la banda: si
   comparten fondo, el campo deja de leerse como algo donde se escribe. */
.bc-filtros input, .bc-filtros select { background: var(--bc-lienzo); }


/* --- Selección múltiple: desplegable con casillas ------------------------
   Sustituye al `<select multiple size="1">`, que obligaba a Ctrl+clic y perdía
   la selección al primer clic (ver `componentes/multiple.html`). */

/* El nombre del grupo. No puede ser un `<label>` —apuntaría a UN control de los
   N que hay dentro—, así que imita su aspecto.
   ⚠ Clase propia y NO `.bc-etiqueta`: esa es la píldora de contexto de la
   lateral y de las cabeceras. Estuvieron definidas con el mismo nombre y ganaba
   la última, así que las píldoras salían como texto suelto. */
.bc-multi-etq {
  display: block;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--bc-ink-suave);
  margin-bottom: var(--e-1);
}

.bc-multi { position: relative; }
.bc-multi > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
  height: var(--alto-control);
  padding: 0 var(--e-3);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-sm);
  background: var(--bc-lienzo);
  font-size: var(--t-md);
  cursor: pointer;
  list-style: none;        /* fuera el triángulo del navegador: ya hay uno */
  transition: border-color .12s ease, box-shadow .12s ease;
}
.bc-multi > summary::-webkit-details-marker { display: none; }
.bc-multi > summary:hover { border-color: var(--bc-ink-tenue); }
.bc-multi[open] > summary {
  border-color: var(--bc-oliva);
  box-shadow: var(--foco);
}
.bc-multi-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bc-multi-flecha {
  color: var(--bc-ink-tenue);
  transition: transform .15s ease;
  flex: 0 0 auto;
  font-size: .8em;
}
.bc-multi[open] > summary .bc-multi-flecha { transform: rotate(180deg); }

/* La lista va SUPERPUESTA y no en el flujo: abrir un filtro no puede empujar
   media pantalla hacia abajo cada vez. */
.bc-multi-lista {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  max-width: 340px;
  /* Diez almacenes caben; ciento cuarenta empleados, no: a partir de ahí la
     lista se desplaza en lugar de salirse de la pantalla. */
  max-height: 46vh;
  overflow-y: auto;
  padding: var(--e-1);
  background: var(--bc-lienzo);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-md);
  box-shadow: var(--sombra-2);
}
.bc-multi-op {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-xs);
  /* `label` global las pone en bloque y en versalitas de etiqueta: aquí son
     opciones de una lista, no nombres de campo. */
  font-size: var(--t-md);
  font-weight: 400;
  color: var(--bc-ink);
  text-transform: none;
  letter-spacing: normal;
  margin: 0;
  cursor: pointer;
}
.bc-multi-op:hover { background: var(--bc-papel); }
.bc-multi-op input { width: auto; height: auto; flex: 0 0 auto; margin: 0; }
.bc-multi-op span { overflow: hidden; text-overflow: ellipsis; }


/* --- Pestañas ------------------------------------------------------------
   Subrayadas, no en forma de carpeta. La pestaña-carpeta con borde a tres lados
   es el patrón de los años 2000 y, además, obligaba a un `margin-bottom`
   negativo para tapar la línea de abajo con el propio fondo de la pestaña. */
.bc-pestanas {
  display: flex;
  gap: var(--e-6);
  border-bottom: 1px solid var(--bc-linea);
  margin: var(--e-2) 0 var(--e-5);
  flex-wrap: wrap;
}
.bc-pestanas a {
  padding: var(--e-2) 0 var(--e-3);
  color: var(--bc-ink-suave);
  font-weight: 600;
  font-size: var(--t-md);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .12s ease, border-color .12s ease;
}
.bc-pestanas a:hover {
  color: var(--bc-ink);
  border-bottom-color: var(--bc-linea);
  text-decoration: none;
}
.bc-pestanas a.activa {
  color: var(--bc-ink);
  border-bottom-color: var(--bc-rojo);
}

/* Pestañas de SEGUNDO nivel (las dos vistas de columnas de 📊 Balance, los
   ámbitos del escandallo de 🏭 Sección): un selector segmentado, no otra barra
   subrayada. Cambian una vista de lo que ya se mira, no la sección de la
   pantalla, y dos barras idénticas a 40 px una de otra no dicen cuál hace qué. */
section .bc-pestanas {
  display: inline-flex;
  gap: 2px;
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-sm);
  background: var(--bc-papel);
  padding: 2px;
  margin: 0 0 var(--e-4);
}
section .bc-pestanas a {
  padding: 0 var(--e-3);
  height: 28px;
  display: inline-flex;
  align-items: center;
  border: 0;
  margin: 0;
  border-radius: var(--r-xs);
  font-size: var(--t-sm);
}
section .bc-pestanas a:hover { background: var(--bc-lienzo); border: 0; }
section .bc-pestanas a.activa {
  background: var(--bc-lienzo);
  box-shadow: var(--sombra-1);
  border: 0;
}


/* --- Texto plegable ------------------------------------------------------
   Estaba escrito como `style="cursor:pointer;font-weight:600"` en once sitios.
   El `<summary>` dice SIEMPRE cuánto hay dentro (`.bc-cuenta`): un pliegue cuyo
   título no declara su tamaño invita a no abrirlo nunca, y entonces no es
   plegar, es borrar con un paso de más. */
.bc-plegable {
  cursor: pointer;
  font-weight: 600;
  font-size: var(--t-md);
  display: flex;
  align-items: baseline;
  gap: var(--e-2);
  flex-wrap: wrap;
}
.bc-plegable::-webkit-details-marker { color: var(--bc-ink-tenue); }
.bc-plegable::marker { color: var(--bc-ink-tenue); }
details[open] > .bc-plegable { margin-bottom: var(--e-3); }
.bc-cuenta {
  font-weight: 400;
  font-size: var(--t-xs);
  color: var(--bc-ink-suave);
}
/* Un pliegue DENTRO de una caja de aviso: sin fondo ni borde propios, que ya
   los pone la caja. Lo que separa es la línea de arriba. */
.bc-plegado-en-caja {
  margin-top: var(--e-2);
  border-top: 1px solid currentColor;
  padding-top: var(--e-2);
  /* `currentColor` al 25 %: la caja de aviso tiene su propio color de texto y
     una línea fija se vería mal en la verde o en la roja. */
  border-color: color-mix(in srgb, currentColor 25%, transparent);
}
.bc-plegado-en-caja > summary { font-size: var(--t-sm); }


/* --- Gráficos ------------------------------------------------------------ */
.bc-grafico {
  background: var(--bc-lienzo);
  border: 1px solid var(--bc-linea);
  border-radius: var(--r-md);
  padding: var(--e-3) var(--e-4);
  margin: var(--e-3) 0;
  /* Red de seguridad, no la solución: lo que de verdad arregla el desborde es
     el `ResizeObserver` de `panel.js`. Pero entre que el SVG se dibuja y que se
     remide hay un instante, y sin esto ese instante se ve — un gráfico pintado
     encima del de al lado. */
  overflow: hidden;
}

/* ⚠ `auto-fit` COLAPSA LAS PISTAS VACÍAS, y aquí los gráficos se insertan uno a
   uno mientras el navegador lee la página: con el primero dentro, la rejilla es
   de una columna y mide el doble de ancho de lo que acabará siendo. Se deja
   `auto-fit` —es lo que hace que en una pantalla estrecha los dos se apilen— y
   del remedido se encarga el `ResizeObserver` de `panel.js`.
   `minmax(min(340px, 100%), 1fr)` y no `1fr` a secas: el mínimo automático de
   una pista de rejilla es su contenido, así que un SVG ancho la estiraría. */
.bc-graficos-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: var(--e-3);
}
.bc-graficos-2 > * { min-width: 0; }


/* --- Entrada al panel ---------------------------------------------------- */
.bc-login-fondo {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e-6);
  background: var(--bc-nav);
}
.bc-login {
  width: 100%;
  /* La usan también `clave_nueva`, `sin_datos` y `sin_pantallas`, que no van
     dentro de una columna: sin este ancho se estirarían a toda la pantalla. */
  max-width: 380px;
  background: var(--bc-lienzo);
  border-radius: var(--r-lg);
  padding: var(--e-7) var(--e-6) var(--e-6);
  box-shadow: var(--sombra-2);
}
/* El logo, sobre el fondo oscuro de la página y encima de la tarjeta. Sin
   recuadro propio: el fondo ya es el suyo. */
.bc-login-columna { width: 100%; max-width: 380px; }
.bc-login-columna > .bc-login { max-width: none; }
.bc-login-marca {
  text-align: center;
  margin-bottom: var(--e-5);
}
.bc-login-marca img { height: 30px; }
.bc-login-marca .bc-marca-txt {
  color: var(--bc-nav-fuerte);
  font-family: var(--bc-fuente-titular);
  font-size: var(--t-xl);
}
.bc-login .bc-campo { margin-bottom: var(--e-3); }
.bc-login h1 { font-size: var(--t-xl); margin-bottom: var(--e-4); }


/* --- Indicador de carga de HTMX ------------------------------------------
   HTMX pone `.htmx-request` mientras hay una petición en vuelo. Sin señal, una
   consulta de tres meses parece que no ha hecho nada y la gente vuelve a
   pulsar. */
.bc-cargando { display: none; }
.htmx-request .bc-cargando, .htmx-request.bc-cargando { display: inline-block; }
.bc-barra-carga {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--bc-rojo);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .2s ease;
  z-index: 50;
}
body.bc-ocupado .bc-barra-carga {
  transform: scaleX(.75);
  transition: transform 8s cubic-bezier(.05, .7, .1, 1);
}


/* --- Espera larga con recarga de página ----------------------------------
   La barra de arriba vale para una consulta de dos segundos. NO vale cuando la
   pantalla se va a SharePoint: son entre 20 y 35 segundos bajando decenas de
   Excel, y durante ese rato el navegador no repinta nada — la página se queda
   exactamente igual. Sin señal, lo razonable es pensar que el clic no ha
   entrado y volver a pulsar, que es empezar la espera otra vez.

   Por eso aquí la señal TAPA la pantalla: además de decir que está trabajando,
   impide el segundo clic. Se activa con `data-cargando` (ver panel.js). */
.bc-espera {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .45);
}
body.bc-esperando .bc-espera { display: flex; }

.bc-espera-caja {
  background: var(--bc-fondo, #fff);
  color: var(--bc-texto, #1a1a1a);
  border-radius: 10px;
  padding: 1.6rem 2rem;
  max-width: 28rem;
  text-align: center;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .35);
}
.bc-espera-caja h4 { margin: .2rem 0 .4rem; font-size: 1.05rem; }
.bc-espera-caja p  { margin: 0; font-size: .85rem; opacity: .8; }

/* El giro. `prefers-reduced-motion` lo deja quieto: para quien marca esa
   preferencia, una rueda girando sin parar es justo lo que pidió no ver. */
.bc-espera-rueda {
  width: 34px; height: 34px;
  margin: 0 auto .8rem;
  border: 3px solid var(--bc-borde, #d8d8d8);
  border-top-color: var(--bc-rojo, #c8102e);
  border-radius: 50%;
  animation: bc-girar .9s linear infinite;
}
@keyframes bc-girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .bc-espera-rueda { animation: none; }
}


/* --- Pantallas estrechas -------------------------------------------------
   El panel es de escritorio, pero se abre desde el móvil para mirar un dato
   suelto. La lateral deja de ser fija y pasa a ser una cabecera. */
@media (max-width: 960px) {
  .bc-shell { display: block; }
  .bc-lateral {
    width: auto;
    height: auto;
    position: static;
    padding-bottom: var(--e-3);
  }
  .bc-marca { padding: var(--e-3) var(--e-4); }
  /* UNA fila que se desplaza, no seis que se envuelven. Envuelta, la barra
     oscura ocupaba la pantalla entera del móvil y había que pasarla de largo
     para llegar al primer dato. En una fila, el menú cabe y se arrastra. */
  .bc-menu {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: var(--e-1);
    padding: 0 var(--e-3) var(--e-2);
    scrollbar-width: none;
  }
  .bc-menu::-webkit-scrollbar { display: none; }
  .bc-menu a {
    font-size: var(--t-sm);
    padding: var(--e-1) var(--e-3);
    white-space: nowrap;
    flex: 0 0 auto;
  }
  .bc-menu a.activa::before { display: none; }
  .bc-menu a.activa { box-shadow: inset 0 -2px 0 var(--bc-rojo); }
  /* Y el pie de la lateral en horizontal: los botones a ancho completo y
     apilados gastaban otros 150 px antes del contenido. */
  .bc-seccion-lateral {
    padding: var(--e-3) var(--e-4) 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-2) var(--e-3);
  }
  .bc-seccion-lateral h4 { width: 100%; margin-bottom: 0; }
  .bc-seccion-lateral form { margin: 0; }
  .bc-btn.es-ancho { width: auto; }
  .bc-form-lateral { margin-bottom: 0; }
  .bc-pie-sesion { margin-top: 0; width: 100%; }
  .bc-principal { padding: 0 var(--e-4) var(--e-7); }
  /* Fija roba demasiado alto en un movil: ahí se queda quieta. */
  .bc-cabecera { position: static; padding-top: var(--e-4); }
  .bc-hero-val { font-size: 2rem; }
  h1 { font-size: var(--t-xl); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}

@media print {
  .bc-lateral, .bc-filtros, .bc-btn, .bc-barra-carga { display: none; }
  /* En papel no hay scroll, así que no hay nada a lo que pegarse — y `sticky`
     al imprimir se solapa con el contenido según el navegador. */
  .bc-cabecera { position: static; }
  .bc-principal { max-width: none; padding: 0; }
  .bc-tabla-caja { max-height: none; overflow: visible; border: none; }
  /* En papel no hay pestañas: se enseña todo, que es lo que se espera de un
     impreso. Lo esconde el JavaScript, así que hay que deshacerlo aquí. */
  [hidden] { display: revert !important; }
  details > summary { list-style: none; }
  .bc-kpi, .bc-tarjeta, .bc-grafico, tr { break-inside: avoid; }
}


/* Un `h2` que encabeza una tarjeta o un panel: sin el margen superior que
   separa secciones, porque aquí ya lo pone el relleno de la tarjeta. */
.bc-h2-plano { margin-top: 0; }
/* Una cabecera ANIDADA (el escandallo dentro de una pantalla): sin la línea
   ni los márgenes que separan la pantalla de su contenido, porque aquí ya
   está dentro de algo. */
.bc-cabecera.es-interior { border: 0; margin: 0; padding: 0; }
