/* ═══════════════════════════════════════════════════════════════════════════
   LA PRUEBA DE AUTOMATIZACIONES · los tres miniprogramas
   ═══════════════════════════════════════════════════════════════════════════

   QUÉ ES ESTO: el vestido de tres instancias de un mismo componente. No hay
   reglas por caso (no existe «lo del restaurante» y «lo de la clínica»): los
   tres comparten TODO el estilo y solo cambian los datos que les inyecta
   `js/automatizaciones-demos.js`.

   POR QUÉ UN ARCHIVO PROPIO Y NO DENTRO DE 07-servicios.css: 07 es el vestido
   de las SIETE secciones de servicio y roza las 2.000 líneas. Los demos son un
   componente cerrado que solo vive aquí; mezclarlo haría más difícil
   encontrar cualquier cosa. La regla del contrato —nada de duplicar CSS por
   sección— se cumple igual: esto NO se repite seis veces, se escribe una vez y
   sirve para todos los casos que haya.

   TOKENS: solo del sistema (--acento, --borde, --superficie, --e-N, --radio,
   --fuente-texto). Cero colores literales, cero gamas paralelas. Los cuatro
   colores de estado (verde de paso cumplido, rojo de fallo) SÍ son literales
   a propósito: son semánticos, no de marca, y no deben cambiar con el tema.
   Están declarados abajo como tokens locales del componente para que no se
   repitan sueltos por las reglas.

   LOS TOKENS LOCALES VAN EN `.mp-demos`, NO EN `:root`: así no contaminan el
   inventario del contrato ni se pueden usar por error fuera de aquí.
   ------------------------------------------------------------------------- */

.mp-demos {
  /* Semánticos del componente: significan «paso cumplido» y «paso fallido»,
     no «color de marca». Por eso no permutan con el tema. */
  --demo-ok: #4ade80;
  --demo-ok-tinta: #062015;
  --demo-fallo: #f87171;

  /* Un pelín más altas que las piezas de vídeo de Diseño web (16/11). Un
     formulario no es un vídeo: necesita el alto de su contenido. */
  --demo-alto-min: 26rem;
}

/* ═══ LA TARJETA ════════════════════════════════════════════════════════════
   Reutiliza `.dn-pieza` (borde, radio, sombra, superficie) y solo anula lo que
   no tiene sentido aquí: el `aspect-ratio: 16/11` y el `overflow: hidden`, que
   recortarían el formulario. */
.mp-demo {
  aspect-ratio: auto;
  overflow: visible;
  min-height: var(--demo-alto-min);
  display: flex;

  /* ── TRAMPA CERRADA (2): hereda el tope de los VIDEOS ─────────────────
     Faltaba esto y por eso la tarjeta seguía cortando 100 px aunque ya fuera
     `align-self: start`.

     En `07-servicios.css` (bloque `@media (max-width: 719px)`) hay
     `.dn-pieza { width: min(100%, alto*1.4545); max-height: var(--dn-video-alto-max); }`.
     Esa regla existe para los VIDEOS de «La prueba» de Diseño web: deducen el
     ancho del alto disponible (ratio 16/11) y se limitan a una pantalla. Mis
     tarjetas usan la misma clase `.dn-pieza` (para heredar borde, radio y
     sombra), así que también quedaban con `max-height: 718px` — medido: la
     tarjeta 718 px con 816 px de contenido.

     Un miniprograma NO es un vídeo: su alto lo dicta el contenido, no una
     proporción. Se anula el tope y el ancho vuelve a ser el de la columna. */
  max-block-size: none;
  block-size: auto;
  inline-size: 100%;

  /* ── TRAMPA CERRADA: la tarjeta NO crecía con su contenido ────────────
     Medido en teléfono (390px) con el ejemplo del restaurante ya procesado:
     `.mp-demo__cuerpo` tenía 818 px de contenido y la tarjeta 716. Se
     perdían 102 px: la comparativa y el registro se salían por abajo y
     quedaban ocultos porque el `<article>` recorta lo que sobresale de su
     caja de flex.

     La causa: en un contenedor flex la altura la fija el PADRE (aquí la
     pista del grid), y `align-items: start` en el grid deja la pista con el
     alto del contenido — pero `.mp-demo` es flex y su `.mp-demo__cuerpo`
     también, así que el cuerpo no empujaba el alto.

     `align-self: start` + `block-size: auto` hacen que la tarjeta se mida
     por su contenido y no por la fila. */
  align-self: start;
  block-size: auto;
}

