/* ── 📐 RITMO VERTICAL DE LA BANDA DE DETALLE — asset COMPARTIDO del RCL InsCore.Ui.Gadgets ──────────
   SSOT del espacio ENTRE bloques de una ficha de detalle, para los tres hosts. Self-contained con
   var(--token, fallback): quien traiga tokens los usa, quien no cae al neutro.

   🌳 QUÉ DEFECTO CIERRA, Y POR QUÉ VIVE AQUÍ Y NO EN UNA PANTALLA
   El ritmo vertical de una ficha NO era propiedad de la ficha: era un accidente de cómo la había
   escrito quien la escribió. Medido renderizado el 17-ago-2026 a 1536 y 1280 px:

     · `/collective-policies/{id}` (COL-2026-000002) apila NUEVE secciones plegables SUELTAS, sin
       rejilla que las envuelva ⇒ hueco entre sección y sección = 0 px. La ficha se lee como un
       bloque continuo: no hay dónde acaba una sección y empieza la siguiente.
     · `/policies/{id}` apila las suyas dentro de un `MudGrid`, así que el ritmo se lo pone el
       `spacing` del grid POR CASUALIDAD — nadie lo declaró, y la ficha de al lado no lo hereda.
     · El `CollapsibleSection` del Backoffice se lo escribe a mano en el marcado
       (`pa-4 mb-4` / `mb-2`), o sea una TERCERA respuesta al mismo problema, en un tercer sitio.

   Tres pantallas, tres mecanismos distintos y un resultado que depende de cuál te tocó. Por eso el
   ritmo se declara UNA vez, sobre lo que la sección ES (`.ins-section`), y no se vuelve a teclear:
   la siguiente ficha que alguien escriba nace con él sin acordarse.

   📏 LA CIFRA NO ESTÁ INVENTADA. 16 px es el ritmo entre tarjetas del estándar del sector para
   fichas densas (Material `spacing 2`, SLDS `spacingMedium`) y es EXACTAMENTE el que el
   `CollapsibleSection` del Backoffice ya se escribía a mano con `mb-4`. Se adopta el que la casa
   ya tenía, en lugar de estrenar un número nuevo. */
:root {
    --ins-detail-rhythm: 16px;
    /* Alto de la barra compacta pegajosa cuando está desplegada. Vive aquí y no en su regla porque hay
       DOS consumidores: la propia barra y el carril lateral, que tiene que pegarse por debajo de ella.
       Cableado en los dos sitios, el día que la barra crezca el carril se le mete debajo en silencio. */
    --ins-detail-stickybar-height: 56px;
}

/* El bloque de una ficha lleva SU PROPIO ritmo hacia abajo. Cubre a la vez la sección plegable del
   corredor (`.ins-section`) y la tarjeta suelta que hace de bloque en una ficha (`.ins-detail-block`,
   la clase que se pone donde el bloque no es una sección plegable). */
.ins-section,
.ins-detail-block {
    margin-bottom: var(--ins-detail-rhythm);
}

/* El ÚLTIMO bloque de su contenedor no empuja contra el pie: el ritmo separa bloques, no fabrica cola.
   Y hace un segundo trabajo, que es el que cierra el caso de la rejilla (ver abajo): cuando la ficha
   envuelve cada bloque en su propio `MudItem`, el bloque es SIEMPRE el último de ese item, así que su
   margen se apaga solo y el hueco lo pone quien de verdad reparte ahí. */
.ins-section:last-child,
.ins-detail-block:last-child {
    margin-bottom: 0;
}

