/* mimi · consola del registro de apps
 *
 * La hoja de ESTE documento: el login y el registro. La otra página —«cómo funciona»— tiene la suya
 * (`panel.css`) y nunca carga ésta.
 *
 * Todo va acotado bajo `.ui-registro`, la clase que llevan las dos vistas. Con las páginas ya
 * separadas el acotamiento no defiende de una colisión de hojas; lo que sostiene es que nombres
 * genéricos como `.topbar`, `.brand`, `.chip` y `.btn` existen con otra forma en la otra página, y
 * sin el prefijo copiar una regla de allá para acá —o al revés— parece funcionar hasta que no.
 *
 * Los tokens de abajo están DUPLICADOS del blueprint de la otra página. Es la deuda consciente del
 * corte: el día que haya un tercer consumidor, se extraen a `site/tokens.css` y las tres lo importan.
 * La excepción ya existe y es `idiomas.css`, el selector de idioma: lo cargan las DOS páginas, y
 * escrito dos veces la primera vez que alguien ajusta el alto en una, dejan de parecer el mismo sitio.
 *
 * Dos criterios que hay que sostener:
 *
 * 1. El chip de estado NO puede depender solo del color. Cada uno lleva su palabra («lista», «no es
 *    inquilino», «sin verificar»): un daltónico tiene que poder operar esto, y el estado GRIS —el que
 *    dice «no sé»— es justo el que más fácil se lee como verde de reojo.
 * 2. Las URLs se rompen donde se puede (`overflow-wrap: anywhere`), nunca se truncan con puntos
 *    suspensivos: media URL de MCP es indistinguible de otra media URL, y esta pantalla existe para
 *    poder comparar exactamente eso.
 */

:root {
  --bg: #ffffff;
  --bg-soft: #f5f5f5;
  --bg-sunken: #eeeeee;
  --text: #1a1a1a;
  --text-2: #5c5c5c;
  /* 4.59:1 sobre --bg-sunken y 4.89 sobre --bg-soft. El anterior (#767676) daba 3.91 sobre el
     hundido — justo bajo el chip gris y el número de paso, que es donde más se lee. */
  --text-3: #6b6b6b;
  --line: #e4e4e4;
  --line-2: #d0d0d0;

  /* El acento es UNO y es violeta. Sale del lavanda que el degradado de la marca ya tiene
     (`--marca-2`, #d5cff9): el relleno es esa misma familia llevada a un tono que aguanta texto
     blanco encima (6,5:1), así el botón que hay que apretar y la superficie de la marca se leen como
     el mismo producto en vez de como dos paletas conviviendo. */
  --brand: #6d28d9;
  /* Lo que se lee ENCIMA del relleno de marca. Es un token y no un `#fff` repetido en tres reglas
     porque es la mitad de un PAR: cuando el relleno cambia, este tiene que poder cambiar con él o
     el texto desaparece. Con el blanco escrito a mano en cada regla, un relleno claro deja tres
     lugares ilegibles y nada lo detecta. */
  --on-brand: #ffffff;
  --brand-ink: #5b21b6;
  --brand-soft: #f4f1fe;
  /* El borde de lo que se apoya en `--brand-soft`. Existe porque un borde gris alrededor de una
     superficie teñida se ve sucio, y uno del color del relleno se pierde. */
  --brand-line: #ddd2fb;
  --ok: #0f6339;
  --ok-soft: #e6f2eb;
  /* El verde de un PUNTO, no de un texto. `--ok` es oscuro porque encima va a haber letras y tiene
     que llegar al piso de contraste; un punto de 16px con ese verde se lee como una manchita gris.
     Este vive aparte para que nadie lo use como color de texto y para que nadie aclare `--ok`
     buscando que el punto se vea. */
  --ok-vivo: #10b981;
  --warn: #8a5a00;
  --warn-soft: #fdf3e0;
  --danger: #b32020;
  --danger-soft: #fceded;

  --sh-1: 0 1px 2px rgba(26, 26, 26, 0.06);
  --sh-2: 0 1px 2px rgba(26, 26, 26, 0.05), 0 8px 20px -8px rgba(26, 26, 26, 0.16);
  --sh-3: 0 10px 40px -12px rgba(26, 26, 26, 0.35);

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* Prefijo propio: una variable NO se acota por clase, así que un nombre compartido con
     `panel.css` se pisa en silencio y cambia la otra pantalla. Ver el docstring de arriba. */
  --r-ctl: 8px;
  --r-caja: 10px;
  --r-tarjeta: 16px;

  /* El bloque de comando: la única superficie oscura que queda en esta pantalla. Lleva el mismo
     sesgo violeta del acento para que no se lea como de otro producto.

     Van los DOS como token —fondo y texto— y con su par de contraste declarado en el catálogo. Con
     el texto quemado, el primer «hazlo todo más claro» dejaba el comando escrito en gris casi blanco
     sobre casi blanco: ilegible, y sin nada que lo impidiera. */
  --riel-cmd: #191634;
  --riel-cmd-txt: #e7ecf2;

  /* El alto de la franja de arriba. */
  --alto-franja: 64px;
}

* { box-sizing: border-box; }

/* `hidden` TIENE que ganar, y por eso lleva `!important`.
 *
 * El atributo esconde por una regla del navegador (`display: none`), y cualquier regla de esta hoja
 * que le fije un `display` a ese mismo elemento le gana por especificidad. El resultado es que
 * `el.hidden = true` deja de hacer nada — sin error, sin aviso, y solo en los elementos que casualmente
 * tienen un `display` declarado. Acá eso ya pasaba: la barra del registro, la lista de aplicaciones y
 * el recuadro de cierre son `flex` y `grid`, así que quien NO tiene permiso sobre el registro veía el
 * bloque que le explica a quién pedirlo Y la pantalla de gestión vacía debajo, a la vez.
 *
 * Se pone una vez y para todos: la alternativa es acordarse de escribir `[hidden]` cada vez que un
 * componente nuevo gane un `display`, y el día que alguien se olvide el síntoma no se parece en nada
 * a la causa. */
[hidden] { display: none !important; }

body[data-vista="consola"],
body[data-vista="login"] {
  margin: 0;
  background: var(--bg-soft);
  color: var(--text);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ui-registro code {
  font-family: var(--mono);
  font-size: 0.875em;
  background: var(--bg-sunken);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

/* ── Barra superior ─────────────────────────────────────────────────────── */

/* La barra lleva la superficie de la MARCA —la misma del fondo del login—, y la
   receta vive en `marca.css`. Acá sólo queda la forma. El fondo y el borde salen
   de `.marca-barra`: declararlos otra vez acá le ganaría por especificidad. */
.ui-registro .topbar {
  /* SE QUEDA al hacer scroll. La lista de aplicaciones crece hacia abajo y sin esto, para volver a
     la marca o para salir, hay que subir toda la pantalla primero. Gana a la `position: relative`
     que declara la superficie de la marca por especificidad, no por orden de archivos. */
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 20px;
  height: var(--alto-franja);
}

/* El contenido, por encima del alambrado. */
.ui-registro .topbar > .brand,
.ui-registro .topbar > .tb-fin { position: relative; z-index: 1; }

/* Sobre el degradado, los grises de la escala neutra se quedan cortos de
   contraste: `--text-3` da 4,2:1 contra el azul más claro. La tinta de la marca
   está calculada para esta superficie. */
.ui-registro .topbar .seccion,
.ui-registro .topbar .quien { color: var(--marca-tinta); }
.ui-registro .topbar .sep { color: var(--marca-tinta-suave); }

.ui-registro .brand { display: flex; align-items: center; gap: 10px; font-size: 0.9375rem; }

/* La cara del producto, con un aro blanco. Sobre el degradado, un dibujo con fondo propio y sin
   borde se ve pegado encima; el aro lo apoya en la superficie. */
.ui-registro .brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.9), 0 1px 3px rgba(40, 56, 96, 0.18);
}

/* ══ LA CARA, ENCUADRADA ══════════════════════════════════════════════════════
   El avatar es un personaje de CUERPO ENTERO metido en un círculo: cabeza arriba, torso claro
   abajo. A 88px eso se lee como un retrato y tiene carácter — por eso la pantalla de entrada lo
   muestra entero. A 34 y a 24 no: la cara queda del tamaño de una arveja en el tercio de arriba, el
   torso blanco pesa más que ella, y el conjunto se ve caído hacia el fondo del disco. Es lo que se
   veía en el chat, donde el avatar aparece tres veces y ninguna pasa de 34px.

   A esos tamaños se muestra la CARA sola. El archivo sigue siendo UNO —acá se lo agranda y se lo
   recorta al disco—, así que retocar el dibujo sigue siendo retocar un archivo y no dos que se van
   separando.

   **El factor lo fija la CABEZA, no la cara.** Es tentador calcularlo sobre el círculo dorado de la
   cara (radio 63.75 en un lienzo de 231, o sea ×1.81 para llenarlo) y ese número está mal: el pelo es
   más ancho que la cara y el rodete asoma por arriba, así que a partir de ×1.2 el recorte les pasa el
   cuchillo y la cabeza queda plana contra el borde. Se ve agrandada y cortada, que es el otro modo de
   verse mal.

   ×1.15 es lo que entra: la cabeza completa con su rodete, aire azul alrededor —el anillo del propio
   dibujo, de donde el disco saca su color— y el torso reducido a una franja fina abajo, que además
   el punto de estado cubre en parte. El techo duro está en ×1.2; de ahí para arriba se corta.

   ── `clip-path` en la imagen, y NO `overflow` en el envoltorio ──
   Alrededor del disco se dibujan cosas —el aro de espera y el punto de estado— y un recorte puesto
   en el envoltorio se las llevaría puestas. Recortando la imagen, el encuadre es el mismo pase lo
   que pase afuera.
   El costo es que `clip-path` recorta también las sombras, así que el halo y el fondo blanco pasan
   al envoltorio — que es además donde tienen que estar, porque son del disco y no del dibujo. */
.ui-registro .brand-mark img,
.lxc-cara {
  --zoom: 1.15;
  width: calc(var(--cara) * var(--zoom));
  height: calc(var(--cara) * var(--zoom));
  /* Devuelve a la línea el espacio que el agrandado se llevó: de layout sigue midiendo `--cara`.
     Escrito con `--zoom` y no con el número ya restado, porque son la MISMA decisión: con dos
     números, retocar el encuadre deja el dibujo corrido y empujando a lo que tiene al lado. */
  margin: calc(var(--cara) * (1 - var(--zoom)) / 2);
  max-width: none;
  clip-path: circle(calc(var(--cara) / 2));
  /* El radio lo pone el recorte. Dejarlo además acá no cambia nada y confunde sobre quién manda. */
  border-radius: 0;
}

.ui-registro .brand-mark img { --cara: 26px; display: block; }
.ui-registro .brand b { font-weight: 650; letter-spacing: -0.01em; }
.ui-registro .sep { color: var(--line-2); }
.ui-registro .seccion { color: var(--text-2); }

