/* ============================================================
   institutional-logic.css
   Tokens y componentes para la migración de Home + Sidebar al
   sistema de diseño Institutional Logic (Propuesta C).
   Ver DESIGN-institutional-logic.md.

   IMPORTANTE — todo en px, nunca rem:
   assets/s1.css fija html { font-size: 62.5% } (1rem = 10px) para
   TODO el sitio. Los valores `rounded` del .md están en rem
   (diseñados asumiendo la base estándar de 16px), así que aquí se
   convierten a px explícitos para no heredar el desfase de s1.css.

   Alcance — todas las clases nuevas usan prefijo il- o están scoped
   bajo .il-sidebar / .il-content, para no colisionar con las 15+
   pantallas que todavía no se migran a este sistema (incluye
   /pagina_prueba, que tiene su PROPIO .sidebar independiente).
   ============================================================ */

:root {
  /* Colores (DESIGN-institutional-logic.md) */
  --il-surface: #f8f9fa;
  --il-surface-dim: #d9dadb;
  --il-surface-bright: #f8f9fa;
  --il-surface-container-lowest: #ffffff;
  --il-surface-container-low: #f3f4f5;
  --il-surface-container: #edeeef;
  --il-surface-container-high: #e7e8e9;
  --il-surface-container-highest: #e1e3e4;
  --il-on-surface: #191c1d;
  --il-on-surface-variant: #43474f;
  --il-outline: #737780;
  --il-outline-variant: #c3c6d0;
  --il-primary: #00305e;
  --il-on-primary: #ffffff;
  --il-primary-container: #1e4779;
  --il-on-primary-container: #92b6ef;
  --il-secondary: #b7102a;
  --il-on-secondary: #ffffff;
  --il-secondary-container: #db313f;
  --il-tertiary-fixed-dim: #98cdf2;
  --il-background: #f8f9fa;
  --il-success: #28A745;
  --il-warning: #FFBF00;
  --il-critical: #DC3545;
  --il-premium-gold: #D4AF37;

  /* Tipografía */
  --il-font: 'Inter', sans-serif;
  /* Mono para identificadores de tabla (nodos, zonas, claves de sistema).
     La familia se carga en app.py; los fallbacks cubren el caso de que el
     CDN de Google Fonts no responda. */
  --il-font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', 'Consolas',
                  'Menlo', monospace;

  /* Spacing (ya en px en el .md) */
  --il-sidebar-width: 280px;
  --il-container-gap: 24px;
  --il-card-padding: 32px;
  --il-stack-sm: 8px;
  --il-stack-md: 16px;
  --il-stack-lg: 24px;

  /* Rounded — convertidos de rem del .md a px (base 16px) */
  --il-radius-sm: 4px;   /* 0.25rem */
  --il-radius: 8px;      /* 0.5rem (DEFAULT) */
  --il-radius-md: 12px;  /* 0.75rem */
  --il-radius-lg: 16px;  /* 1rem */
  --il-radius-xl: 24px;  /* 1.5rem */
  --il-radius-full: 9999px;
}

/* ---------- Tipografía ---------- */
.il-headline-xl { font-family: var(--il-font); font-size: 32px; font-weight: 700; line-height: 40px; letter-spacing: -0.02em; margin: 0; }
.il-headline-lg { font-family: var(--il-font); font-size: 24px; font-weight: 700; line-height: 32px; margin: 0; }
.il-title-md    { font-family: var(--il-font); font-size: 18px; font-weight: 600; line-height: 24px; margin: 0; }
.il-body-lg     { font-family: var(--il-font); font-size: 16px; font-weight: 400; line-height: 24px; margin: 0; }
.il-body-md     { font-family: var(--il-font); font-size: 14px; font-weight: 400; line-height: 20px; margin: 0; }

/* label-caps — clase explícita, no depende de config de Tailwind
   (bug documentado en el .md: font-label-caps solo aplicaba la
   familia tipográfica, nunca tamaño/peso/letter-spacing). */
.label-caps { font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 700; line-height: 16px; letter-spacing: 0.05em; text-transform: uppercase; }
.label-caps-sm { font-size: 9px; }

/* Material Symbols Outlined (misma técnica que el mockup) */
.material-symbols-outlined {
  font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24;
  font-size: 20px;
  vertical-align: middle;
  line-height: 1;
}

/* ============================================================
   Sidebar — .il-sidebar (reemplaza .sidebar SOLO en app.py;
   /pagina_prueba sigue usando .sidebar/style.css sin cambios)
   ============================================================ */
.il-sidebar {
  position: fixed;
  left: 0;
  top: 0;
  height: 100vh;
  width: var(--il-sidebar-width);
  background-color: var(--il-primary);
  color: var(--il-on-primary);
  display: flex;
  flex-direction: column;
  z-index: 1050;
  overflow-y: auto;
}
.il-sidebar::-webkit-scrollbar { width: 4px; }
.il-sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: var(--il-radius-full); }