.mp-demo__cuerpo {
  display: flex;
  flex-direction: column;
  padding: var(--e-4);
  gap: var(--e-3);
  /* `min-inline-size: 0` es el blindaje del flex: sin él, un hijo ancho (el
     textarea) empuja al padre y la columna del grid crece con él. Es el mismo
     motivo por el que la rejilla lleva `minmax(0, …)`: los dos mínimos hay que
     anularlos, no solo uno. */
  min-inline-size: 0;
  inline-size: 100%;
  /* El cuerpo es quien dicta el alto de la tarjeta: si se le deja
     `min-block-size: auto` en un flex, su contenido puede sobresalir en vez
     de estirarlo. */
  block-size: auto;
  min-block-size: 0;
  overflow: visible;
}

/* Todos los hijos directos pueden encogerse. Un <textarea> dentro de un flex
   conserva su ancho intrínseco (20 caracteres) salvo que se le diga lo
   contrario, y ese ancho es justo lo que hacía desbordar la tarjeta. */
.mp-demo__cuerpo > * {
  min-inline-size: 0;
  max-inline-size: 100%;
}

/* Los controles de formulario no heredan el ancho del contenedor: cada
   navegador les da un tamaño por defecto. Se les dice explícitamente. */
.mp-demo__campo,
.mp-demo__campo textarea,
.mp-demo__acciones,
.mp-demo__pasos,
.mp-demo__salida,
.mp-demo__registro {
  inline-size: 100%;
  max-inline-size: 100%;
  box-sizing: border-box;
}

/* ═══ CABECERA ══════════════════════════════════════════════════════════════ */
.mp-demo__etq {
  display: block;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--acento);
}

/* La cabecera de la tarjeta solo lleva la etiqueta del caso. `margin-block-end`
   la separa del campo sin depender del `gap` del cuerpo: si mañana se añade un
   elemento entre medias, la distancia se mantiene. */
.mp-demo__cab {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin-block-end: var(--e-1);
}

/* ═══ ENTRADA ═══════════════════════════════════════════════════════════════ */
.mp-demo__campo {
  display: block;
}

.mp-demo__campo span {
  display: block;
  font-size: 0.72rem;
  color: var(--mut);
  margin-block-end: var(--e-2);
}

.mp-demo__campo textarea {
  inline-size: 100%;
  /* ALTO POR CONTENIDO, NO FIJO (y sin barra de scroll interna).

     Antes: `min-block-size: 5.5rem` + `resize: vertical`. Con un ejemplo
     largo —los de la rotación lo son— el texto se cortaba dentro de una caja
     de alto fijo y había que arrastrar la esquina para leerlo. En un teléfono
     eso es inaceptable: el textarea es el campo principal.

     `field-sizing: content` deja que el navegador mida el texto (Safari 18+ y
     Chrome 123+). Donde no existe (Firefox) se cae al JS `autoAjusta()`, y de
     último recurso al `min-block-size`, así que nunca queda peor que antes. */
  field-sizing: content;
  min-block-size: 4.25rem;   /* ~3 líneas vacías: mantiene el ritmo visual */
  max-block-size: 16rem;     /* techo: un texto enorme no come la tarjeta */
  padding: var(--e-3);
  border: 1px solid var(--borde);
  border-radius: var(--radio-2);
  background: var(--fondo);
  color: var(--fg);
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.5;
  resize: none;              /* no tiene sentido si crece solo */
  overflow-y: auto;          /* solo si topa con el techo */
}

.mp-demo__campo textarea:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 1px;
  border-color: var(--acento);
}

/* ═══ ACCIONES ══════════════════════════════════════════════════════════════ */
.mp-demo__acciones {
  display: flex;
  gap: var(--e-2);
  flex-wrap: wrap;
}

.mp-demo__btn {
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--borde);
  border-radius: var(--radio-2);
  background: transparent;
  color: var(--fg);
  cursor: pointer;
  transition: border-color 0.18s, color 0.18s;
}

.mp-demo__btn:hover:not(:disabled) {
  border-color: var(--acento);
  color: var(--acento);
}

.mp-demo__btn--pri {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--fondo);
}

.mp-demo__btn--pri:hover:not(:disabled) {
  color: var(--fondo);
  filter: brightness(1.1);
}

.mp-demo__btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ═══ PASOS ═════════════════════════════════════════════════════════════════
   La lista la genera el motor. `--paso` controla el estado de cada uno:
   pendiente (por defecto) → corriendo → hecho | fallo. */
.mp-demo__pasos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
}

.mp-demo__paso {
  display: flex;
  gap: var(--e-2);
  align-items: flex-start;
  font-size: 0.74rem;
  line-height: 1.45;
  color: var(--mut);
  transition: color 0.25s;
}

.mp-demo__paso-marca {
  inline-size: 1.1rem;
  block-size: 1.1rem;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border: 1px solid var(--borde);
  border-radius: 50%;
  font-size: 0.62rem;
  font-weight: 700;
  transition: background-color 0.25s, border-color 0.25s, color 0.25s;
}