.ui-registro .tb-fin { display: flex; align-items: center; gap: 10px; }

/* ── Quién está operando ────────────────────────────────────────────────────
   Una FICHA con la inicial y el correo, no el correo suelto. Suelto sobre el degradado era el único
   texto sin superficie de la franja y se leía como una nota al margen; con la inicial adelante se
   reconoce de un vistazo con quién está abierta la sesión, que es la pregunta que ese dato contesta. */
.ui-registro .cuenta {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px 0 4px;
  border: 1px solid;
  border-radius: 999px;
}

.ui-registro .cuenta-disco {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--brand);
  color: var(--on-brand);
  font-size: 0.75rem;
  font-weight: 650;
  line-height: 1;
}
/* Quién está operando. En la tipografía del texto y no en monoespaciada: un correo no es un dato
   que haya que comparar carácter por carácter, y la monoespaciada lo hacía leer como un valor
   técnico más de la pantalla. */
.ui-registro .quien {
  color: var(--text-3);
  font-size: 0.8125rem;
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-registro main { max-width: 1080px; margin: 0 auto; padding: 32px 24px 80px; }

.ui-registro .estado-carga { color: var(--text-3); text-align: center; padding: 64px 0; }

/* ════════════════════════════════════════════════════════════════════════════
   LOGIN

   Es la primera pantalla de todos y la única sin datos: la que puede permitirse
   atmósfera. Una tarjeta blanca sobre gris plano no dice nada sobre el producto
   que hay detrás; el fondo sí, y no cuesta ni un dato ni una petición de red.

   Tres decisiones que hay que sostener:

   1. El fondo es DECORACIÓN y no lleva ni una palabra. Todo lo que hay que leer
      está en la tarjeta, y la tarjeta se sostiene sola sobre blanco.
   2. El contraste NO se mide contra el vidrio: se mide contra lo que queda
      debajo del vidrio, que es el fondo. Por eso la tarjeta es 62% blanca y no
      30%, y por eso el pie usa una tinta propia, más oscura que `--text-2`.
   3. Nada se mueve. Es la pantalla que más gente ve y la que menos tiempo mira;
      una animación de entrada retrasa la sensación de que está lista.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── El fondo ─────────────────────────────────────────────────────────────── */

/* La receta —degradado y alambrado— vive en `marca.css` y la comparten las dos barras superiores.
   Acá sólo queda DÓNDE se pone.

   Vive dentro de `#vista-login` y no en el `body` a propósito: en el body tendría que pintarse
   también durante «cargando» —el instante previo a saber si hay sesión— y quien ya está adentro
   vería un destello azul antes del gris de la consola. Acá aparece exactamente cuando aparece el
   login. */
.fondo-login {
  position: fixed;
  inset: 0;
  z-index: 0;
}

/* ── La capa ──────────────────────────────────────────────────────────────── */

/* Dos filas: la tarjeta centrada en el alto disponible, y el pie apoyado abajo. */
.capa-login {
  /* `dvh` y no `vh`: en móvil `100vh` cuenta la barra del navegador y deja la tarjeta bajo el
     pliegue. */
  min-height: 100dvh;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: 1fr auto;
  justify-items: center;
  /* `safe center`, porque un centrado duro esconde el borde de arriba —inalcanzable— cuando el
     contenido crece (un error largo, por ejemplo). */
  align-items: safe center;
  gap: 24px;
  /* Gana a `.ui-registro main` (0-1-1), que si no le impone su padding de página. */
  padding: 24px !important;
}

/* ── La tarjeta ───────────────────────────────────────────────────────────── */

.ui-registro .tarjeta-login {
  position: relative;
  width: 100%;
  max-width: 544px;
  /* 48 arriba deja lugar al avatar, que monta el borde. */
  margin: 48px 0 0;
  padding: 68px 40px 36px;
  border-radius: 24px;
  text-align: center;

  /* Vidrio. El fallback de abajo es lo que hace que esto sea seguro: sin
     `backdrop-filter` la tarjeta se vuelve casi opaca en vez de transparente, que
     es la diferencia entre «se ve distinto» y «no se lee». */
  background: rgba(255, 255, 255, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  /* Sombra en dos capas y con tinte frío, del color del fondo: una sombra negra
     sobre un degradado azul se ve sucia. */
  box-shadow:
    0 24px 60px -20px rgba(40, 56, 96, 0.34),
    0 2px 6px rgba(40, 56, 96, 0.08);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ui-registro .tarjeta-login { background: rgba(255, 255, 255, 0.94); }
}

/* El avatar a caballo del borde. Absoluto y no un margen negativo: con `top: -48`
   sobre una caja de 96 queda EXACTAMENTE la mitad afuera, sin depender de cómo
   colapsen los márgenes del primer hijo. */
.ui-registro .avatar-login {
  position: absolute;
  top: -48px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border-radius: 999px;
  background: #fff;
  /* El ARO de marca va ANTES de la sombra en la lista: las sombras se pintan en orden y la primera
     queda arriba. Con el orden al revés, la sombra difusa cae encima del aro y lo deja sucio.
     El aro existe porque detrás no hay un plano: es la malla de la marca, y sobre un fondo con
     dibujo un disco blanco sin borde se lee como un recorte. */
  box-shadow: 0 0 0 3px var(--brand), 0 8px 22px -8px rgba(40, 56, 96, 0.4);
}

.ui-registro .avatar-login img { border-radius: 999px; display: block; }

/* ── EL PUNTO: hay con quién hablar ───────────────────────────────────────────
   Es el mismo par —cara con aro y punto— que la barra del chat monta sobre su propia cara, a la
   escala de esta pantalla.

   **No es un adorno que siempre pueda estar verde**, y esa es la única razón por la que se puede
   poner: esta pantalla la sirve EL MISMO proceso que atiende los turnos, así que tenerla a la vista
   ya es la prueba de que el servicio está arriba. Un punto verde en una pantalla servida por otra
   cosa afirmaría algo que nadie comprobó.

   A 45° sobre la circunferencia: en un disco de 96 el punto de las 4:30 cae a poco más de 6px de la
   esquina de la caja, así que en porcentaje queda montado en el aro —y sigue montado cuando el disco
   se achica a 80 en pantalla angosta, sin una segunda regla que mantener en sincronía. */
.ui-registro .avatar-login::after {
  content: "";
  position: absolute;
  right: 6.5%;
  bottom: 6.5%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ok-vivo);
  /* El anillo del color de la tarjeta es lo que lo despega del dibujo: sin él, un punto verde
     apoyado sobre el pelo se lee como parte del pelo. */
  box-shadow: 0 0 0 3px var(--bg);
}

.ui-registro .tarjeta-login h1 {
  /* El titular vive lejos del cuerpo: un h1 a 1,2× del párrafo es lo que hace que una pantalla se
     lea como documentación interna en vez de como un producto. */
  font-size: 2rem;
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.025em;
  margin: 0 0 14px;
}

/* El glifo a la izquierda del párrafo. No informa —lo dice el texto— pero da el
   punto de entrada de la lectura, que en un bloque centrado no existe. */
.ui-registro .lede {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  margin: 0 0 28px;
  color: var(--text-2);
  font-size: 0.9375rem;
  text-align: left;
}

.ui-registro .lede-ic {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ui-registro .acciones-login { display: grid; gap: 12px; }

/* ── El pie: información de la PÁGINA, no del acto de entrar ──────────────── */

.pie-login {
  align-self: end;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 20px;
  width: 100%;
  /* El MISMO ancho que la tarjeta: alineados por los bordes se leen como una sola
     columna, en vez de como dos bloques centrados que casualmente coinciden. */
  max-width: 544px;
  padding: 0 4px;
}

/* Tinta propia y no `--text-2`: el pie es lo ÚNICO que se apoya directo en el
   degradado, sin el vidrio de la tarjeta abajo, y ahí un gris medio se queda
   corto de contraste. */
.pie-acceso {
  margin: 0;
  color: #3c4a66;
  font-size: 0.8125rem;
}

/* El selector, en vidrio, para que pertenezca al fondo en vez de posarse encima. */
.idiomas-login {
  background: rgba(255, 255, 255, 0.5);
  border-color: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.idiomas-login .idioma-op { color: #47566f; }
.idiomas-login .idioma-op:hover { color: #1f2937; }
.idiomas-login .idioma-op[aria-checked="true"] { background: #fff; color: #1f2937; }

/* ── Angosto ──────────────────────────────────────────────────────────────── */

@media (max-width: 560px) {
  .capa-login { padding: 16px !important; gap: 16px; }
  .ui-registro .tarjeta-login { margin-top: 40px; padding: 58px 22px 26px; border-radius: 20px; }
  .ui-registro .avatar-login { width: 80px; height: 80px; top: -40px; }
  .ui-registro .avatar-login img { width: 72px; height: 72px; }
  .ui-registro .tarjeta-login h1 { font-size: 1.625rem; }
  /* El pie se apila y se centra: en una fila, la nota de acceso parte en tres líneas
     al lado del selector y deja de leerse. */
  .pie-login { justify-content: center; text-align: center; }
}

/* ── Botones ────────────────────────────────────────────────────────────── */

.ui-registro .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* 44px: el piso táctil de verdad (Apple HIG). Estaba en 40 con un comentario que lo llamaba
     "el piso" — no lo es, y esta pantalla se abre en tablet tanto como en escritorio. */
  min-height: 44px;
  padding: 0 16px;
  border-radius: var(--r-ctl);
  border: 1px solid transparent;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 550;
  cursor: pointer;
  /* El botón de descarga es un `<a>` de verdad —tiene que serlo, descarga un archivo— y sin esto
     sale con el subrayado del navegador adentro de un botón relleno. */
  text-decoration: none;
  transition: background-color var(--mov-rapido) var(--e-entra), border-color var(--mov-rapido) var(--e-entra), box-shadow var(--mov-rapido) var(--e-entra);
}

.ui-registro .btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.ui-registro .btn-pri { background: var(--brand); color: var(--on-brand); }
.ui-registro .btn-pri:hover { background: var(--brand-ink); }

.ui-registro .btn-sec { background: var(--bg); color: var(--text); border-color: var(--line-2); }
.ui-registro .btn-sec:hover { background: var(--bg-soft); }

/* Los dos de entrar. Sobre el vidrio no llevan borde: un borde gris sobre una
   superficie translúcida se lee como un recuadro pegado encima. Lo que los separa
   del fondo es que son BLANCO OPACO y levantan sombra — que además es lo que los
   hace leer como los únicos dos objetos accionables de la pantalla. */
.ui-registro .btn-prov {
  background: #fff;
  color: var(--text);
  border-color: transparent;
  border-radius: 12px;
  min-height: 52px;
  font-weight: 600;
  box-shadow:
    0 1px 2px rgba(40, 56, 96, 0.1),
    0 6px 14px -8px rgba(40, 56, 96, 0.28);
  transition: box-shadow var(--mov-rapido) var(--e-entra), transform var(--mov-rapido) var(--e-entra);
}

.ui-registro .btn-prov:hover {
  background: #fff;
  box-shadow:
    0 2px 4px rgba(40, 56, 96, 0.12),
    0 12px 22px -10px rgba(40, 56, 96, 0.36);
  transform: translateY(-1px);
}

/* Al presionar vuelve a su sitio: el botón se hunde hacia el dedo, no se aleja. */
.ui-registro .btn-prov:active { transform: none; box-shadow: 0 1px 2px rgba(40, 56, 96, 0.14); }

@media (prefers-reduced-motion: reduce) {
  .ui-registro .btn-prov { transition: box-shadow var(--mov-rapido) var(--e-entra); }
  .ui-registro .btn-prov:hover { transform: none; }
}

/* Salir NO puede ser lo más llamativo de la pantalla. Relleno blanco sobre el degradado, era el
   objeto de más contraste del documento —más que descargar la guía o registrar una aplicación, que
   son a lo que se viene— y el ojo aterrizaba en la salida. En vidrio sigue estando a la vista y a un
   clic, pero deja de competir con la acción del día. */
.ui-registro .btn-salir {
  height: 36px;
  min-height: 0;
  padding: 0 14px;
  border-radius: 999px;
  color: var(--marca-tinta);
  border: 1px solid;
}

.ui-registro .btn-salir:hover { background: rgba(255, 255, 255, 0.8); }

.ui-registro .btn-peligro { background: var(--bg); color: var(--danger); border-color: var(--line-2); }
.ui-registro .btn-peligro:hover { background: var(--danger-soft); border-color: var(--danger); }

/* ── Panel ──────────────────────────────────────────────────────────────── */

/* EL ENCABEZADO DE UNA SECCIÓN, y es el mismo para las dos que tienen lista —aplicaciones y
   clientes—: qué es esta pantalla a la izquierda, la acción a la derecha, y una línea fina que la
   separa de lo que viene abajo. Sin la línea, el título y la primera fila de la lista quedaban a la
   misma distancia que dos filas entre sí, y el encabezado se leía como un elemento más de la lista. */
.ui-registro .barra {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin: 0 0 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

/* Sin `h1`: con el elemento, esta regla le gana a `.hoja-t` por especificidad y el título del
   paso 3 deja de encoger en móvil como los otros dos. La jerarquía la fija `.hoja-t`. */
.ui-registro .barra .hoja-t { margin: 0 0 8px; }

.ui-registro .alerta {
  padding: 12px 16px;
  border-radius: var(--r-caja);
  font-size: 0.875rem;
  margin: 0 0 16px;
  border: 1px solid transparent;
}

.ui-registro .alerta-info { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand-ink); }
.ui-registro .alerta-error { background: var(--danger-soft); border-color: #f0c8c8; color: var(--danger); text-align: left; }

/* ── Diálogo ────────────────────────────────────────────────────────────── */

.dialogo {
  width: min(520px, calc(100vw - 32px));
  /* Con el teclado virtual abierto y un error largo, sin techo el formulario se sale de pantalla. */
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-tarjeta);
  box-shadow: var(--sh-3);
  color: var(--text);
}

.dialogo::backdrop { background: rgba(26, 26, 26, 0.45); }
.dialogo form { padding: 28px; }
.dialogo h2 { font-size: 1.25rem; letter-spacing: -0.01em; margin: 0 0 20px; }

.campo { display: block; margin-bottom: 20px; }
.et { display: block; font-size: 0.8125rem; font-weight: 600; margin-bottom: 6px; }

.campo input {
  width: 100%;
  min-height: 40px;
  padding: 0 12px;
  /* 16px reales: por debajo, Safari en iOS hace zoom al enfocar y descoloca el diálogo. */
  font-size: 1rem;
  font-family: var(--mono);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: var(--r-ctl);
}

.campo input:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand); }
.campo input[readonly] { background: var(--bg-sunken); color: var(--text-2); }

.ayuda { display: block; color: var(--text-3); font-size: 0.8125rem; margin-top: 6px; }

.acciones-form { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }

/* ══ LA TABLA DE IDENTIFICADORES ══════════════════════════════════════════════
   Dos columnas de datos y una de acción, y es una TABLA de verdad y no una grilla de divs: el tipo y
   el valor son columnas CON NOMBRE, y quien navega con lector de pantalla necesita que se lo digan
   al entrar en cada celda.

   El diálogo de la organización es más ancho que el de una aplicación por esto: con 520 px la
   columna del valor quedaba en 200 y un dominio no entra sin cortarse.
   ═══════════════════════════════════════════════════════════════════════════ */

.dialogo-ancho { width: min(600px, calc(100vw - 32px)); }

.ui-registro .puertas {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 12px;
}

.ui-registro .puertas th {
  padding: 0 8px 6px 0;
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

.ui-registro .puertas .col-tipo { width: 34%; }
.ui-registro .puertas .col-quitar { width: 40px; }

.ui-registro .puertas td { padding: 0 8px 8px 0; vertical-align: top; }
.ui-registro .puertas td:last-child { padding-right: 0; }

/* La lista de tipos lleva la misma caja que un campo de texto —alto, borde, radio— y su propio
   ángulo dibujado: con la flecha que pone el sistema, los dos controles de una misma fila se ven de
   dos épocas distintas. */
.ui-registro .puerta-tipo {
  width: 100%;
  min-height: 40px;
  padding: 0 32px 0 10px;
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  font-size: 0.875rem;
  color: var(--text);
  background-color: var(--bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%236b6b6b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-ctl);
  cursor: pointer;
}

.ui-registro .puerta-tipo:hover { border-color: var(--text-3); }

.ui-registro .puerta-tipo[aria-invalid="true"] {
  border-color: var(--danger);
  background-color: var(--danger-soft);
  color: var(--danger);
}

.ui-registro .puerta-tipo:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
  border-color: var(--brand);
}

/* Una fila marcada se ve por el BORDE y por el relleno, no solo por el texto rojo de abajo: el
   motivo puede quedar fuera de la pantalla cuando la tabla es larga, y el campo no. */
.ui-registro .campo .puerta-valor[aria-invalid="true"] {
  border-color: var(--danger);
  background: var(--danger-soft);
}

.ui-registro .puerta-err {
  margin: 4px 0 0;
  color: var(--danger);
  font-size: 0.75rem;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.ui-registro .puerta-quitar {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  color: var(--text-3);
  cursor: pointer;
  transition: background var(--mov-rapido) var(--e-entra), color var(--mov-rapido) var(--e-entra);
}

.ui-registro .puerta-quitar:hover { background: var(--danger-soft); color: var(--danger); }
.ui-registro .puerta-quitar:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

.ui-registro .puerta-quitar svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

/* Agregar una fila NO es la acción del formulario —esa es guardar— así que no compite con ella. */
.ui-registro .btn-agregar {
  min-height: 38px;
  padding: 0 14px;
  font-size: 0.8125rem;
}

.ui-registro .btn-agregar svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.ui-registro .btn-agregar:disabled { opacity: 0.55; cursor: default; }
.ui-registro .btn-agregar:disabled:hover { background: var(--bg); }

.ui-registro .tope { color: var(--warn); }

/* ── La fila, acostada ──────────────────────────────────────────────────────
   Tres columnas no entran en un teléfono: la del valor quedaría en 136 px y un dominio se lee a
   pedazos. La fila se acuesta —tipo arriba, valor abajo, quitar a la derecha— y las filas se separan
   con una línea, que es lo que la columna hacía por posición.

   Cambiarle el `display` a una tabla le saca la semántica de tabla en varios navegadores; por eso el
   marcado declara los roles a mano (`role="table"`, `"row"`, `"cell"`) y acá no se pierde nada. */
@media (max-width: 520px) {
  .ui-registro .puertas,
  .ui-registro .puertas tbody { display: block; }
  .ui-registro .puertas thead { display: none; }

  .ui-registro .puertas tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 40px;
    gap: 8px;
    padding: 12px 0;
    border-bottom: 1px solid var(--line);
  }

  .ui-registro .puertas tr:first-child { padding-top: 0; }

  .ui-registro .puertas td { display: block; padding: 0; }
  .ui-registro .puertas td:nth-child(1) { grid-column: 1; grid-row: 1; }
  .ui-registro .puertas td:nth-child(2) { grid-column: 1; grid-row: 2; }
  .ui-registro .puertas td:nth-child(3) { grid-column: 2; grid-row: 1; }
}


@media (max-width: 640px) {
  .topbar { padding: 0 12px; }
  /* Sin el correo, la ficha queda siendo el disco: un óvalo con relleno a un solo lado se ve
     desbalanceado, así que el hueco se reparte parejo. */
  .ui-registro .quien { display: none; }
  .ui-registro .cuenta { padding: 4px; }
  .ui-registro main { padding: 20px 16px 60px; }
  .ui-registro .barra { flex-direction: column; align-items: stretch; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* La salida de la pantalla de login: quien no es del equipo no debería quedar mirando un muro. */
.ui-registro .salida {
  margin: 24px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  color: var(--text-3);
  font-size: 0.8125rem;
}

.ui-registro .salida a { color: var(--brand); }


/* El `app_id` derivado del nombre, en el formulario. Se muestra porque NO es una etiqueta: es lo que
   el gateway despacha y lo que se interpola en la URL del MCP. Verlo al tipear es lo que hace que
   una colisión con otra app se note antes de guardar y no en el rechazo. */
.ui-registro .id-derivado {
  font-family: var(--mono);
  font-size: 0.8125rem;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--bg-sunken);
  color: var(--text);
}

.ui-registro .id-derivado[data-estado="ocupado"] { background: var(--danger-soft); color: var(--danger); }
.ui-registro .id-derivado[data-estado="fijo"] { color: var(--text-3); }

/* El id bajo el nombre en la tabla: presente para poder comparar, sin competir con el nombre. */
.ui-registro .id-chico { color: var(--text-3); margin-top: 2px; }

/* ── LA HOJA ──────────────────────────────────────────────────────────────── */

/* Una superficie propia para lo que hay que LEER Y HACER, separada del fondo de la pantalla. La
   sección de marcas no la lleva sobre su contenido: ahí lo que hay son tarjetas, y una tarjeta
   adentro de otra pierde la separación que hace la lista. */
.ui-registro .hoja { animation: hoja-entra var(--mov-normal) var(--e-entra); }

/* **La hoja es ancha y la PROSA no.** Son dos decisiones distintas y conviene no confundirlas: la
   medida de lectura cómoda son ~62 caracteres y eso no cambia con el monitor, pero lo que hay debajo
   de la prosa —cinco tarjetas, un bloque de comando de 106 caracteres— sí necesita el ancho, y
   apretarlo en una columna de texto lo deja con desplazamiento horizontal o partido en tres
   renglones. Así que la hoja da el ancho, cada párrafo se queda en su medida, y lo que se usa con
   las manos lo aprovecha entero. */
.ui-registro .hoja-lectura {
  max-width: 980px;
  margin-inline: auto;
  padding: 32px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-tarjeta);
  box-shadow: var(--sh-1);
}

.ui-registro .hoja:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; border-radius: var(--r-caja); }

@keyframes hoja-entra {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* Lo que se lee a la izquierda, lo que se hace a la derecha. La columna del panel es
   fija: es una tarjeta con un botón adentro y estirarla no la mejora. */
.ui-registro .hoja-t {
  /* 24px contra 15px del cuerpo: la jerarquía la hace la distancia, no el negrita. */
  font-size: 1.5rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}

/* 70 caracteres, no 62: el rango de lectura cómoda va de 45 a 75, y en una hoja que ahora es ancha
   —porque las tarjetas y el comando lo necesitan— el extremo bajo se lee como una columna olvidada
   al costado. Sigue siendo prosa medida; lo que cambia es cuál de los dos extremos se elige. */
/* EL LEDE ocupa el ANCHO de la hoja, y esa es una decisión tomada a propósito contra la regla de
   siempre.

   La regla dice que una línea de texto se lee mejor a ~66 caracteres, y a ese techo el párrafo medía
   605px en una hoja de 916: quedaba arrinconado contra el margen izquierdo con 300px de blanco al
   lado, y eso se ve como un error de maquetación aunque cada línea se lea perfecta. Un bloque de
   texto que parece incompleto no invita a leerlo, así que la línea cómoda no servía de nada.

   Lo que compensa la línea larga es lo demás: 17px en vez de 15 —más grande que el cuerpo, porque es
   una introducción y se lee como tal—, el interlineado a 1.75 para que el ojo encuentre el renglón
   siguiente, y la tinta del texto principal en lugar del gris de apoyo, que lo dejaba pareciendo una
   nota al pie de su propio título. */
.ui-registro .hoja-l {
  max-width: none;
  margin: 0 0 28px;
  color: var(--text);
  font-size: 1.0625rem;
  line-height: 1.75;
  letter-spacing: -0.003em;
}

.ui-registro .hoja-l-corta { margin-bottom: 0; }

/* ══ LOS TRES CAMINOS ═════════════════════════════════════════════════════════
   Tres formas de poner la misma guía a trabajar. Pestañas y no una lista: son ALTERNATIVAS —se
   elige una— y una lista de tres donde solo una te toca obliga a leer dos de más.

   La caja es una superficie hundida dentro de la hoja, con las pestañas montadas en su borde de
   arriba: así se ve que el contenido de abajo PERTENECE a la pestaña encendida, que es lo único
   que un grupo de pestañas tiene que dejar claro. */
.ui-registro .caminos {
  margin: 0 0 24px;
}

/* Los textos de esta hoja usan el ancho de su caja, y no el techo de ~66 caracteres que dice la
   regla de lectura. Es la misma decisión que el lede, por la misma razón: a ese techo cada párrafo
   quedaba arrinconado contra su margen izquierdo, con un tercio de la caja en blanco al lado, y un
   bloque que parece incompleto no invita a leerlo. Lo que compensa la línea larga es el interlineado
   —1.6 y más— y que cada caja ya acota lo suyo: adentro de un camino o de una fila del acordeón, el
   ancho disponible nunca es el de la pantalla entera. */

.ui-registro .caminos-t {
  margin: 0 0 12px;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.006em;
  color: var(--text);
}

.ui-registro .caminos-tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-sunken);
  border-radius: var(--r-caja) var(--r-caja) 0 0;
  overflow-x: auto;
  /* Sin esto, en pantalla angosta las tres pestañas se encogen hasta partir sus nombres en dos
     renglones de tres letras. Prefiere desbordar y desplazarse. */
  scrollbar-width: none;
}
.ui-registro .caminos-tabs::-webkit-scrollbar { display: none; }

.ui-registro .camino-tab {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 14px;
  appearance: none;
  border: 0;
  border-radius: calc(var(--r-caja) - 2px);
  background: transparent;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 550;
  color: var(--text-2);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--mov-rapido) var(--e-entra), color var(--mov-rapido) var(--e-entra);
}
.ui-registro .camino-tab:hover { color: var(--text); }
.ui-registro .camino-tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* La encendida se distingue por SUPERFICIE y peso, no solo por color: un cambio de color a secas
   no sobrevive a un daltónico ni a una pantalla al sol. */