.il-sidebar-header {
  padding: var(--il-stack-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* Lockup navy (isotipo + wordmark en dos líneas). 190px se veía grande
   contra el resto del sidebar (nav items a 13px, "Bienvenido" a 16px);
   150px, confirmado a ojo por Anahí, da ~97px de alto según el aspect
   ratio nativo del PNG (1772×1142), que se conserva con height:auto — no
   se distorsiona. max-width:100% es el resguardo si el ancho disponible
   llegara a ser menor a 150px. .il-sidebar-header ya centra horizontal
   (align-items:center), así que no hace falta margin:auto.
   margin-bottom sin tocar: baja de 122px a 97px de imagen pero el
   margen de 24px no se ve ni apretado ni suelto a este tamaño. */
.il-sidebar-logo {
  display: block;
  width: 150px;
  max-width: 100%;
  height: auto;
  margin-bottom: var(--il-stack-lg);
}

.il-sidebar-user { width: 100%; display: flex; flex-direction: column; gap: 2px; }
.il-sidebar-user-greeting { font-family: var(--il-font); font-size: 12px; color: rgba(152, 205, 242, 0.7); }
.il-sidebar-user-name { font-family: var(--il-font); font-size: 16px; font-weight: 600; color: #ffffff; }

.il-membership-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--il-font); font-size: 10px; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--il-radius-full);
  margin-top: 6px; width: fit-content;
}
.il-membership-chip--premium { color: var(--il-premium-gold); border: 1px solid rgba(212, 175, 55, 0.35); }
.il-membership-chip--basica  { color: var(--il-tertiary-fixed-dim); border: 1px solid rgba(152, 205, 242, 0.3); }

/* Navegación */
.il-sidebar-nav-main { padding: 4px 12px 0; }
.il-sidebar-nav { padding: 4px 12px; }
.il-sidebar-section-title {
  color: rgba(152, 205, 242, 0.5) !important;
  padding: 8px 16px 4px;
  margin-top: 8px;
}