.mp-demo__paso[data-estado="corriendo"] { color: var(--fg); }
.mp-demo__paso[data-estado="corriendo"] .mp-demo__paso-marca {
  border-color: var(--acento);
  color: var(--acento);
}

.mp-demo__paso[data-estado="hecho"] { color: var(--fg); }
.mp-demo__paso[data-estado="hecho"] .mp-demo__paso-marca {
  background: var(--demo-ok);
  border-color: var(--demo-ok);
  color: var(--demo-ok-tinta);
}

.mp-demo__paso[data-estado="fallo"] { color: var(--demo-fallo); }
.mp-demo__paso[data-estado="fallo"] .mp-demo__paso-marca {
  border-color: var(--demo-fallo);
  color: var(--demo-fallo);
}

.mp-demo__paso-det {
  display: block;
  color: var(--mut);
  font-size: 0.68rem;
}

/* ═══ SALIDA ════════════════════════════════════════════════════════════════
   La respuesta que recibiría el cliente. Aparece cuando el motor termina. */
.mp-demo__salida {
  padding: var(--e-3);
  border: 1px solid var(--acento-borde);
  border-inline-start-width: 2px;
  border-radius: var(--radio-2);
  background: var(--superficie-2);
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--fg);
  animation: mp-demo-entra 0.35s ease both;
}

.mp-demo__salida b {
  display: block;
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--acento);
  margin-block-end: var(--e-1);
}

/* La salida de FALLO no se viste como la de éxito. Si el automatismo no puede
   actuar, no hay «respuesta automática»: hay un motivo y qué falta. El color
   de acento pasaría por buenas noticias, así que usa el rojo semántico. */
.mp-demo__salida--fallo {
  border-color: var(--demo-fallo);
  border-inline-start-color: var(--demo-fallo);
}

.mp-demo__salida--fallo b {
  color: var(--demo-fallo);
}

/* ═══ COMPARATIVA humano vs automatización ═════════════════════════════════
   Tres zonas en una fila: el humano a la izquierda, la diferencia en medio y
   la automatización a la derecha. La forma EN SÍ comunica: dos extremos con un
   salto en el medio es como se lee una comparación.

   En una tarjeta de ~330 px (teléfono ancho) tres columnas dejarían el número
   en 60 px y el texto en cuatro líneas. Por eso se apilan: humano arriba,
   porcentaje en medio, automatización abajo, y la «X» del medio pasa a ser una
   barra horizontal fina. */
.mp-cmp {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-3);
  border: 1px solid var(--borde);
  border-radius: var(--radio-2);
  background: var(--superficie-2);
}

.mp-cmp__lado {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}

.mp-cmp__lado--auto {
  text-align: right;
}

.mp-cmp__rot {
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mut);
}

.mp-cmp__tiempo {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}

/* LOS DOS TIEMPOS, EN EL MISMO COLOR.

   Antes el humano iba en `--mut` (gris apagado) y la automatización en
   `--acento`. Se leía mal por dos motivos:
     · el gris apagado hacía que la cifra del humano pareciera deshabilitada o
       menos importante, cuando el número es la referencia de la comparación;
     · si los dos tiempos se comparan entre sí, tienen que verse igual: el
       color no debe insinuar quien gana, porque quien gana ya lo dice el ×
       del medio.

   Se unifican en `--fg` (el color de texto normal). El acento queda solo para
   el número del medio, que es la conclusión. */
.mp-cmp__lado--humano .mp-cmp__tiempo,
.mp-cmp__lado--auto .mp-cmp__tiempo {
  color: var(--fg);
}

/* El detalle («leer, consultar, responder») explica de dónde sale el número.
   Sin él, «6 min» es una cifra que el visitante no puede discutir. */
.mp-cmp__det {
  font-size: 0.62rem;
  line-height: 1.35;
  color: var(--mut);
}

/* Cerrado: el tiempo del humano es «esperar a que abran». Se marca en el
   lateral para que no se lea como «tarda 9 horas en leer un mensaje». */
.mp-cmp__lado--humano[data-abierto="no"] .mp-cmp__det {
  color: var(--demo-fallo);
}

.mp-cmp__medio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding-inline: var(--e-2);
  border-inline: 1px solid var(--borde);
}

/* Sin comparación (el negocio estaba cerrado): el «0 esperas» no es un logro,
   es una constancia. Va en gris para que no se lea como un multiplicador. */
.mp-cmp[data-compara="no"] .mp-cmp__pct {
  color: var(--mut);
  font-size: 0.95rem;
}

/* El «VS» del centro: pequeño y en gris, no compite con el × — el × es la
   conclusión, el VS es solo el marco de la comparación. */
.mp-cmp__vs {
  font-size: 0.5rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--mut);
  opacity: 0.75;
  margin-block-end: 2px;
}

.mp-cmp__pct {
  font-size: 1.15rem;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--acento);
  white-space: nowrap;
}

