/* ============================================================
   ATAZEL · índice de funcionalidades y fichas de cada módulo
   ============================================================ */
* { box-sizing: border-box; }
/* background-color, NO el atajo `background`: el atajo reiniciaría a none la
   textura de papel que pone colors_and_type.css, que se carga antes. */
html, body { margin: 0; padding: 0; background-color: var(--bg-page); width: 100%; max-width: 100%; overflow-x: hidden; }
body { color: var(--fg-default); font-family: var(--font-sans); font-size: var(--text-md); line-height: var(--leading-relaxed); -webkit-font-smoothing: antialiased; }
img, svg { display: block; max-width: 100%; }
/* Mismo ancho y mismos márgenes laterales que la página de precios, para que
   barra, contenido y pie queden alineados en todo el sitio. */
.wrap, .wrap-lee { max-width: 1360px; margin: 0 auto; padding: 0 clamp(24px, 3vw, 48px); }
section { padding: 84px 0; position: relative; }
section + section { border-top: 1px solid var(--border-subtle); }
section.muted { background: var(--bg-muted); }

.eyebrow { font-family: var(--font-sans); font-size: 12px; font-weight: 600; letter-spacing: 0.20em; text-transform: uppercase; color: var(--iris-500); display: inline-flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.eyebrow::before { content: ""; width: 28px; height: 1px; background: var(--iris-500); }
.h-display { font-family: var(--font-serif); font-weight: 600; font-size: clamp(38px, 5vw, 66px); line-height: 1.05; letter-spacing: -0.025em; color: var(--fg-strong); margin: 0; text-wrap: balance; }
.h-section { font-family: var(--font-serif); font-weight: 600; font-size: clamp(28px, 3vw, 40px); line-height: 1.08; letter-spacing: -0.02em; color: var(--fg-strong); margin: 0; text-wrap: balance; }
.h-display em, .h-section em { font-style: italic; font-weight: 500; color: var(--iris-500); }
.lede { font-family: var(--font-serif); font-weight: 400; font-size: clamp(18px, 1.4vw, 22px); line-height: 1.5; color: var(--fg-muted); margin: 26px 0 0; max-width: 68ch; text-wrap: pretty; }

/* Barra superior */
.nav { position: sticky; top: 0; z-index: 50; background: color-mix(in oklch, var(--bg-page) 92%, transparent); backdrop-filter: blur(8px); border-bottom: 1px solid transparent; transition: border-color 200ms var(--ease-out); }
.nav.scrolled { border-bottom-color: var(--border-subtle); }
.nav-inner { max-width: 1360px; margin: 0 auto; padding: 18px clamp(24px, 3vw, 48px); display: flex; align-items: center; gap: 32px; }
.nav-brand { display: flex; align-items: center; gap: 12px; color: var(--fg-strong); text-decoration: none; }
.nav-brand .wm { font-family: var(--font-serif); font-weight: 600; font-size: 18px; letter-spacing: 0.18em; white-space: nowrap; }
.nav-links { display: flex; align-items: center; gap: 20px; margin-left: auto; }
.nav-link { font-size: 13px; color: var(--fg-muted); text-decoration: none; white-space: nowrap; transition: color 120ms var(--ease-out); position: relative; }
.nav-link:hover { color: var(--fg-default); }
.nav-link.active { color: var(--fg-strong); }
.nav-cta { background: var(--iris-500); color: var(--fg-on-iris); padding: 8px 16px; border-radius: var(--radius-md); font-size: 13px; font-weight: 500; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; transition: background 120ms var(--ease-out); }
.nav-cta:hover { background: var(--iris-600); }
.beta-tag { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--amber-700); background: var(--amber-50); border: 1px solid #F4D79B; padding: 4px 10px; border-radius: var(--radius-pill); white-space: nowrap; }
.lang { position: relative; }
.lang-pill { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; color: var(--fg-muted); padding: 4px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border-subtle); cursor: pointer; background: transparent; transition: border-color 120ms var(--ease-out), color 120ms var(--ease-out); }
.lang-pill:hover { border-color: var(--border-default); color: var(--fg-default); }
.lang-menu { position: absolute; right: 0; top: calc(100% + 6px); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--shadow-2); list-style: none; margin: 0; padding: 4px; min-width: 156px; display: none; z-index: 60; }
.lang.open .lang-menu { display: block; }
.lang-menu li { font-size: 13px; color: var(--fg-default); padding: 8px 12px; border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap; transition: background 120ms var(--ease-out); }
.lang-menu li:hover { background: var(--bg-muted); }
.lang-menu li[aria-selected="true"] { color: var(--iris-700); font-weight: 600; }
.scroll-progress { position: fixed; top: 0; left: 0; height: 2px; width: 0; background: var(--iris-500); z-index: 70; pointer-events: none; transition: width 80ms linear; }

/* Índice: rejilla de módulos */
.hero { padding: 68px 0 56px; }
/* ============================================================
   FIGURAS de ficha. Cada módulo lleva la suya, dibujada a medida, pero todas
   se escriben con esta misma gramática para que no parezcan de sitios
   distintos: superficie blanca sobre la banda, pauta fina, cifras mono
   tabulares y el azul como único acento (ámbar = aviso, verde = sano).
   Sin librerías de gráficos y sin <canvas>: HTML y SVG en línea, como las
   maquetas de la portada. Los números salen del texto de la ficha, que ya
   está contrastado contra el código: son ejemplos, no datos de un cliente.
   ============================================================ */
/* La figura abre la banda: es lo primero que se ve tras el titular, así que
   entra ella primero y luego se dibuja por dentro. */
.fig { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--shadow-1); padding: 20px 22px; margin: 0 0 30px; }
.fig { opacity: 0; transform: translateY(14px) scale(.99); transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out), box-shadow 300ms var(--ease-out); }
.reveal.in .fig { opacity: 1; transform: none; }
/* Al pasar por encima se levanta un punto: invita a mirarla de cerca. */
.fig:hover { box-shadow: var(--shadow-2); }
.fig-cap { font-family: var(--font-sans); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-subtle); margin: 0 0 14px; }
/* Filas de libro: etiqueta a la izquierda, cifra tabular a la derecha. */
.fig-fila { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--border-subtle); font-size: 13.5px; color: var(--fg-default); }
.fig-fila:last-child { border-bottom: 0; }
.fig-fila .k { color: var(--fg-muted); }
.fig-n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum","zero"; color: var(--fg-strong); }
.fig-total { border-top: 2px solid var(--fg-strong); border-bottom: 0; margin-top: 4px; padding-top: 9px; font-weight: 600; }
/* Estados. Llevan SIEMPRE palabra, nunca sólo color. */
.fig-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; letter-spacing: .02em; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.fig-chip.ok { background: var(--success-50); color: var(--success-700); }
.fig-chip.av { background: var(--amber-50); color: var(--amber-700); }
.fig-chip.in { background: var(--iris-50); color: var(--iris-700); }
/* Barras: magnitud. Extremo redondeado de 4px y hueco de 2px entre barras. */
.fig-barras { display: grid; gap: 9px; }
.fig-barra { display: grid; grid-template-columns: 84px 1fr auto; align-items: center; gap: 12px; font-size: 13px; }
.fig-pista { position: relative; height: 12px; background: var(--bg-muted); border-radius: 4px; overflow: hidden; }
.fig-relleno { position: absolute; inset: 0 auto 0 0; border-radius: 4px; background: var(--iris-500); }
.fig-relleno.av { background: var(--amber-500); }
.fig-relleno.ok { background: var(--success-500); }
/* Pasos de un flujo. */
.fig-pasos { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.fig-paso { flex: 1 1 0; min-width: 128px; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: 12px 13px; background: var(--bg-page); }
.fig-paso .p-n { font-family: var(--font-mono); font-size: 11px; color: var(--fg-subtle); }
.fig-paso .p-t { font-weight: 600; font-size: 13px; color: var(--fg-strong); margin-top: 3px; }
.fig-paso .p-d { font-size: 12.5px; color: var(--fg-muted); margin-top: 2px; line-height: 1.4; }
.fig-flecha { align-self: center; color: var(--fg-subtle); flex: none; }
/* Marco de dispositivo (ticket, PDA, móvil). */
.fig-disp { border: 1px solid var(--border-default); border-radius: 10px; padding: 14px 15px; background: var(--bg-page); max-width: 340px; }
/* Un ticket o una PDA son estrechos: sueltos en una figura ancha dejaban un
   socavón de aire a la derecha. Van en columna centrada, con las filas que los
   acompañan a su misma anchura. */
.fig-col { max-width: 420px; margin-inline: auto; }
.fig-col .fig-disp { max-width: none; }
.fig-disp.tk { font-family: var(--font-mono); font-size: 12px; line-height: 1.55; color: var(--fg-default); }
.fig-dos { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

/* --- Piezas que hacen que la figura parezca el producto y no un esquema ---
   Marco de ventana (barra de título + cuerpo) y rejilla de datos con cabecera
   de columnas. Con esto la figura se lee como una pantalla de la app. */
.fig-win { border: 1px solid var(--border-default); border-radius: 8px; overflow: hidden; background: var(--bg-page); }
.fig-win-cab { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--bg-muted); border-bottom: 1px solid var(--border-subtle); }
.fig-win-cab::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--border-strong); opacity: .35; box-shadow: 11px 0 0 var(--border-strong), 22px 0 0 var(--border-strong); margin-right: 22px; }
.fig-win-t { font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--fg-muted); }
.fig-win-cuerpo { padding: 12px 14px; }
/* Rejilla de datos. Las columnas numéricas van a la derecha y en tabular. */
.fig-tab { width: 100%; border-collapse: collapse; font-size: 13px; }
.fig-tab th { text-align: left; font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-subtle); padding: 0 0 7px; border-bottom: 1px solid var(--border-default); white-space: nowrap; }
.fig-tab td { padding: 7px 0; border-bottom: 1px solid var(--border-subtle); color: var(--fg-default); vertical-align: baseline; }
.fig-tab tr:last-child td { border-bottom: 0; }
.fig-tab .n { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum","zero"; color: var(--fg-strong); white-space: nowrap; }
.fig-tab th.n { text-align: right; }
/* La fila del hallazgo: es lo que el módulo quiere que veas. */
.fig-tab tr.mira td, .fig-tab tr.bien td { transition: background-color 500ms var(--ease-out); transition-delay: 980ms; }
.fig-tab tr.mira td { font-weight: 600; }
.reveal.in .fig-tab tr.mira td { background: var(--amber-50); }
.reveal.in .fig-tab tr.bien td { background: var(--success-50); }
/* El filete de tinta de la fila marcada baja como una barra: es lo último que
   ocurre, cuando ya has leído la tabla. */
.fig-tab tr.mira td:first-child, .fig-tab tr.bien td:first-child { position: relative; padding-left: 8px; }
.fig-tab tr.mira td:first-child::before, .fig-tab tr.bien td:first-child::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  transform: scaleY(0); transform-origin: top;
  transition: transform 420ms var(--ease-out); transition-delay: 980ms; }