.il-sidebar .nav-link {
  display: flex; align-items: center; gap: 16px;
  padding: 8px 16px; margin: 1px 0;
  border-radius: 0 8px 8px 0;
  color: rgba(152, 205, 242, 0.7);
  font-family: var(--il-font); font-size: 13px; font-weight: 500; line-height: 20px;
  border-left: 4px solid transparent;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.il-sidebar .nav-link:hover {
  color: #ffffff;
  background-color: rgba(255,255,255,0.05);
}
.il-sidebar .nav-link.active {
  color: #ffffff;
  background-color: rgba(255,255,255,0.1);
  border-left-color: var(--il-secondary);
}
.il-sidebar .nav-link.active .material-symbols-outlined {
  font-variation-settings: 'FILL' 1, 'wght' 300, 'GRAD' 0, 'opsz' 24;
}
.il-sidebar .nav-link.disabled,
.il-sidebar .nav-link.premium-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.il-sidebar .nav-link.disabled:hover,
.il-sidebar .nav-link.premium-disabled:hover {
  background-color: transparent;
  color: rgba(152, 205, 242, 0.7);
}

.il-sidebar-admin-section {
  margin: 12px -12px 0;
  padding: 8px 12px 12px;
  background-color: rgba(255,255,255,0.05);
  border-left: 3px solid var(--il-secondary);
}

.il-sidebar-footer {
  padding: 16px;
  border-top: 1px solid rgba(255,255,255,0.1);
  margin-top: auto;
}

/* ============================================================
   Content wrapper — .il-content (reemplaza .content)
   ============================================================ */
.il-content {
  margin-left: var(--il-sidebar-width);
  min-height: 100vh;
  background-color: var(--il-background);
}

/* Link del aviso de privacidad, dentro de .il-home-footer (Home,
   solamente — ver app.py). Neutraliza el estilo de link por defecto
   (color heredado, sin subrayado salvo :hover) — mismo patrón que
   .il-module-link en la lista de módulos del Home, pero como clase
   propia para no mezclar nombres de contextos distintos. Ya no es
   sitewide: se quitó del wrapper compartido dashboard_layout() (era
   .il-sitewide-footer, ahora retirada por quedar huérfana) porque
   aparecía en los 16+ módulos y en admin, y solo debía vivir en Home. */
.il-sitewide-footer-link {
  color: inherit;
  text-decoration: none;
}
.il-sitewide-footer-link:hover {
  text-decoration: underline;
}

/* ============================================================
   Home — pie de página
   Franja de ancho completo: hermano de .il-home-canvas dentro de
   .il-content (ver app.py), así no hereda su max-width:1200px ni su
   padding lateral. Mismo azul que el sidebar (background-color +
   color con el mismo par de tokens que .il-sidebar). Reutiliza
   .il-body-md para el tamaño de letra en vez de .label-caps: una
   leyenda de copyright en mayúsculas se lee más agresiva que discreta,
   y body-md ya es el tamaño que usa el resto de la microcopia
   secundaria del Home (ej. "Tu membresía actual es:"). Sin position
   sticky/fixed — es un cierre de página, no una barra flotante.
   Dos líneas (fuente/procesamiento + copyright): flex-column en vez de
   una altura fija, así el contenedor crece solo con el contenido real en
   vez de forzar el texto a una sola línea o encimarlo. gap con
   var(--il-stack-sm), el token más chico ya definido, para separarlas
   sin dejarlas sueltas. text-align:center queda como resguardo por si
   algún hijo se vuelve inline-level.
   ============================================================ */
.il-home-footer {
  background-color: var(--il-primary);
  color: var(--il-on-primary);
  text-align: center;
  padding: var(--il-stack-md) var(--il-stack-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--il-stack-sm);
}

/* ============================================================
   Home
   ============================================================ */
.il-home-canvas {
  padding: 40px;
  max-width: 1200px;
  margin: 0 auto;
}
@media (max-width: 768px) {
  .il-home-canvas { padding: 16px; }
  /* NOTA: el sidebar fijo de 280px se mantiene visible tal cual en
     mobile (sin colapso ni menú hamburguesa) — ver alcance responsive
     en el reporte de esta migración. No se oculta para no dejar sin
     navegación a quien entre desde un celular. */
}

/* Modificador de .il-home-canvas para páginas de trabajo con tablas
   (hoy: Gestión de Usuarios) — 40px se sentía excesivo ahí. Aditivo: se
   usa junto a la clase base como "il-home-canvas il-home-canvas--compact"
   y solo pisa padding; max-width/centrado siguen viniendo de la base, así
   que Home no se toca. var(--il-stack-lg) en vez de un valor nuevo: mismo
   token que ya usa .il-sidebar-header para su propio padding — 24px es
   notablemente menor que 40px sin quedar tan angosto como --il-stack-md
   (16px) en una página con tablas de hasta 10 columnas. */
.il-home-canvas--compact {
  padding: var(--il-stack-lg);
}

.il-welcome-title { color: var(--il-primary); }

/* Título de la tarjeta que lista los módulos del Home. Aditivo: se usa como
   "il-headline-lg il-welcome-title il-module-list-title" y no altera
   .il-headline-lg, que también viste otros títulos de la app.
   Va después de .il-headline-lg para ganarle por orden de aparición: ambos
   son selectores de una clase y tienen la misma especificidad.
   22px en vez de reutilizar un token de la escala porque ninguno encaja:
   .il-title-md (18px) es el tamaño de los 16 nombres de módulo que este
   título encabeza — igualarlo aplanaría la jerarquía — y .il-body-lg (16px)
   lo dejaría más chico que su propia lista. Solo se toca font-size; el
   line-height y el peso siguen viniendo de .il-headline-lg. */
.il-module-list-title { font-size: 22px; }

.il-membership-badge {
  font-family: var(--il-font); font-size: 10px; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 10px; border-radius: var(--il-radius-full);
  height: fit-content;
}
.il-membership-badge--premium { background-color: var(--il-premium-gold); color: #ffffff; }
.il-membership-badge--basica  { background-color: transparent; color: var(--il-primary); border: 1px solid var(--il-primary); }

.il-card {
  background-color: var(--il-surface-container-lowest);
  border: 1px solid var(--il-outline-variant);
  border-radius: var(--il-radius-lg);
  padding: var(--il-card-padding);
  position: relative;
  overflow: hidden;
  transition: box-shadow 0.2s ease;
}
.il-card:hover {
  box-shadow: 0px 4px 20px rgba(0,0,0,0.05);
}
.il-card-accent-left {
  position: absolute; top: 0; left: 0; width: 4px; height: 100%;
  background-color: var(--il-secondary);
}

.il-module-icon-hex {
  width: 48px; height: 48px;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  background-color: rgba(183, 16, 42, 0.05);
  border: 1px solid rgba(183, 16, 42, 0.2);
  color: var(--il-secondary);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}

.il-module-list { display: grid; grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .il-module-list { grid-template-columns: 1fr 1fr; column-gap: 48px; }
}
.il-module-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px;
  border-bottom: 1px solid var(--il-outline-variant);
}
.il-module-item--locked { opacity: 0.5; }
.il-module-item-left { display: flex; align-items: center; gap: 16px; }

/* Tamaño de letra del nombre de módulo. Punto medio entre il-title-md
   (18px, el original) e il-body-md (14px, quedó muy chico). No reusa
   il-body-lg pese a compartir el mismo font-size de 16px: ese token viste
   párrafos de cuerpo (el saludo de Home, las tarjetas de promo) — un
   contexto distinto al de una etiqueta de navegación — y acoplar ambos
   haría que un cambio pensado para párrafos alterara esta lista sin
   querer. weight 400 y line-height 24px se mantienen alineados a la
   escala existente (mismo peso que body-md, mismo line-height que
   il-title-md/il-body-lg) en vez de inventar valores nuevos. */
.il-module-name {
  font-family: var(--il-font);
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  margin: 0;
}

/* Nombre de módulo como dcc.Link (renderiza <a>). color:inherit y
   text-decoration:none neutralizan el estilo de link por defecto para
   que quede igual que el texto plano de antes; el subrayado solo aparece
   en :hover, para que la lista se lea como navegación discreta y no
   "grite" que cada fila es clickeable. */
.il-module-link {
  color: inherit;
  text-decoration: none;
}
.il-module-link:hover {
  text-decoration: underline;
}

/* Row-limit / system notice: warning/10 bg + warning/40 border,
   nunca una alerta dura tipo error (patrón documentado en el .md). */
.il-notice-warning {
  background-color: rgba(255, 191, 0, 0.1);
  border: 1px solid rgba(255, 191, 0, 0.4);
  border-radius: var(--il-radius);
  padding: 12px 16px;
  font-family: var(--il-font); font-size: 12px; color: var(--il-on-surface-variant);
}

.il-promo-grid { display: grid; grid-template-columns: 1fr; gap: var(--il-container-gap); }
@media (min-width: 768px) {
  .il-promo-grid { grid-template-columns: 1fr 1fr; }
}
.il-promo-card {
  display: flex; align-items: center; gap: 24px;
  background-color: var(--il-surface-container-lowest);
  border: 1px solid var(--il-outline-variant);
  border-radius: var(--il-radius-lg);
  padding: 32px;
}
.il-promo-icon {
  width: 64px; height: 64px; flex-shrink: 0;
  border-radius: var(--il-radius-md);
  display: flex; align-items: center; justify-content: center;
}
.il-promo-icon--primary { background-color: rgba(0, 48, 94, 0.05); border: 2px solid rgba(0, 48, 94, 0.2); }
.il-promo-icon--primary .material-symbols-outlined { color: var(--il-primary); font-size: 28px; }
.il-promo-icon--secondary { background-color: rgba(183, 16, 42, 0.05); border: 2px solid rgba(183, 16, 42, 0.2); }
.il-promo-icon--secondary .material-symbols-outlined { color: var(--il-secondary); font-size: 28px; }

/* ============================================================
   PML y Precios Zonales — tabs, tarjetas de filtro y botones.
   Clases nuevas SCOPED a esta página vía paginas/pmlPrecioszonales.py,
   paginas/MarginalZonal/{Precio_Marginal,Precio_Zonal,html_mda_mtr,
   html_comparacion}.py — se agregan ADEMÁS de .tabs1/.tabs2/
   .create_container3/.button (no las reemplazan), porque esas 5 clases
   las usan ~20-45 páginas más del sitio que todavía no migran a este
   sistema de diseño.
   ============================================================ */
.il-tabs {
  margin-bottom: 10px;
}
.il-tabs .nav-item .nav-link {
  font-family: var(--il-font);
  color: var(--il-on-surface-variant);
  border: none;
  border-radius: var(--il-radius-sm) var(--il-radius-sm) 0 0;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 20px;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.il-tabs .nav-item .nav-link:hover {
  color: var(--il-primary);
  background-color: var(--il-surface-container-low);
}
.il-tabs .nav-item .nav-link.active {
  color: var(--il-on-primary);
  background-color: var(--il-primary);
  font-weight: 700;
  border-bottom: 3px solid var(--il-secondary);
}
/* Nivel 2 (MDA/MTR/MDA vs MTR) un tono más claro que nivel 1 (PML/PCZ),
   misma jerarquía visual que ya tenían .tabs1/.tabs2 con rgb(53,86,133)
   vs rgb(75,107,147). */
.il-tabs--level2 .nav-item .nav-link.active {
  background-color: var(--il-primary-container);
}

/* Tarjeta de filtro — Opción A: acento superior.
   Línea navy sólida de 3px arriba, esquinas superiores rectas y las
   inferiores en 8px. El border-top no lleva radius; los otros 3 lados
   conservan el borde de 1px. */
.il-filter-card {
  background-color: var(--il-surface-container-lowest);
  border: 1px solid var(--il-outline-variant);
  border-top: 3px solid var(--il-primary);
  border-radius: 0 0 var(--il-radius) var(--il-radius);
  padding: 8px 10px;
}

/* Fila de tarjetas de filtro. El espaciado entre tarjetas se resuelve con
   un único gap en el contenedor, no con margin-left por tarjeta: antes
   convivían el margin-left:15px de .create_container3 con inline styles de
   20px y uno de 0px, lo que dejaba a Periodo pegado a Nodo en la fila de
   Datos crudos.
   Los margin se anulan SCOPED a esta fila para no tocar .create_container3,
   que usan ~20 páginas más. Especificidad (0,2,0) > (0,1,0). */
.il-filter-row {
  gap: var(--il-stack-md);
}
.il-filter-row > .il-filter-card {
  margin-left: 0;
  margin-right: 0;
}

/* Variante para la fila SUPERIOR de filtros de la vista de gráficas de
   PML/Precios Zonales: Sistema Interconectado, Gerencia de Control
   Regional (Checklist de 9 opciones, CEN…BCS) y Periodo. Nodo/Zona de
   carga vive en su propia fila aparte (--checklist-bottom): con hasta 15
   chips seleccionados necesita crecer libremente en altura, algo que no
   encajaba compartiendo fila con tarjetas de altura fija.

   flex-grow/flex-basis/min-width en vez de porcentajes fijos con calc()
   atados a viewports específicos (1440/1920/2560px): esa fórmula se
   rompía con cualquier cambio de contenido o de orden de tarjetas. Aquí
   GCR (la más ancha, 9 checkboxes) absorbe el espacio sobrante con
   flex-grow:1; Sistema y Periodo se mantienen compactos. flex-wrap
   permite que, si no caben las 3 en una línea, se envuelvan a un segundo
   renglón en vez de desbordar o comprimirse de forma ilegible. */
.il-filter-row--checklist-top,
.il-filter-row--checklist-bottom {
  margin-right: calc(5vw - 55px);
}
.il-filter-row--checklist-top {
  flex-wrap: wrap;
}
.il-filter-row--checklist-top > .il-filter-card:nth-child(1) { /* Sistema Interconectado */
  flex: 0 1 180px;
  min-width: 140px;
}
.il-filter-row--checklist-top > .il-filter-card:nth-child(2) { /* Gerencia de Control Regional */
  flex: 1 1 420px;
  min-width: 320px;
}
.il-filter-row--checklist-top > .il-filter-card:nth-child(3) { /* Periodo */
  flex: 0 1 260px;
  min-width: 220px;
}

/* Laptop (~1366-1430px): con los min-width de arriba sin ajustar, Sistema
   (140px) + GCR (320px) + Periodo (220px) + gaps + padding de la fila
   superan el ancho disponible y las 3 tarjetas se comprimen de forma
   incómoda antes de envolver. Se bajan los min-width lo suficiente para
   que sigan cabiendo en una sola línea en ese rango. Por debajo de esto,
   flex-wrap ya resuelve envolviendo a un segundo renglón — aceptable
   como último recurso, no hace falta evitarlo a toda costa. */
@media (max-width: 1430px) {
  .il-filter-row--checklist-top > .il-filter-card:nth-child(1) {
    min-width: 120px;
  }
  .il-filter-row--checklist-top > .il-filter-card:nth-child(2) {
    min-width: 260px;
  }
  .il-filter-row--checklist-top > .il-filter-card:nth-child(3) {
    min-width: 180px;
  }
}

/* Fila INFERIOR: Nodo/Zona de carga sola, a todo el ancho del
   contenedor. Sin max-height ni overflow-y a propósito: con
   maximo=15 el dropdown puede acumular hasta 15 chips y debe poder
   crecer libremente en altura en vez de recortarse o scrollear
   internamente. */
.il-filter-row--checklist-bottom > .il-filter-card:nth-child(1) {
  flex: 1 1 100%;
}

/* Periodo: el DatePickerRange de react-dates trae tres anchos fijos
   heredados de style.css, todos vivos:
     .my-datepicker                       width: 240px
     .my-datepicker .DateRangePickerInput width: 250px
     .my-datepicker input                 width: 100px  (x2)
   El más restrictivo es el de 250px del contenedor interno: aunque la
   tarjeta se achique, ese hijo no encoge y se sale por el borde derecho.
   Aquí se vuelve todo fluido SOLO en esta fila, para que el control se
   adapte al ancho que le toque. Los dos campos de fecha se reparten el
   espacio con flex en vez de exigir 100px cada uno. */
.il-filter-row--checklist-top .my-datepicker {
  width: 100%;
}
/* El recuadro del control llena el ancho de la tarjeta, igual que el
   dropdown de Nodo llena la suya. No son los 250px fijos de style.css:
   es 100% de la tarjeta, sea cual sea su ancho.

   El tope de 320px existe porque con flex:0 1 260px la tarjeta de
   Periodo puede crecer bastante cuando GCR envuelve o cuando sobra
   ancho. Con solo 168px de contenido, llenar ese ancho separaría las dos
   fechas hasta parecer elementos sueltos; con el tope se queda compacto
   y el aire sobrante queda a su derecha, dentro de la tarjeta. */
.il-filter-row--checklist-top .my-datepicker .DateRangePickerInput {
  width: 100%;
  max-width: 320px;
  justify-content: space-between;
}
/* El hueco lo absorbe la flecha, no los campos de fecha.
   Es la diferencia con el flex:1 1 0 que se revirtió en 65f47ee: aquel
   estiraba CADA campo, dejando el texto de la fecha flotando en una caja
   demasiado ancha. Aquí los campos conservan sus 64px de contenido y solo
   el contenedor de la flecha crece, así que la fecha inicial queda pegada
   al extremo izquierdo, la final al derecho y la flecha centrada entre
   ambas — un único hueco a cada lado en vez de tres repartidos. */
.il-filter-row--checklist-top .my-datepicker .DateRangePickerInput_arrow {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
}
/* flex:0 0 auto en vez de 1 1 0: los campos NO estiran para llenar el
   contenedor, que era lo que separaba la flecha de las fechas. */
.il-filter-row--checklist-top .my-datepicker .DateInput {
  flex: 0 0 auto;
  width: auto;
  min-width: 0;
}
/* "28-07-2026" a 11px mide ~56px. Con el box-sizing:border-box global
   (auth_styles_fixed.css:5) el width incluye el padding, así que 64px
   dejan 60px de contenido: 4px de holgura sobre el texto. Los 100px
   globales de style.css dejaban ~44px muertos por campo. */
.il-filter-row--checklist-top .my-datepicker input {
  width: 64px;
  padding-left: 2px;
  padding-right: 2px;
}
/* El botón de limpiar trae margin 0 10px 0 5px de react-dates, que suma
   15px de aire justo donde no sobra. */
.il-filter-row--checklist-top .my-datepicker .DateRangePickerInput_clearDates {
  margin: 0 2px;
}

/* Alineación vertical de los controles entre tarjetas.
   "Sistema Interconectado" se parte en 2 líneas por ser la tarjeta más
   angosta y empujaba su control más abajo que el de las otras 3. En vez de
   ensanchar la tarjeta, la tarjeta se vuelve columna flex y el control
   (último hijo) se ancla al fondo con margin-top:auto. Como las tarjetas ya
   estiran a la altura de la más alta, los controles quedan a la misma
   altura sin importar si la etiqueta ocupa 1 o 2 líneas.
   Se prefirió esto a reservar 2 líneas de alto en la etiqueta: eso habría
   sumado 16px a la fila cuando ninguna etiqueta se parte (caso de Datos
   crudos en pantallas anchas). Aquí la holgura ya existe y solo se
   redistribuye. */
.il-filter-card {
  display: flex;
  flex-direction: column;
}
.il-filter-card > *:last-child {
  margin-top: auto;
}

/* Etiqueta de la tarjeta en estilo label-caps. Se usa junto a .label-caps
   ("label-caps il-filter-label"): esa clase ya trae 11px / 700 / uppercase
   / letter-spacing 0.05em, y aquí solo se agrega el color del sistema y el
   margen inferior que antes venía del style_componente inline. */
.il-filter-label {
  color: var(--il-on-surface-variant);
  margin-bottom: 5px;
  display: block;
}

/* Fila etiqueta + ícono de ayuda. Antes el ícono era una clase de
   Bootstrap Icons montada sobre el mismo html.Label que contenía el texto,
   lo que hacía que el label heredara la familia tipográfica del ícono.
   Ahora son dos elementos independientes. */
.il-filter-label-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 5px;
}
.il-filter-label-row .il-filter-label {
  margin-bottom: 0;
}
.il-filter-info {
  color: var(--il-outline);
  font-size: 12px;
  line-height: 1;
  cursor: help;
}
.il-filter-info:hover {
  color: var(--il-primary);
}

.il-btn {
  font-family: var(--il-font);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  border-radius: var(--il-radius);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 22px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.il-btn-primary {
  background-color: var(--il-primary);
  color: var(--il-on-primary);
}
.il-btn-primary:hover {
  background-color: var(--il-primary-container);
}
/* Modificador de tamaño reducido. Aditivo: se usa como
   "il-btn il-btn-primary il-btn-sm" y no altera .il-btn, que comparten
   otros botones de la app.
   font-size 13->11px (-15%), padding 8px 22px -> 6px 18px (-25% vertical,
   -18% horizontal), alto total ~-20%.
   El gap baja de 8 a 6px porque el ícono bi-download escala con el
   font-size (1em) y con 8px quedaba muy separado del texto a 11px. */
.il-btn-sm {
  font-size: 11px;
  padding: 6px 18px;
  gap: 6px;
}

/* Modificador de color para acciones de aprobación (ej. "Aprobar" en
   Gestión de Usuarios). Mismo patrón que .il-btn-primary: solo cambia el
   par background/color, el resto (padding, radius, font) sigue viniendo
   de .il-btn / .il-btn-sm. Se usa sobre dbc.Button (que ya trae sus
   propias clases .btn.btn-success de Bootstrap); como los estilos externos
   (dbc.themes.BOOTSTRAP) se inyectan antes que assets/*.css, esta regla
   gana el empate de especificidad por orden de carga sin necesitar
   !important — a diferencia de .il-ag-grid, que compite contra
   style.css, un archivo que carga DESPUÉS de este. */
.il-btn-success {
  background-color: var(--il-success);
  color: #ffffff;
}
.il-btn-success:hover {
  filter: brightness(0.92);
}

/* ============================================================
   Descarga restringida — módulos sin descarga habilitada.
   Componentes en paginas/limites_descarga.py:
     overlay_descarga_restringida()  ->  .il-download-restricted-overlay
     boton_descarga_restringido()    ->  .il-btn-restricted

   El overlay se posiciona contra el ancestro posicionado más cercano.
   .create_container2 ya trae position:relative, así que basta con agregarlo
   como último hijo de esa tarjeta para cubrirla completa: alerta, filtros,
   calendario, tabla y botón. No hace falta ningún wrapper adicional.
   ============================================================ */
.il-download-restricted-overlay {
  position: absolute;
  /* inset:0 cubre exactamente la tarjeta, borde a borde. El bloque
     contenedor de un absolute es el PADDING BOX del ancestro posicionado,
     y ese padding box YA incluye el padding:20px de .create_container2;
     como esa clase no declara border, su padding box coincide además con
     el border box. Un inset negativo saca el velo fuera de la tarjeta.
     El radio iguala el border-radius:20px de .create_container2
     (style.css:136) para seguir la curva de las esquinas. */
  inset: 0;
  z-index: 5;                 /* por encima del header sticky de AgGrid */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 16px;
  background-color: rgba(0, 48, 94, 0.85);
  border-radius: 20px;
}
.il-overlay-icon {
  font-size: 26px;
  line-height: 1;
  color: #ffffff;
}
.il-overlay-title {
  font-family: var(--il-font);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  color: #ffffff;
  margin: 0;
}
.il-overlay-text {
  font-family: var(--il-font);
  font-size: 13px;
  line-height: 18px;
  color: #cfe0f2;
  margin: 0;
}
.il-overlay-cta {
  font-family: var(--il-font);
  font-size: 13px;
  font-weight: 600;
  background-color: #ffffff;
  color: #00305e;
  padding: 8px 16px;
  border-radius: 6px;
  text-decoration: none;
  margin-top: 4px;
}
.il-overlay-cta:hover {
  background-color: #e7e8e9;
  color: #00305e;
  text-decoration: none;
}

/* Mismas medidas que "il-btn il-btn-primary il-btn-sm", el botón de descarga
   de PML/Precios Zonales: padding 6px 18px, font-size 11px, gap 6px,
   font-weight 600 y border-radius var(--il-radius). Antes copiaba las del
   .button legacy de style.css (80x25 fijos, 8px), y al reskinear el resto de
   la app los dos tamaños convivían en pantalla.
   No lleva width ni height: el alto sale del padding y del font-size, igual
   que en .il-btn, para que ambos botones midan lo mismo sin fijar números.

   Mismo azul que .il-btn-primary (var(--il-primary)), no gris: el botón
   debe leerse como parte del sistema, no como un control roto. Lo que
   comunica el bloqueo es el candado, el cursor not-allowed y la opacidad
   reducida, que lo diferencia de un botón activo del mismo color.
   border: none para igualar a .il-btn-primary, que hereda ese valor de
   .il-btn; el borde gris anterior dejaba un halo claro sobre el navy. */
.il-btn-restricted {
  font-family: var(--il-font);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  padding: 6px 18px;
  border: none;
  border-radius: var(--il-radius);
  background-color: var(--il-primary);
  color: var(--il-on-primary);
  opacity: 0.65;
  cursor: not-allowed;
  float: right;
}

/* ---------- Encabezado de sección: título ----------
   El eyebrow ("MDA · PML") se retiró del layout por decisión de diseño;
   .il-eyebrow y la función eyebrow() de los layouts se conservan por si
   se reactiva. Hoy .il-section-head envuelve solo el título, así que el
   gap no tiene efecto y solo aporta el margen inferior. */
/* margin-bottom 2px (antes --il-stack-sm = 8px): junto al margin-top:5px
   que las AgGrid traen inline, el título quedaba a 13px del header navy
   de la tabla. Solo afecta el espacio DEBAJO del título; el de arriba lo
   define el elemento previo (fila de filtros) y no cambia.
   La clase se usa en los 6 bloques título+tabla de html_mda_mtr.py y
   html_comparacion.py, y en ningún otro lado de la app, así que el ajuste
   ya queda acotado a esta área sin necesidad de un selector extra. */
.il-section-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 2px;
}
.il-eyebrow {
  font-family: var(--il-font);
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--il-on-surface-variant);
}
.il-section-title {
  font-family: var(--il-font);
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  color: var(--il-primary);
  margin: 0;
}