.mp-cmp__pct-rot {
  font-size: 0.56rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mut);
  white-space: nowrap;
}

.mp-cmp--entra {
  animation: mp-cmp-entra 0.4s ease both;
}

@keyframes mp-cmp-entra {
  from { opacity: 0; translate: 0 8px; }
  to   { opacity: 1; translate: 0 0; }
}

/* ── CONTAINER QUERY: DÓNDE VA EL CONTENEDOR ──────────────────────────────
   TRAMPA CERRADA: primero lo puse en `.mp-demo__cuerpo`, que es el PADRE de
   `.mp-cmp`. Una container query se resuelve contra el contenedor ANCESTRO,
   y ese elemento también lo es de sí mismo en el árbol de consulta… pero al
   declarar `container-type` en el padre y consultar dentro, el navegador mide
   el padre — no la tarjeta. Resultado medido: en 1440 la tarjeta era 417 px y
   se apilaba (debería caber en 3 columnas), y en 834 era 751 px y se quedaba
   en 3 columnas (debería apilar). Al revés en los dos casos.

   El contenedor va en la TARJETA (`.mp-demo`), que es el elemento cuyo ancho
   nos importa, y la consulta se hace desde dentro. Así el corte sigue al ancho
   real de la tarjeta en cualquier rejilla. */
.mp-demo {
  container-type: inline-size;
}

/* 420px de tarjeta: por debajo, tres columnas dejarían el «443x» en 60px y el
   texto en cuatro líneas. Por encima (tarjeta de 417px en 1440) caben. */
@container (max-width: 400px) {
  .mp-cmp {
    grid-template-columns: 1fr;
    gap: var(--e-2);
  }

  .mp-cmp__lado--auto {
    text-align: left;
  }

  .mp-cmp__medio {
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--e-2);
    padding-inline: 0;
    padding-block: var(--e-2);
    border-inline: 0;
    border-block: 1px solid var(--borde);
  }
}

@keyframes mp-demo-entra {
  from { opacity: 0; translate: 0 6px; }
  to   { opacity: 1; translate: 0 0; }
}

/* ═══ REGISTRO ══════════════════════════════════════════════════════════════
   La traza tipo terminal: cada línea con su hora. Es lo que hace que el
   visitante vea que «está pasando algo», no una caja que cambia de golpe. */
.mp-demo__registro {
  margin-block-start: auto;
  padding-block-start: var(--e-2);
  border-block-start: 1px solid var(--borde);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.66rem;
  line-height: 1.6;
  color: var(--mut);
  /* Sin tope ni scroll interno en el registro.

     Antes: `max-block-size: 5.5rem` + `overflow-y: auto`. La traza cortaba la
     última línea a media altura y el visitante tenía que hacer scroll dentro
     de una caja de 66 px — en un teléfono, con el dedo, eso no se lee.

     `margin-block-start: auto` ya lo empuja al fondo de la tarjeta, y la
     tarjeta crece con el contenido, así que no hay nada que recortar. */
  overflow: visible;
}

.mp-demo__registro-linea {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mp-demo__registro-linea time {
  color: var(--acento);
  margin-inline-end: var(--e-1);
  font-variant-numeric: tabular-nums;
}

/* ═══ REJILLA ═══════════════════════════════════════════════════════════════
   `.dn-riel` base es `repeat(3, 1fr)`, y eso NO basta cuando las piezas llevan
   formularios dentro:

     Con `1fr` la pista mide `minmax(auto, 1fr)`, y `auto` como mínimo significa
     «el min-content del contenido». El min-content de un <textarea> con
     `rows="3"` es su ancho por defecto de 20 caracteres, y el de un botón es
     el ancho de su texto. La suma de esos mínimos supera el ancho de la escena
     y las tarjetas se salen por la derecha.

   COMO SE VE EN LOS DATOS: en 1920 el riel medía 1750 px dentro de un
   contenedor de 1910 — ya al límite — y con textos más largos desbordaba.
   Es la MISMA trampa que el contrato documenta para el riel en tablet
   (§21.8): «con 1fr la pista se encoge al min-content».

   LA REGLA: `minmax(0, 1fr)`. El mínimo 0 es explícito, así que la pista NO
   puede pasar de su fracción por mucho que el contenido pida. El textarea y
   los botones reciben `inline-size: 100%` y se adaptan.

   `align-items: start`: cada tarjeta mide lo suyo y no se estiran a la más
   alta, que dejaría dos con un hueco muerto abajo. */
.mp-demos {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
}

/* Tablet y teléfono: una columna, como el resto de la web. El corte es el
   mismo (1099 px) para que toda la página cambie a la vez y no a destiempo. */
@media (max-width: 1099px) {
  .mp-demos {
    grid-template-columns: minmax(0, 1fr);
  }

  .mp-demo {
    min-height: 0;
  }
}