.fig-tab tr.mira td:first-child::before { background: var(--amber-500); }
.fig-tab tr.bien td:first-child::before { background: var(--success-500); }
.reveal.in .fig-tab tr.mira td:first-child::before,
.reveal.in .fig-tab tr.bien td:first-child::before { transform: scaleY(1); }
/* Las filas caen una a una, como si la tabla se fuera llenando. */
.fig-tab tbody tr { opacity: 0; transform: translateY(6px); transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out); }
.reveal.in .fig-tab tbody tr { opacity: 1; transform: none; }
.reveal.in .fig-tab tbody tr:nth-child(1) { transition-delay: 320ms; }
.reveal.in .fig-tab tbody tr:nth-child(2) { transition-delay: 420ms; }
.reveal.in .fig-tab tbody tr:nth-child(3) { transition-delay: 520ms; }
.reveal.in .fig-tab tbody tr:nth-child(4) { transition-delay: 620ms; }
.reveal.in .fig-tab tbody tr:nth-child(5) { transition-delay: 720ms; }
/* El marco de la ventana entra antes que su contenido. */
.fig-win-cab { opacity: 0; transition: opacity 400ms var(--ease-out); transition-delay: 180ms; }
.reveal.in .fig-win-cab { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .fig-tab tbody tr, .fig-win-cab { opacity: 1 !important; transform: none !important; }
  .fig-tab tr.mira td:first-child::before,
  .fig-tab tr.bien td:first-child::before { transform: scaleY(1) !important; }
}
/* Anotación al pie de la figura: la frase que remata lo que se está viendo. */
/* Bloque, NO flex: lleva <b> dentro y en flex cada trozo se vuelve un ítem,
   con lo que el `gap` metía huecos en mitad de la frase. */
.fig-nota { display: block; margin-top: 12px; font-size: 12.5px; line-height: 1.45; color: var(--fg-muted); }
.fig-nota b { color: var(--fg-strong); font-weight: 600; }

/* --- Cómo se mueven las figuras -------------------------------------------
   Se disparan al revelarse la sección: la figura SE DIBUJA delante de quien la
   mira en vez de aparecer ya hecha. Las barras crecen con scaleX y no con
   width, porque el ancho va en el `style` de cada barra y así no hay que
   duplicarlo aquí. */
.fig-relleno { transform: scaleX(0); transform-origin: left center; transition: transform 900ms var(--ease-out); }
/* El retardo base deja que la figura entre antes de empezar a dibujarse. */
.reveal.in .fig-relleno { transform: scaleX(1); transition-delay: 280ms; }
.reveal.in .fig-barras > .fig-barra:nth-child(2) .fig-relleno { transition-delay: 390ms; }
.reveal.in .fig-barras > .fig-barra:nth-child(3) .fig-relleno { transition-delay: 500ms; }
.reveal.in .fig-barras > .fig-barra:nth-child(4) .fig-relleno { transition-delay: 610ms; }
/* Las filas del libro y los pasos del flujo entran escalonados, como si se
   fueran escribiendo. */
.fig-fila, .fig-paso { opacity: 0; transform: translateY(7px); transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out); }
.reveal.in .fig-fila, .reveal.in .fig-paso { opacity: 1; transform: none; }
.reveal.in .fig .fig-fila:nth-child(1), .reveal.in .fig-pasos > *:nth-child(1) { transition-delay: 280ms; }
.reveal.in .fig .fig-fila:nth-child(2), .reveal.in .fig-pasos > *:nth-child(3) { transition-delay: 370ms; }
.reveal.in .fig .fig-fila:nth-child(3), .reveal.in .fig-pasos > *:nth-child(5) { transition-delay: 460ms; }
.reveal.in .fig .fig-fila:nth-child(4) { transition-delay: 550ms; }
.reveal.in .fig .fig-fila:nth-child(5) { transition-delay: 640ms; }
/* La flecha del flujo avanza sola: el documento va pasando de paso en paso. */
.reveal.in .fig-flecha { animation: fig-avanza 2.6s var(--ease-inout) infinite; }
.fig-pasos > .fig-flecha:nth-child(4) { animation-delay: .5s; }
@keyframes fig-avanza { 0%, 100% { transform: translateX(0); opacity: .55; } 50% { transform: translateX(4px); opacity: 1; } }
/* El aviso llama la atención tres veces y se está quieto: no es una alarma.
   Late con la escala, NO con un halo: un resplandor incumpliría la regla 5. */
.reveal.in .fig-chip.av { animation: fig-late 1.5s var(--ease-out) 3; }
@keyframes fig-late { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.055); } }
@media (prefers-reduced-motion: reduce) {
  .fig-flecha, .fig-chip.av { animation: none !important; }
  .fig-relleno { transform: scaleX(1); }
}
@media (max-width: 720px) { .fig-dos { grid-template-columns: 1fr; } .fig-barra { grid-template-columns: 68px 1fr auto; } }

.fam { max-width: 820px; margin-bottom: 44px; }
.fam .rule-broadsheet { margin-bottom: 22px; }
/* El lema de la familia: la cita en serif que explica por qué van juntos. */
.fam-lema { font-family: var(--font-serif); font-weight: 600; font-size: 27px; line-height: 1.25; letter-spacing: -0.015em; color: var(--fg-strong); margin: 10px 0 0; }
.fam-lema em { font-style: italic; color: var(--iris-500); }
/* Sólo para lectores de pantalla: el texto que ya no se repite en pantalla. */
.vis-oculto { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.mods { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.mod { position: relative; display: flex; flex-direction: column; background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--shadow-1); padding: 24px; text-decoration: none; transition: box-shadow 200ms var(--ease-out), transform 200ms var(--ease-out), border-color 200ms var(--ease-out); }
.mod:hover { box-shadow: var(--shadow-2); transform: translateY(-2px); border-color: var(--iris-300, var(--border-default)); }
.mod-top { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 14px; }
.mod-ic { width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; background: var(--iris-50); color: var(--iris-600); }
/* El folio, en grande y fantasma. Al pasar por encima se enciende. */
.mod-folio { font-size: 34px; opacity: 0.5; transition: color 200ms var(--ease-out), opacity 200ms var(--ease-out); }
.mod:hover .mod-folio { color: var(--iris-500); opacity: 1; }
.mod-t { font-family: var(--font-serif); font-weight: 600; font-size: 20px; line-height: 1.2; letter-spacing: -0.015em; color: var(--fg-strong); margin: 0 0 8px; text-decoration-line: underline; text-decoration-thickness: 1px; text-decoration-color: transparent; text-underline-offset: 3px; transition: text-decoration-color 200ms var(--ease-out); }
.mod:hover .mod-t { text-decoration-color: var(--border-default); }
.mod-c { font-size: 14px; line-height: 1.5; color: var(--fg-muted); margin: 0 0 16px; }
/* La flecha se insinúa siempre (en táctil no hay hover) y avanza al pasar. */
.mod-ir { margin-top: auto; align-self: flex-end; display: inline-flex; color: var(--iris-500); opacity: 0.35; transition: opacity 180ms var(--ease-out), transform 180ms var(--ease-out); }
.mod:hover .mod-ir { opacity: 1; transform: translateX(4px); }

/* Ficha de un módulo */
.miga { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--fg-muted); text-decoration: none; margin-bottom: 26px; }
.miga:hover { color: var(--iris-600); }
.ficha-cab { display: flex; align-items: flex-start; gap: 20px; }
.ficha-ic { width: 56px; height: 56px; border-radius: 15px; display: grid; place-items: center; background: var(--iris-50); color: var(--iris-600); flex: none; }
.ficha-n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; letter-spacing: 0.08em; color: var(--fg-subtle); margin-bottom: 8px; }
.ficha-cuerpo { display: grid; grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: start; }
/* El texto va en parrafos, no en un ladrillo: al lado de las filas de «Qué
   hace», que respiran, un bloque de 300 a 560 caracteres parecía la letra
   pequeña de un contrato. El corte se hace por una frontera de frase que ya
   existía (`tools/aplicar_parrafos.py`), sin reescribir nada. */
.ficha-d { font-size: 16.5px; line-height: 1.7; color: var(--fg-muted); margin: 0; max-width: 68ch; }
.ficha-d p { margin: 0 0 17px; text-wrap: pretty; }
.ficha-d p:last-child { margin-bottom: 0; }
.ficha-q h2 { font-family: var(--font-sans); font-size: 11.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-subtle); margin: 0 0 18px; }
.puntos { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.puntos li { position: relative; padding-left: 26px; font-size: 15.5px; line-height: 1.5; color: var(--fg-default); }
.puntos li::before { content: ""; position: absolute; left: 0; top: 6px; width: 12px; height: 12px; border-radius: 50%; background: var(--iris-50); border: 1.5px solid var(--iris-500); }

/* «Qué hace»: cada punto es una fila con icono, titular y explicación.
   Antes era una lista de frases con una bolita delante: todas pesaban lo
   mismo y había que leerlas enteras para saber cuál te interesaba. Aquí el
   titular dice QUÉ ganas y la frase de debajo dice CÓMO, así que la columna
   se puede recorrer de un vistazo y sólo se lee entero el punto que importa.
   La bolita se queda para /seguridad, que sí es una lista de hechos sueltos.

   El icono va a pelo, sin baldosa: la baldosa es de la navegación de la app
   (regla del sistema) y aquí compite con la cabecera de la ficha, que ya
   lleva la suya. Un separador de pelo entre filas y nada más: la fila no es
   una tarjeta, es un renglón.

   TODO va colgado de `.qs`, nunca suelto. `.q` YA existe en esta hoja: es la
   cantidad de la pantalla de la PDA (`.pda-lin .q`) y la hora del mensaje del
   chat (`.ch-m .q`). Escrito a pelo, `.q { display: grid; border-bottom; }`
   les caía encima y los descuadraba, y como esas dos reglas sólo tocan la
   tipografía no había conflicto que avisara: se veía renderizando y de
   ninguna otra forma. */
   La columna del icono mide lo que mide el icono (18 px), ni un pixel más.
   Con 26 px sobraban 8 que se sumaban al hueco de 12, así que el icono se
   quedaba a 20 px de su propio título: parecía de la fila de al lado. Y el
   hueco entre título y frase sube a 5 px, porque con 3 pesaban lo mismo los
   dos renglones de la fila que la separación entre filas distintas. */
.qs { display: grid; }
.qs .q { display: grid; grid-template-columns: 18px 1fr; gap: 12px; padding: 15px 0; border-bottom: 1px solid var(--border-subtle); }
.qs .q:first-child { padding-top: 0; }
.qs .q:last-child { padding-bottom: 0; border-bottom: 0; }
/* El icono se alinea con la MAYÚSCULA del título, no con su caja: la caja de
   línea es 18,9 px para una mayúscula de unos 10, así que sin este empujón
   el dibujo flota por encima del texto al que acompaña. */
.qs .q-ic { color: var(--iris-600); padding-top: 1px; }
.qs .q-ic svg { width: 18px; height: 18px; display: block; }
.qs .q .t { font-size: 14px; font-weight: 600; line-height: 1.35; color: var(--fg-strong); text-wrap: pretty; }
.qs .q .d { font-size: 13.5px; line-height: 1.55; color: var(--fg-muted); margin-top: 5px; text-wrap: pretty; }

/* Entran escalonadas con el resto de la banda. Aquí `:nth-child` SÍ vale:
   dentro de `.qs` no hay separadores ni nada intercalado, sólo `.q`, que es
   justo lo que hacía fallar el escalonado del carril de etapas. */
.qs .q { opacity: 0; transform: translateY(6px); transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out); }
.reveal.in .qs .q { opacity: 1; transform: none; }
.reveal.in .qs .q:nth-child(1) { transition-delay: 120ms; }
.reveal.in .qs .q:nth-child(2) { transition-delay: 190ms; }
.reveal.in .qs .q:nth-child(3) { transition-delay: 260ms; }
.reveal.in .qs .q:nth-child(4) { transition-delay: 330ms; }
.reveal.in .qs .q:nth-child(5) { transition-delay: 400ms; }
.reveal.in .qs .q:nth-child(6) { transition-delay: 470ms; }
@media (prefers-reduced-motion: reduce) { .qs .q { opacity: 1 !important; transform: none !important; transition: none !important; } }