/* ── ⚠️ EL RITMO NO SE PONE DOS VECES, Y TAMPOCO SE CEDE A CUALQUIER CIFRA ──────────────────────────
   Este es el filo del arreglo. Hay DOS contenedores en la casa que ya separan a sus hijos, y sobre
   ellos un margen propio se SUMA (el `gap` de flex no absorbe el margen del hijo: lo apila detrás).
   La s72 lo resolvió NEUTRALIZANDO el margen del bloque y cediéndoles el hueco. Medido el 17-ago-2026
   con el stack en pie, eso dejaba el ritmo así:

     · `/policies/{id}` — 13 pares de bloques a **12 px** (el `padding` de los `MudItem` de un
       `MudGrid Spacing="3"`, que es la mitad del spacing por lado);
     · la columna lateral de esa MISMA ficha — **24 px** (`.ins-detail-col { gap: 24px }`);
     · `/collective-policies/{id}` — 16 px, que es el único sitio donde mandaba el SSOT.

   ⇒ **Tres ritmos distintos, dos de ellos en la misma pantalla**, que es exactamente el defecto que
   este fichero existe para cerrar: declarar 16 px y no aplicarlos en la ficha más leída de la app es
   declarar sin entregar. Así que el bloque sigue cediendo el hueco a quien reparte —eso estaba bien—
   pero **el que reparte lo hace AL RITMO**, no a la cifra que le tocara.

   `:has()` es lo que permite decirlo sin nombrar pantallas: se ajusta la rejilla que apila BLOQUES DE
   FICHA, y ninguna otra (una rejilla de campos dentro de una sección no lleva `.ins-section` colgando
   de sus items, y no la toca). */
.ins-detail-col:has(> .ins-section),
.ins-detail-col:has(> .ins-detail-block) {
    row-gap: var(--ins-detail-rhythm);
}

.ins-detail-col > .ins-section,
.ins-detail-col > .ins-detail-block {
    margin-bottom: 0;
}

/* La rejilla reparte con el `padding` de sus items (la mitad del hueco a cada lado) y con un margen
   negativo del mismo valor para que la banda no se desplace. Se reescriben SOLO los dos ejes
   verticales: el hueco horizontal entre columnas es el reparto de la rejilla y no es asunto de este
   fichero, que declara el ritmo VERTICAL entre bloques. */
.mud-grid:has(> .mud-grid-item > .ins-section) > .mud-grid-item,
.mud-grid:has(> .mud-grid-item > .ins-detail-block) > .mud-grid-item {
    padding-top: calc(var(--ins-detail-rhythm) / 2);
    padding-bottom: calc(var(--ins-detail-rhythm) / 2);
}

.mud-grid:has(> .mud-grid-item > .ins-section),
.mud-grid:has(> .mud-grid-item > .ins-detail-block) {
    margin-top: calc(var(--ins-detail-rhythm) / -2);
    margin-bottom: calc(var(--ins-detail-rhythm) / -2);
}

/* ── 🏷️ TEXTO AL PIE DE UN BLOQUE ───────────────────────────────────────────────────────────────────
   Una nota que describe a un bloque vive DENTRO de él. Esta clase es para la nota que cierra una
   sección (alcance, qué no cubre, qué se congeló): la separa de su contenido sin inventar un margen
   suelto en cada pantalla, que es como acababa flotando entre dos tarjetas y perteneciendo a
   ninguna. */
.ins-section__note {
    display: block;
    margin-top: 12px;
}

/* ── 🛤️ M-591 · EL CARRIL LATERAL DE UNA FICHA ───────────────────────────────────────────────────────
   La ficha deja de ser DOS PILAS y pasa a ser columna principal + carril lateral acotado y pegajoso.

   🌳 POR QUÉ, y es lo que ninguna recolocación cerraba: mientras dos pilas se repartan contenido cuya
   altura la fijan los DATOS (36 recibos o 1, sublímites o ninguno), la diferencia entre pilas es una
   variable de NEGOCIO. Cualquier orden fijo acierta en la ficha que se midió y falla en la de al lado.
   M-573 midió 357 px de aire muerto a la derecha y los movió a la izquierda; la izquierda llegó a 472.
   El hueco no era un defecto de ORDEN: era una propiedad de la FIGURA.

   Aquí el carril lleva solo lo de altura CONOCIDA —tomador, vigencia— porque identidad y acciones ya
   viven en la cabecera de la página; todo lo que crece por datos baja a la principal a banda entera.
   Y el aire bajo el carril deja de ser hueco muerto porque el carril ACOMPAÑA al scroll.

   📐 `align-self: flex-start` no es cosmética: la rejilla estira sus items al alto de la fila, y un item
   estirado no tiene por dónde despegarse — el `sticky` sería inerte. Es la línea que hace que funcione.

   📌 Y se pega POR DEBAJO de la barra compacta, no a su misma altura: la barra ocupa el ancho de la
   banda con `z-index: 30`, así que compartir `top` le comería la cabecera al carril. El desplazamiento
   sale del token, no de un 56 tecleado otra vez. */
