/* Utilidades de LAYOUT/SCROLL transversales — asset COMPARTIDO del RCL InsCore.Ui.Gadgets.
   Único hogar para los 3 hosts (broker / backoffice / portal-cliente). Self-contained con
   var(--token, fallback): no depende de los tokens de ningún host en concreto.

   Razón de ser: el shell (MudLayout → MudMainContent → MudContainer) ya aporta el scroll de la
   PÁGINA. Cualquier hijo que declare su propio height/max-height + overflow crea una SEGUNDA barra
   ("doble scroll"). Estas clases dan el patrón de scroll ÚNICO por superficie. */

/* ── Pane de altura completa (chat, consolas, paneles "tipo app") ──────────────────
   El panel llena el viewport y SOLO su contenido interno scrollea; la página NO scrollea.
   Misma filosofía ya probada en .app-drawer .mud-navmenu (flex column + min-height:0 + overflow
   en el hijo). El descuento de "chrome" (AppBar + paddings del MudContainer + cabecera de página)
   se afina por página vía la variable --ins-chrome (style inline), con un fallback razonable. */
.ins-fill {
    display: flex;
    flex-direction: column;
    height: calc(100dvh - var(--ins-chrome, 13rem));
    min-height: 18rem; /* en viewports muy bajos no colapsa por debajo de lo usable */
}

/* Zona desplazable del pane: ocupa el espacio libre y es la ÚNICA que scrollea. min-height:0 es
   imprescindible en flex para que el hijo pueda encoger y mostrar su barra (sin él, desbordaría). */
.ins-fill__scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Pie fijo del pane (input de chat, barra de acciones): no scrollea, queda siempre visible. */
.ins-fill__footer {
    flex: 0 0 auto;
}

/* ── Selects con lista larga (ej. filtro de Ramo) ─────────────────────────────────
   El popover y la MudList interna traen ambos max-height + overflow:auto → DOS scrollbars
   anidados ("doble scroll"). Dejamos que scrollee solo el popover (lista interna sin límite) → un
   único scroll, holgado para que la lista quepa en pantallas normales. Se aplica con
   PopoverClass="ins-tall-popover" en MudSelect/MudAutocomplete. SSOT compartido por los 3 hosts
   (antes duplicado en los theme.css de broker y backoffice; el portal-cliente no lo tenía). */
.ins-tall-popover {
    max-height: 70vh !important;
    overflow-y: auto !important;
}
.ins-tall-popover .mud-list {
    max-height: none !important;
    overflow-y: visible !important;
}

/* ── DOBLE SCROLL, red de seguridad GLOBAL (no opt-in) ─────────────────────────────
   El patrón .ins-tall-popover de arriba solo actúa si el MudSelect/MudAutocomplete recuerda poner
   PopoverClass="ins-tall-popover"; en la práctica se olvida y el doble scroll reaparece (p. ej. los
   filtros de /cima/log). Esta regla lo cubre para CUALQUIER popover que contenga una MudList
   (select, autocomplete, menú) sin depender de ninguna clase por componente: el popover es el ÚNICO
   scroller (cap 70vh) y la lista interna nunca añade su propia barra. Los popovers sin lista
   (date/color/pickers) no tienen .mud-list → no se ven afectados. */
.mud-popover:has(.mud-list) {
    max-height: 70vh !important;
    overflow-y: auto !important;
}
.mud-popover .mud-list {
    max-height: none !important;
    overflow-y: visible !important;
}