/* Relacionados y paso al siguiente */
.rel { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 32px; }
.pasos { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.paso { display: inline-flex; flex-direction: column; gap: 3px; text-decoration: none; max-width: 46%; }
.paso .lab { font-size: 11.5px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-subtle); }
.paso .tit { font-family: var(--font-serif); font-size: 20px; font-weight: 600; color: var(--fg-strong); }
.paso:hover .tit { color: var(--iris-600); }
.paso.izq { text-align: left; margin-right: auto; }
.paso.der { text-align: right; margin-left: auto; }

/* Cierre y pie */
.cta-final { text-align: center; padding: 104px 0; }
.cta-final .lede { margin: 22px auto 0; }
.cta-final .botones { display: flex; gap: 12px; justify-content: center; margin-top: 34px; flex-wrap: wrap; }
.btn-primary, .btn-secondary { font-size: 15px; font-weight: 500; border-radius: var(--radius-md); padding: 13px 22px; border: 1px solid transparent; display: inline-flex; align-items: center; gap: 8px; line-height: 1.2; text-decoration: none; white-space: nowrap; transition: background 120ms var(--ease-out), border-color 120ms var(--ease-out); }
.btn-primary { background: var(--iris-500); color: var(--fg-on-iris); }
.btn-primary:hover { background: var(--iris-600); }
.btn-secondary { background: transparent; border-color: var(--border-default); color: var(--fg-default); }
.btn-secondary:hover { background: var(--bg-muted); }
footer { background: var(--bg-inverse); color: var(--fg-on-inverse); padding: 60px 0 36px; }
.footer-inner { max-width: 1360px; margin: 0 auto; padding: 0 clamp(24px, 3vw, 48px); display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px; }
.footer-col h6 { font-size: 11px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: color-mix(in oklch, var(--fg-on-inverse) 60%, transparent); margin: 0 0 16px; }
.footer-col a, .footer-col p { display: block; font-size: 13px; text-decoration: none; margin-bottom: 8px; line-height: 1.5; color: color-mix(in oklch, var(--fg-on-inverse) 80%, transparent); }
.footer-col a:hover { color: var(--fg-on-inverse); }
.footer-col .lockup { display: flex; align-items: center; gap: 12px; color: var(--fg-on-inverse); margin-bottom: 16px; }
.footer-col .lockup .wm { font-family: var(--font-serif); font-weight: 600; font-size: 20px; letter-spacing: 0.18em; }
.footer-col .lema-pie { font-family: var(--font-serif); font-style: italic; font-size: 15px; line-height: 1.5; color: color-mix(in oklch, var(--fg-on-inverse) 88%, transparent); max-width: 340px; margin: 0 0 12px; }
.footer-bottom { max-width: 1360px; margin: 56px auto 0; padding: 30px clamp(24px, 3vw, 48px) 0; border-top: 1px solid color-mix(in oklch, var(--fg-on-inverse) 10%, transparent); display: flex; align-items: center; justify-content: space-between; color: color-mix(in oklch, var(--fg-on-inverse) 55%, transparent); font-size: 12px; }
.footer-bottom .by { display: flex; align-items: center; gap: 14px; }
.footer-bottom .by-label { font-size: 10px; letter-spacing: 0.20em; text-transform: uppercase; }
.footer-bottom .by-sig { height: 32px; width: auto; opacity: 0.85; }
.footer-bottom .legal { font-family: var(--font-mono); }

/* Aparición */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out); }
.reveal.in { opacity: 1; transform: none; }
.reveal .mod { opacity: 0; transform: translateY(12px); transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out); }
.reveal.in .mod { opacity: 1; transform: none; }
.reveal.in .mod:nth-child(2) { transition-delay: 70ms; }
.reveal.in .mod:nth-child(3) { transition-delay: 140ms; }
.reveal.in .mod:nth-child(4) { transition-delay: 210ms; }
@media (prefers-reduced-motion: reduce) { .reveal, .reveal .mod { opacity: 1 !important; transform: none !important; transition: none !important; } .scroll-progress { transition: none; } }

@media (max-width: 1100px) { .mods { grid-template-columns: repeat(2, 1fr); } .rel { grid-template-columns: 1fr; } .ficha-cuerpo { grid-template-columns: 1fr; gap: 34px; } }
@media (max-width: 880px) {
  section { padding: 60px 0; }
  .hero { padding: 44px 0; }
  .mods { grid-template-columns: 1fr; }
  .footer-inner { grid-template-columns: 1fr; gap: 32px; }
  .nav-links .nav-link, .nav-links .beta-tag { display: none; }
  .nav-cta { padding: 7px 14px; font-size: 12px; }
  .ficha-cab { gap: 16px; }
  .ficha-ic { width: 46px; height: 46px; border-radius: 13px; }
}
@media (max-width: 560px) {
  section { padding: 44px 0; }
  .mod { padding: 20px; }
  .cta-final { padding: 68px 0; }
  .cta-final .botones .btn-primary, .cta-final .botones .btn-secondary { flex: 1 1 100%; justify-content: center; }
  .paso { max-width: 100%; }
  .paso.der { text-align: left; margin-left: 0; }
  .pasos { flex-direction: column; }
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 14px; }
}

/* ---------- Página «Seguridad» ----------
   Siete bloques a dos columnas. Cada uno: icono, titular, párrafo y la lista
   de hechos, que reutiliza .puntos para no inventar una lista nueva. */
.seg-bloques {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--border-subtle);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.seg-b { background: var(--bg-surface); padding: 34px 32px; }
/* Mismo lenguaje que Funcionalidades: filete que abre, folio al margen y
   entrada escalonada, para que las siete se lean como un recorrido. */
.seg-b .rule-broadsheet { margin-bottom: 18px; }
.seg-folio { margin-left: auto; font-size: 22px; opacity: .45; line-height: 1; }
.seg-b { opacity: 0; transform: translateY(14px); transition: opacity 560ms var(--ease-out), transform 560ms var(--ease-out); }
.reveal.in .seg-b { opacity: 1; transform: none; }
.reveal.in .seg-b:nth-child(2) { transition-delay: 90ms; }
.reveal.in .seg-b:nth-child(3) { transition-delay: 180ms; }
.reveal.in .seg-b:nth-child(4) { transition-delay: 270ms; }
.reveal.in .seg-b:nth-child(5) { transition-delay: 360ms; }
.reveal.in .seg-b:nth-child(6) { transition-delay: 450ms; }
.reveal.in .seg-b:nth-child(7) { transition-delay: 540ms; }
@media (prefers-reduced-motion: reduce) { .seg-b { opacity: 1 !important; transform: none !important; } }
/* Son siete, impar: el último ocupa el ancho entero para no dejar un hueco
   gris al final de la rejilla. Sus puntos pasan a dos columnas. */
.seg-b:last-child { grid-column: 1 / -1; }
.seg-b:last-child .puntos { grid-template-columns: repeat(2, 1fr); gap: 14px 40px; }
.seg-b-cab { display: flex; align-items: center; gap: 13px; margin-bottom: 16px; }
.seg-b-ic {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  display: grid; place-items: center;
  background: var(--iris-50); color: var(--iris-600);
}
.seg-b h3 {
  font-family: var(--font-serif); font-weight: 600; font-size: 20px;
  line-height: 1.2; letter-spacing: -0.01em; color: var(--fg-strong); margin: 0;
}
.seg-b > p {
  font-size: 14.5px; line-height: 1.65; color: var(--fg-muted);
  margin: 0 0 18px; max-width: 52ch;
}
.seg-b .puntos { margin: 0; }
/* La nota de cierre: un aviso sobrio, no una alarma. */
.seg-nota {
  margin-top: 28px; padding: 20px 24px;
  border: 1px solid var(--border-subtle); border-left: 3px solid var(--iris-500);
  border-radius: var(--radius-sm); background: var(--bg-surface);
}
.seg-nota p { font-size: 14px; line-height: 1.65; color: var(--fg-muted); margin: 0; }
@media (max-width: 880px) {
  .seg-bloques { grid-template-columns: 1fr; }
  .seg-b { padding: 28px 24px; }
  .seg-b:last-child .puntos { grid-template-columns: 1fr; }
}


/* ============================================================
   EL GUIÓN DE LA FIGURA  ·  2026-07-29
   La figura deja de dibujarse una vez al entrar en pantalla y pasa a contar
   una historia en bucle, en tres etapas, con su carril arriba y un botón de
   repetir. Se engancha al vocabulario que YA tenían las 26 fichas
   (fig-win-cab, fig-tab, fig-fila, fig-paso, fig-relleno, fig-chip), así que
   ninguna figura hay que redibujarla: cada una anima SU contenido.

   CUATRO REGLAS QUE NO SE SALTAN AL TOCAR ESTO:

   1) UNA KEYFRAME POR GRUPO, con porcentajes ABSOLUTOS sobre --fig-loop. El
      `animation-delay` queda sólo para el escalonado dentro del grupo (<= 6 %).
      Todas se apagan en el 92 % y vuelven al inicio en el 100 %: así ninguna
      pieza sigue en pantalla cuando el guión ya ha vuelto a empezar. Con UNA
      keyframe común repartida por `delay`, la salida cae en (delay + 92 %) y
      las últimas se solapan con el arranque siguiente.

   2) CADA ETAPA TIENE SU CLASE (.e1 .e2 .e3) Y SU PROPIA KEYFRAME. Nada de
      ordenar con `:nth-of-type`: entre las píldoras hay un separador, y
      `:nth-of-type` cuenta TODOS los hermanos del mismo tag, con lo que la 2ª
      píldora no casaba y se encendían la 1ª y la 3ª a la vez.

   3) EL ESCALONADO VA CON `:nth-child` SOBRE UN PADRE DE UN SOLO TIPO de hijo
      (tbody > tr, fig-barras > fig-barra). Así gana por especificidad y no
      depende del orden de las reglas: `animation` es un atajo y reinicia
      `animation-delay` a 0, de modo que a igual especificidad ganaría la
      escrita después.

   4) El movimiento explica de dónde sale el dato; nunca decora. Un solo acento
      azul, ámbar SÓLO avisa, verde SÓLO sano, sin degradados ni resplandor.

   Reparto del bucle:  etapa 1 = 0-14 %   etapa 2 = 14-56 %   etapa 3 = 56-92 %
   ============================================================ */
.fig.demo { --fig-loop: 8s; }