.ins-detail-rail {
    align-self: flex-start;
    position: sticky;
    top: calc(var(--mud-appbar-height, 64px) + var(--ins-detail-stickybar-height, 56px) + var(--ins-detail-rhythm));
}

/* ⛔ POR DEBAJO DE `md` EL CARRIL BAJA, NO SE ENCOGE. Una tarjeta acotada en una pantalla estrecha es
   una tira inútil, y un pegajoso en móvil se come el alto útil que ya escasea. El punto de corte es el
   `md` de MudBlazor (960 px), el mismo con el que la rejilla apila sus columnas: si el carril siguiera
   pegado cuando ya no hay dos columnas, se pegaría sobre el contenido que acaba de quedar debajo. */
@media (max-width: 959.98px) {
    .ins-detail-rail {
        position: static;
        top: auto;
    }
}

/* ── 🕳️ UN BLOQUE QUE RECORTA NO PUEDE COMERSE UN DATO ───────────────────────────────────────────────
   `.ins-section` lleva `overflow: hidden` (theme.css del corredor) para que su redondeo valga. El
   precio es que cualquier desbordamiento horizontal de su contenido **borra texto sin avisar**: no hay
   barra, no hay elipsis, no queda rastro de que faltaba algo.

   Medido el 17-ago-2026 a 1280 px en `/policies/{id}`: el selector de cuenta de cobro —cuyo valor es
   «IBAN · titular», un renglón sin puntos de corte— se salía **58 px** de su bloque, con el rótulo del
   titular cortado a media palabra. A 1536 px no ocurre: lo dispara el ANCHO, y por eso una sola
   captura no lo veía.

   🌳 La causa no es el selector, es la CLASE: un control flex cuyo contenido no envuelve reclama su
   `min-content` entero (`min-width: auto`) y no encoge. Se le da suelo cero y se le pide que **avise**
   con elipsis en vez de callarse — el valor completo sigue a un clic, en el desplegable. */
.ins-section .mud-select,
.ins-section .mud-input-control {
    min-width: 0;
    max-width: 100%;
}