.ui-registro .camino-tab[aria-selected="true"] {
  background: var(--bg);
  color: var(--text);
  font-weight: 650;
  box-shadow: var(--sh-1);
}

.ui-registro .camino {
  padding: 20px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 var(--r-caja) var(--r-caja);
}
.ui-registro .camino[hidden] { display: none; }

/* ── LOS PASOS DE CADA CAMINO ─────────────────────────────────────────────────
   Una lista numerada de verdad, y el número lo dibuja la lista con un contador propio en vez de
   dejarlo en el margen: los `<li>` traen adentro cosas altas —el bloque del comando, un botón— y un
   marcador de lista se centra contra la primera línea del ítem, así que con dos renglones y una caja
   debajo el número queda flotando arriba del todo, lejos del renglón que enumera. Con un pseudo
   posicionado, el disco se ancla al TEXTO y se queda ahí mida lo que mida el paso.

   El disco es la única marca: sin línea que una los pasos ni estado de «hecho». Nada acá sabe si la
   persona hizo el paso 1 —el comando se copia en su terminal, fuera de esta pantalla— y una marca de
   completitud que no puede saberlo es una que miente o que nadie prende nunca. */
.ui-registro .pasos {
  counter-reset: paso;
  list-style: none;
  margin: 0;
  padding: 0;
}