/* --- Carril de etapas + botón de repetir --- */
.fig.demo .fig-cap { margin-bottom: 10px; }
.fig-guion { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0 0 14px; }
.fig-etapas { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.fig-et { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--fg-subtle); border: 1px solid var(--border-subtle); border-radius: 999px; padding: 4px 12px 4px 9px; background: var(--bg-surface); }
.fig-et .pt { width: 7px; height: 7px; border-radius: 50%; background: var(--border-default); flex: none; }
.fig-et-sep { width: 14px; height: 1px; background: var(--border-subtle); flex: none; }
.fig-rep { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-sans); font-size: 12px; color: var(--fg-muted); background: transparent; border: 1px solid var(--border-subtle); border-radius: 999px; padding: 4px 11px; cursor: pointer; transition: border-color 120ms var(--ease-out), color 120ms var(--ease-out); }
.fig-rep svg { width: 13px; height: 13px; }
.fig-rep:hover { border-color: var(--border-default); color: var(--fg-default); }
.fig-rep:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg-page), 0 0 0 4px var(--iris-500); }

.fig.demo.corre .e1 { animation: fig-et1 var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .e2 { animation: fig-et2 var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .e3 { animation: fig-et3 var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .e1 .pt { animation: fig-pt1 var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .e2 .pt { animation: fig-pt2 var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .e3 .pt { animation: fig-pt3 var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-et1 {
  0%, 13% { border-color: var(--iris-500); color: var(--iris-700); background: var(--iris-50); }
  14%, 100% { border-color: var(--border-subtle); color: var(--fg-subtle); background: var(--bg-surface); }
}
@keyframes fig-et2 {
  0%, 13% { border-color: var(--border-subtle); color: var(--fg-subtle); background: var(--bg-surface); }
  14%, 55% { border-color: var(--iris-500); color: var(--iris-700); background: var(--iris-50); }
  56%, 100% { border-color: var(--border-subtle); color: var(--fg-subtle); background: var(--bg-surface); }
}
@keyframes fig-et3 {
  0%, 55% { border-color: var(--border-subtle); color: var(--fg-subtle); background: var(--bg-surface); }
  56%, 92% { border-color: var(--iris-500); color: var(--iris-700); background: var(--iris-50); }
  93%, 100% { border-color: var(--border-subtle); color: var(--fg-subtle); background: var(--bg-surface); }
}
@keyframes fig-pt1 { 0%, 13% { background: var(--iris-500); } 14%, 100% { background: var(--border-default); } }
@keyframes fig-pt2 { 0%, 13% { background: var(--border-default); } 14%, 55% { background: var(--iris-500); } 56%, 100% { background: var(--border-default); } }
@keyframes fig-pt3 { 0%, 55% { background: var(--border-default); } 56%, 92% { background: var(--iris-500); } 93%, 100% { background: var(--border-default); } }

/* --- Etapa 1: se abre la pantalla --- */
.fig.demo.corre .fig-win-cab { animation: fig-ent-cab var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-ent-cab { 0%, 2% { opacity: 0; } 8%, 92% { opacity: 1; } 100% { opacity: 0; } }

/* --- Etapa 2: se llena de datos --- */
.fig.demo.corre .fig-tab tbody tr,
.fig.demo.corre .fig-fila { animation: fig-ent-fila var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .fig-paso { animation: fig-ent-paso var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .fig-disp { animation: fig-ent-disp var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-ent-fila { 0%, 20% { opacity: 0; transform: translateY(6px); } 26%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(6px); } }
@keyframes fig-ent-paso { 0%, 18% { opacity: 0; transform: translateY(7px); } 24%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(7px); } }
@keyframes fig-ent-disp { 0%, 16% { opacity: 0; transform: translateY(7px); } 24%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(7px); } }
/* Las barras crecen con scaleX porque el ancho real va en el `style` de cada
   una: animar `width` obligaría a duplicar aquí cada porcentaje. */
.fig.demo.corre .fig-relleno { animation: fig-crece var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-crece { 0%, 20% { transform: scaleX(0); } 42%, 92% { transform: scaleX(1); } 100% { transform: scaleX(0); } }

/* --- Etapa 3: el veredicto --- */
/* La fila del hallazgo se tiñe y le baja su filete de tinta cuando la tabla ya
   se ha leído entera: primero el dato, después el juicio. */
.fig.demo.corre .fig-tab tr.mira td { animation: fig-mira var(--fig-loop) var(--ease-out) infinite; }
.fig.demo.corre .fig-tab tr.bien td { animation: fig-bien var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-mira { 0%, 58% { background-color: transparent; } 64%, 92% { background-color: var(--amber-50); } 100% { background-color: transparent; } }
@keyframes fig-bien { 0%, 58% { background-color: transparent; } 64%, 92% { background-color: var(--success-50); } 100% { background-color: transparent; } }
.fig.demo.corre .fig-tab tr.mira td:first-child::before,
.fig.demo.corre .fig-tab tr.bien td:first-child::before { animation: fig-filete var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-filete { 0%, 58% { transform: scaleY(0); } 64%, 92% { transform: scaleY(1); } 100% { transform: scaleY(0); } }
/* El estado se sella al final: la fila ya estaba, lo que llega ahora es el
   veredicto. Lleva SIEMPRE palabra, nunca sólo color. */
.fig.demo.corre .fig-chip { animation: fig-sella var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-sella { 0%, 60% { opacity: 0; transform: scale(.94); } 66%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(.94); } }
/* El aviso late DENTRO de su etapa, ya sellado. No es una alarma: late con la
   escala, nunca con un halo (regla 5). */
.fig.demo.corre .fig-chip.av { animation: fig-sella var(--fig-loop) var(--ease-out) infinite, fig-avisa var(--fig-loop) var(--ease-out) infinite; }
@keyframes fig-avisa { 0%, 68% { transform: scale(1); } 73% { transform: scale(1.055); } 78%, 100% { transform: scale(1); } }
/* La flecha del flujo deja de ir a su aire y avanza cuando toca. */
.fig.demo.corre .fig-flecha { animation: fig-avanza-guion var(--fig-loop) var(--ease-inout) infinite; }
@keyframes fig-avanza-guion { 0%, 20% { transform: translateX(0); opacity: .55; } 30% { transform: translateX(4px); opacity: 1; } 40%, 100% { transform: translateX(0); opacity: .55; } }

/* --- Escalonado dentro de cada grupo (regla 3: `:nth-child` sobre un padre de
       un solo tipo de hijo, para ganar por especificidad y no por orden) --- */
.fig.demo.corre .fig-tab tbody tr:nth-child(2) { animation-delay: calc(var(--fig-loop) * .015); }
.fig.demo.corre .fig-tab tbody tr:nth-child(3) { animation-delay: calc(var(--fig-loop) * .03); }
.fig.demo.corre .fig-tab tbody tr:nth-child(4) { animation-delay: calc(var(--fig-loop) * .045); }
.fig.demo.corre .fig-tab tbody tr:nth-child(5) { animation-delay: calc(var(--fig-loop) * .06); }
.fig.demo.corre .fig-tab tbody tr:nth-child(2) .fig-chip { animation-delay: calc(var(--fig-loop) * .015); }
.fig.demo.corre .fig-tab tbody tr:nth-child(3) .fig-chip { animation-delay: calc(var(--fig-loop) * .03); }
.fig.demo.corre .fig-tab tbody tr:nth-child(4) .fig-chip { animation-delay: calc(var(--fig-loop) * .045); }
.fig.demo.corre .fig-barras > .fig-barra:nth-child(2) .fig-relleno { animation-delay: calc(var(--fig-loop) * .02); }
.fig.demo.corre .fig-barras > .fig-barra:nth-child(3) .fig-relleno { animation-delay: calc(var(--fig-loop) * .04); }
.fig.demo.corre .fig-barras > .fig-barra:nth-child(4) .fig-relleno { animation-delay: calc(var(--fig-loop) * .06); }
/* En .fig-pasos alternan paso y flecha: los pasos son el 1.º, 3.º y 5.º. */
.fig.demo.corre .fig-pasos > *:nth-child(3) { animation-delay: calc(var(--fig-loop) * .03); }
.fig.demo.corre .fig-pasos > *:nth-child(5) { animation-delay: calc(var(--fig-loop) * .06); }
.fig.demo.corre .fig-fila:nth-child(2) { animation-delay: calc(var(--fig-loop) * .015); }
.fig.demo.corre .fig-fila:nth-child(3) { animation-delay: calc(var(--fig-loop) * .03); }
.fig.demo.corre .fig-fila:nth-child(4) { animation-delay: calc(var(--fig-loop) * .045); }
.fig.demo.corre .fig-fila:nth-child(5) { animation-delay: calc(var(--fig-loop) * .06); }

/* Quien no quiere movimiento ve el ESTADO FINAL, que es el que cuenta la
   historia, y no el inicial en blanco. */
@media (prefers-reduced-motion: reduce) {
  .fig.demo.corre .e1, .fig.demo.corre .e2, .fig.demo.corre .e3,
  .fig.demo.corre .e1 .pt, .fig.demo.corre .e2 .pt, .fig.demo.corre .e3 .pt,
  .fig.demo.corre .fig-win-cab, .fig.demo.corre .fig-tab tbody tr,
  .fig.demo.corre .fig-fila, .fig.demo.corre .fig-paso, .fig.demo.corre .fig-disp,
  .fig.demo.corre .fig-relleno, .fig.demo.corre .fig-tab tr.mira td,
  .fig.demo.corre .fig-tab tr.bien td, .fig.demo.corre .fig-chip,
  .fig.demo.corre .fig-chip.av, .fig.demo.corre .fig-flecha,
  .fig.demo.corre .fig-tab tr.mira td:first-child::before,
  .fig.demo.corre .fig-tab tr.bien td:first-child::before { animation: none !important; }
  .fig.demo.corre .fig-win-cab, .fig.demo.corre .fig-tab tbody tr,
  .fig.demo.corre .fig-fila, .fig.demo.corre .fig-paso, .fig.demo.corre .fig-disp,
  .fig.demo.corre .fig-chip { opacity: 1 !important; transform: none !important; }
  .fig.demo.corre .fig-relleno { transform: scaleX(1) !important; }
  .fig.demo.corre .fig-tab tr.mira td:first-child::before,
  .fig.demo.corre .fig-tab tr.bien td:first-child::before { transform: scaleY(1) !important; }
  .fig.demo.corre .e3 { border-color: var(--iris-500); color: var(--iris-700); background: var(--iris-50); }
  .fig.demo.corre .e3 .pt { background: var(--iris-500); }
}
@media (max-width: 720px) { .fig-rep { margin-left: 0; } }


/* ============================================================
   DEMOS DE FICHA v2  ·  2026-07-29
   Las figuras dejan de ser una tabla quieta con entrada escalonada y pasan a
   ENSEÑAR EL MECANISMO de su modulo. Piezas compartidas, composicion propia
   por ficha: lo que se repite es la gramatica, no el dibujo.

   El movimiento tiene que hacer VISIBLE una derivacion. Un dato que aparece
   con un fundido no explica nada; un dato que pasa de hueso a texto al paso de
   la regla de lectura dice «esto se ha leido de ahi». Esa es la diferencia.

   Reparto del bucle, igual que el carril:
     etapa 1 = 0-14 %   el origen (documento, peticion, compra)
     etapa 2 = 14-56 %  la maquina trabaja (lee, empareja, calcula)
     etapa 3 = 56-92 %  el resultado (asiento, veredicto, aviso)
   Todas las keyframes salen al 92 % y vuelven al inicio en el 100 %.
   ============================================================ */

.d { display: grid; gap: 14px; }
/* Las tarjetas de una demo miden LO MISMO. Con `align-items: start` cada
   columna tomaba su altura natural y el panel del resultado quedaba mas corto
   que el del origen: la demo se veia descuadrada. Con `stretch` manda la
   columna mas alta, y el cuerpo de la ventana crece para rellenar. */
.d.duo { grid-template-columns: 1.12fr .88fr; align-items: stretch; }
.d.duo.par { grid-template-columns: 1fr 1fr; }
.d.duo > *, .d.tri > * { min-width: 0; }
.d .fig-win, .d .d-doc { height: 100%; }
.d .fig-win { display: flex; flex-direction: column; }
.d .fig-win-cuerpo { flex: 1 1 auto; }
.d.tri { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 820px) { .d.duo, .d.tri { grid-template-columns: 1fr; } }

/* --- La regla de lectura. Sin resplandor: lo que convence no es el brillo,
       es que a su paso el dato se resuelve. --- */
.d-doc { position: relative; }
.d-scan { position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--iris-500); opacity: 0; pointer-events: none; z-index: 3; }
.corre .d-scan { animation: d-scan var(--fig-loop) var(--ease-inout) infinite; }
@keyframes d-scan {
  0%, 14% { transform: translateY(0); opacity: 0; }
  17% { opacity: 1; }
  46% { transform: translateY(var(--d-alto, 200px)); opacity: 1; }
  50%, 100% { transform: translateY(var(--d-alto, 200px)); opacity: 0; }
}

/* --- Hueso -> texto. El gesto que dice «esto se acaba de leer». --- */
.d-v { position: relative; min-height: 19px; font-size: 13.5px; font-weight: 600; color: var(--fg-strong); }
.d-k { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-subtle); margin-bottom: 4px; }
.d-h { position: absolute; inset: 2px 0; background: var(--bg-muted); border-radius: 4px; }
.d-t { opacity: 0; }
.corre .d-h { animation: d-sale-h var(--fig-loop) var(--ease-out) infinite; }
.corre .d-t { animation: d-entra-t var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-sale-h { 0%, 20% { opacity: 1; } 26%, 92% { opacity: 0; } 100% { opacity: 1; } }
@keyframes d-entra-t { 0%, 20% { opacity: 0; transform: translateY(3px); } 26%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(3px); } }
.d-campos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; margin-bottom: 12px; }
@media (max-width: 560px) { .d-campos { grid-template-columns: 1fr 1fr; } }

/* --- Lineas del resultado (asiento, ficha, modelo): se montan en la etapa 3. --- */
.d-l { display: grid; grid-template-columns: 44px 1fr auto; gap: 9px; align-items: baseline; padding: 7px 0; border-bottom: 1px solid var(--border-subtle); font-size: 13px; opacity: 0; }
.d-l:last-of-type { border-bottom: 0; }
.d-l .c { color: var(--iris-700); font-weight: 600; font-family: var(--font-mono); }
.d-l .n { color: var(--fg-muted); font-size: 12.5px; }
.d-l .i { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.corre .d-l { animation: d-monta var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-monta { 0%, 58% { opacity: 0; transform: translateY(5px); } 64%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(5px); } }
.d-suma { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; padding-top: 9px; border-top: 2px solid var(--fg-strong); font-size: 13px; font-weight: 600; color: var(--fg-strong); }

/* --- El sello del final: el veredicto, siempre con palabra. --- */
.d-sel { opacity: 0; }
.corre .d-sel { animation: d-sella var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-sella { 0%, 70% { opacity: 0; transform: scale(.94); } 75%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(.94); } }

/* --- Grafico: la cortina se retira y la curva SE DIBUJA. Mas fiable que
       animar un clip-path o un stroke-dashoffset con longitudes reales. --- */
.d-graf { position: relative; }
.d-graf svg { display: block; width: 100%; height: auto; }
.d-linea { fill: none; stroke: var(--iris-500); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.d-area { fill: var(--iris-50); }
.d-umbral { stroke: var(--border-default); stroke-width: 1; stroke-dasharray: 4 4; fill: none; }
.d-eje { stroke: var(--border-subtle); stroke-width: 1; }
.d-cort { fill: var(--bg-page); }
.corre .d-cort { animation: d-cortina var(--fig-loop) var(--ease-inout) infinite; }
@keyframes d-cortina { 0%, 14% { transform: translateX(0); } 54%, 92% { transform: translateX(660px); } 100% { transform: translateX(0); } }
/* Etiquetas del grafico: HTML sobre el lienzo, NUNCA <text> dentro del SVG.
   «Mindestbestand» no cabe donde cabia «minimo operativo», y en SVG se sale
   sin que nadie se entere; en HTML fluye. */
.d-lab { position: absolute; font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-subtle); white-space: nowrap; pointer-events: none; }
.d-pin-l { stroke: var(--amber-500); stroke-width: 1; stroke-dasharray: 3 3; }
.d-pin-p { fill: var(--amber-500); stroke: var(--bg-page); stroke-width: 2; }
.d-pin { opacity: 0; }
.corre .d-pin { animation: d-entra-pin var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-entra-pin { 0%, 56% { opacity: 0; transform: translateY(-5px); } 62%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-5px); } }
/* El envoltorio COLOCA y el hijo ANIMA: si lo hiciera el mismo elemento, la
   keyframe pisaria el centrado y la etiqueta saltaria de sitio al arrancar. */
.d-pin-et { position: absolute; transform: translate(-50%, -100%); pointer-events: none; }
.d-pin-et > span { display: inline-block; font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--amber-700); white-space: nowrap; opacity: 0; }
.corre .d-pin-et > span { animation: d-entra-pin var(--fig-loop) var(--ease-out) infinite; }

/* --- Barras que crecen: magnitud comparada. --- */
.d-bars { display: grid; gap: 9px; }
.d-bar { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: 11px; font-size: 12.5px; }
.d-bar .k { color: var(--fg-muted); }
/* Rotulos largos («Compras sobre ingresos») necesitan mas carril. */
.d-bars.ancho .d-bar { grid-template-columns: 146px 1fr auto; }
.d-bar .p { position: relative; height: 12px; background: var(--bg-muted); border-radius: 4px; overflow: hidden; }
.d-bar .r { position: absolute; inset: 0 auto 0 0; border-radius: 4px; background: var(--iris-500); transform: scaleX(0); transform-origin: left center; }
.d-bar .r.av { background: var(--amber-500); }
.d-bar .r.ok { background: var(--success-500); }
.d-bar .r.nt { background: var(--border-strong); }
.d-bar .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.corre .d-bar .r { animation: d-crece var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-crece { 0%, 20% { transform: scaleX(0); } 44%, 92% { transform: scaleX(1); } 100% { transform: scaleX(0); } }

/* --- Pila que se descompone: un bruto que se parte en sus trozos. --- */
.d-pila { display: flex; height: 30px; border-radius: 5px; overflow: hidden; background: var(--bg-muted); }
.d-pila > span { display: grid; place-items: center; font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--fg-on-iris); transform: scaleX(0); transform-origin: left center; white-space: nowrap; }
.d-pila .a { background: var(--iris-500); }
.d-pila .b { background: var(--amber-500); }
.d-pila .c2 { background: var(--iris-300); color: var(--fg-strong); }
.d-pila .d2 { background: var(--success-500); }
.corre .d-pila > span { animation: d-crece var(--fig-loop) var(--ease-out) infinite; }

/* --- Emparejado: dos columnas que se casan con un trazo. --- */
.d-par { display: grid; grid-template-columns: 1fr 34px 1fr; gap: 0 10px; align-items: center; }
.d-par .cel { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 36px; border: 1px solid var(--border-subtle); border-radius: 6px; padding: 7px 10px; font-size: 12.5px; background: var(--bg-page); margin: 3px 0; }
.d-par .cel .n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.d-par .lig { height: 2px; background: var(--border-default); transform: scaleX(0); transform-origin: left center; }
.d-par .lig.ok { background: var(--success-500); }
.d-par .lig.no { background: var(--amber-500); }
.corre .d-par .lig { animation: d-liga var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-liga { 0%, 26% { transform: scaleX(0); } 38%, 92% { transform: scaleX(1); } 100% { transform: scaleX(0); } }
.d-par .cel.casa { border-color: color-mix(in oklch, var(--success-500) 45%, transparent); }
.d-par .cel.suelta { border-color: color-mix(in oklch, var(--amber-500) 45%, transparent); }

/* --- Cadena de bloques: cada eslabon se engancha al anterior. --- */
.d-cad { display: flex; align-items: center; gap: 0; flex-wrap: wrap; }
.d-cad .blo { flex: 1 1 0; min-width: 96px; min-height: 52px; border: 1px solid var(--border-subtle); border-radius: 6px; padding: 9px 10px; background: var(--bg-page); opacity: 0; }
.d-cad .blo .h { font-family: var(--font-mono); font-size: 10.5px; color: var(--iris-700); }
.d-cad .blo .t { font-size: 12px; color: var(--fg-muted); margin-top: 2px; }
.d-cad .esl { width: 18px; height: 2px; background: var(--border-default); flex: none; transform: scaleX(0); transform-origin: left center; }
.d-cad .esl.roto { background: var(--danger-500); }
.d-cad .blo.roto { border-color: color-mix(in oklch, var(--danger-500) 50%, transparent); }
.corre .d-cad .blo { animation: d-entra-blo var(--fig-loop) var(--ease-out) infinite; }
.corre .d-cad .esl { animation: d-liga var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-entra-blo { 0%, 16% { opacity: 0; transform: translateY(6px); } 24%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(6px); } }

/* --- Rejilla de celdas: turnos, mesas, cesta, planograma. --- */
.d-rej { display: grid; gap: 5px; }
.d-rej .c { border: 1px solid var(--border-subtle); border-radius: 5px; padding: 7px 6px; font-size: 11.5px; text-align: center; color: var(--fg-muted); background: var(--bg-page); opacity: 0; }
.d-rej .c.on { background: var(--iris-50); border-color: var(--iris-300); color: var(--iris-700); font-weight: 600; }
.d-rej .c.av { background: var(--amber-50); border-color: var(--amber-300); color: var(--amber-700); font-weight: 600; }
.d-rej .c.ok { background: var(--success-50); border-color: color-mix(in oklch, var(--success-500) 40%, transparent); color: var(--success-700); font-weight: 600; }
.corre .d-rej .c { animation: d-entra-cel var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-entra-cel { 0%, 18% { opacity: 0; transform: scale(.94); } 26%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(.94); } }

/* --- Filas que caen (ticket, libro, lista). --- */
.d-fila { display: grid; grid-template-columns: 1fr auto; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--border-subtle); font-size: 12.5px; opacity: 0; }
.d-fila:last-child { border-bottom: 0; }
.d-fila .n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.corre .d-fila { animation: d-cae var(--fig-loop) var(--ease-out) infinite; }
@keyframes d-cae { 0%, 20% { opacity: 0; transform: translateY(5px); } 27%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(5px); } }

/* --- Escalonado. Va DESPUES de todas las animaciones: `animation` es un atajo
       y reinicia `animation-delay` a 0; a igual especificidad manda la ultima. --- */
.corre .s1 { animation-delay: calc(var(--fig-loop) * .015); }
.corre .s2 { animation-delay: calc(var(--fig-loop) * .03); }
.corre .s3 { animation-delay: calc(var(--fig-loop) * .045); }
.corre .s4 { animation-delay: calc(var(--fig-loop) * .06); }

@media (prefers-reduced-motion: reduce) {
  .corre .d-scan { animation: none; opacity: 0; }
  .corre .d-h, .corre .d-t, .corre .d-l, .corre .d-sel, .corre .d-cort,
  .corre .d-pin, .corre .d-pin-et > span, .corre .d-bar .r, .corre .d-pila > span,
  .corre .d-par .lig, .corre .d-cad .blo, .corre .d-cad .esl, .corre .d-rej .c,
  .corre .d-fila { animation: none !important; }
  .corre .d-h { opacity: 0; }
  .corre .d-t, .corre .d-l, .corre .d-sel, .corre .d-pin, .corre .d-pin-et > span,
  .corre .d-cad .blo, .corre .d-rej .c, .corre .d-fila { opacity: 1; transform: none; }
  .corre .d-cort { transform: translateX(660px); }
  .corre .d-bar .r, .corre .d-pila > span, .corre .d-par .lig, .corre .d-cad .esl { transform: scaleX(1); }
}

/* El texto TAL CUAL lo escribe el proveedor en su factura: mono, en gris, para
   que se lea como dato crudo y no como algo ya interpretado. */
.mono-cruda { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-muted); }

/* ============================================================
   PANTALLAS DEL PRODUCTO
   ------------------------------------------------------------
   Una figura abstracta explica un MECANISMO; hay módulos en los que lo que
   hay que enseñar no es el mecanismo sino el aparato: el TPV, la PDA del
   almacén, el chat, la carta en el móvil. Para esos, la ficha enseña la
   pantalla de verdad.

   POR QUÉ NO SON CAPTURAS. Un PNG no se traduce, y aquí todo el contenido de
   la ficha tiene que poder cambiar de idioma. Además pesaría veinte veces más
   y se vería borroso al escalar. Así que la pantalla se reconstruye en HTML
   con los MISMOS tokens y las MISMAS medidas que la app real
   (frontend-react/src/styles/app.css y pda/src/estilos.css): lateral de
   240 px, baldosa de icono de 29 px, `.card` con hairline y sombra 1, cifras
   mono tabulares, azul como único acento. Si cambia el producto, se cambia
   aquí; no hay que volver a fotografiar nada.

   Los datos son ficticios y los mismos de toda la landing (Mermon, Goya,
   Torrent, Bar Manolo). Nunca salen datos de un cliente.
   ============================================================ */

.pant {
  border: 1px solid var(--border-default);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-muted);
  box-shadow: var(--shadow-1);
}

/* ---------- Barra del navegador (solo la app web) ---------- */
.pant-bar { display: flex; align-items: center; gap: 10px; padding: 7px 12px; background: var(--bg-muted); border-bottom: 1px solid var(--border-subtle); }
.pant-bar .sem { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); opacity: .34; box-shadow: 13px 0 0 var(--border-strong), 26px 0 0 var(--border-strong); margin-right: 30px; flex: none; }
.pant-url { flex: 1; min-width: 0; font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-subtle); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: 999px; padding: 3px 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- El armazón de la app: lateral + contenido ---------- */
.pant-app { display: grid; grid-template-columns: 208px 1fr; background: var(--bg-muted); }

.pa-side { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); box-shadow: var(--shadow-1); padding: 13px 9px 10px; margin: 9px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pa-marca { display: flex; align-items: center; gap: 8px; padding: 2px 7px 11px; border-bottom: 1px solid var(--border-subtle); margin-bottom: 7px; color: var(--fg-strong); }
.pa-marca .wm { font-family: var(--font-serif); font-weight: 600; font-size: 13px; letter-spacing: var(--tracking-wordmark); line-height: 1; white-space: nowrap; }
.pa-sec { font-size: 8.5px; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase; color: var(--fg-subtle); display: flex; align-items: center; gap: 8px; padding: 9px 6px 4px; white-space: nowrap; }
.pa-sec::after { content: ""; height: 1px; flex: 1; background: var(--border-subtle); }

/* La fila del menú, con su BALDOSA de icono: vacía en reposo, azul plena
   cuando es la página en la que estás. Es exactamente el trato de la app. */
.pa-it { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border-radius: var(--radius-sm); font-size: 11.5px; font-weight: 500; color: var(--fg-muted); white-space: nowrap; min-width: 0; }
.pa-it > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.pa-it .ic { width: 22px; height: 22px; flex: none; box-sizing: border-box; padding: 3.5px; border-radius: 6px; border: 1px solid transparent; color: var(--fg-muted); }
.pa-it .ic svg { width: 100%; height: 100%; }
.pa-it.on { background: var(--iris-50); color: var(--iris-700); font-weight: 600; }
.pa-it.on .ic { background: var(--iris-500); color: var(--fg-on-iris); border-color: var(--iris-600); box-shadow: var(--shadow-1); }

.pa-user { margin-top: auto; padding: 10px 7px 2px; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; gap: 3px; }
.pa-user .nom { font-size: 11.5px; font-weight: 600; color: var(--fg-default); }
.pa-user .rol { font-family: var(--font-mono); font-size: 9.5px; color: var(--fg-muted); }
.pa-user .salir { display: inline-flex; align-items: center; gap: 7px; font-size: 10.5px; color: var(--fg-subtle); margin-top: 5px; }
.pa-user .salir svg { width: 13px; height: 13px; }

.pa-main { padding: 16px 18px 18px; min-width: 0; display: flex; flex-direction: column; gap: 11px; }
.pa-h1 { font-family: var(--font-serif); font-weight: 600; font-size: 17px; letter-spacing: var(--tracking-snug); color: var(--fg-strong); margin: 0; }
.pa-sub { font-size: 11.5px; color: var(--fg-muted); margin: -7px 0 0; }
.pa-fila { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.pa-fila.der { justify-content: space-between; }

/* Tarjeta: hairline + sombra de reposo, como la de la app (regla 9). */
.pa-card { background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--shadow-1); padding: 12px 14px; min-width: 0; }
.pa-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 9px; }
.pa-kpi .k { font-size: 9.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-subtle); }
.pa-kpi .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 19px; font-weight: 600; color: var(--fg-strong); line-height: 1.25; margin-top: 3px; }
.pa-kpi .v.ok { color: var(--success-700); }
.pa-kpi .v.av { color: var(--amber-700); }
.pa-kpi .d { font-size: 10.5px; color: var(--fg-muted); }