/* ── 🫨 UN DESPLEGABLE NACE COLOCADO — nunca un frame en la esquina de la pantalla ─────────────
   Reportado por él en vivo sobre el listado de recibos: «hay un PARPADEO en la parte superior
   IZQUIERDA de la pantalla».

   🔬 MEDIDO el 17-ago-2026 contra la app en pie (muestreo por requestAnimationFrame, 3 aperturas de 3):
   el panel se pinta DOS frames (~20-35 ms) en (0,0) a tamaño completo —214×189 px, opacidad 1,
   `mud-popover-open`— y solo entonces salta a su sitio. En ese frame su `style` inline NO tiene `left`,
   `top` ni `z-index`: solo las transiciones. Blazor pone la clase que lo hace VISIBLE y el colocador de
   MudBlazor escribe las coordenadas uno o dos frames después; un popover sin coordenadas cae en el
   origen. ⇒ No era M-589 falso: hoy dura dos frames en vez de quedarse.

   📊 Y NO ES DE LOS «FIJOS», que fue la primera hipótesis: censado abriendo cada activador de 5 rutas,
   **10 de 25** popovers abiertos se pintan en la esquina — 9 de 23 NO fijos y 1 de 2 fijos. Por eso la
   regla no lleva `.mud-popover-fixed`: apuntarla ahí habría cubierto 1 de los 10.

   🎫 LA PREMISA, con su denominador: esta regla usa el `style` inline como testigo de que el colocador
   ya pasó, así que solo vale si el colocador coloca SIEMPRE por `left/top` y nunca por `transform`.
   Medido sobre la misma población: **24/24** popovers acaban con `top:` y `left:` en el style inline y
   **0/24** colocados por `transform`. Si algún día apareciera uno colocado por transform, esta regla lo
   apagaría y hay que reapuntarla al hecho nuevo — el guard e2e lo cantaría.

   🚪 FALLA ABIERTA, Y ESO ES PARTE DE LA REGLA, NO UN ADORNO. Escrita como un simple `opacity: 0`, un
   popover al que el colocador nunca le escribiera `top:` quedaría invisible PARA SIEMPRE: eso cambia un
   parpadeo de dos frames por un menú que no se abre, que es peor que el defecto. Por eso la opacidad la
   devuelve una animación con retardo: el peor caso posible es «aparece 200 ms tarde», nunca «no
   aparece». En el caso normal el colocador llega en dos frames, el selector deja de casar y no hay
   retardo ninguno.

   ⚠️ Trampa conocida y asumida: `[style*="top:"]` casa por SUBCADENA, así que un `padding-top:` en el
   style inline la engañaría. Hoy no ocurre (MudBlazor solo escribe ahí `max-width`, `left`, `top`,
   `z-index` y las transiciones), y si ocurriera el fallo es hacia el lado seguro —el popover se pinta
   antes de tiempo, o sea vuelve el parpadeo— y lo caza el guard, no lo esconde. */
@keyframes ins-popover-fail-open {
    to { opacity: 1; }
}

.mud-popover.mud-popover-open:not([style*="top:"]) {
    opacity: 0;
    animation: ins-popover-fail-open 1ms linear 200ms forwards;
}

/* ── 🔔 EL CONTADOR DE LA CAMPANA SE PEGA AL ICONO, NO AL BOTON ────────────────────────────────
   Reportado por el en vivo (s76): «el numero de la campanita que quede mas cerca pegado de la
   campanita, que no quede tan suelto».

   🔬 CAUSA, MEDIDA contra la app en pie el 18-ago-2026 (viewport 1440x900, tema claro):
   el `MudBadge` envuelve un `MudIconButton`, y MudBlazor ancla el globo a la caja del BOTON
   (`.mud-badge.mud-badge-top.right.mud-badge-overlap { inset: auto auto calc(100% - 12px) calc(100% - 12px) }`).
   El boton mide 48x48 (padding 12px) y el glifo solo 24x24 centrado, asi que la esquina del globo
   caia exactamente sobre la esquina de la CAJA del glifo — pero la campana dibujada dentro de esa
   caja deja ~4px de margen lateral y ~2px arriba, y el globo se iba ademas a y=0, pegado al borde
   superior de la barra. Cifras: glifo [1044,20 → 1068,44] · globo [1068,0 → 1088,20]. Es decir, el
   globo salia 20px por encima del glifo y 20px a su derecha: flotaba en el aire entre dos iconos.

   🎯 EL ARREGLO: correr el globo hacia dentro 9px en cada eje. 9 = los 12px de relleno del boton
   menos los 3px de solape que queremos sobre el glifo. Su esquina inferior-izquierda cae entonces
   en el CUADRANTE SUPERIOR DERECHO del glifo, que en la campana de Material esta VACIO (la cupula
   no llega ahi), asi que se pega sin tapar nada. Medido tras el cambio: globo [1059,9 → 1079,29].

   ⚠️ VIVE AQUI Y NO EN CADA .razor, Y SIN CLASE QUE ALGUIEN PUEDA OLVIDAR PONER: la pieza esta
   declarada DOS veces byte a byte (`InsCore.Web/Components/Shared/InboxBell.razor` y
   `InsCore.PortalCliente/Components/Layout/InboxBell.razor`). Un `Style` en linea en cada una divergiria
   en cuanto alguien tocase una sola, y una clase de adhesion se olvida en el tercer host. El selector
   apunta al MECANISMO del defecto —un globo anclado a un boton de icono— y no a la captura.

   📊 POBLACION, censada el 18-ago-2026 sobre el repo entero: `<MudBadge` aparece **2 veces**, y
   **2 de 2** envuelven un `MudIconButton` (las dos campanas). O sea, la regla cubre el 100 % de los
   globos que hay y no toca ninguno que no exista. Si algun dia nace un `MudBadge` sobre un boton de
   icono que NO quiera pegarse, se le da una clase de escape aqui — no se retira la regla.

   El area de clic NO se toca: el `transform` mueve el globo, nunca el boton; y `pointer-events:auto`
   del propio globo sigue siendo suyo, sobre el mismo boton que ya habia debajo. */
.mud-badge-root:has(> .mud-icon-button) .mud-badge {
    transform: translate(-9px, 9px);
}