.ui-registro .paso {
  counter-increment: paso;
  position: relative;
  /* El texto empieza a la derecha del disco (26) más su aire (12). Todo lo que el paso trae debajo
     —el comando, el botón— arranca en la misma columna, así que el bloque entero se lee alineado. */
  padding-left: 38px;
  margin-bottom: 18px;
}
.ui-registro .paso:last-child { margin-bottom: 0; }

.ui-registro .paso::before {
  content: counter(paso);
  position: absolute;
  left: 0;
  /* Centrado ÓPTICO contra la primera línea del texto, no contra el borde de arriba del ítem: la
     línea mide 0.9375rem × 1.6 ≈ 24, su centro está a 12, y el disco de 26 pide 12 − 13 = −1. */
  top: -1px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--brand);
  color: var(--on-brand);
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ui-registro .paso-t {
  margin: 0 0 10px;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-2);
}
/* Un paso que es SOLO su renglón no lleva el hueco de abajo: ese hueco existe para separar el texto
   de lo que el paso trae debajo, y sin nada debajo suma un espacio que descuadra la lista. */
.ui-registro .paso-t:last-child { margin-bottom: 0; }

.ui-registro .camino-nota {
  margin: 14px 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-3);
}
.ui-registro .camino-arch {
  background: none;
  padding: 0;
  margin-right: 6px;
  font-size: 0.75rem;
  color: var(--text-3);
}

.ui-registro .camino .btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* El rótulo y la frase en UNA fila: son una sola instrucción —«pedile esto»— y partidas en dos
   renglones se leen como dos pasos, dentro de uno que ya está numerado. Envuelve sola cuando no
   entra, que es lo que pasa en un teléfono; ahí sí valen dos renglones, porque la alternativa es
   que se salga de la pantalla. */
.ui-registro .pedile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* El hueco entre filas es más grande que el de la columna porque la píldora se sale de su renglón
     por arriba y por abajo (ver el margen negativo de abajo): cuando envuelve en un teléfono, ese
     desborde se comería un hueco de 8. */
  gap: 12px 10px;
}
.ui-registro .pedile-t {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-2);
}

/* ── POR QUÉ LA PÍLDORA MIDE MENOS DE LO QUE OCUPA ────────────────────────────
   La píldora mide 33 —el botón de copiar tiene su propia área táctil— y la línea de texto que la
   acompaña, 24. Dejada crecer, la FILA pasa a medir 33 y su texto se centra ahí adentro, o sea 4 o 5
   píxeles más abajo de donde estaría solo. El disco del número está anclado donde va una línea normal
   y no se entera, así que queda flotando por encima del renglón que enumera — que es exactamente lo
   que se veía en el paso 3.

   Los 9 de diferencia se sacan de la fila por arriba y por abajo. La fila vuelve a medir una línea,
   el disco le queda a la altura exacta, y la píldora se sigue viendo entera: un margen negativo no
   recorta nada, solo deja de reservar el espacio. Y el margen de 6 que la separa cuando va DEBAJO de
   un texto no aplica acá: en la fila solo la haría más alta. */
.ui-registro .pedile .copiable { margin-block: -4.5px; }

/* ── EL COMANDO ───────────────────────────────────────────────────────────────
   En tinta oscura y monoespaciado: es lo único de esta pantalla que se pega en una terminal, y
   parecerse a una terminal es lo que dice qué hacer con él sin escribirlo.

   ENVUELVE en vez de desplazarse. Un comando que se desplaza se copia igual —el botón se lleva el
   texto entero— pero para LEERLO hay que arrastrarlo, y el que hay que leer antes de pegarlo es
   justo este. Dos renglones que se ven enteros valen más que uno que hay que perseguir; el corte
   cae en un espacio, así que ninguna palabra queda partida. */
/* La caja entera: las pestañas del sistema y el comando comparten superficie y radio, así que se
   leen como UNA cosa —«el comando, en su sabor»— y no como un control suelto encima de un bloque. */
.ui-registro .comando-caja {
  margin-bottom: 18px;
  background: var(--riel-cmd);
  border-radius: var(--r-caja);
  overflow: hidden;
}

.ui-registro .so-tabs {
  display: flex;
  gap: 2px;
  padding: 6px 6px 0;
}

.ui-registro .so-op {
  min-height: 28px;
  padding: 0 12px;
  appearance: none;
  border: 0;
  border-radius: 7px 7px 0 0;
  background: transparent;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 550;
  color: rgba(255, 255, 255, 0.55);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--mov-rapido) var(--e-entra), color var(--mov-rapido) var(--e-entra);
}
.ui-registro .so-op:hover { color: rgba(255, 255, 255, 0.85); }
.ui-registro .so-op:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.9);
  outline-offset: -2px;
}
/* La encendida se apoya sobre el comando: la misma tinta un punto más clara, sin línea que las
   separe. Es lo que dice «este comando es el de esta pestaña» sin escribirlo. */
