/* ═══════════════════════════════════════
   ▓ COMPONENTE · Tooltip — gemelo vanilla ▓
   v2.1 · 2026-10-25 (el globo de un valor recortado, de varios renglones a 260 sin cortar; decisión 290-5 B). v2.0 · 2026-09-07. Ficha: `design-system/COMPONENTE_CAPA_EFIMERA.md`
   Kit: `catalogo-cd/components/Tooltip.jsx`

   La etiqueta de una línea que aparece al pasar por encima o al enfocar con el teclado. La
   otra mitad de la capa efímera; su hermano es el `toast`, que vive en su propia carpeta
   (el porqué, en el README).

   REQUISITOS DEL ANFITRIÓN:
     1. Los tokens del canon (`colors_and_type.css`).
     2. `box-sizing: border-box`.

   ⛔ DOS TONOS, DECIDIDOS POR RICARDO (2026-09-07) — la diferencia entre ellos es
   EXCLUSIVAMENTE el tono. Mismo tamaño, mismo radio, misma sombra, mismo gesto:

     · CONTENIDO (por defecto, sin atributo) — oscuro, para el globo que explica algo DENTRO
       de la pantalla (una fila, un botón de una tabla). Sigue siendo la regla vieja de esta
       capa: lo que flota sobre la UI persistente es oscuro y monocromático.
     · SHELL (`data-tono="shell"`) — claro, SÓLO para disparadores que viven en la barra
       lateral o la barra superior (sidebar/topbar). Su porqué, en palabras de Ricardo: «la
       situación principal a evitar es cuando la barra lateral está plegada y el cursor pasa
       por los módulos: ahí el globo es el único lugar donde se lee el nombre» — y un globo
       oscuro sobre una barra clara desentona con el resto del shell.

   Por qué el tono NO se decide solo (mirando dónde vive el disparador en el DOM): dos apps
   pueden anidar su sidebar de formas distintas, y adivinar por selector es exactamente el
   tipo de regla frágil que este catálogo evita. El tono se declara en el marcado
   (`data-tip-tono="shell"`), igual que la posición ya se declara con `data-tip-pos`.

   ⚠ UNA DIFERENCIA MEDIDA, NO UN DESCUIDO: el tooltip pinta `--color-action-ink` (#21272C) y
   el toast pinta `--color-bg-inverse` (#0F1419). Son dos oscuros distintos y la ficha los
   describe a los dos como «#0F1419», que era cierto antes de que el ink pasara a slate. Se
   copia lo que dice el kit, no lo que dice la prosa de la ficha, y se declara aquí: unificar
   los dos oscuros es una DECISIÓN DE DISEÑO y le toca a Ricardo, no a este gemelo.

   ⛔ EL GESTO — RECETA ÚNICA PARA LAS DOS VARIANTES (Ricardo, 2026-09-07):
     · espera 80ms antes de aparecer (las dos variantes; en el shell, el PRIMER módulo de un
       grupo caliente — la lógica vive en `tooltip.js`, no aquí);
     · entra en 150ms, escala 0.98 → 1;
     · sale en 50ms, sin retardo — salir siempre más rápido que entrar.
   Ninguno de los tres números (80/150/50) tiene un token de duración que lo nombre hoy
   (`--motion-fast` vale 120ms, no 80/150/50): se dejan literales y se declara aquí — crear
   esos tokens es decisión de Ricardo, no efecto colateral de este gemelo. Sí se reutilizan
   los dos tokens de curva que ya existen y encajan: `--ease-default` para entrar,
   `--ease-exit` para salir.

   ⛔ RETIRADOS (2026-09-07): los 120ms de retardo de esta misma pieza, y las demás
   velocidades sueltas del backoffice que nadie había decidido (350ms de Notificaciones,
   380ms×2 heredados) — quedan documentadas y retiradas en `COMPONENTE_CAPA_EFIMERA.md`.
   ═══════════════════════════════════════ */

/* ══ EL DISPARADOR ═══════════════════════════════════════════════════════════
   Envuelve al elemento que abre el tooltip. Es quien crea el sistema de coordenadas: sin
   `position: relative` aquí, la burbuja se ancla a la ventana y aparece en la esquina. */