/* ---------- Celdas de AgGrid ----------
   AgGrid renderiza <div class="ag-cell"><span class="ag-cell-value">…</span></div>,
   así que la píldora se aplica al span interno: si se aplicara al .ag-cell
   ocuparía todo el alto de la fila y dejaría de leerse como badge.
   Se usan vía 'cellClass' en el columnDef, junto al 'cellStyle' que ya
   traían las columnas — es aditivo, no reemplaza el mecanismo existente. */
.il-cell-badge {
  display: flex;
  align-items: center;
}
.il-cell-badge .ag-cell-value {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--il-font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.02em;
  color: var(--il-primary);
  background-color: var(--il-surface-container);
  border: 1px solid var(--il-outline-variant);
  border-radius: var(--il-radius-full);
  padding: 0 8px;
}

/* Números: misma tipografía (Inter), solo dígitos de ancho fijo para que
   las columnas de precio aliñen por posición decimal. Nunca mono.
   No se toca text-align: los headers de AgGrid siguen alineados a la
   izquierda y cambiar solo la celda los descuadraría. */
.il-cell-num {
  font-family: var(--il-font);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}

/* ---------- Encabezado navy de las tablas AgGrid ----------
   SCOPE: solo las 6 tablas del área de datos PML/Precios Zonales, que
   declaran className="ag-theme-alpine il-ag-grid". Las otras 56 AgGrid de
   la app conservan el encabezado claro de siempre.

   ESPECIFICIDAD — por qué el selector es compuesto y lleva !important:
   assets/style.css:559 ya define, desde fuera de esta rama,

       .ag-theme-alpine .ag-header-cell-label { color: rgba(30,71,121,1) !important; }

   Esa regla tiene especificidad (0,2,0) Y !important, y style.css se carga
   después que este archivo (Dash sirve assets/ en orden alfabético:
   institutional-logic.css < s1.css < style.css). Para ganarle hay que
   competir en su misma capa: !important contra !important, y desempatar
   por especificidad. Por eso el selector encadena ambas clases del mismo
   nodo raíz — .ag-theme-alpine.il-ag-grid (0,3,0) > (0,2,0) — y gana sin
   depender del orden de carga. No se toca ni se borra la regla de
   style.css: sigue vigente para las otras 56 tablas. */