.ui-registro .so-op[aria-selected="true"] {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.ui-registro .comando {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 14px;
  overflow: hidden;
}

.ui-registro .comando code {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  background: none;
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--riel-cmd-txt);
  /* `pre-wrap` y no `pre`: conserva los espacios del comando y deja que corte al final de la línea.
     El corte cae en un espacio —no hay palabras más largas que el ancho— así que nada queda partido. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* El botón sobre tinta oscura necesita su propia paleta: el claro del resto de la pantalla
   desaparece acá. Y es el ÚNICO objeto con color de acción del bloque, porque es la acción del
   bloque — el resto es texto para leer. */
.ui-registro .comando .copiar-cmd {
  flex: 0 0 auto;
  margin-top: 1px;
  background: var(--brand);
  color: var(--on-brand);
  border-color: transparent;
  font-weight: 600;
}
.ui-registro .comando .copiar-cmd:hover { background: var(--brand-ink); color: #fff; }
.ui-registro .comando .copiar-cmd:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.9);
  outline-offset: 2px;
}
.ui-registro .comando .copiar-cmd[data-copiado] { background: var(--ok); color: #fff; }

/* ══ EL CIERRE: qué te llevás ═════════════════════════════════════════════════
   Era un párrafo con tres cosas enumeradas adentro, en el ancho de una columna de texto y contra el
   margen izquierdo de una hoja que mide 980. Separadas en tres, ocupan el ancho que ya estaba ahí y
   se cuentan de un vistazo — que es lo único que se le pide a esta parte.

   La superficie de marca y no el gris de siempre: es lo último que se lee y lo que promete el
   resultado, así que cierra con el color del producto en vez de apagarse. */
/* El relleno lateral es EL MISMO que el del panel de los caminos, y no es un detalle de gusto: las
   dos tarjetas van una debajo de la otra y arrancan en el mismo píxel, así que con 22 acá y 20 allá
   su contenido caía en dos columnas separadas por 2px. Dos columnas casi iguales se leen peor que
   dos claramente distintas: el ojo registra que algo no cierra y no encuentra qué. Si una cambia,
   cambian las dos — también en la consulta de pantalla angosta. */
.ui-registro .cierre {
  margin: 0;
  padding: 20px;
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  border-radius: var(--r-tarjeta);
}

.ui-registro .cierre-t {
  margin: 0 0 14px;
  font-size: 0.9375rem;
  font-weight: 650;
  letter-spacing: -0.006em;
  color: var(--brand-ink);
}

/* `auto-fit` reparte las tres en las columnas que entren y las devuelve a una sola en un teléfono,
   sin una consulta de medios que mantener. */
.ui-registro .cierre-lista {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px 20px;
}

/* El tilde va ABSOLUTO y el `li` es un bloque normal: la sangría colgante deja el texto de la
   segunda línea alineado con el de la primera y no debajo del marcador. Y es un tilde y no un
   número — son cosas que van a ESTAR, no pasos que haya que dar. */
.ui-registro .cierre-lista li {
  position: relative;
  padding-left: 24px;
  color: var(--text);
  font-size: 0.875rem;
  line-height: 1.5;
}

.ui-registro .cierre-lista li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 4px;
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);
}

.ui-registro .cierre-nota {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--brand-line);
  color: var(--text-2);
  font-size: 0.8125rem;
  line-height: 1.55;
}

/* ── Copiar lo que hay que llevarse a otro lado ───────────────────────────── */

/* La carpeta donde va la guía y la frase con la que se la invoca se escriben en OTRA aplicación, y
   tienen que salir exactas: una letra distinta en la carpeta es una guía que el asistente no
   encuentra. Por eso van con su propio botón y no como texto suelto para seleccionar a mano. */
.ui-registro .copiable {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-top: 6px;
  padding: 2px 2px 2px 0;
  background: var(--bg-sunken);
  border-radius: 8px;
  max-width: 100%;
}

.ui-registro .copiable code {
  background: none;
  padding: 4px 2px 4px 10px;
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

/* La frase que se le dice al asistente es lenguaje, no una ruta: va entre comillas y en la
   tipografía del texto, o se lee como algo que hay que tipear literal con su puntuación. */
.ui-registro .copiable .cita {
  font-family: var(--sans);
  font-style: italic;
  color: var(--text-2);
}

.ui-registro .copiable .cita::before { content: "\00ab"; }
.ui-registro .copiable .cita::after { content: "\00bb"; }

/* Con RÓTULO al lado del glifo. Un botón de ícono solo obliga a adivinar o a pasar el mouse por
   encima —que en una pantalla táctil no existe—, y este es la acción principal de su bloque.
   Los 28px de alto se conservan: lo que crece es el ancho. */
.ui-registro .copiar {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 550;
  color: var(--text-3);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--mov-rapido) var(--e-entra), color var(--mov-rapido) var(--e-entra);
}

/* El piso táctil sin engordar el dibujo: el área alcanza 44 px, el botón sigue midiendo 28. */
.ui-registro .copiar::before { content: ""; position: absolute; inset: -8px; }

.ui-registro .copiar svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ui-registro .copiar:hover { background: var(--bg); color: var(--text); }
.ui-registro .copiar:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* El acuse en el propio botón. El aviso de abajo lo dice además en palabras, para quien no está
   mirando ese píxel — y para quien no ve la pantalla. */
.ui-registro .copiar[data-copiado] { background: var(--ok-soft); color: var(--ok); }

/* ── El encabezado del paso 3 ─────────────────────────────────────────────── */

.ui-registro .barra-txt { min-width: 0; }
.ui-registro .barra-acc { display: flex; gap: 8px; flex: none; }

.ui-registro #btn-actualizar svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ui-registro #btn-actualizar[data-girando] svg { animation: girar 900ms linear infinite; }
.ui-registro #btn-actualizar[disabled] { opacity: 0.7; cursor: default; }

@keyframes girar { to { transform: rotate(360deg); } }

/* ── Cuántas hay, y cómo buscarlas ────────────────────────────────────────── */

/* El resumen cuenta por el estado QUE EL CHAT RESPONDIÓ, no por lo que la base tiene. «4
   registradas» y nada más repetiría lo que ya se ve; lo que no se ve de un vistazo en una lista de
   diez es cuántas están realmente atendidas. */
.ui-registro .listado-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 12px;
}

.ui-registro .resumen {
  margin: 0;
  color: var(--text-3);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.ui-registro .buscador {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 300px;
}

.ui-registro .buscador-ic {
  position: absolute;
  left: 12px;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  color: var(--text-3);
  pointer-events: none;
}

.ui-registro .buscador input {
  width: 100%;
  min-height: 40px;
  padding: 0 12px 0 34px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-ctl);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  /* 16px en pantalla táctil: por debajo de eso iOS hace zoom al enfocar y el layout salta. */
  font-size: 1rem;
}

@media (min-width: 721px) {
  .ui-registro .buscador input { font-size: 0.875rem; }
}

.ui-registro .buscador input:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* ── El aviso de que algo pasó ────────────────────────────────────────────── */

/* Para lo que no tiene lugar propio en la pantalla: que un texto se copió. Sin esto, la única forma
   de saber si el botón hizo algo era ir a pegar a otro lado. */
.aviso {
  position: fixed;
  left: 50%;
  /* Por ENCIMA de la barra del chat, que es `fixed` abajo, mide ~60px y gana en apilamiento. Sin
     esto el aviso queda tapado entero — y lo que se pierde no es la confirmación de que se copió
     (eso el propio botón lo acusa) sino el FALLO del portapapeles, que no acusa en ningún lado: la
     persona cree que copió y no copió. Sube también con el teclado virtual. */
  bottom: calc(24px + var(--lxc-barra, 0px) + var(--lxc-teclado, 0px));
  transform: translateX(-50%);
  z-index: 20;
  margin: 0;
  max-width: calc(100vw - 32px);
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-family: var(--sans);
  font-size: 0.875rem;
  box-shadow: var(--sh-2);
  animation: aviso-entra var(--mov-normal) var(--e-entra);
}

@keyframes aviso-entra {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* ── El sprite de glifos ──────────────────────────────────────────────────── */

/* Los `<symbol>` viven una vez y se instancian con `<use>`. El contenedor no ocupa lugar, pero
   tampoco puede ser `display: none`: eso rompe las referencias en varios navegadores. */
.sr-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── Angosto ──────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  .ui-registro .hoja-lectura { padding: 20px 16px; }
  .ui-registro .hoja-t { font-size: 1.25rem; }
  /* El comando se lleva casi todo el ancho: el relleno del camino se achica para devolvérselo. Y el
     cierre lo acompaña, o su contenido queda 8px a la derecha del de arriba (ver `.cierre`). */
  .ui-registro .camino,
  .ui-registro .cierre { padding: 16px 14px; }
  .ui-registro .comando { padding: 10px 12px; }

  /* La barra superior tiene que entrar en UNA fila. Lo primero que se va es el correo: no hace
     falta para operar, y es lo único de ahí que no es un control. La barra de la marca se va CON la
     sección que separaba — sola queda colgando después del nombre. */
  .ui-registro .topbar { padding: 0 14px; gap: 10px; }
  .ui-registro .seccion,
  .ui-registro .sep { display: none; }
  .ui-registro .quien { display: none; }
  .ui-registro .tb-fin { gap: 8px; }

  /* El buscador ocupa el ancho: apretado al lado del resumen no entra ni una palabra. */
  .ui-registro .buscador { flex: 1 1 100%; }
  .ui-registro .barra-acc { flex: 1 1 100%; }
  .ui-registro .barra-acc .btn { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .ui-registro .hoja { animation: none; }
  .ui-registro #btn-actualizar[data-girando] svg { animation: none; }
  .aviso { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ui-registro .hoja { animation: none; }
}

/* La explicación del estado, bajo el chip. Vive en la celda y no en un `title` porque un tooltip no
   existe en una pantalla táctil ni lo lee un lector de pantalla — y quien más necesita entender por
   qué su app aparece en gris es justamente quien no va a pasar el mouse por encima. */
.ui-registro .chip-nota {
  margin-top: 6px;
  max-width: 34ch;
  color: var(--text-3);
  font-size: 0.75rem;
  line-height: 1.4;
}


/* ── Deshabilitado y en curso ──────────────────────────────────────────────
   No existía ninguna regla `:disabled` en esta hoja. Sin ella «Guardar» no puede
   decir que está trabajando, y un doble Enter escribe dos veces. */

.ui-registro .btn[disabled],
.ui-registro .btn[aria-busy="true"] {
  opacity: 0.55;
  cursor: default;
  pointer-events: none;
}

/* ── El chip mientras se pregunta ───────────────────────────────────────────
   Falta el cuarto estado: «todavía no pregunté» no es «no pude». La consulta es serial y con techo
   de 5 s por fila, así que sin este estado una tabla de 10 apps pasa casi un minuto pareciendo rota. */

.ui-registro .chip-preguntando {
  background: var(--bg-soft);
  color: var(--text-3);
  border-color: var(--line);
  font-style: italic;
}

/* ── Estados de la tabla ───────────────────────────────────────────────────── */


/* ════════════════════════════════════════════════════════════════════════════
   LOS REGISTROS  ·  estructura tomada de la referencia de diseño

   Cuatro zonas en una fila: disco · identidad · estado · acciones. Es una LISTA
   y no una tabla — acá nadie ordena ni compara columnas, se busca una aplicación
   y se mira su estado — pero la fila se lee de izquierda a derecha como en la
   referencia, que es lo que la hace escaneable con muchas.

   Separación por ESPACIO entre registros, no por líneas: cada uno es su propia
   superficie sobre el fondo de la página.
   ════════════════════════════════════════════════════════════════════════════ */

.ui-registro .apps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.ui-registro .app {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 20px;
  padding: 20px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-tarjeta);
  transition: border-color var(--mov-rapido) var(--e-entra),
              box-shadow var(--mov-rapido) var(--e-entra);
}

.ui-registro .app:hover { border-color: var(--line-2); box-shadow: var(--sh-1); }

/* El disco de la izquierda. La referencia lo pone y funciona como ancla de lectura; lo que cambia
   es qué muestra — repetir el mismo avatar en cada fila no distingue nada, la inicial sí. */
.ui-registro .app-disco {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand-ink);
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.ui-registro .app-ident { min-width: 0; }

/* Tres niveles: nombre (20/650), dirección (13/mono) y clave (12/atenuada). Sin el tercero, el
   identificador compite con el nombre y ninguno manda. */
.ui-registro .app-nombre {
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0;
}

.ui-registro .app-url {
  margin: 4px 0 0;
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.ui-registro .app-clave {
  margin: 4px 0 0;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--text-3);
}

/* El estado y su globo. La columna es el contenedor posicionante del globo. */
.ui-registro .app-estado-col {
  position: relative;
  display: grid;
  justify-items: center;
}

.ui-registro .app-acciones { display: flex; gap: 8px; }

/* Los botones con glifo: mismo lienzo y mismo grosor de trazo, alineados con el texto. */
.ui-registro .app-acciones .btn { min-height: 44px; padding: 0 14px; font-size: 0.8125rem; }

.ui-registro .app-acciones svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* «Quitar» lleva el color de la acción como la referencia, pero SOLO en el borde y el texto: el
   relleno rojo aparece al apuntarla, cuando está por ocurrir. */
.ui-registro .btn-quitar {
  background: var(--bg);
  color: var(--danger);
  border-color: #f0c8c8;
}

.ui-registro .btn-quitar:hover,
.ui-registro .btn-quitar:focus-visible {
  background: var(--danger-soft);
  border-color: var(--danger);
}

/* ── Los tres estados de la lista ──────────────────────────────────────────── */

.ui-registro .app-estado {
  padding: 56px 24px;
  background: var(--bg);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-tarjeta);
  text-align: center;
}