/* Tabla: cabecera versalita fina, celdas numéricas mono a la derecha. La
   simetría por columna (th y td con la misma clase) es la regla de la app. */
.pa-tab { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.pa-tab th { font-size: 8.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-subtle); text-align: left; padding: 0 8px 6px; border-bottom: 1px solid var(--border-subtle); white-space: nowrap; }
.pa-tab td { padding: 7px 8px; border-bottom: 1px solid var(--border-subtle); color: var(--fg-default); vertical-align: middle; }
.pa-tab tr:last-child td { border-bottom: 0; }
.pa-tab .num, .pa-tab th.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; color: var(--fg-strong); white-space: nowrap; }
.pa-tab .men { color: var(--fg-subtle); font-size: 10.5px; }

.pa-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 600; padding: 2px 8px; border-radius: 999px; white-space: nowrap; background: var(--bg-muted); color: var(--fg-muted); }
.pa-pill .pt { width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
.pa-pill.ok { background: var(--success-50); color: var(--success-700); }
.pa-pill.av { background: var(--warning-50); color: var(--warning-700); }
.pa-pill.no { background: var(--danger-50); color: var(--danger-700); }
.pa-pill.in { background: var(--iris-50); color: var(--iris-700); }

.pa-btn { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; padding: 5px 12px; border-radius: var(--radius-sm); background: var(--iris-500); color: var(--fg-on-iris); white-space: nowrap; }
.pa-btn.sec { background: var(--bg-surface); color: var(--fg-default); border: 1px solid var(--border-default); }
.pa-campo { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--fg-subtle); background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-sm); padding: 6px 11px; min-width: 0; }
.pa-campo.foco { border-color: var(--iris-500); box-shadow: var(--focus-ring); color: var(--fg-strong); }