.ag-theme-alpine.il-ag-grid {
  /* Variables del tema alpine: la vía soportada por AgGrid, sin pelear
     especificidad. Cubren el fondo y los iconos. */
  --ag-header-background-color: var(--il-primary);
  --ag-header-foreground-color: #ffffff;
  --ag-header-column-separator-color: rgba(255, 255, 255, 0.25);
  --ag-header-column-resize-handle-color: rgba(255, 255, 255, 0.35);
  --ag-icon-font-color: #ffffff;
  --ag-header-height: 60px;
}
.ag-theme-alpine.il-ag-grid .ag-header {
  background-color: var(--il-primary);
  border-bottom: none;
}
/* Único punto que necesita !important, y solo para empatar el de
   style.css:559 (ver arriba). */
.ag-theme-alpine.il-ag-grid .ag-header-cell-label {
  color: #ffffff !important;
  justify-content: center;
  text-align: center;
}
/* Permite que el texto del header envuelva a 2 líneas en vez de
   cortarse con "..." cuando --ag-header-height crece (ver arriba). */
.ag-theme-alpine.il-ag-grid .ag-header-cell-text {
  white-space: pre-line;
  line-height: 20px;
}
/* Iconos de sort/menú/filtro: sobre navy heredarían el gris oscuro del
   tema y se perderían. */