.ui-registro .app-estado h2 { font-size: 1rem; font-weight: 600; margin: 0 0 6px; }

.ui-registro .app-estado p {
  max-width: 46ch;
  margin: 0 auto 20px;
  color: var(--text-3);
  font-size: 0.875rem;
}

@media (max-width: 860px) {
  /* La fila se apila: en cuatro columnas bajo 860px la dirección queda en una tira ilegible. */
  .ui-registro .app {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 14px 16px;
  }
  .ui-registro .app-estado-col { grid-column: 1 / -1; justify-items: start; text-align: left; max-width: none; }
  .ui-registro .app-acciones { grid-column: 1 / -1; }
  .ui-registro .app-acciones .btn { flex: 1; }
}

@media (max-width: 480px) {
  .ui-registro .app { padding: 16px; }
  .ui-registro .app-disco { width: 38px; height: 38px; font-size: 0.9375rem; }
  .ui-registro .app-nombre { font-size: 1.125rem; }
}

/* ════════════════════════════════════════════════════════════════════════════
   EL ESTADO: punto de color + globo

   El chip es un BOTÓN. Un globo que solo aparece al pasar el mouse no existe en
   una pantalla táctil ni para quien navega con teclado, y quien más necesita
   entender por qué su aplicación dice «Sin verificar» es justamente quien no va
   a pasar el mouse por encima. Se abre por hover (donde hay hover de verdad),
   por foco y por toque.

   El COLOR nunca va solo: cada estado lleva su palabra y su punto. Un daltónico
   tiene que poder operar esto, y el gris —el que dice «no sé»— es el que más
   fácil se lee como verde de reojo.
   ════════════════════════════════════════════════════════════════════════════ */

.ui-registro .chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: filter var(--mov-rapido) var(--e-entra);
}

.ui-registro .chip:hover { filter: brightness(0.97); }
.ui-registro .chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ui-registro .chip-inerte { cursor: default; }

/* El punto: la mitad no textual de la señal. Sin él, el estado depende del fondo del chip, que es
   suave a propósito para no gritar — y suave más daltonismo es indistinguible. */
.ui-registro .chip-punto {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: currentColor;
  flex: none;
}