.ins-section .mud-select .mud-input-slot {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Fuera de una ficha (una pantalla de captura, donde el bloque NO recorta) el selector de cuenta sí
   pide un ancho decente: un IBAN en 90 px no se lee. La regla de arriba, más específica, se lo quita
   allí donde el recorte convertiría ese suelo en texto perdido. */
.ins-payer-account {
    min-width: 220px;
    max-width: 100%;
}

/* ── 📌 BARRA COMPACTA PEGAJOSA DE UNA FICHA DE DETALLE ──────────────────────────────────────────────
   Vive en la columna de contenido (se alinea sola a su ancho) y se pega bajo el AppBar fijo. En reposo
   ocupa 0 de alto (invisible); al salir la cabecera grande, JS le añade `.is-stuck` y se despliega.
   Estaba TRIPLICADA: los dos `theme.css` (idénticas carácter a carácter, 35 líneas) y `portal.css`
   (divergente en cuatro puntos). Self-contained con `var(--token, fallback)`, como el resto de este
   fichero: quien trae tokens los usa, quien no cae al neutro — y así el portal, que no tiene las
   variables de cristal, deja de necesitar su propia copia.

   Lo que NO vive aquí es el TEMA: el tinte opaco + desenfoque de los dos hosts de cristal y la sombra
   del portal se quedan en su hoja, porque son de su tema y no del ritmo. Las cuatro divergencias, con
   su resolución, para que nadie las vuelva a descubrir:
     1. `border-radius` — portal 8px literal, cristal `var(--app-radius-input)` = 12px ⇒ el fallback
        reproduce los dos exactos.
     2. `border-bottom` — ídem con `--glass-border` sobre `--mud-palette-lines-default`.
     3. `box-shadow` es SOLO del portal y NO sube: dársela a los hosts de cristal sería un cambio
        visual que nadie ha medido.
     4. Transiciones — al portal le cambia la CURVA de un fundido de 180 ms (de `ease` a la del
        cristal). Es la única diferencia real que introduce la unificación, y queda declarada.

   ⚠️ NO DECLARAR AQUÍ `background-image`: corredor y backoffice cargan `theme.css` ANTES que esta hoja,
   así que su tinte (`linear-gradient` + `backdrop-filter`) sobrevive solo mientras este bloque no pise
   esa propiedad. En el portal el orden es el inverso (`portal.css` después), y por eso su sombra gana
   sin más. */
.ins-detail-stickybar {
    position: sticky;
    top: var(--mud-appbar-height, 64px);
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 12px;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
    padding: 0 10px;
    border-radius: var(--app-radius-input, 8px);
    border-bottom: 1px solid var(--glass-border, var(--mud-palette-lines-default));
    background-color: var(--mud-palette-surface);
    transition: max-height var(--anim-normal, 280ms) var(--anim-ease, cubic-bezier(0.16, 1, 0.3, 1)),
                opacity var(--anim-fast, 180ms) var(--anim-ease, cubic-bezier(0.16, 1, 0.3, 1));
}

.ins-detail-stickybar.is-stuck {
    max-height: var(--ins-detail-stickybar-height, 56px);
    opacity: 1;
    pointer-events: auto;
    padding-top: 6px;
    padding-bottom: 6px;
    margin-bottom: 1rem;
}

/* ── 🖱️ EL CHROME FIJO RESERVA SU FRANJA — WCAG 2.2 SC 2.4.11 «Focus Not Obscured» ─────────────────
   🌳 QUÉ DEFECTO CIERRA. La barra superior de la app (`header.mud-appbar-fixed-top`, con su
   `.mud-toolbar` dentro) y la barra compacta de la ficha ocupan los primeros píxeles del viewport de
   forma PERMANENTE. Ocupar no es reservar: hasta hoy nadie le había dicho al navegador que esa franja
   está tomada, así que cualquier «tráeme esto a la vista» —tabular con el teclado, un ancla, un
   `scrollIntoView` de Blazor, el salto al primer campo con error— dejaba el control DEBAJO de la barra:
   ni se ve ni se puede pulsar.

   📐 MEDIDO el 18-ago-2026 con el stack en pie, a 1280x800, llamando a `scrollIntoView()` sobre cada
   control de la banda y comparando su borde superior con la franja del chrome —derivada preguntándole
   al navegador quién recibe el clic a cada altura, no tecleada—: reserva **64 px**, dueño
   `mud-appbar mud-appbar-fixed-top`. **31 de 62** controles acababan DEBAJO: /policies 22 de 31,
   /claims 9 de 17, /persons 0 de 14. Con la regla puesta: **0 de 62**, `scroll-padding-top` = 136 px.
   No es un caso raro: es la mitad de la ficha.

   🏆 El estándar del sector para esto es `scroll-padding` en el contenedor de scroll (CSS Scroll
   Snap §7), no un `scroll-margin` por control ni un desplazamiento a mano en JS: se declara UNA vez
   sobre lo que el chrome MIDE y lo aplica el navegador a cualquier vía de «traer a la vista», incluidas
   las que aún no existen.

   La cifra sale de los MISMOS tokens con los que el carril lateral se pega por debajo de la barra
   compacta (arriba, `.ins-detail-rail`): appbar + barra compacta + un ritmo de aire, para que el
   control aterrice separado del borde y no lamiéndolo. En las pantallas sin barra compacta la reserva
   sobra por 56 px, y eso NO hace daño —el control queda un poco más abajo—, mientras que quedarse
   corto sí lo hace: lo esconde. */
:root {
    scroll-padding-top: calc(var(--mud-appbar-height, 64px) + var(--ins-detail-stickybar-height, 56px) + var(--ins-detail-rhythm));
}

.ins-detail-stickybar__title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}
