/* ═══════════════════════════════════════
   ▓ COMPONENTE · FieldRow / FieldRows — gemelo vanilla ▓
   v0.2 · 2026-08-15. Ficha: `design-system/COMPONENTE_FIELDROW.md`

   La fila de PROPIEDAD de un cajón o formulario: **etiqueta a la izquierda, control a la
   derecha**, hairline entre filas, a ras de los bordes. `FieldRows` es el contenedor;
   `FieldRow` es cada fila.

   ⛔ POR QUÉ NACE ESTE GEMELO, y es una factura ya pagada dos veces. La ficha existe desde
   el 2026-07-31 y el kit React también — pero **las apps no pueden consumir React**, así que
   el cotizador la volvió a dibujar a mano el 2026-08-15 (`.lzc-filas`/`.lzc-fila`) con
   58/11-18/12 donde el canon dice 64/13-18/16, y con la línea ABAJO en vez de arriba. Su
   comentario afirmaba haber copiado las medidas del canon — no coincidía ninguna.
   *Un componente que tu producto no puede usar no está canonizado: está documentado.*
   Es la misma lección del acordeón guiado (14-ago) y de la ficha del Input (13-ago).

   REQUISITOS DEL ANFITRIÓN — los tres, o se ve mal en silencio:
     1. Los tokens del canon (`colors_and_type.css`). Los 6 que consume están abajo.
     2. Un reinicio con `box-sizing: border-box`.
     3. El contenedor padre debe tener **relleno lateral conocido** si se usa a sangre
        (`--fr-bleed`), porque la lista lo cancela con margen negativo y cada fila lo repone.
   ═══════════════════════════════════════ */