.ui-registro .chip-verde { background: var(--ok-soft); color: var(--ok); border-color: #bcdcc9; }
.ui-registro .chip-ambar { background: var(--warn-soft); color: var(--warn); border-color: #ecd5a6; }
.ui-registro .chip-rojo { background: var(--danger-soft); color: var(--danger); border-color: #f0c0c0; }
.ui-registro .chip-gris { background: var(--bg-sunken); color: var(--text-3); border-color: var(--line-2); }

/* «Verificando» no es un estado de la aplicación: es un estado NUESTRO. El punto late para decir
   que algo está pasando, y el borde punteado lo separa de los cuatro que sí describen la app. */
.ui-registro .chip-preguntando {
  background: var(--bg-soft);
  color: var(--text-3);
  border-style: dashed;
  border-color: var(--line-2);
}

.ui-registro .chip-preguntando .chip-punto { animation: latir 1.4s ease-in-out infinite; }

@keyframes latir { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* ── El globo ─────────────────────────────────────────────────────────────── */

.ui-registro .globo {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  z-index: 5;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 8px;
  width: max-content;
  max-width: min(30ch, calc(100vw - 48px));
  padding: 10px 12px;
  background: #26282e;
  color: #f2f3f5;
  border-radius: var(--r-caja);
  /* Elevación en dos capas: una amplia difusa y una de contacto. Una sola sombra dura es el tell
     de UI genérica más visible que hay. */
  box-shadow: 0 12px 32px -8px rgba(17, 24, 39, 0.35), 0 2px 6px rgba(17, 24, 39, 0.12);
  font-size: 0.75rem;
  line-height: 1.45;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--mov-rapido) var(--e-entra), transform var(--mov-rapido) var(--e-entra),
              visibility 0s linear 140ms;
}

/* La punta. Se dibuja con el mismo color del globo para que no se despegue al cambiarlo. */
.ui-registro .globo::before {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-bottom-color: #26282e;
}

.ui-registro .globo b { grid-column: 2; font-weight: 650; }
.ui-registro .globo span { grid-column: 2; color: #c6c9d0; }

.ui-registro .globo-ic {
  grid-row: 1 / span 2;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
}

/* Tres disparadores, y los tres hacen falta:
   · `hover` solo donde el puntero lo soporta de verdad — en touch, `:hover` se queda pegado tras
     un toque y deja el globo abierto sin forma de cerrarlo;
   · `focus-within` para el teclado;
   · la clase, que la pone el toque. */
.ui-registro .app-estado-col:focus-within .globo,
.ui-registro .app-estado-col.globo-abierto .globo {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  transition-delay: 0s;
}

@media (hover: hover) {
  .ui-registro .app-estado-col:hover .globo {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
    transition-delay: 0s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ui-registro .chip-preguntando .chip-punto { animation: none; }
  .ui-registro .globo { transition: none; transform: translateX(-50%); }
}

@media (max-width: 860px) {
  /* Apilado, la columna del estado se alinea a la izquierda: el globo centrado sobre un chip
     pegado al borde se sale de pantalla. */
  .ui-registro .globo { left: 0; transform: none; }
  .ui-registro .globo::before { left: 22px; }
  .ui-registro .app-estado-col:focus-within .globo,
  .ui-registro .app-estado-col.globo-abierto .globo { transform: none; }
}

/* La marca de campo opcional. Va en la etiqueta y no en el placeholder: un placeholder desaparece
   al escribir, justo cuando alguien duda de si el campo hacía falta. */
.ui-registro .et-opcional {
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--bg-sunken);
  color: var(--text-3);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  vertical-align: middle;
}

/* Un identificador escrito a mano que no pasa el charset, marcado al tipear. El rechazo duro sigue
   en el submit; esto evita llegar hasta ahí a ciegas. */
.ui-registro .id-derivado[data-estado="invalido"] {
  background: var(--danger-soft);
  color: var(--danger);
  text-decoration: line-through;
}

.ui-registro .campo input:disabled {
  background: var(--bg-sunken);
  color: var(--text-3);
  cursor: default;
}

/* ── El paso 3 para quien no puede gestionar ────────────────────────────────
   No es un permiso denegado: esa persona hizo los pasos 1 y 2 igual que cualquiera y solo le falta
   que alguien con el claim escriba la fila. Por eso la pantalla le ARMA el pedido en vez de negarle
   el acceso — y en este punto tiene la dirección del servicio en la mano, que es el dato a pasar. */

.ui-registro .pedido {
  max-width: 70ch;
  margin: 0 0 24px;
  padding: 20px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-tarjeta);
}

.ui-registro .pedido dt {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}

.ui-registro .pedido dt + dd {
  margin: 2px 0 16px;
  color: var(--text-3);
  font-size: 0.8125rem;
}

.ui-registro .pedido dd:last-child { margin-bottom: 0; }

/* ══ EL CONTENIDO ════════════════════════════════════════════════════════════
   Una sola columna centrada, con techo: debajo de la franja de la marca no hay chasis, hay
   documento. Un ancho libre estira una lista de renglones cortos hasta volverla ilegible en una
   pantalla de 2000px; el techo la corta donde el ojo todavía vuelve solo al principio del renglón
   siguiente.

   **No hay menú, y la regla es que un menú se gana con los destinos.** Con uno solo —el que la
   franja de arriba ya nombra— no orienta: agrega un lugar donde mirar, una decisión que tomar, y se
   lleva el ancho que las direcciones de un MCP necesitan para compararse carácter por carácter. A
   las dos secciones se entra por su dirección. */
.ui-registro .consola {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: 32px 40px 80px;
}

/* ══ LAS ORGANIZACIONES ══════════════════════════════════════════════════════
   La fila NO reusa `.app`: esa es una grilla de cuatro columnas (disco · identidad · estado ·
   acciones) y una organización no tiene estado que verificar contra nadie. Reusarla dejaba el botón
   cayendo en la columna elástica del medio — una caja vacía enorme, que es exactamente lo que se
   veía. Acá son tres columnas y la del medio es la que crece. */
.ui-registro .orgs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.ui-registro .org {
  display: grid;
  /* Cuatro columnas y la de las PUERTAS es la que crece: con la fila ancha, apiladas debajo del
     nombre dejaban medio renglón vacío a la derecha y el dato amontonado a la izquierda. El ancho
     se llena con información, no con aire. */
  grid-template-columns: auto minmax(140px, 260px) minmax(0, 1fr) auto;
  align-items: start;
  gap: 24px;
  padding: 24px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-tarjeta);
  transition: border-color var(--mov-rapido) var(--e-entra),
              box-shadow var(--mov-rapido) var(--e-entra);
}

.ui-registro .org:hover { border-color: var(--line-2); box-shadow: var(--sh-1); }

.ui-registro .org > .app-disco { margin-top: 2px; }

.ui-registro .org-datos { min-width: 0; display: grid; gap: 8px; }

/* La acción se sienta en la línea del nombre por el mismo motivo que el disco. */
.ui-registro .org > .app-acciones { align-self: start; }



.ui-registro .org-nombre {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* El identificador propio: es un dato de máquina y se lee carácter por carácter. */
.ui-registro .org-id {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--text-3);
  overflow-wrap: anywhere;
}

/* Las PUERTAS, como fichas y no como una lista separada por puntos: cada una es un par
   tipo+valor —el invariante del modelo— y una ficha por par lo hace visible sin explicarlo. */
.ui-registro .org-puertas {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.ui-registro .org-puerta {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  max-width: 100%;
  padding: 4px 10px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/* El TIPO adelante, en versalitas: es la mitad que distingue el corporativo 42 del programa 42, y
   sin jerarquía las dos mitades se leen como una sola cadena. */
.ui-registro .org-puerta-t {
  font-family: var(--sans);
  font-size: 0.625rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* Una clave que el LECTOR va a descartar. Se marca acá porque es el único lugar donde alguien puede
   ver por qué un cliente se quedó sin su marca: pintada igual que una sana, la pantalla hecha para
   diagnosticar el problema era la que lo escondía. El color no es la única señal —el tipo pasa a ser
   un signo de admiración y la ficha lleva su explicación al pasar el puntero—, así que también se
   distingue sin ver el color. */
.ui-registro .org-puerta-rota {
  background: var(--danger-soft);
  border-color: #f0c0c0;
  color: var(--danger);
}

.ui-registro .org-puerta-rota .org-puerta-t { color: var(--danger); }

/* ── La fila, apilada ───────────────────────────────────────────────────────
   Cuatro columnas dejan de entrar mucho antes que un teléfono: a ~800px la identidad y las fichas ya
   se pisan.

   Y las puertas ocupan las DOS columnas: en la columna del disco su ancho manda sobre el de la
   columna —`auto` toma su contenido— y le come el lugar al nombre, que termina partido letra por
   letra contra el borde. Se ve exactamente como un bug de datos y es una regla de grilla. */
@media (max-width: 860px) {
  .ui-registro .org {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 12px 16px;
    padding: 20px;
  }
  .ui-registro .org > .org-puertas { grid-column: 1 / -1; }
  /* Las acciones bajan a su propia fila y ocupan el ancho: un botón de 44px alcanzable con el pulgar
     vale más que la simetría de la fila. */
  .ui-registro .org .app-acciones { grid-column: 1 / -1; }
  .ui-registro .org .app-acciones .btn { flex: 1; }
}

@media (max-width: 560px) {
  .ui-registro .org { padding: 16px; }
}

/* El margen de la página en un teléfono. Va acá, DESPUÉS de la regla que fija el relleno de escritorio
   y con su mismo selector: escrito más arriba y más corto perdía en silencio, y quedaban 40 px de aire
   a cada lado de una pantalla de 390 — el contenido se apretaba en 310 y lo que no entraba empujaba la
   página hacia el costado. */
@media (max-width: 640px) {
  .ui-registro .consola { padding: 20px 16px 60px; }
}

/* ══ LA SECCIÓN DE MARCAS ══════════════════════════════════════════════════════
   El documento de un cliente y la tabla de lo que entendimos.

   La tabla es lo que justifica la pantalla: no es un resumen, es la superficie donde alguien revisa
   una deducción de la máquina y la corrige. Por eso cada fila lleva su selector a la vista y no
   detrás de un clic — una corrección escondida es una corrección que no se hace.

   Se apoya en las variables y las clases que ya usa el resto de la consola; acá solo lo que no
   existía. */

/* El diálogo de una marca es más ancho que el de una organización: el documento es texto largo y
   la tabla tiene cuatro columnas. Con el ancho de los otros, la columna del valor queda en dos
   renglones y la tabla deja de leerse de un vistazo. */
.dialogo-marca-ancho { width: min(880px, calc(100vw - 32px)); }

.marca-doc {
  width: 100%;
  /* En una pantalla propia el cuadro puede crecer, que es la razón de haberlo sacado del diálogo.
     El alto se calcula contra el de la ventana y no en filas fijas: un documento de marca son miles
     de caracteres y editarlos de a doce renglones es lo que hacía incómodo el diálogo. */
  min-height: 26rem;
  height: calc(100vh - 20rem);
  resize: vertical;
  /* Monoespaciada porque es un archivo, no prosa: la sangría del documento es información —marca
     dónde termina el bloque de valores— y con una tipografía proporcional se pierde. */
  font: 12.5px/1.55 var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: 8px;
  padding: 10px 12px;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
}
.marca-doc:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* Una marca sin aplicaciones habilitadas no la puede usar nadie, y del lado del turno eso se ve como
   un silencio. Acá se ve. */
.org-meta-alerta { color: var(--danger); }

/* Empuja las acciones normales a la derecha y deja el borrado en el extremo opuesto: son de dos
   clases distintas y ponerlos juntos invita al clic equivocado. */
.acciones-espacio { flex: 1; }

/* El identificador ya no cuelga de la ayuda de un campo: es un bloque propio, porque es lo único que
   la aplicación necesita de esta pantalla. */
.ayuda-id { margin: 4px 0 18px; }

/* La vuelta a la lista desde el editor.

   Va ARRIBA del título y no al lado de las acciones: es navegación, no una acción sobre la marca, y
   mezclarla con guardar y borrar invita al clic equivocado justo donde uno cuesta caro. La flecha
   apunta a la izquierda —el mismo glifo que el resto, girado— porque el que existe apunta al avance. */
.btn-volver {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 0;
  padding: 0;
  margin: 0 0 6px;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  color: var(--muted);
}
.btn-volver:hover { color: var(--text); }
.btn-volver:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.btn-volver-ic {
  width: 14px;
  height: 14px;
  transform: rotate(180deg);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* En el editor, la ayuda del cuadro y el error van pegados abajo y sin el margen del formulario. */
#marcas-editor .ayuda { margin-top: 6px; }

/* «(no cambia al renombrar)» al lado del identificador, en una marca que ya existe. Es una nota, no
   un estado: va en el mismo renglón y apagada, para que no compita con el identificador. */
.id-fijo { color: var(--muted); font-weight: 400; font-size: 11.5px; margin-left: 6px; }

/* ══ EL CHAT DE LA PROPIA PÁGINA ═══════════════════════════════════════════
   Es el MISMO chat que el cliente va a embeber, y por eso no se parece al resto de esta pantalla:
   se parece al widget. Quien prueba acá tiene que estar mirando la cosa real, no una versión de
   nuestra consola con forma de chat.

   ── Por qué el chat NO sigue el tema de esta página, y no es un olvido ──
   Todo lo demás de la consola sale de los tokens del catálogo y cambia cuando alguien pide un
   cambio. El chat no: es una ISLA con la paleta del widget, igual que en una app de verdad, donde
   vive en su propio shadow DOM y conserva su identidad mientras la app cambia alrededor. Que el
   panel siguiera al tema haría dos cosas malas: mentiría sobre lo que el cliente va a ver, y
   pintaría la burbuja del usuario con el color de la marca — que es lo que el widget evita a
   propósito, porque un verde de marca sobre una app roja choca. El neutro oscuro no choca con
   ninguna.

   Lo que sí queda del tema: la página DETRÁS del panel. Eso es lo que la demostración demuestra.

   Los valores de acá son los del widget, no aproximaciones. Si allá cambian, acá quedan viejos —
   es el precio de tener el mismo dibujo en dos repos, y se paga a ojo. */

.lxc,
.lxc-sheet {
  /* La paleta del widget. Nombres propios y no los del catálogo: son de otro producto que vive
     adentro de este, y mezclarlos es lo que haría que un retoque del tema despinte el chat. */
  --lx-accent-1: #10b981;
  --lx-accent-2: #0ea5e9;
  --lx-accent-3: #7c3aed;
  --lx-glow: rgba(16, 185, 129, 0.28);
  --lx-text: #12141c;
  --lx-muted: #64748b;
  --lx-surface: #ffffff;
  --lx-hover: rgba(17, 24, 39, 0.045);
  --lx-border: rgba(17, 24, 39, 0.07);
  /* Los tres de alerta. La isla no tenía NINGUNO, así que un fallo del turno se pintaba con el
     mismo gris que una respuesta y se leía como si mimi hubiera contestado eso. */
  --lx-danger: #b42318;
  --lx-danger-soft: #fef3f2;
  --lx-danger-border: rgba(180, 35, 24, 0.22);
  /* Elevación en CAPAS —difusa amplia + contacto sutil— y nunca una sombra dura. */
  --lx-elev-2: 0 10px 30px rgba(17, 24, 39, 0.13), 0 2px 6px rgba(17, 24, 39, 0.06);
  --lx-focus: 0 0 0 3px var(--lx-glow);
}

/* ── LA BARRA: una sola superficie que crece ──────────────────────────────────
   No hay dos objetos —una pastilla y una ventana—: hay una hoja anclada abajo. En reposo es una
   píldora de 54px; con conversación se estira hacia arriba hasta un tope y scrollea adentro.

   El envoltorio no pinta nada: posiciona, y dibuja el aro de foco. Está aparte de la hoja porque la
   hoja recorta a sus hijos y se lo comería. */
.lxc {
  position: fixed;
  left: 0;
  right: 0;
  /* Pegada al borde de abajo, no flotando en el medio: es una barra de comando. */
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  /* La franja que la barra ocupa sin pintar no puede comerse los clics de la página de atrás. */
  pointer-events: none;
}

.lxc-caja {
  position: relative;
  width: 620px;
  max-width: calc(100vw - 24px);
}

/* EL ARO: un solo elemento para el estado de foco. Va 3px afuera de la píldora y espeja su radio. */
.lxc-caja::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 999px;
  border: 2px solid transparent;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--mov-rapido) var(--e-entra),
              border-color var(--mov-rapido) var(--e-entra);
}
.lxc-caja:focus-within::after { opacity: 1; border-color: rgba(16, 185, 129, 0.32); }

.lxc-sheet {
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  background: var(--lx-surface);
  color: var(--lx-text);
  border: 1px solid var(--lx-border);
  /* La barra ES una píldora y se queda píldora: no crece, no se despliega, no cambia de forma. */
  border-radius: 999px;
  box-shadow: var(--lx-elev-2);
  overflow: hidden;
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* ── LA FILA DE LA BARRA ──────────────────────────────────────────────────────
   Es la barra entera, y su alto es el de la píldora: 48px = 32 de contenido + 7 de aire arriba y
   abajo + el borde. De esos 48 sale el radio de 24.

   **Los TRES contenidos miden lo mismo (32) a propósito.** El alto de una fila lo pone el más alto
   de sus hijos, así que basta con que uno crezca —el campo con su relleno, el botón con su disco—
   para que la barra engorde sin que nadie lo haya pedido. Cuando eran 34, 40 y 42 la píldora medía
   63px: el número que se veía no estaba escrito en ninguna parte. */
.chat-form {
  display: flex;
  /* Una sola fila: los ítems ENCOGEN para caber en vez de envolver a otra. */
  flex-wrap: nowrap;
  /* Al pie y no al centro: el campo crece hacia arriba con el texto, y con `center` la cara y el
     botón se irían flotando al medio de un campo de tres renglones. */
  align-items: flex-end;
  gap: 8px;
  padding: 7px 7px 7px 9px;
}

/* LA IDENTIDAD, a la izquierda del campo. Acá hay un solo asistente, así que no ofrece cambiarlo:
   sin cursor y sin hover, porque lo que no hace nada no puede parecer que hace algo. Sin nombre al
   lado tampoco: costaría el ancho del campo de escritura, que es lo único que hay que proteger. */
.lxc-lead { flex: none; display: flex; align-items: center; min-width: 0; }
.lxc-id {
  flex: none;
  display: flex;
  align-items: center;
  height: 32px;
  padding: 0 2px;
  border-radius: 999px;
}
.lxc-id.is-static { cursor: default; }
.lxc-cara-wrap {
  position: relative;
  display: inline-flex;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 12px rgba(16, 185, 129, 0.28);
}
.lxc-cara { --cara: 28px; }

/* ── EL PUNTO DE ESTADO, montado sobre la cara ────────────────────────────────
   El anillo del color de la superficie es lo que lo despega del dibujo: sin él, un punto verde
   apoyado sobre el pelo negro se lee como parte del pelo. Va sobre el borde del disco y no adentro,
   que es donde el ojo lo busca por costumbre.

   El tamaño es el mínimo que sigue leyéndose como un punto y no como suciedad de la pantalla: 9px
   de color más 2 de anillo. Y NO parpadea: un indicador que se mueve dice "algo está pasando", y lo
   que este dice es lo contrario — que no hay nada que esperar. El movimiento de esta barra tiene un
   solo dueño, y es el aro de la espera. Por eso el punto se APAGA mientras el turno corre: los dos
   viven sobre el mismo disco de 28px, y dos indicadores encimados se leen como uno roto. */
.lxc-pulso {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--lx-accent-1);
  box-shadow: 0 0 0 2px var(--lx-surface);
  transition: background var(--mov-normal) var(--e-entra),
              opacity var(--mov-rapido) var(--e-entra);
}
/* Sin servicio: gris y sin brillo. NO rojo — el rojo de esta hoja es el de un error que alguien
   tiene que atender, y esto es un estado que se arregla solo en cuanto el próximo pedido conecte. */
.lxc-pulso[data-estado="sin-servicio"] { background: var(--lx-muted); }

/* ── LA ESPERA: un aro que gira alrededor de la cara ──────────────────────────
   Es el ÚNICO lugar donde se dibuja que el turno está corriendo, porque es la única superficie que
   la barra tiene. No son tres puntos rebotando, y no es cuestión de gusto: la FRECUENCIA de un
   indicador es una señal de esfuerzo. Uno rápido y nervioso se lee como "el sistema está forzando" y
   ALARGA el tiempo percibido; el mismo indicador lento y continuo se lee como "esto está bajo
   control".

   ── Por qué un pseudo ABSOLUTO y no una caja que crezca ──
   El envoltorio mide 28px y está en una fila de flex con el campo y el botón: si creciera para
   contener el aro, la píldora entera engordaría al empezar cada turno y volvería a adelgazar al
   terminar. Absoluto en `inset: -4px` el aro se dibuja 4px afuera del disco sin ocupar una sola
   columna de layout — el espacio de sobra ya está ahí, en los 7px de aire de la fila.

   Los 400ms de retardo son la regla de siempre: un turno que se resuelve antes no llega a encender
   nada, y lo que se evita es el parpadeo que hace ver lento a lo que fue rápido. */
.lxc-cara-wrap.cargando::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg 190deg,
    var(--lx-accent-1) 255deg,
    var(--lx-accent-2) 310deg,
    var(--lx-accent-3) 360deg
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0);
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0);
  animation: lxc-aparecer var(--mov-normal) var(--e-entra) 400ms both,
             girar 2.4s linear infinite;
}
/* El punto de estado se retira mientras gira el aro: ver el comentario de `.lxc-pulso`. */
.lxc-cara-wrap.cargando .lxc-pulso { opacity: 0; }

@keyframes lxc-aparecer { from { opacity: 0; } to { opacity: 1; } }

/* El aviso de validación, flotando ARRIBA de la barra. Absoluto para no deformar la píldora ni
   estirar el aro de foco de la caja. */
.chat-aviso {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 8px 14px;
  border-radius: 12px;
  background: var(--lx-danger-soft);
  color: var(--lx-danger);
  border: 1px solid var(--lx-danger-border);
  box-shadow: var(--lx-elev-2);
  font-size: 13px;
  line-height: 1.45;
}
.chat-aviso[hidden] { display: none; }

/* El campo NO tiene caja propia: la caja es la barra. Un input con borde y fondo adentro de una
   píldora que ya tiene borde y fondo son dos marcos anidados, y es lo que hacía que esto se leyera
   como un formulario de nuestra consola en vez de como un chat. */
.chat-form textarea {
  flex: 1 1 96px;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--lx-text);
  font: inherit;
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: -0.01em;
  /* 24 de renglón + 8 de relleno = los mismos 32 que la cara y el botón. Subirlo engorda la barra. */
  padding: 4px 2px;
  outline: none;
  /* De una fila, creciendo hasta un techo y scrolleando adentro. `resize:none` porque la manija
     del navegador dentro de una píldora es exactamente el "tell" de formulario que esta barra
     evita. El alto lo pone el JS midiendo el contenido. */
  resize: none;
  overflow-y: auto;
  max-height: 120px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.chat-form textarea::placeholder { color: var(--lx-muted); }

/* Enviar: un disco con el gradiente de la marca del widget. 42px es el tamaño real; el pseudo suma
   el área táctil hasta 48 sin agrandar el dibujo. */
.chat-enviar {
  position: relative;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: linear-gradient(135deg, var(--lx-accent-1), var(--lx-accent-2) 60%, var(--lx-accent-3));
  color: #fff;
  box-shadow: 0 4px 14px rgba(14, 165, 233, 0.4);
  transition: transform var(--mov-rapido) var(--e-entra), box-shadow var(--mov-rapido) var(--e-entra), opacity var(--mov-rapido) var(--e-entra);
}
/* El disco mide 32 y el área que se puede tocar, 44: el pseudo la agranda sin agrandar el dibujo. */
.chat-enviar::before { content: ""; position: absolute; inset: -6px; }
.chat-enviar svg { width: 17px; height: 17px; fill: none; stroke: currentColor; }
/* El :hover vive en un @media (hover: hover) al final del bloque: en táctil se queda pegado. */
.chat-enviar:active:not(:disabled) { transform: scale(0.96); }
.chat-enviar:focus-visible {
  outline: none;
  box-shadow: 0 4px 14px rgba(14, 165, 233, 0.4), var(--lx-focus);
}
.chat-enviar:disabled { opacity: 0.45; cursor: default; box-shadow: none; }

@media (max-width: 560px) {
  /* En pantalla chica la barra ocupa el ancho: 620px sobre 360 de ventana no entra. */
  .lxc { bottom: calc(12px + var(--lxc-teclado, 0px) + env(safe-area-inset-bottom, 0px)); }
  .lxc-caja { width: 100%; }
  /* 16px o iOS AMPLÍA la página entera al tocar el campo — y no lo deshace solo al terminar: queda
     ampliada, con enviar fuera del borde derecho, hasta que la persona pellizque. En escritorio se
     quedan los 15 del widget. */
  .chat-form textarea { font-size: 16px; }
}

/* El hover solo donde HAY hover. En una pantalla táctil el navegador deja el último estado de hover
   pegado después de cada toque: enviar queda levantado y con la sombra fuerte sin que nadie lo
   señale. `:active` y `:focus-visible` quedan AFUERA: esos sí valen en táctil. */
@media (hover: hover) {
  .chat-enviar:hover:not(:disabled) {
    transform: translateY(-1px) scale(1.05);
    box-shadow: 0 6px 18px rgba(14, 165, 233, 0.5);
  }
}

/* Alto contraste de Windows: el sistema reemplaza los colores del autor y NO pinta `box-shadow`.
   Los dos controles apagan el subrayado del navegador y dibujan el foco con un halo de sombra, así
   que ahí quedaba un aro que dice "el foco está en el chat" y que nunca se mueve entre ellos. */
@media (forced-colors: active) {
  .chat-form textarea:focus-visible,
  .chat-enviar:focus-visible {
    outline: 2px solid Highlight;
    outline-offset: 2px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lxc-caja::after { transition: none; }
  .chat-enviar { transition: none; }
  .chat-enviar:hover:not(:disabled) { transform: none; }
  .chat-enviar:active:not(:disabled) { transform: none; }

  /* ── EL CASO QUE NO SE PUEDE PERDER ──
     El indicador de espera no tiene texto y es lo ÚNICO que dice que el chat está trabajando, así
     que apagar las animaciones dejaría a quien pidió menos movimiento sin ninguna señal. El estado
     se imprime entonces por FORMA y COLOR: el aro pasa de arco-cometa a ANILLO COMPLETO de acento —
     un arco congelado se lee como un spinner roto; un anillo entero se lee como un estado.

     La opacidad se repone EXPLÍCITAMENTE y no es redundante: la aparición usa `both` para quedarse
     en opacity 0 durante los 400ms de retardo, así que apagar la animación sin reponerla dejaría el
     indicador invisible PARA SIEMPRE, justo para quien no puede leerlo por movimiento. El canje que
     se acepta a propósito: acá se pierde la supresión de los 400ms y una espera corta parpadea.
     Garantizar que se VEA gana sobre evitar el parpadeo. */
  .lxc-cara-wrap.cargando::after {
    animation: none;
    opacity: 1;
    background: var(--lx-accent-1);
  }
}