.ag-theme-alpine.il-ag-grid .ag-header-icon,
.ag-theme-alpine.il-ag-grid .ag-header-cell-menu-button,
.ag-theme-alpine.il-ag-grid .ag-sort-indicator-icon,
.ag-theme-alpine.il-ag-grid .ag-header-cell-filter-button,
.ag-theme-alpine.il-ag-grid .ag-icon {
  color: #ffffff;
  opacity: 0.9;
}
.ag-theme-alpine.il-ag-grid .ag-header-icon:hover,
.ag-theme-alpine.il-ag-grid .ag-icon:hover {
  opacity: 1;
}

/* ============================================================
   Paginador de AG Grid — botones atrás/adelante visibles
   El tema alpine trae esos iconos en gris claro por default, y
   encima la regla .ag-theme-alpine.il-ag-grid .ag-icon de arriba
   (pensada para los iconos del header) los pisa a blanco sin
   querer, porque no está scoped a .ag-header y los de paginación
   comparten la misma clase .ag-icon. Contra el fondo blanco del
   paging panel, en ambos casos quedan invisibles.
   Va con !important para ganarle a esa regla. El estado disabled
   necesita !important también (si no, el !important de los iconos
   activos de abajo le gana) y una clase extra (.ag-disabled) para
   ganar por especificidad y quedar gris en vez de navy.
   ============================================================ */