.exds-tip-wrap {
  position: relative;
  display: inline-flex;
}

/* ══ LA BURBUJA ══════════════════════════════════════════════════════════════
   Una línea, sin salto (`nowrap`): ~~si el texto no cabe en una línea, no es un tooltip — es
   un párrafo, y va en la pantalla~~ (RETIRADO el 2026-10-25 para el globo de un valor recortado, que
   es de varios renglones: ver el bloque v2.1, abajo; decisión 290-5 B). La línea única sigue para todo
   otro globo. `pointer-events: none` para que la burbuja no se
   interponga entre el ratón y su propio disparador.

   Variante por defecto: CONTENIDO (oscura). El shell es el caso especial y se marca con
   `data-tono="shell"` más abajo — nunca al revés. */
.exds-tip {
  position: absolute;
  z-index: var(--z-tooltip, 1400);
  white-space: nowrap;
  background: var(--color-action-ink, #21272C);
  color: var(--fg-inverse, #FFFFFF);
  font: 500 var(--fs-caption, 12px) var(--font-sans, "Inter", -apple-system, "system-ui", sans-serif);
  padding: 6px 9px;
  border-radius: var(--radius-sm, 6px);
  box-shadow: var(--shadow-md, 0 4px 12px -2px rgba(15, 20, 25, 0.06));
  pointer-events: none;
}

/* ══ VARIANTE SHELL — TONO + BORDE (Ricardo, 2026-09-07 · borde añadido 2026-09-07,
   defecto cazado a ojo el mismo día) ═══════════════════════════════════════
   Mismo tamaño, mismo radio, misma sombra, mismo gesto. Fondo y texto medidos en la pieza
   viva: rgb(255,255,255) sobre rgb(15,20,25) — exactamente `--color-surface` y `--fg1` del
   canon.
   ⛔ EL BORDE: esta variante vive en la MISMA barra que el desplegable del riel
   (`.exds-sb-flyout`, `shell.css`) — «el mismo gesto, en el mismo sitio» (decisión 1 de
   Ricardo, 2026-08-27, «los dos claros»). El desplegable SÍ lleva `1px solid
   --color-border-subtle` porque una superficie BLANCA sobre un fondo BLANCO no se separa
   sin uno; el globo claro tiene el mismo problema y no llevaba borde — es la MISMA razón,
   aplicada a la mitad que faltaba. La variante CONTENIDO (oscura, sobre fondo claro) NO lo
   necesita y no lo lleva: ahí el contraste de color ya separa la burbuja del fondo. */
.exds-tip[data-tono="shell"] {
  background: var(--color-surface, #FFFFFF);
  color: var(--fg1, #0F1419);
  border: 1px solid var(--color-border-subtle, #E5E7EB);
}

/* ⛔ v2.1 (2026-10-25) · EL GLOBO DE UN VALOR RECORTADO ES DE VARIOS RENGLONES, CON ANCHO MÁXIMO, Y NUNCA CORTA (decisión 290-5 B).
   Hoja plans/decisiones/_decision_cajonfila_pendientes2_2026-10-25.html, decisión 5, opción B.
   DECISION-FUENTE: Ricardo, 2026-10-25 — «Te ha dado gran parte de las respuestas de esas decisiones. Y cuando te las di, definimos reglas adicionales. Como por ejemplo, en el punto 8, la tabla no llevaba la sangría extra, porque la jerarquía ya estaba visualizada por estar contenida la tabla dentro del cajón fila. En la 5, vamos con tu recomendación, pero lo que pusiste son pastillas de estado de color neutral, cuando deberían ser chips, sin relleno y con outline neutro. Todo lo demás tal y como lo recomiendas.»
   El globo que abre un valor recortado con «…» (data-tip-si-recorte en el disparador: la descripción de dos renglones de una lista,
   un folio, un nombre largo) toma la regla del globo de varios renglones que el catálogo ya tenía para el signo (i) (decisión 28,
   signo-info.css): salta de renglón, mide como mucho 260 (y nunca más que la ventana menos 48), width max-content para que un texto
   corto no se infle, alineado a la izquierda, line-height normal. Y overflow-wrap anywhere: una palabra más ancha que 260 (un
   correo, un enlace) parte en vez de salirse. SIN tope de renglones y SIN recorte: el texto entero, sea del largo que sea (medido
   con 890 letras a 1440 y a 420 de ancho: tooltip.js lo voltea o lo corre para que no se salga por arriba ni por abajo).
   RETIRA, para este globo, el «una línea, sin salto» de la burbuja base (arriba) y el «una ayuda que pasa de tres líneas no va en
   este globo» del signo (i), que era una regla de CONTENIDO de una ayuda escrita, no del dato recortado. Todo otro globo sigue igual. */
.exds-tip-wrap:has(> [data-tip-si-recorte]) > .exds-tip {
  white-space: normal;
  width: max-content;
  max-width: min(260px, calc(100vw - 48px));
  text-align: left;
  line-height: normal;
  overflow-wrap: anywhere;
}

/* ⛔ EL GLOBO NO LLEVA FLECHA — EN NINGUNA DE SUS DOS VARIANTES (Ricardo, 2026-09-07).
   `DECISION-FUENTE: Ricardo, 2026-09-07 — «Mejor vamos a quitarlo de todos lados» · «claro no,
   oscuro no».`

   Aquí vivían `.exds-tip-flecha` y sus cuatro posiciones. Se retiran enteras, y también el nodo
   que las creaba en `tooltip.js`.

   ⛔ POR QUÉ, y es de COSTE, no de gusto: **la flecha no es un adorno, es parte del CONTORNO.**
   En la variante clara —que desde hoy lleva delineado para separarse del fondo blanco— hay que
   casar DOS siluetas al píxel, y eso se paga **en cada una de las cuatro posiciones y en cada
   sitio donde alguien monte un globo**. Se probaron cuatro geometrías con aumento de 10× y aun
   así Ricardo lo vio: *«no conecta el triángulo con el globo perfectamente»*.

   ⛔ Y LO QUE LO VUELVE CARO DE VERDAD: **ningún medidor lo ve.** Es una costura de 1px; los
   estilos computados salen correctos en las cuatro variantes y sólo se distingue mirando una
   foto ampliada. *Un defecto que sólo caza el ojo, en una pieza que se monta en muchos sitios,
   se paga cada vez que alguien la monta.* Ésa fue la pregunta que Ricardo hizo —«¿va a provocar
   este tipo de errores continuamente?»— y la respuesta medida fue que sí.

   ⛔ CONTRA ESO, LO QUE APORTABA NO RESOLVÍA NADA: decir de qué elemento sale la burbuja, cuando
   la burbuja nace **a 8px de su disparador y no hay nada más cerca**. No había ambigüedad.

   ⛔ Y EL ARGUMENTO QUE DECIDIÓ: el **desplegable de submódulos** —la pieza hermana, en el mismo
   sitio, con el mismo gesto, la que el propio Ricardo mandó ese día que se viera de la misma
   familia— **tampoco tiene flecha**. Quitarla no aleja al globo de su familia: lo acerca.

   ⚠ SE PASÓ POR UNA VERSIÓN INTERMEDIA («oscura sí, clara no») y se descartó **porque rompía la
   regla 1**: las dos variantes difieren SÓLO en el tono. *Una excepción que arregla un problema
   de una variante abriendo una diferencia nueva entre las dos no es una solución: es mover el
   defecto de sitio.*

   ⛔ Y AQUÍ NO SE VUELVE. Si alguien propone la flecha «por consistencia con otros sistemas», lo
   que está proponiendo es la costura de 1px que nadie puede medir. */

/* ══ LAS CUATRO POSICIONES ═══════════════════════════════════════════════════
   `data-pos` dice DE QUÉ LADO del disparador sale la burbuja. Los 6px de separación van en
   el `translate`, no en un margen: un margen ensancharía la caja y movería la flechita. */
.exds-tip[data-pos="top"] {
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
}

.exds-tip[data-pos="bottom"] {
  top: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(6px);
}

.exds-tip[data-pos="left"] {
  right: 100%;
  top: 50%;
  transform: translateY(-50%) translateX(-6px);
}

.exds-tip[data-pos="right"] {
  left: 100%;
  top: 50%;
  transform: translateY(-50%) translateX(6px);
}

/* ══ SHELL + «right» — LA MISMA DISTANCIA QUE EL DESPLEGABLE (2026-09-07, medido) ═══════════
   El desplegable del riel (`.exds-sb-flyout`, `shell.css`) nace a `módulo.right + 8px`
   (`backoffice-2.js`, `_sbxFlyoutWire`). Los 6px de arriba son la separación GENÉRICA de
   cualquier globo con cualquier disparador — no tocan aquí. Pero en la barra lateral los dos
   disparadores (módulo con hijos → desplegable · módulo plano → este globo) son el MISMO
   gesto en el MISMO sitio, y con 6 quedaban a 2px de distancia entre sí del borde de la
   barra. Se homologa SOLO para esta combinación exacta. */
.exds-tip[data-tono="shell"][data-pos="right"] {
  transform: translateY(-50%) translateX(8px);
}

/* ══ LA FLECHITA — RETIRADA, Y ESTE COMENTARIO CON ELLA (2026-09-08) ═══════════
   Aquí vivía la regla de color de `.exds-tip-flecha` en sus cuatro posiciones y dos tonos.
   Se fue con la flecha entera (retiro documentado arriba, línea 99, Ricardo 2026-09-07) y
   dejó un selector HUÉRFANO sin bloque de declaraciones: la lista de `.exds-tip[...]`
   corría sin `{` hasta la primera llave real, que resultaba ser la de
   `@keyframes exds-tip-in` — el navegador descartaba la regla entera Y se comía el
   keyframe con ella. Medido en Chromium (2026-09-08): antes del arreglo la hoja
   conservaba 10 reglas y sólo sobrevivía `exds-tip-out`; `exds-tip-in` nunca llegaba a
   `document.styleSheets`, así que el globo aparecía de golpe en vez de con el gesto de
   150ms. Se retira el residuo completo: no hace falta un bloque nuevo, porque el color
   de la flecha no existe si la flecha no existe. */

/* ══ EL GESTO — entra 150ms con escala, sale 50ms sin retardo (Ricardo, 2026-09-07) ═══════
   La espera de 80ms YA NO vive aquí: la controla `tooltip.js` (necesita saber si el grupo
   del shell está «caliente» para saltársela), así que el nodo se inserta cuando ya toca
   aparecer y sólo falta animar la entrada. `scale` y `translate` son propiedades
   INDEPENDIENTES de `transform` (ya usadas así en `switch.css`): así la escala del gesto no
   pisa el `transform: translateX/Y(...)` que posiciona la burbuja según `data-pos`.

   ⛔ SIN MOVIMIENTO · y apagar el movimiento NO es dejar sin señal (INC-405). La regla se
   escribe al revés que en las otras piezas —`no-preference` en vez de `reduce`— y el efecto
   es el mismo: quien pide no moverse recibe la burbuja ESTÁTICA, entera y de inmediato (o
   retirada de inmediato al cerrar — sin el atributo `data-estado="saliendo"`, que sólo se
   añade con movimiento activo; ver `tooltip.js`). */
@keyframes exds-tip-in {
  from { opacity: 0; scale: 0.98; }
  to   { opacity: 1; scale: 1; }
}

@keyframes exds-tip-out {
  from { opacity: 1; scale: 1; }
  to   { opacity: 0; scale: 0.98; }
}

@media (prefers-reduced-motion: no-preference) {
  .exds-tip {
    scale: 1;
    animation: exds-tip-in 150ms var(--ease-default, cubic-bezier(0.32, 0.72, 0, 1)) both;
  }

  .exds-tip[data-estado="saliendo"] {
    animation: exds-tip-out 50ms var(--ease-exit, cubic-bezier(0.4, 0, 1, 1)) both;
  }
}
