/* Componentes de formulario transversales (InsFormActions / InsFormSection).
   Enlazado una vez por host desde App.razor: _content/InsCore.Ui.Gadgets/insForms.css */

/* ── Barra de acciones fija al pie del formulario ───────────────────────────── */
.ins-form-actions {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 16px;
    padding: 12px 16px;
    background: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
    border-radius: 0 0 var(--mud-default-borderradius) var(--mud-default-borderradius);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, .06);
}

/* ── Barra de acciones del asistente de pasos (`StepperPage`) ─────────────────
   La geometría vivía escrita a mano en el `style` del componente. Sube aquí por el motivo de siempre
   —el `Style` en línea solo debe llevar lo que CAMBIA— y por uno nuevo y concreto (M-310): un estilo en
   línea gana a cualquier hoja de autor, así que mientras estuviera ahí la reserva de la esquina del
   asistente (`insAiLauncher.css`) no podía alcanzar a esta barra. Los márgenes negativos compensan el
   `padding` lateral para que el borde superior llegue de lado a lado del panel.
   ⚠️ El nombre es un CONTRATO: `StepperPage` vive en el RCL y lo pintan diez pantallas en tres hosts. */
.stepper-actions {
    position: sticky;
    bottom: 0;
    z-index: 2;
    gap: 8px;
    padding: 12px 4px;
    margin-left: -4px;
    margin-right: -4px;
    background: var(--mud-palette-background);
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* ── Barra de acciones fija que NO es ni `InsFormActions` ni `StepperPage` ────────────────────────
   El tercer sitio donde la plataforma pone una acción al pie: una tarjeta flotante que aparece solo
   cuando hay algo que guardar (editor de textos de documento, editor de condicionado). Existía ya, pero
   sin nombre: cada pantalla se escribía su `position:sticky; bottom:16px; z-index:5` a mano y —lo que
   importa— su propio esquive del asistente flotante (`margin-right:76px`), o sea la clase parcheándose
   de una en una. Con nombre, la reserva de la esquina la aplica UNA regla (M-310) y no catorce.
   Lleva su propio `padding` a propósito, para no depender de una utilidad de espaciado del marco que
   podría declararse `!important` y ganarle a la reserva. */
.ins-sticky-actions {
    position: sticky;
    bottom: 16px;
    z-index: 5;
    padding: 12px 16px;
    border-radius: 8px;
}

.ins-form-actions__status {
    display: flex;
    align-items: center;
    font-size: .875rem;
}

.ins-form-actions__buttons {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.ins-form-actions__dirty { color: var(--mud-palette-warning); font-weight: 500; }
.ins-form-actions__saved { color: var(--mud-palette-success); font-weight: 500; }
.ins-form-actions__clean { color: var(--mud-palette-text-secondary); }

/* ── Sección de formulario colapsable ───────────────────────────────────────── */
.ins-form-section { margin-bottom: 12px; }

.ins-form-section__head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

/* ── M-575 · El título ENCABEZA: filete + aire entre la cabecera y su contenido ────────────────────
   Re-medido el 17-ago (tercera visita del mismo defecto, tras M-021 y M-149): título de sección y
   rótulo de ítem quedaron a TRES píxeles de cuerpo (17 vs 14), mismo token de color y cero separación
   estructural, así que el 600→700 de M-149 solo no alcanza — el título CONVIVE con el contenido en
   lugar de encabezarlo, y el usuario lo re-reportó mirándolo en vivo. Los dos ejes tipográficos ya
   gastados (cuerpo y peso) demostraron no bastar, y el COLOR quedó cerrado en S45: ya separa
   `.ins-field-label` de `.ins-field-value`, y usarlo aquí lo dejaría diciendo dos cosas.

   El eje NUEVO es ESTRUCTURAL, no tipográfico: un FILETE bajo la fila del título y AIRE a ambos lados
   —cómo separa el sector «de qué se habla» de «lo que se dice» cuando la tipografía ya no da más—.
   (La BANDA de fondo se descartó: añadiría otra superficie al problema de contraste de superficies.)

   Cubre los TRES componentes de título con UNA regla, por sus dos clases de cabecera:
     · `.ins-section__head`      — CollapsibleSection del corredor Y del backoffice (ambos la llevan);
     · `.ins-form-section__head` — InsFormSection del RCL (27 sitios en 11 pantallas).

   ⚠️ El filete solo existe cuando hay CONTENIDO debajo — una raya que no separa nada es ruido:
     · `:not(:last-child)`: plegada, la cabecera es el último hijo de su tarjeta, y una raya pegada al
       borde inferior sería un doble canto;
     · `.mud-panel-expanded`: el MudExpansionPanel NO saca la cabecera del árbol al plegar, así que ahí
       decide la clase de estado de la librería. ⚠️ Verificada en el DOM VIVO (17-ago, MudBlazor 8.4.0),
       no en sus fuentes: el dll ni siquiera contiene la cadena legible y el min.css la menciona sin que
       eso pruebe uso — medido: un panel que NACE abierto la lleva desde el primer render y el plegado no.

   El aire de ENCIMA lo declara esta regla (12px, el mismo que ya tenía el corredor: para él es un
   no-op deliberado); el de DEBAJO lo pone cada superficie donde ya vivía su geometría (el body de la
   sección del corredor, el `pt-3` del backoffice, el padding del panel del RCL). El color es
   `--mud-palette-lines-default` porque es el único separador que los TRES hosts inyectan siempre — el
   portal enlaza esta hoja SIN theme.css propio, así que aquí no puede entrar ningún token de host. */
.ins-section__head:not(:last-child),
.mud-expand-panel.mud-panel-expanded .ins-form-section__head {
    border-bottom: 1px solid var(--mud-palette-lines-default);
    padding-bottom: 12px;
}

/* El título de sección consume la jerarquía declarada abajo; aquí no decide nada por su cuenta. */

/* ── Jerarquía tipográfica de lectura — DECLARADA UNA VEZ ────────────────────────────
   El defecto que esto cierra NO es la densidad: es la DISPERSIÓN. Hoy cada pantalla decide por su
   cuenta cómo se ve el rótulo de un dato de solo lectura y cómo se ve su valor.

   MEDIDO en el host de correduría (fase 9 · L4·B.7): **431** `Typo="Typo.caption"`, de los cuales
   **277** llevan además `Style="color:var(--mud-palette-text-secondary)"` escrito a mano y **154**
   NO lo llevan. Es el mismo papel —el rótulo de un dato— pintado de dos maneras distintas según
   quién escribiera la pantalla. Con 431 sitios, ninguna revisión visual puede sostener eso.

   Tres clases, tres papeles, un solo sitio donde se cambian. Viven en el RCL, así que los TRES
   hosts (correduría, backoffice, portal) heredan la misma jerarquía sin copiar nada.

   ⚠️ Cuatro de los cinco papeles NO declaran `display`: `MudText Typo="Typo.caption"` emite un `<span>`
   (no un `<p>`), y hay marcado que cuenta con que sea en línea y marcado que añade `d-block` a mano.
   Forzar `display:block` en ellos movería de sitio cosas que no se han medido. Lo elige el llamante.
   🔻 La EXCEPCIÓN es `.ins-hint`, y no por gusto: ese hueco es el que produjo M-214/M-340 y se cerró
   MIDIENDO sus 330 consumidores uno a uno. El razonamiento entero vive en su propio bloque, abajo. */

/* Título de un bloque de formulario o de una tarjeta.

   M-149 · El peso sube de 600 a 700, y el eje elegido es el PESO —no el cuerpo ni el color—, uno solo, como
   pedía el mandato. Por qué el peso:

     · el CUERPO no vale: lo fija el `Typo` que elige cada llamante (h6, subtitle1, body1…), así que meter un
       `font-size` aquí pelearía con la escala de MudBlazor en más de cien sitios y movería el ritmo vertical
       de pantallas que nadie ha mirado. Además el cuerpo ya diferenciaba —17 px contra 14— y esos tres
       píxeles son justo la distancia que el mandato mide como INSUFICIENTE;
     · el COLOR ya está gastado en esta jerarquía: es lo que separa `.ins-field-label` (secundario) de
       `.ins-field-value` (primario). Usarlo también aquí lo dejaría diciendo dos cosas distintas;
     · el PESO es el eje en el que esta jerarquía ya habla (600 · 500 · 500 · 400 heredado), sobra un escalón
       por arriba y 600→700 se nota a 14 px, que es donde los tres píxeles no se notan.

   Queda la escalera completa y monótona: título 700 · rótulo de ítem 600 · valor 500 · rótulo de campo 500
   (secundario) · pista 400 (secundario). */
.ins-section-title,
.ins-form-section__title {
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--mud-palette-text-primary);
}

/* ── `.ins-item-label` · el QUINTO papel: el rótulo de un ÍTEM dentro de una lista ────────────────
   El nombre de una fila, de una tarjeta de una rejilla, de un paso de una línea de tiempo: «Cobertura de
   daños», «Alta de producto», el número de una póliza. Nombra un elemento del conjunto, no un dato suelto,
   y por eso pesa más que `.ins-field-label` y lleva color primario: es lo que el ojo usa para navegar.

   Por qué nace (M-149): M-021 declaró cuatro papeles y este se quedó fuera, así que cada pantalla se lo
   inventaba con un `font-weight` en línea. Medido el 5-ago sobre los tres hosts: 136 `font-weight` en línea,
   de los que 32 son exactamente este papel (`Typo.body2` + peso a mano). Y el resultado era el defecto que
   el mandato describe: salían a 14 px/600, el mismo peso y el mismo color que un título de sección a 17 px,
   o sea tres píxeles de diferencia y ninguna otra.

   ⚠️ El nombre es un CONTRATO: lo consumen los tres hosts. No declara `font-size` por el mismo motivo que
   sus hermanas —lo elige el `Typo` del llamante— ni `display`, para no mover marcado que cuenta con que sea
   en línea. */
.ins-item-label {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

/* Rótulo de un dato de solo lectura ("Tomador", "Vigencia desde"). Secundario: nombra, no informa. */
.ins-field-label {
    font-weight: 500;
    letter-spacing: .02em;
    color: var(--mud-palette-text-secondary);
}

/* Valor de un dato de solo lectura. Es lo que el usuario viene a leer, así que manda sobre su rótulo.
   `overflow-wrap: anywhere` es sustantivo, no adorno: un valor de negocio (nombre de tomador,
   descripción de garantía, referencia externa) NO tiene longitud acotada, así que parte antes que
   desbordar su tarjeta. Es el mismo criterio del barrido de `white-space:nowrap`. */
.ins-field-value {
    font-weight: 500;
    color: var(--mud-palette-text-primary);
    overflow-wrap: anywhere;
}

/* ── `.ins-hint` · el CUARTO papel de la jerarquía de lectura ─────────────────────
   Nació en `theme.css` del host del corredor porque durante la ola Z el RCL era zona de otro lote y
   quien lo escribió no podía tocar `src/Shared/**`. Sube aquí al fundir (M-138): partir una jerarquía
   de lectura en dos ficheros es exactamente la dispersión que M-021 venía a cerrar, y el reparto por
   zonas la habría dejado creada. Los cuatro papeles viven juntos o dejan de ser una jerarquía.

   Qué es: al barrer el host se midió que de los 449 `Typo.caption`, los que escribían el color
   secundario a mano NO eran todos rótulos — 216 son texto EXPLICATIVO, y las claves lo dicen solas:
   `*_Note`, `*_Intro`, `*_Helper`, `*_Hint`. Meterlos en `.ins-field-label` los habría puesto en peso
   500: una nota que debe hablar bajo, hablando un poco más alto. Son un papel propio y les faltaba su
   clase.

   Por eso NO declara `font-weight`: hereda el 400 del `Typo.caption` que lo lleva.

   ── M-214 (y M-220, que es el mismo defecto) · POR QUÉ AHORA DECLARA `display` ────────────────────
   El usuario lo reportó con captura TRES veces, en tres pantallas distintas: en «Datos que solicita» de
   la ficha de producto se leía literalmente «Zona geográfica de riesgo**Banda del eje "Zona geográfica de
   riesgo"; modula la prima…**» —sin espacio, sin salto, sin nada, y en las SEIS filas—; en «Qué cubre» de
   la misma ficha; y en la del multitarificador. Textual suyo: «siempre que se ponen esas letricas
   pequeñas quedan todas solapadas».

   🌳 La causa: esta clase resolvió el COLOR y no resolvió la CAJA. Declaraba `color` y nada más, así que
   el `<span>` de `Typo.caption` caía en la misma línea de texto que el rótulo y el navegador los
   concatenaba — haciendo exactamente lo que se le pedía. El defecto no era del `<td>` de la captura: era
   que el cuarto papel de la jerarquía no decía cómo se COLOCA.

   ⚖️ Por qué `display:block` a secas SÍ vale, cuando el mandato avisaba de que no. Se midieron las 330
   apariciones una a una, clasificadas por lo que les PASA con la declaración, no por dónde viven:

     · **104** son hijas de un contenedor flex (`MudStack` o `d-flex`). El layout flex YA blocifica a sus
       hijos —CSS Flexible Box §4, *«the display value of a flex item is blockified»*—, así que ahí esta
       línea es INERTE. Y no es un rincón: es justo donde vive el uso «en línea» que el mandato temía
       romper (la pista junto a un icono, junto a una fila de chips). El flex lo protege solo.
     · **51** ya eran bloque: `d-block` escrito a mano, o un `Typo` que emite `<p>`/`<h*>`. INERTE también.
     · **175** son el `<span>` en flujo normal. Aquí es donde actúa, y es donde estaban las tres capturas.

   De esas 175, las que de verdad querían ir EN LÍNEA son **UNA** —medida, no estimada—, y lleva escrita
   la excepción de abajo. Ese es el criterio: bloque por defecto porque el papel de este texto es
   EXPLICAR el rótulo que tiene encima, y quien lo quiera en línea lo DICE.

   🚫 Y no declara `margin`: 45 de los consumidores ya se escriben su `mt-1`/`mt-2`, así que un margen por
   defecto se sumaría al suyo y movería el ritmo vertical de pantallas que nadie ha mirado. Un solo eje. */
.ins-hint {
    display: block;
    color: var(--mud-palette-text-secondary);
}

/* ── `.ins-muted` · el SEXTO papel: un DATO que habla bajo ────────────────────────────────────────
   Qué es: una línea de dato que acompaña sin reclamar — «899,00 €/mes», «Periodo vigente: 23/08 – 22/09»,
   «Método de pago: Domiciliación SEPA ···· 1332». No es un rótulo (`.ins-field-label` nombra un campo),
   no es una pista (`.ins-hint` EXPLICA lo de encima y por eso es bloque): es el propio dato, dicho en voz
   baja porque el ojo va a otra cosa.

   🔴 De qué defecto nace, y es la parte que importa. Estas líneas se pintaban con
   `MudText Color="Color.Secondary"`, que NO es «texto secundario»: es el color de MARCA. Censado en la
   s110: **110 usos en 42 ficheros** del host del corredor, de los que **59 son `MudText`** (31 `caption`,
   24 `body2`, 2 `overline`, 1 `body1`). Con el violeta de la marca anterior el par daba **2,23:1** sobre
   la tarjeta oscura, contra un suelo de 4,5:1 — y el usuario lo reportó en vivo con una captura de
   `/suscripcion` donde el precio, el periodo y el método de pago salían todos en violeta apagado.

   🪤 Y el defecto se AGRAVÓ sin que nadie tocara esas 59 pantallas: hasta el 25-ago `Secondary` era un
   cian legible; el rebranding le cambió la ENTRADA y se apagaron todas a la vez. Es la razón de que el
   papel necesite CLASE y no un color escrito en cada sitio: lo que estaba mal no era el tono, era que
   59 pantallas dependieran de un token cuyo trabajo es otro.

   🚫 Un solo eje, igual que sus hermanas: **solo el color**. Ni peso (lo pone el `Typo` del llamante) ni
   `display` (estas líneas viven en flujo o dentro de un flex, y blocificarlas movería ritmo vertical de
   pantallas que nadie ha mirado). Lo que este papel arregla es de QUÉ token sale la tinta. */
.ins-muted {
    color: var(--mud-palette-text-secondary);
}

/* ── `.ins-hint--inline` · la EXCEPCIÓN, y se declara ────────────────────────────────────────────────
   Para la pista que va DENTRO de una frase, no debajo de ella: hoy, el paréntesis que califica el título
   de una cláusula («Cobertura de daños **(limitativa)**»), donde partirla a su propia línea rompería la
   lectura en vez de arreglarla.

   ⚠️ Va DESPUÉS de `.ins-hint` a propósito: las dos son un selector de clase, o sea la MISMA
   especificidad (0,1,0), y con especificidad empatada gana la última en orden de aparición. Si alguien
   mueve este bloque por encima del de arriba, la excepción deja de ganar y no lo dice ningún error.

   🚦 Criterio para usarla, para que no se convierta en el escape de todo: la pista comparte LÍNEA con el
   contenido al que acompaña porque se lee como parte de esa frase. Si va debajo de un rótulo —aunque sea
   corto, aunque quepa al lado— NO es este caso, es el de arriba. Lo vigila el guard
   `AHintNeverGluesToTheLabelItExplainsTests`, que cuenta los que comparten línea sin declararla. */
.ins-hint--inline {
    display: inline;
}

/* ── `.ins-grow` / `.ins-hold` · QUIÉN CEDE cuando falta sitio ─────────────────────────────────────
   El patrón «lo que crece + la acción que NO se encoge», declarado UNA vez para los tres hosts.

   Qué defecto cierra. M-172 (nueve filas), M-176 (la tabla del catastro) y M-124 son EL MISMO defecto:
   una fila con un campo/texto y una acción al lado en la que **nadie declara quién cede**. En flex el
   reparto por defecto es `flex-shrink:1` para todos, así que el navegador reparte la falta entre el
   campo y el botón y el rótulo de la acción se recorta («Guarda…»); en tabla, ninguna columna renuncia
   y la tabla sale más ancha que su contenedor, dejando la acción detrás de un scroll horizontal. En los
   dos casos lo que se esconde es la ACCIÓN, que es lo único irrecuperable: un texto cortado se adivina,
   un botón que no se ve no existe.

   Por qué UNA pareja y no dos. Las declaraciones que hacen falta en fila flex y en celda de tabla son
   disjuntas y mutuamente inertes: `width:1%` no significa nada para un ítem flex y `flex:0 0 auto` no
   significa nada para un `<td>`. Juntándolas, el mismo par de nombres sirve a `<MudStack Row>` y a
   `<MudTr>` — y así M-172 no tiene que estrenar una tercera clase para decir lo mismo.

   🔑 `min-width: 0` en `.ins-grow` es la RAÍZ, no un adorno: el mínimo automático de un ítem flex es su
   contenido, así que sin esta línea el campo se niega a encoger y la falta cae entera sobre el vecino.

   ⚠️ El nombre es un CONTRATO (lo consumen los tres hosts) y el par es INSEPARABLE: `.ins-hold` sin un
   `.ins-grow` que ceda no reparte nada, solo mueve el problema. Se usan SIEMPRE juntos en la misma fila.
   🚫 Y sustituye al `Style` en línea: así nacieron las nueve de M-172. */
.ins-grow {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
    overflow-wrap: anywhere;
}

.ins-hold {
    flex: 0 0 auto;
    width: max-content;
    max-width: 100%;
    white-space: nowrap;
}

/* ── `.ins-basis-wide` · el campo que pide MÁS SITIO en su fila ────────────────────────────────────
   Acompaña a `.ins-grow` cuando un campo debe llevarse una tajada mayor del ancho antes de que la fila
   se parta: `.ins-grow` dice quién CEDE, esto dice cuánto PIDE de salida.

   🪤 EXISTE PORQUE `Style` NO PUEDE HACER ESTE TRABAJO, y la trampa costó dos intentos y una medición en
   el navegador (s122). En un input de MudBlazor, `Class` y `Style` aterrizan en ELEMENTOS DISTINTOS:
     · `Class` → `.mud-input-control`, que es el ítem de la FILA (por eso `.ins-grow` sí funciona ahí);
     · `Style` → `.mud-input` interior, que vive dentro de `.mud-input-control-input-container`, un flex
       en COLUMNA.
   O sea que un `flex-basis` escrito en `Style` pensando en el ancho cae sobre el eje principal de una
   columna y fija la ALTURA. Medido en `/settings/legal-limits`: el `<input>` medía sus 40 px correctos y
   su contenedor 260, con `inline-style="flex-basis:260px"` — una caja vacía de 260 px de alto que el
   corredor reportó dos veces. Leyendo el `.razor` no se ve; hay que preguntárselo al navegador.
   ⇒ Toda medida de reparto de fila va por CLASE. `Style` solo sirve aquí para el eje transversal
   (`max-width`, `width`), que en esa columna sí es el horizontal. */
.ins-basis-wide {
    flex-basis: 260px;
}

/* 🪤 `width: 1%` era un BUG, y lo cazó el usuario en la primera pantalla que miró: el botón «Gestionar
   usuarios» se leía «nar usuari».

   Por qué fallaba: `flex: 0 0 auto` toma su base del `width`, así que `width:1%` **fija la base en el 1 %
   del contenedor**; el `nowrap` impide que el texto envuelva, y el ancestro lo recorta. El resultado no es
   un botón encogido —eso lo impedía el `flex-shrink:0`— sino un rótulo **amputado**, que es peor porque
   parece un texto mal escrito y no un problema de caja.

   🥇 La lección: `width:1%` es el truco de TABLAS (una celda que se ajusta a su contenido) y ahí funciona.
   En FLEX no significa lo mismo. **Una sola clase servía a dos cajas con reglas incompatibles**, y al
   migrar los 28 sitios de M-172 el defecto viajó con ella. Hoy: `max-content` (la base es el contenido, que
   es lo que se quería) + `max-width:100%` para que en un contenedor estrecho ceda en vez de desbordar.
   ⚠️ Los DOS consumidores de tabla (`MudTh`/`MudTd`) necesitan la semántica de tabla: si alguno se rompe,
   su sitio es una clase hermana `.ins-hold-cell`, no volver atrás aquí. */

/* ── `.ins-stepper` · la cabecera de pasos ENVUELVE en vez de deshilacharse ────────────────────────
   M-276 · el síntoma llegó por captura a 14": los rótulos del asistente («Ramo, perfil, comisión»,
   «Recomendada o a medida») salían partidos LETRA A LETRA, en columnas de un carácter.

   🌳 La causa es la SUMA de dos decisiones que por separado parecen sanas, y por eso ninguna lectura de
   una sola de ellas la encuentra:

     · la fila de pasos era un `d-flex` SIN `flex-wrap`, así que ante la falta de sitio no tenía más
       salida que encoger — envolver no estaba permitido;
     · y cada paso vestía `.ins-grow`, que declara `min-width:0` + `overflow-wrap:anywhere`. Eso es
       exactamente lo que quiere el VALOR de un dato de negocio —una referencia externa larga parte
       antes que desbordar su tarjeta— y exactamente lo contrario de lo que quiere un rótulo de
       NAVEGACIÓN, que por debajo de cierto ancho deja de leerse.

   Sin suelo y con permiso para partir por cualquier sitio, el navegador hizo lo que se le pidió. Por eso
   el paso ya NO viste `.ins-grow`: la clase no está mal, es que este contenido no es el suyo. Queda
   intacta y con sus catorce consumidores.

   El suelo es `min(12rem, 100%)`, no `12rem` a secas: 12rem es lo que mide un paso con su rótulo y su
   subtítulo sin partir palabras, y el `100%` impide que el propio suelo desborde el panel cuando el panel
   es más estrecho que él — un `min-width` fijo cambiaría un texto ilegible por un desbordamiento, que es
   peor. Con seis pasos la fila cae a dos líneas antes que encoger: un asistente se lee, no se adivina.

   ⚠️ Los nombres son CONTRATO: `StepperPage` vive en el RCL y lo pintan los tres hosts (corredor,
   cliente, Backoffice) en diez pantallas. */
.ins-stepper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 8px;
}

/* El paso completo —número + rótulo + su conector— es UNA unidad de envoltura. Van juntos a propósito:
   un avatar huérfano al final de una línea, o un conector abriendo la siguiente, se leen como un fallo
   de pintado y no como un asistente de varias filas. */
.ins-stepper__step {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    min-width: min(12rem, 100%);
}

/* Aquí `min-width:0` SÍ: es el TEXTO el que debe poder encoger dentro del suelo del paso; sin esta línea
   el mínimo automático del bloque vuelve a ser su contenido y el suelo no decidiría nada. Lo que NO
   hereda es `overflow-wrap:anywhere`: parte por palabras, nunca por letras. */
.ins-stepper__text {
    min-width: 0;
}

/* El conector al paso siguiente. `margin-left:auto` lo deja pegado al borde derecho del paso, que es
   donde el ojo ya lo tenía cuando el paso crecía. La geometría vive aquí y no en el marcado porque el
   `Style` en línea solo debe llevar lo que CAMBIA (el color, según el paso esté hecho o no). */
.ins-stepper__link {
    flex: 0 0 auto;
    align-self: center;
    min-width: 24px;
    max-width: 80px;
    margin-left: auto;
    margin-inline-start: auto;
}

/* ── `.ins-pager-wrap` · el paginador envuelve DENTRO de su panel ──────────────────────────────────
   M-296 · llegó por captura: con más de ocho inmuebles, la barra del paginador de la lista del Catastro
   («Filas por página · 1-8 de 24 · ⏮ ◀ ▶ ⏭») salía más ancha que la columna `md=5` en la que vive y los
   botones se pintaban FUERA de la tarjeta, sobre lo que hubiera al lado.

   🌳 Misma raíz que `.ins-stepper`: contenido que no sabe envolver dentro de un contenedor estrecho.
   Medido en MudBlazor 8.4.0, son tres declaraciones encadenadas:

     · `.mud-table-pagination-toolbar` es `display:flex` con `flex-wrap:nowrap`, y TODOS sus hijos
       (rótulo, selector, información, acciones) llevan `flex-shrink:0` — nadie puede ceder ni envolver;
     · `.mud-table-pagination` es `display:initial`, o sea INLINE, y su `overflow:auto` es inerte en una
       caja en línea: no recorta ni hace scroll, deja pasar;
     · y `.mud-table` no declara `overflow`, así que lo que se sale no encuentra nada que lo pare hasta
       fuera del panel.

   🥇 La lección, y por qué esto no lo arregla la librería sola: MudBlazor SÍ tiene la regla correcta
   —`flex-wrap:wrap` + `spacer` a `flex:none`—, pero la esconde tras `@media (max-width: 416px)`. Una
   media query pregunta por el VIEWPORT, y aquí el viewport es un portátil de 1440 px: lo estrecho es la
   COLUMNA. Un contenedor estrecho dentro de una pantalla ancha es invisible para una media query, y por
   eso el arreglo tiene que declararlo el contenedor.

   El `spacer` a `flex:none` NO es adorno: su `flex:1 1 100%` significa «mi base es el ancho entero», y en
   un flex que envuelve eso le da una LÍNEA ENTERA para él solo, empujando toda la barra a una segunda
   fila vacía por arriba. Envolver sin neutralizarlo cambia un defecto por otro.

   ⚠️ Se viste en el `MudTable`/`MudDataGrid` que vive en una columna estrecha, no en todos: es una
   declaración de «aquí no hay ancho», no una preferencia estética. */
.ins-pager-wrap .mud-table-pagination {
    display: block;
}

.ins-pager-wrap .mud-table-pagination-toolbar {
    flex-wrap: wrap;
    height: auto;
    min-height: 52px;
    padding-top: 4px;
    padding-bottom: 4px;
    row-gap: 4px;
}

.ins-pager-wrap .mud-table-pagination-spacer {
    flex: none;
}

.ins-pager-wrap .mud-table-pagination-actions {
    margin-left: auto;
    margin-inline-start: auto;
}

.ins-form-section__summary {
    margin-left: auto;
    padding-left: 12px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
    text-align: right;
}

.ins-form-section__help { color: var(--mud-palette-text-secondary); }

/* ── M-624 · LA CAJA DE LÍNEA DEL RÓTULO FLOTANTE DE UN CAMPO ──────────────────────────────────────
   Medido en vivo el 22-ago-2026 con sonda de navegador sobre el stack en pie (`/policies`): los rótulos
   con descendente —«Agrupar por», «Origen»— salen AMPUTADOS por abajo, **5,40 px** de recorte.

   🌳 La causa NO es de ninguna pantalla: son dos declaraciones de MudBlazor 8.4.0 que por separado
   parecen sanas y que juntas cortan:

     · `.mud-input-control>.mud-input-control-input-container>.mud-input-label-inputcontrol`
       fija `font-size:1rem` y `line-height:1.15rem` — o sea una caja de línea de 1,15 em;
     · `.mud-input-label` declara `overflow:hidden` (+ `text-overflow:ellipsis`, `white-space:nowrap`),
       que es lo que evita que un rótulo largo se derrame sobre el campo vecino.

   El `overflow:hidden` recorta por la CAJA DE RELLENO, y en este rótulo la caja de relleno ES la caja de
   línea (relleno vertical 0). Con 1,15 em de caja y un área de contenido mayor, el medio-interlineado es
   NEGATIVO: el glifo asoma por arriba y por abajo de su propia caja, y ahí lo corta el `overflow`.

   📏 Las tres métricas que deciden el número, MEDIDAS en el navegador con las fuentes cargadas
   (`document.fonts.check`, caras 600 y 700 confirmadas) — no leídas de la documentación de la fuente:

       Syne 1,188 em · **Inter 1,250 em** · **system-ui (respaldo) 1,313 em**

   El suelo NO lo pone Syne (que es la de los titulares) sino el respaldo del sistema: el rótulo de un
   campo se pinta en **Inter**, que llega de Google Fonts por red, así que hasta que la cara aterriza
   —y para siempre si la red la bloquea— lo que se ve es `system-ui`, la MÁS ALTA de las tres. Una caja
   calculada solo contra Inter (1,25) dejaría el defecto vivo justo en el primer render de cada visita.

   🎯 Por eso 1,45 em, y no es un número inventado: es el mismo valor que la SSOT tipográfica ya da a los
   titulares pequeños (H5/H6 en `MudThemeFactory`), y es el único escalón redondo de esa escala que deja
   holgura real (0,0685 em ≈ 1,1 px por lado) sobre la peor de las tres caras.

   🚫 Por qué NO se toca `overflow`, que es la tentación evidente:
     · quitarlo mata la elipsis, que es lo único que hoy impide que «Fecha de efecto de la renovación»
       se derrame encima del campo de al lado;
     · y `overflow-x:hidden` + `overflow-y:visible` **no existe**: la especificación de Overflow dice que
       si un eje computa a `visible` y el otro no, el `visible` computa a `auto` — cada uno de los ~1.450
       rótulos de los tres hosts se convertiría en un contenedor de scroll.
   El recorte vertical desaparece porque la caja de recorte (= la caja de línea) pasa a ser MÁS ALTA que
   la tinta; la elipsis horizontal sigue intacta porque `overflow` sigue donde estaba.

   ⚠️ El selector es largo A PROPÓSITO: la regla de MudBlazor que hay que ganar tiene especificidad
   (0,4,0) —tres clases encadenadas más una compuesta—, así que un `.mud-input-label` a secas (0,1,0)
   perdería aunque esta hoja se enlace después. Con `label…` esto suma (0,4,1) y gana por un pelo
   declarado, no por orden de enlace. */
.mud-input-control > .mud-input-control-input-container > label.mud-input-label.mud-input-label-inputcontrol {
    line-height: 1.45em;
}

/* Y el rótulo NO se mueve de donde estaba. Subir la caja de línea 0,30 em reparte 0,15 em de
   medio-interlineado por arriba, o sea que el texto BAJARÍA 2,4 px en los ~1.450 campos de los tres
   hosts — cambiar un recorte por una desalineación no es arreglarlo. El rótulo está `position:absolute`
   con `top:0`, así que un margen superior negativo del MISMO medio-interlineado devuelve la caja a su
   sitio sin tocar el `top` ni el `transform` de la librería.

   🪤 Y aquí está la trampa que obliga a razonar en `em` y no en px: el rótulo ENCOGIDO lleva
   `transform: scale(0.75)` con origen arriba-izquierda. El medio-interlineado vive DENTRO de la caja
   transformada (se escala ×0,75); el margen vive FUERA (mueve la caja ANTES de transformarla, no se
   escala). Por eso la compensación es exacta en reposo —donde la escala es 1 y donde el rótulo se lee
   junto al texto del campo— y deja 0,6 px de residuo hacia arriba en el estado encogido, que es el que
   flota sobre el borde y donde nadie tiene con qué compararlo. Es el reparto correcto de los dos, no un
   descuido: la alternativa (no compensar) son 2,4 px de caída en el estado que SÍ se compara.

   ⚠️ La equivalencia 1,15 rem = 1,15 em de la que sale el 0,15 solo se sostiene porque MudBlazor fija
   `font-size:1rem` en este mismo rótulo, con especificidad (0,3,0). Si esa cifra cambiara, este número
   se recalcula: es la MITAD de (caja nueva − caja vieja). */
.mud-input-control > .mud-input-control-input-container > label.mud-input-label.mud-input-label-inputcontrol {
    margin-block-start: -0.15em;
}

/* ── 🎛️ `.ins-segmented` · EL CONMUTADOR DE DOS OPCIONES — UN control, no dos botones ────────────────
   Reportado por él con la app delante, sobre el diálogo «Contáctanos»: *«los dos botones de "Algo no
   funciona" y "Propongo una mejora" están muy pegados»*. Y es exacto: se pintaban con
   `MudButtonGroup OverrideStyles="false"`, que junta a sus hijos SIN separación y sin contenedor, así
   que dos botones con variantes distintas —uno relleno y otro con canto— quedaban soldados por el
   costado y se leían como dos cosas, no como un control con una opción elegida.

   🔎 Y ES UNA CLASE, censada el 23-ago-2026 sobre `src/`: la misma forma se resolvía de TRES maneras.
   `ReportIssueDialog` y `ProductDetail` con `MudButtonGroup OverrideStyles="false"` (los dos pegados), y
   `PortalCliente/MainLayout` con su propio `.ins-area-switch` en `portal.css` — con un comentario que
   RECHAZA `MudButtonGroup` por este mismo motivo. O sea: la casa ya sabía que el grupo no servía, pero
   la respuesta se quedó encerrada en un host. Aquí se declara UNA vez para los tres.

   🏆 LA FORMA ES LA DEL SECTOR (Material 3 «segmented buttons», y el mismo patrón que iOS): un CARRIL
   que contiene a los segmentos, aire dentro, y el segmento elegido como pastilla rellena. Lo que
   distingue no es el canto de cada botón —eso es lo que los soldaba— sino el relleno de UNO contra el
   carril de los dos.

   🌗 EL CARRIL, con su pareja clara/oscura y medido, porque vive sobre DOS fondos muy distintos: el
   diálogo `rgb(7,16,38)` y la tarjeta `rgb(38,55,93)`. Ese es justo el motivo de que en oscuro el tinte
   sea un LEVANTE NEUTRO y no el `rgba(10,22,50,…)` recesivo que usan la cabecera de tabla o el hueco de
   un campo: medido, el recesivo se separa 1,30:1 del diálogo pero solo **1,04:1** de la tarjeta —o sea
   desaparece justo en `ProductDetail`—, mientras el levante neutro da 1,230:1 y 1,253:1, por encima del
   suelo 1,15 de la casa EN LOS DOS. En claro el papel se invierte y el recesivo sirve para ambos
   (1,179:1 y 1,174:1), con el mismo valor que ya usa la superficie de una cláusula.

   ⚠️ El rótulo del segmento NO elegido va en texto PRIMARIO, no secundario, y tampoco es un capricho:
   es lo que manda Material (el no elegido se lee en `on-surface`) y además evita estrenar un par
   rótulo-secundario/superficie que ningún guard vigila. Medido sobre el carril: 12,49:1 en oscuro y
   15,14:1 en claro. */
:root {
    --ins-segmented-track: rgba(148, 163, 184, 0.14);
}

body.ins-light {
    --ins-segmented-track: rgba(226, 232, 240, 0.80);
}

.ins-segmented {
    display: inline-flex;
    align-items: center;
    /* El aire que él echaba en falta: 4 px DENTRO del carril y 4 px entre segmentos. Sin el carril, un
       hueco entre dos botones los separaría en dos controles; con él, el hueco es lo que hace que se
       lean como uno solo con una opción encendida. */
    gap: 4px;
    padding: 4px;
    border-radius: 999px;
    background: var(--ins-segmented-track, rgba(148, 163, 184, 0.14));
    border: 1px solid var(--glass-border-card, rgba(148, 163, 184, 0.22));
    /* Con poco sitio los segmentos bajan de línea en vez de desbordar el diálogo. */
    flex-wrap: wrap;
}

.ins-segmented > .mud-button-root {
    /* Pastilla, para que el elegido case con la curva del carril. `!important` porque MudBlazor declara
       el radio del botón con más peso desde su propia hoja; es el mismo recurso que usa theme.css. */
    border-radius: 999px !important;
    margin: 0;
    /* Sin sombra: dentro de un carril, una sombra por segmento vuelve a leerse como botones sueltos. */
    box-shadow: none !important;
}

/* ── 💶 LA ETIQUETA NO SE MONTA ENCIMA DEL SIMBOLO DE MONEDA ────────────────────────────────────────
   Reportado por el (28-ago-2026) con captura: «los input de indemnizacion estan muy mal, el texto se
   solapa con el simbolo de euro». Literal — se leia «Indemnizacion por dí€».

   Mecanismo: `InsMoneyField` pone la divisa como ADORNO AL FINAL, y MudBlazor no reserva sitio para el.
   Mientras el campo esta vacio la etiqueta descansa dentro, a lo ancho completo, asi que en una columna
   estrecha —`sm="4"` dentro de un dialogo— acaba por debajo del simbolo. No pasa al escribir, porque
   entonces la etiqueta sube: el defecto vive justo en el estado en el que el corredor esta LEYENDO para
   saber que campo es.

   ⚖️ Se corta con puntos suspensivos en vez de dejar que se solape. Truncar pierde texto, pero solaparse
   pierde LAS DOS COSAS —no se lee la etiqueta ni se ve la divisa— y ademas parece un fallo de pintado.
   El `title` mantiene el texto entero a un palmo del raton.
   📐 El arreglo de fondo seria dar mas ancho a esos campos, y eso es de cada pantalla; esto cubre la
   clase entera mientras tanto, y cubre tambien las que aun no existen. */
.mud-input-control:has(.mud-input-adorned-end) .mud-input-label:not(.mud-input-label-inputcontrol-shrink) {
    max-width: calc(100% - 2.25rem);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Bloque con fase de lectura y fase de edición (InsReadEditBlock) ──────────────────────────────────
   Sin colores propios: hereda el tema. La única señal visual es que en LECTURA no hay controles, que es
   justo lo que se quería ganar. */
.ins-readedit { display: flex; flex-direction: column; gap: .25rem; }
.ins-readedit__head { display: flex; align-items: center; gap: .5rem; min-height: 2rem; }
.ins-readedit__title { font-weight: 600; font-size: .875rem; }
.ins-readedit__spacer { flex: 1 1 auto; }
.ins-readedit__body { display: flex; flex-direction: column; gap: .5rem; }

/* ── 🪟⏳ El cuerpo de un diálogo con la operación en vuelo (InsDialog, `Busy`) ───────────────────────
   Se CONGELA, no se esconde: quien espera tiene que poder leer qué confirmó. `inert` ya lo saca del
   foco y del ratón; esto solo lo DICE, para que la espera se vea y no parezca que la app no responde.
   Atenuación suave a propósito: bajarla más lo volvería ilegible, que es el defecto contrario. */
.ins-dialog__content--busy {
    opacity: .62;
    transition: opacity .15s ease-in-out;
    cursor: progress;
}