.ag-theme-alpine .ag-paging-button {
  color: var(--il-primary);
}

.ag-theme-alpine .ag-icon-previous,
.ag-theme-alpine .ag-icon-next,
.ag-theme-alpine .ag-icon-first,
.ag-theme-alpine .ag-icon-last {
  color: var(--il-primary) !important;
}

.ag-theme-alpine .ag-paging-button.ag-disabled .ag-icon {
  color: #b0b8c1 !important; /* estado disabled, gris claro */
}

/* ============================================================
   Gestión de Usuarios (dashboard_admin/admin_render.py) — las dos
   tablas son dbc.Table, no AgGrid, así que .il-ag-grid no aplica aquí;
   esta es la variante equivalente para thead/th planos.
   ============================================================ */

/* Encabezado navy. th,td tienen padding:12px 5px desde style.css:373
   (selector de elemento, especificidad (0,0,1)) — no se toca porque
   .il-table-navy thead th ya le gana por especificidad (0,1,1) sin
   necesidad de !important, y de cualquier forma esta regla no declara
   padding. Bootstrap tampoco fija background-color en thead por
   defecto, así que no hay una segunda regla que competir. */
.il-table-navy thead th {
  background-color: var(--il-primary);
  color: #ffffff;
  font-family: var(--il-font);
  font-weight: 600;
  border-color: var(--il-primary);
  text-align: center;
}