.exds-frs {
  /* Relleno lateral del anfitrión. A sangre (por defecto) la lista SALE de él y cada fila
     lo REPONE: así el texto sigue alineado con el resto del panel y la línea cruza entero.
     ⛔ Una línea que no toca el borde no separa una sección: dibuja una caja dentro de otra
     (Ricardo, 2026-08-15, con el ejemplo del deber ser). Es la misma técnica full-bleed que
     usa el acordeón un nivel más arriba. */
  --fr-bleed: 18px;

  display: flex;
  flex-direction: column;
  margin-inline: calc(var(--fr-bleed) * -1);

  /* La lista se separa de su cabecera con un hairline propio. Las filas traen el suyo
     ARRIBA (no abajo): así la última no deja dos remates seguidos —su borde y el del
     contenedor— con el aire del panel en medio. */
  border-top: 1px solid var(--color-border-subtle, #E5E7EB);
}

/* Variante SIN sangre: la lista respeta el relleno del anfitrión. Para paneles donde la
   línea no debe tocar el borde porque hay algo más a los lados. */
.exds-frs[data-bleed="no"] { margin-inline: 0; --fr-bleed: 0px; }

.exds-fr-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 13px var(--fr-bleed);
  min-height: 64px;
  border-top: 1px solid var(--color-border-subtle, #E5E7EB);
  /* El kit lo declara explícito (COSECHADO desde aquí, 2026-08-23: `gate_gemelos_conducta.js`
     lo medía como «falta»). Este gemelo lo daba por supuesto vía el reset del anfitrión
     (§REQUISITOS DEL ANFITRIÓN, arriba) — correcto en producción, pero invisible al gate. */
  box-sizing: border-box;

  /* Ancla del desplegable de ESTA fila. Sin esto, un popover se posiciona contra el
     contenedor y se alinea con la fila equivocada. */
  position: relative;
}
.exds-fr-row:first-child { border-top: 0; }

/* Etiqueta a la izquierda, con línea de apoyo opcional. */
.exds-fr-lab { flex: 1; min-width: 0; }
/* ⛔ LOS DOS VAN EN BLOQUE. Con `<span>` en línea, «Precio» y «Antes de impuestos» salían
   PEGADOS en el mismo renglón y el `margin-top` no hacía nada — se ve en el render, no en el
   CSS, que era «correcto» leyéndolo. (INC-488, otra vez: el estado se mira.) */
.exds-fr-l { display: block; font: 500 var(--fs-body-sm, 13px) var(--font-sans); color: var(--fg1, #0F1419); }
.exds-fr-h { display: block; font: 400 var(--fs-eyebrow, 11px) var(--font-sans); color: var(--fg3, #5C6B7A); margin-top: 2px; }

/* Alineación arriba cuando la etiqueta lleva línea de apoyo: el bloque baja 4px para
   alinearse ÓPTICAMENTE con la caja del control, no con su borde. */
.exds-fr-row[data-align="top"] { align-items: flex-start; }
.exds-fr-row[data-align="top"] .exds-fr-lab { padding-top: 4px; }

/* Control a la derecha. El ancho fijo es lo que alinea el borde derecho entre filas —
   sin él, cada control termina donde le toca y la columna se deshace. */
.exds-fr-ctl { flex-shrink: 0; display: flex; justify-content: flex-end; }
.exds-fr-ctl > * { width: var(--fr-ctl-w, 236px); max-width: 100%; }

/* Modo LECTURA: sin control, la fila encoge y la tinta se invierte. La altura de captura
   la marcaba el control; sin él, esos 64px son aire que SEPARA el dato de su etiqueta en
   vez de juntarlos. Y el dato pasa a mandar sobre la etiqueta porque es a lo que se viene. */
.exds-fr-row[data-modo="lectura"] { min-height: 44px; padding-top: 11px; padding-bottom: 11px; }
.exds-fr-row[data-modo="lectura"] .exds-fr-l { font-weight: 400; color: var(--fg3, #5C6B7A); }

/* ⛔ LAS DOS REGLAS QUE HACEN QUE `overflow-wrap` SIRVA DE ALGO (traídas del kit el
   2026-08-20, tres días tarde). El kit las ganó el 17-ago y aquí faltaban.

   ⭐ Y LO QUE ENSEÑA EL HUECO: este gemelo YA TENÍA `overflow-wrap:anywhere` y `min-width:0`
   en `.exds-fr-val` — la parte que PARECE el arreglo. Le faltaba la que lo hace funcionar.
   *Alguien copió la mitad reconocible y dejó fuera la mitad que actúa, y el resultado se lee
   como arreglado: la declaración está ahí, a la vista, sin hacer nada.*

   POR QUÉ HACEN FALTA LAS DOS, y no basta con dejarlo encoger:
     · `.exds-fr-ctl` nace `flex-shrink:0` —correcto para un CONTROL, que tiene su propia
       medida— y en LECTURA eso deja al valor sin poder estrecharse, así que `overflow-wrap`
       no llega a actuar nunca porque la caja nunca se estrecha;
     · y en lectura el valor DEJA DE SER UN CONTENEDOR FLEX (`display:block`): siendo flex,
       el texto de dentro se vuelve un ítem de flex anónimo, y un ítem anónimo no baja de su
       ancho mínimo aunque su contenedor tenga `min-width:0`.
   Medido en el kit dentro del cajón de 420 px: un domicilio completo se salía del panel y se
   pintaba ENCIMA de su propia etiqueta. */
.exds-fr-row[data-modo="lectura"] .exds-fr-lab { flex: 0 0 auto; }
.exds-fr-row[data-modo="lectura"] .exds-fr-ctl { display: block; flex: 1 1 0; min-width: 0; }
.exds-fr-val {
  font: 500 var(--fs-body-sm, 13px) var(--font-sans); color: var(--fg1, #0F1419);
  text-align: right; min-width: 0; overflow-wrap: anywhere;
}

/* ⛔ EL DESPLEGABLE NO PUEDE TAPAR LA FILA SIGUIENTE (Ricardo, 2026-08-15, expresamente).
   Dos mitades del mismo problema:
     · la fila con la lista abierta se pone POR DELANTE de las de abajo;
     · el contenedor NO recorta — un `overflow` aquí cortaría la lista en la primera fila.
   `:has()` cubre el caso declarativo; `[data-fr-abierto]` es la salida para navegadores o
   controles que no lo marquen en el DOM. */
.exds-fr-row:focus-within,
.exds-fr-row[data-fr-abierto="true"],
.exds-fr-row:has([aria-expanded="true"]),
.exds-fr-row:has([data-open="true"]) { z-index: 5; }

/* Un panel cuyo contenido TERMINA en una lista a sangre no lleva el aire de abajo: la
   propia lista cierra contra el borde. El relleno existe para los formularios, donde el
   último control sí necesita separarse del filo. */
.exds-frs-host:has(> .exds-frs:last-child) { padding-bottom: 0; }

@media (max-width: 600px) {
  .exds-fr-row { min-height: 56px; }
  .exds-fr-ctl > * { width: var(--fr-ctl-w-sm, 168px); }
}

/* ── LOS 6 TOKENS QUE CONSUME ───────────────────────────────────────────────
   --color-border-subtle · --fg1 · --fg3 · --fs-body-sm · --fs-eyebrow · --font-sans
   Todos con reserva, para que la pieza no desaparezca si el canon llega incompleto. */