/* El cursor del campo activo: dice «esperando a que dispares la pistola».
   Es el único movimiento del sitio que no depende del guion, porque no marca
   un paso: marca un estado. */
.pa-cur { display: inline-block; width: 1px; height: 12px; background: var(--iris-500); vertical-align: -2px; }
.corre .pa-cur { animation: pa-late 1.05s steps(1, end) infinite; }
@keyframes pa-late { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

/* El armazon web es el unico que necesita alto minimo: sin el, una pantalla
   de dos filas dejaria el lateral mas alto que el contenido. */
.pant.web .pant-app { min-height: 264px; }

/* ---------- La PDA: un aparato de mano ---------- */
/* Las medidas NO son las de la web: en el pasillo se toca con guantes, así
   que nada pulsable baja de 56 px. El tema de fábrica de la PDA es el claro;
   aquí se enseña el OSCURO, que es el de la cámara y el que se reconoce al
   instante como «esto es un aparato, no una web». */
.pant.pda {
  --pd-bg: #14181d; --pd-sup: #1c2128; --pd-alta: #262c35; --pd-bor: #333b45;
  --pd-tx: #e8ecf1; --pd-tn: #97a3b2; --pd-az: #4a8bea;
  max-width: 292px; margin-inline: auto; border-radius: 22px; border: 6px solid #0d1116;
  background: var(--pd-bg); box-shadow: var(--shadow-2); overflow: hidden;
}
.pda-barra { display: flex; align-items: center; gap: 8px; padding: 10px 12px; background: var(--pd-sup); border-bottom: 1px solid var(--pd-bor); color: var(--pd-tx); }
.pda-barra .wm { font-family: var(--font-serif); font-weight: 600; font-size: 12px; letter-spacing: var(--tracking-wordmark); }
.pda-chapa { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono); font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 999px; background: rgba(216, 139, 18, .18); color: #e5a63f; }
.pda-chapa.ok { background: rgba(46, 125, 67, .2); color: #6cc98a; }
.pda-tit { padding: 9px 14px 0; font-size: 12.5px; color: var(--pd-tn); }
.pda-cuerpo { padding: 11px 12px 13px; display: grid; gap: 9px; }
.pda-menu { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.pda-op { min-height: 62px; border: 1px solid var(--pd-bor); border-radius: 12px; background: var(--pd-sup); color: var(--pd-tx); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; font-size: 11.5px; font-weight: 600; text-align: center; padding: 6px; }
.pda-op .ic { width: 22px; height: 22px; color: var(--pd-az); }
.pda-op .ic svg { width: 100%; height: 100%; }
.pda-op.on { border-color: var(--pd-az); background: rgba(74, 139, 234, .13); }
/* La ventana del lector: el visor por el que entra el código. */
.pda-lente { position: relative; height: 66px; border: 1px solid var(--pd-bor); border-radius: 10px; background: #0f1318; overflow: hidden; display: grid; place-items: center; }
.pda-lente .ean { font-family: var(--font-mono); font-size: 13px; letter-spacing: .08em; color: var(--pd-tx); }
.pda-haz { position: absolute; left: 10%; right: 10%; top: 50%; height: 2px; background: #de4133; box-shadow: 0 0 10px rgba(222, 65, 51, .75); opacity: .9; }
.corre .pda-haz { animation: pda-haz var(--fig-loop) var(--ease-inout) infinite; }
@keyframes pda-haz { 0% { transform: translateY(-22px); } 12% { transform: translateY(20px); } 24% { transform: translateY(-22px); } 25%, 100% { transform: translateY(-22px); opacity: 0; } }
/* El destello del acierto: la PDA confirma la lectura sin sonido. */
.pda-flash { position: absolute; inset: 0; background: rgba(74, 139, 234, .3); opacity: 0; }
.corre .pda-flash { animation: pda-flash var(--fig-loop) steps(1, end) infinite; }
@keyframes pda-flash { 0%, 23% { opacity: 0; } 24%, 27% { opacity: 1; } 28%, 100% { opacity: 0; } }
.pda-lin { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; min-height: 56px; border: 1px solid var(--pd-bor); border-radius: 10px; background: var(--pd-sup); padding: 8px 11px; color: var(--pd-tx); font-size: 12px; }
.pda-lin .d small { display: block; color: var(--pd-tn); font-size: 10.5px; margin-top: 2px; }
.pda-lin .q { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 17px; font-weight: 600; }
.pda-lin .q small { font-size: 10px; font-weight: 400; color: var(--pd-tn); margin-left: 4px; }
.pda-lin.mal { border-color: rgba(222, 65, 51, .55); }
.pda-lin.mal .q { color: #ff8e82; }
.pda-pie { margin-top: auto; padding: 11px 14px 12px; display: flex; align-items: center; justify-content: space-between; color: var(--pd-tn); font-size: 11px; }
.pda-pie .senal { display: inline-flex; align-items: center; gap: 6px; }
.pda-pie .punto { width: 7px; height: 7px; border-radius: 50%; background: #6cc98a; flex: none; }
.pda-pie .ajus { width: 20px; height: 20px; color: var(--pd-tn); }
.pda-pie .ajus svg { width: 100%; height: 100%; }
.pant.pda { display: flex; flex-direction: column; }
.pda-bot { min-height: 56px; border-radius: 12px; background: var(--pd-az); color: #fff; display: grid; place-items: center; font-size: 13.5px; font-weight: 600; }

/* ---------- El TPV: pantalla táctil apaisada ---------- */
/* Dos zonas, como la botonera real: arriba los menús, debajo la parrilla del
   menú elegido; el ticket vivo a la derecha. Botón cuadrado con la banda del
   nombre abajo, que es como lo dibuja el configurador del ERP. */
.pant.tpv { border: 5px solid #0d1116; border-radius: 14px; background: var(--bg-muted); max-width: 940px; margin-inline: auto; }
.pant.tpv.corta { max-width: 640px; }
.tpv-cab { display: flex; align-items: center; gap: 9px; padding: 8px 13px; background: var(--bg-surface); border-bottom: 1px solid var(--border-subtle); }
.tpv-cab .wm { font-family: var(--font-serif); font-weight: 600; font-size: 12px; letter-spacing: var(--tracking-wordmark); color: var(--fg-strong); }
.tpv-cuerpo { display: grid; grid-template-columns: 1fr 244px; min-height: 0; }
.tpv-izq { padding: 11px; display: grid; gap: 10px; align-content: start; }
.tpv-menus, .tpv-rejilla { display: flex; flex-wrap: wrap; gap: 7px; border: 1px solid var(--border-subtle); border-radius: 8px; padding: 9px; background: var(--bg-surface); align-content: flex-start; }
.tpv-b { position: relative; width: 88px; height: 88px; border: 1px solid var(--border-subtle); border-radius: 8px; background: var(--bg-page); overflow: hidden; flex: none; display: grid; place-items: center; padding: 6px; }
.tpv-b .et { text-align: center; font-size: 11px; line-height: 1.25; font-weight: 600; color: var(--fg-strong); }
.tpv-b.on { border-color: var(--iris-500); background: var(--iris-50); }
.tpv-b.on .et { color: var(--iris-700); }
/* El dedo: aparece justo donde se pulsa y desaparece. Sin él no se entiende
   que la parrilla de abajo cambió PORQUE se tocó el menú de arriba. */
/* La onda de la pulsacion: sale del dedo y se abre. */
.tpv-onda { position: absolute; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--iris-500); transform: translate(-50%, -50%) scale(.5); opacity: 0; pointer-events: none; }
.corre .tpv-onda { animation: pa-onda var(--fig-loop) var(--ease-out) infinite; }
@keyframes pa-onda { 0%, 19% { opacity: 0; transform: translate(-50%, -50%) scale(.5); } 21% { opacity: .5; } 34%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(2.6); } }
.tpv-dedo { position: absolute; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--iris-500); background: color-mix(in oklch, var(--iris-500) 18%, transparent); transform: translate(-50%, -50%) scale(.4); opacity: 0; pointer-events: none; }
.tpv-der { border-left: 1px solid var(--border-subtle); background: var(--bg-surface); padding: 11px 12px; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.tpv-tk { font-family: var(--font-mono); font-size: 10px; color: var(--fg-subtle); letter-spacing: .04em; }
.tpv-lin { display: grid; grid-template-columns: 1fr auto; gap: 9px; font-size: 11.5px; padding: 5px 0; border-bottom: 1px solid var(--border-subtle); color: var(--fg-default); }
.tpv-lin .n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.tpv-lin.dto { color: var(--success-700); }
.tpv-lin.dto .n { color: var(--success-700); }
.tpv-tot { margin-top: auto; padding-top: 9px; border-top: 2px solid var(--fg-strong); display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.tpv-tot .k { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-subtle); }
.tpv-tot .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 22px; font-weight: 600; color: var(--fg-strong); }
.tpv-cobrar { min-height: 44px; border-radius: 8px; background: var(--iris-500); color: var(--fg-on-iris); display: grid; place-items: center; font-size: 13px; font-weight: 600; }
.tpv-sin { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 600; color: var(--amber-700); background: var(--amber-50); border-radius: 999px; padding: 2px 8px; margin-left: auto; }

/* ---------- El móvil: carta y portal del cliente ---------- */
.pant.tel { max-width: 264px; margin-inline: auto; border-radius: 24px; border: 6px solid #0d1116; background: var(--bg-surface); overflow: hidden; box-shadow: var(--shadow-2); }
.tel-cab { padding: 12px 14px 9px; border-bottom: 1px solid var(--border-subtle); }
.tel-cab .wm { font-family: var(--font-serif); font-weight: 600; font-size: 13px; letter-spacing: .1em; color: var(--fg-strong); }
.tel-cab .s { font-size: 10.5px; color: var(--fg-subtle); margin-top: 2px; }
.tel-tabs { display: flex; gap: 5px; padding: 9px 12px 0; overflow: hidden; }
.tel-tab { font-size: 10.5px; font-weight: 600; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border-subtle); color: var(--fg-muted); white-space: nowrap; }
.tel-tab.on { background: var(--iris-500); border-color: var(--iris-500); color: var(--fg-on-iris); }
.tel-cuerpo { padding: 10px 12px 13px; display: grid; gap: 8px; }
.tel-plato { display: grid; grid-template-columns: 1fr auto; gap: 9px; align-items: baseline; padding-bottom: 8px; border-bottom: 1px solid var(--border-subtle); font-size: 12px; color: var(--fg-strong); }
.tel-plato:last-child { border-bottom: 0; }
.tel-plato small { display: block; color: var(--fg-subtle); font-size: 10.5px; margin-top: 2px; font-weight: 400; }
.tel-plato .p { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.tel-bar { min-height: 42px; border-radius: 10px; background: var(--iris-500); color: var(--fg-on-iris); display: flex; align-items: center; justify-content: space-between; padding: 0 13px; font-size: 12px; font-weight: 600; }
.tel-bar .n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ---------- El chat: el panel flotante, tal cual ---------- */
/* 388 × 560 en la app; aquí se deja encoger pero no crecer, porque parte de
   lo que cuenta la imagen es que NO ocupa la pantalla: vive en una esquina
   mientras sigues trabajando. */
.pant.chat { max-width: 340px; margin-inline: auto; border: 1px solid var(--border-subtle); border-radius: 18px; background: var(--bg-surface); box-shadow: var(--shadow-2); overflow: hidden; display: flex; flex-direction: column; }
.ch-cab { display: flex; align-items: center; gap: 9px; padding: 0 14px; height: 44px; flex: none; background: var(--bg-inverse); color: var(--fg-on-inverse); }
.ch-cab .mk { width: 26px; height: 26px; border-radius: 9px; background: rgba(255,255,255,.13); display: grid; place-items: center; flex: none; }
.ch-cab .mk svg { width: 14px; height: 14px; }
.ch-cab .t { font-family: var(--font-serif); font-size: 11.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; flex: 1; }
.ch-tabs { display: flex; gap: 4px; padding: 7px 7px 0; border-bottom: 1px solid var(--border-subtle); flex: none; }
.ch-tab { flex: 1; text-align: center; padding: 6px 0 8px; font-size: 10.5px; font-weight: 500; color: var(--fg-muted); border-bottom: 2px solid transparent; }
.ch-tab.on { color: var(--iris-500); border-bottom-color: var(--iris-500); font-weight: 600; }
.ch-ctx { display: flex; align-items: center; gap: 5px; padding: 7px 13px; font-size: 10.5px; color: var(--fg-subtle); border-bottom: 1px solid var(--border-subtle); background: var(--bg-page); }
.ch-ctx b { color: var(--iris-700); font-weight: 600; }
.ch-cuerpo { position: relative; min-height: 166px; padding: 11px 13px; display: flex; flex-direction: column; gap: 9px; }
.ch-m { max-width: 84%; display: flex; flex-direction: column; align-items: flex-start; }
.ch-m.yo { margin-left: auto; align-items: flex-end; }
.ch-m .q { font-size: 9.5px; color: var(--fg-subtle); margin: 0 4px 3px; }
.ch-m .b { font-size: 11.5px; line-height: 1.4; padding: 7px 11px; border-radius: 13px; background: var(--bg-muted); color: var(--fg-default); border-bottom-left-radius: 4px; }
.ch-m.yo .b { background: var(--iris-500); color: var(--fg-on-iris); border-bottom-left-radius: 13px; border-bottom-right-radius: 4px; }
.ch-m.sis { align-items: center; max-width: 100%; }
.ch-m.sis .b { background: var(--warning-50); color: var(--warning-700); font-size: 10.5px; border-radius: 999px; }
.ch-esc { display: inline-flex; gap: 3px; padding: 9px 11px; }
.ch-esc i { width: 5px; height: 5px; border-radius: 50%; background: var(--fg-subtle); display: block; }
.corre .ch-esc i { animation: ch-pto 1.15s var(--ease-inout) infinite; }
.corre .ch-esc i:nth-child(2) { animation-delay: .16s; }
.corre .ch-esc i:nth-child(3) { animation-delay: .32s; }
@keyframes ch-pto { 0%, 100% { opacity: .3; transform: none; } 50% { opacity: 1; transform: translateY(-3px); } }
.ch-pie { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border-top: 1px solid var(--border-subtle); flex: none; }
.ch-pie .campo { flex: 1; font-size: 11px; color: var(--fg-subtle); background: var(--bg-page); border: 1px solid var(--border-subtle); border-radius: 999px; padding: 6px 12px; min-width: 0; }
.ch-pie .env { width: 28px; height: 28px; border-radius: 50%; background: var(--iris-500); color: var(--fg-on-iris); display: grid; place-items: center; flex: none; }
.ch-pie .env svg { width: 14px; height: 14px; }
/* La llamada entrante tapa el panel: es lo que pasa de verdad. */
.ch-llam { position: absolute; inset: 0; background: var(--bg-inverse); color: var(--fg-on-inverse); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; opacity: 0; }
.ch-llam .av { width: 58px; height: 58px; border-radius: 50%; background: rgba(255,255,255,.14); display: grid; place-items: center; font-family: var(--font-mono); font-size: 19px; font-weight: 600; }
.ch-llam .qn { font-size: 13px; font-weight: 600; }
.ch-llam .st { font-size: 10.5px; opacity: .72; }
.ch-llam .bt { display: flex; gap: 13px; margin-top: 4px; }
.ch-llam .bt span { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; }
.ch-llam .bt .si { background: var(--success-500); color: #fff; }
.ch-llam .bt .no { background: var(--danger-500); color: #fff; }
.ch-llam .bt svg { width: 17px; height: 17px; }
.pant.chat { position: relative; }

/* ============================================================
   EL GUION, DENTRO DE LA PANTALLA
   Los mismos tres tiempos del carril de arriba: lo que aparece en el paso 1
   lleva `.g1`, lo del paso 2 `.g2a/.g2b/.g2c` y lo del paso 3 `.g3a/.g3b`.
   Un solo fotograma por grupo y porcentajes absolutos sobre --fig-loop: no
   hay `animation-delay` que se pueda quedar descolgado. Todo sale a 92 % y
   vuelve a su sitio a 100 %, que es cuando el bucle reengancha.
   ============================================================ */
.pant .sale3, .pant .g1, .pant .g2a, .pant .g2b, .pant .g2c, .pant .g3a, .pant .g3b {
  opacity: 0; --dx: 0px; --dy: 4px; --sc: 1;
}
/* La DIRECCION de la entrada es un dato, no un fotograma nuevo: asi un mensaje
   entra por su lado, una linea de ticket por la derecha (viene del boton que
   acabas de pulsar) y la llamada desde el fondo, sin multiplicar keyframes. */
.pant .ent-der   { --dx: 14px;  --dy: 0px; }
.pant .ent-izq   { --dx: -14px; --dy: 0px; }
.pant .ent-fondo { --dx: 0px;   --dy: 0px; --sc: .93; }
.corre .pant .g1  { animation: pa-g1  var(--fig-loop) var(--ease-out) infinite; }
.corre .pant .g2a { animation: pa-g2a var(--fig-loop) var(--ease-out) infinite; }
.corre .pant .g2b { animation: pa-g2b var(--fig-loop) var(--ease-out) infinite; }
.corre .pant .g2c { animation: pa-g2c var(--fig-loop) var(--ease-out) infinite; }
.corre .pant .g3a { animation: pa-g3a var(--fig-loop) var(--ease-out) infinite; }
.corre .pant .g3b { animation: pa-g3b var(--fig-loop) var(--ease-out) infinite; }
@keyframes pa-g1 { 0%, 3% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 9%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }
@keyframes pa-g2a { 0%, 17% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 23%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }
@keyframes pa-g2b { 0%, 27% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 33%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }
@keyframes pa-g2c { 0%, 37% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 43%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }
@keyframes pa-g3a { 0%, 58% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 64%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }
@keyframes pa-g3b { 0%, 68% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } 74%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--sc)); } }

/* Lo que estaba y DEJA de estar al llegar el paso 3. Un contador de
   pendientes no puede seguir ahi cuando ya se ha subido todo. */
.corre .pant .sale3 { animation: pa-sale3 var(--fig-loop) var(--ease-out) infinite; }
@keyframes pa-sale3 { 0%, 3% { opacity: 0; } 9%, 55% { opacity: 1; } 61%, 100% { opacity: 0; } }

/* El dedo que pulsa (paso 2): entra, aprieta y se va. */
.corre .tpv-dedo { animation: pa-dedo var(--fig-loop) var(--ease-out) infinite; }
@keyframes pa-dedo { 0%, 14% { opacity: 0; transform: translate(-50%, -50%) scale(.4); } 19% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 26% { opacity: 1; transform: translate(-50%, -50%) scale(.82); } 32%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(.4); } }

/* Un valor que CAMBIA (no que aparece): parpadea en azul al recalcularse. */
.corre .pant .rec { animation: pa-rec var(--fig-loop) var(--ease-out) infinite; }
@keyframes pa-rec { 0%, 56% { background: transparent; } 62% { background: var(--iris-50); } 76%, 100% { background: transparent; } }

/* El relevo de marca (marca blanca): la misma pantalla, otro rótulo. */
.corre .pant .mk-a { animation: pa-mk-a var(--fig-loop) steps(1, end) infinite; }
.corre .pant .mk-b { animation: pa-mk-b var(--fig-loop) steps(1, end) infinite; }
@keyframes pa-mk-a { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
@keyframes pa-mk-b { 0%, 55% { opacity: 0; } 56%, 92% { opacity: 1; } 93%, 100% { opacity: 0; } }

/* El widget flotando sobre la app, que es donde vive de verdad. */
.pant.web.conflota .pant-app { position: relative; }
.pant.web .flota { position: absolute; right: 16px; bottom: 16px; width: 306px; max-width: calc(100% - 32px); z-index: 3; margin: 0; }
.pant.web.conflota .pa-main { padding-right: 338px; }

/* ---------- Adaptación a pantallas estrechas ---------- */
/* Igual que la app: por debajo de 900 px el lateral se queda en baldosas y
   por debajo de 640 desaparece, que es cuando la app pasa a cajón. */
@media (max-width: 900px) {
  .pant-app { grid-template-columns: 62px 1fr; }
  .pa-it > span:last-child, .pa-sec, .pa-marca .wm { display: none; }
  .pa-it { justify-content: center; padding: 3px; }
  .pa-marca { justify-content: center; padding: 2px 0 9px; }
  .tpv-cuerpo { grid-template-columns: 1fr 186px; }
}
@media (max-width: 640px) {
  .pant-app { grid-template-columns: 1fr; }
  /* Igual que en la app: una tabla ancha se desplaza DENTRO de su tarjeta en
     vez de romper el ancho. Sin esto la tarjeta la recorta y desaparecen
     columnas enteras, que es peor que tener que arrastrar. */
  .pa-card { overflow-x: auto; }
  .pa-kpis { grid-template-columns: 1fr 1fr; }
  .pa-kpi .v { font-size: 16px; }
  .pa-side { display: none; }
  .pa-main { padding: 13px 12px 14px; }
  .tpv-cuerpo { grid-template-columns: 1fr; }
  .tpv-der { border-left: 0; border-top: 1px solid var(--border-subtle); }
  .tpv-b { width: 72px; height: 72px; }
  .d.duo, .d.duo.par { grid-template-columns: 1fr; }
  .pant.web.conflota .pa-main { padding-right: 12px; }
  .pant.web .flota { position: static; width: auto; max-width: none; margin: 10px 9px 9px; }
}

/* ---------- Piezas sueltas que piden algunas pantallas ---------- */
/* El dedo se coloca en coordenadas de la zona de menús. */
.tpv-menus, .tpv-rejilla { position: relative; }

/* La tarjeta del cliente en el portal (fidelización). El código de barras se
   dibuja con bandas repetidas: no es decoración, es el objeto. */
.tel-tar { border: 1px solid var(--border-default); border-radius: 12px; padding: 11px 12px; background: var(--bg-page); display: grid; gap: 8px; }
.tel-ean { height: 34px; border-radius: 3px; background-color: var(--bg-surface); background-image: repeating-linear-gradient(90deg, var(--fg-strong) 0 2px, transparent 2px 4px, var(--fg-strong) 4px 5px, transparent 5px 9px, var(--fg-strong) 9px 12px, transparent 12px 14px); }
.tel-tar .cod { font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em; text-align: center; color: var(--fg-muted); }
.tel-cifras { display: flex; gap: 9px; }
.tel-cifras > div { flex: 1; border: 1px solid var(--border-subtle); border-radius: 9px; padding: 7px 9px; background: var(--bg-page); }
.tel-cifras .k { font-size: 8.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-subtle); }
.tel-cifras .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 15px; font-weight: 600; color: var(--fg-strong); margin-top: 2px; white-space: nowrap; }
.tel-cifras .v.ok { color: var(--success-700); }
.tel-li { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 11.5px; color: var(--fg-muted); padding: 6px 0; border-bottom: 1px solid var(--border-subtle); }
.tel-li:last-child { border-bottom: 0; }

/* MARCA BLANCA. El color de OTRO es contenido, no cromatismo de la landing:
   la ficha trata precisamente de que el portal sale con los colores del
   cliente. Por eso `--wl` es un valor literal y no un token: no pertenece al
   sistema, pertenece al ejemplo. No se use en ninguna otra pantalla. */
.wl { --wl: #8a3b2a; }
.wl .tel-bar { background: var(--wl); }
.wl .tel-cab .mk-b, .wl .tel-plato .p { color: var(--wl); }
.wl .tel-tab.on { background: var(--wl); border-color: var(--wl); }
/* Los dos rotulos ocupan la MISMA celda: el relevo es un cambio de marca en
   el mismo sitio, no dos lineas que se turnan y mueven todo lo de abajo. */
.relevo, .wm-relevo { display: grid; }
.relevo > *, .wm-relevo > * { grid-area: 1 / 1; }
/* El total no aparece: CAMBIA. Se releva justo despues de entrar la ultima
   linea, que es lo que hace que se lea como una suma y no como un rotulo. */
.corre .pant .val-a { animation: pa-val-a var(--fig-loop) steps(1, end) infinite; }
.corre .pant .val-b { animation: pa-val-b var(--fig-loop) steps(1, end) infinite; }
@keyframes pa-val-a { 0%, 37% { opacity: 1; } 38%, 100% { opacity: 0; } }
@keyframes pa-val-b { 0%, 37% { opacity: 0; } 38%, 92% { opacity: 1; } 93%, 100% { opacity: 0; } }
/* El interruptor: al encenderlo cambian rotulo y color a la vez.
   OJO: `animation` es un ATAJO. Si esta regla declarase solo el color, se
   cargaria la entrada `pa-g2c` que el boton lleva por su grupo, y el boton no
   aparecia nunca. Las dos animaciones tienen que ir en la MISMA declaracion. */
.corre .wl .tel-bar {
  animation: pa-g2c var(--fig-loop) var(--ease-out) infinite,
             pa-wl var(--fig-loop) steps(1, end) infinite;
}
@keyframes pa-wl { 0%, 55% { background: var(--iris-500); } 56%, 100% { background: var(--wl); } }

/* Etiqueta de estado sobre una fila de la app (la que se «sella» al final). */
.pa-sello { display: inline-flex; align-items: center; gap: 6px; font-size: 10.5px; font-weight: 600; color: var(--success-700); background: var(--success-50); border-radius: 999px; padding: 3px 10px; }
.pa-sello.av { color: var(--amber-700); background: var(--amber-50); }
.pa-sello.in { color: var(--iris-700); background: var(--iris-50); }