/* Toggle Activo/Inactivo (dbc.Button con color="success"/"danger", que
   ya trae .btn.btn-success/.btn.btn-danger de Bootstrap). Misma lógica de
   orden de carga que .il-btn-success: dbc.themes.BOOTSTRAP se inyecta
   antes que assets/*.css, así que estas reglas ganan el empate de
   especificidad (0,1,0) contra .btn-success/.btn-danger, y (0,2,0) contra
   sus :hover, sin !important.
   Tamaño reducido (12px/4px-14px -> 10px/3px-12px), y luego una vez más
   (10px/3px-12px -> 9px/2px-10px) con la misma proporción que .il-btn ->
   .il-btn-sm: se veía grande junto al resto de controles de la fila
   (dropdown de Membresía a 13px). Ambas variantes heredan de este
   selector base, así que --activo y --inactivo quedan del mismo tamaño
   sin necesidad de repetir la regla. */
.il-status-toggle {
  font-family: var(--il-font);
  font-size: 9px;
  font-weight: 600;
  border-radius: var(--il-radius-full);
  padding: 2px 10px;
  border: 1px solid transparent;
}
.il-status-toggle--activo,
.il-status-toggle--activo:hover {
  background-color: var(--il-success);
  border-color: var(--il-success);
  color: #ffffff;
}
.il-status-toggle--inactivo,
.il-status-toggle--inactivo:hover {
  background-color: transparent;
  border-color: var(--il-outline-variant);
  color: var(--il-on-surface-variant);
}

/* dbc.Alert de confirmación (aprobar, cambiar membresía, toggle
   Activo/Inactivo). Por defecto Bootstrap lo hace block-level de ancho
   completo — se ve como una franja que domina la pantalla para un mensaje
   puntual tipo "Usuario actualizado correctamente.". max-width lo contiene
   sin centrarlo (sigue a la izquierda, igual que el resto del contenido de
   la página); el padding vertical baja de 1rem a 8px. No toca color de
   fondo/borde/texto: eso lo sigue resolviendo Bootstrap vía la prop
   color="success"/"danger" (.alert-success/.alert-danger). Misma lógica de
   orden de carga que .il-status-toggle: gana el empate de especificidad
   (0,1,0) contra .alert sin necesitar !important. Comportamiento
   (cuándo aparece, botón de cerrar) no cambia — es puramente de tamaño. */
.il-alert-compact {
  max-width: 480px;
  padding: 8px 16px;
}
