/* ============================================================================
   AI DATA LINEAGE MAPPER — Landing page
   ---------------------------------------------------------------------------
   00. Design tokens
   01. Reset & base
   02. Typography & utilities
   03. Layout
   04. Buttons, chips, tags
   05. Header, nav, drawer
   06. Hero + lineage visual
   07. Trust band
   08. Sections (generic)
   09. Problem
   10. How it works
   11. Product showcase + UI mockups
   12. Pillars
   13. Column-level lineage
   14. Use cases
   15. Flexibility
   16. AI differentiator
   17. Roadmap
   18. Security
   19. Adoption
   20. Contact form
   21. Footer
   22. Motion / reveal
   23. Responsive
   ========================================================================= */

/* ============================================================
   00. DESIGN TOKENS
   ============================================================ */
:root {
  /* Hace animable la transicion a `auto`, que es lo que necesita la apertura
     del acordeon. Los navegadores que no lo entienden lo ignoran. */
  interpolate-size: allow-keywords;

  /* — Color: surfaces — */
  --bg:            #05070D;
  --bg-2:          #070A12;
  --surface:       #0B0F1A;
  --surface-2:     #101623;
  --surface-3:     #141B2B;

  /* — Color: lines — */
  --line:          rgba(255, 255, 255, .07);
  --line-2:        rgba(255, 255, 255, .11);
  --line-3:        rgba(255, 255, 255, .18);

  /* — Color: text (all AA on --bg) — */
  --text:          #E9EEF8;
  --text-2:        #9FABC4;
  --text-3: #8C98B4; /* antes #7C89A6. El encargo pide mas contraste en el texto
                        secundario: de 5.2-5.7:1 pasa a unos 6.5:1 sobre los fondos. */

  /* — Color: accents — */
  --cyan:          #22D3EE;   /* lineage / data flow */
  --blue:          #3B82F6;   /* structure / tables  */
  --violet:        #8B5CF6;   /* AI                  */
  --green:         #34D399;   /* trust / validation  */
  --amber:         #F59E0B;   /* AWS / warning only  */

  --cyan-soft:     rgba(34, 211, 238, .12);
  --blue-soft:     rgba(59, 130, 246, .12);
  --violet-soft:   rgba(139, 92, 246, .13);
  --green-soft:    rgba(52, 211, 153, .12);
  --amber-soft:    rgba(245, 158, 11, .13);

  /* — Typography —
     Sin peticiones a terceros. Si "Inter" / "JetBrains Mono" no están disponibles
     localmente, se usa la tipografía de sistema (Segoe UI Variable, SF Pro, Roboto),
     que mantiene el registro visual. Para auto-alojarlas, ver el bloque @font-face
     al final de este archivo. */
  --font-sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --fs-display: clamp(2.6rem, 5.6vw, 4.6rem);
  --fs-h2:      clamp(1.85rem, 3.3vw, 2.8rem);
  --fs-h3:      clamp(1.05rem, 1.3vw, 1.2rem);
  --fs-lead:    clamp(1.02rem, 1.25vw, 1.18rem);
  --fs-body:    1rem;
  --fs-sm:      .9rem;
  --fs-xs:      .8rem;
  --fs-mono:    .74rem;

  /* — Spacing (4px base) — */
  --s-1: .25rem;  --s-2: .5rem;   --s-3: .75rem;  --s-4: 1rem;
  --s-5: 1.5rem;  --s-6: 2rem;    --s-7: 2.5rem;  --s-8: 3rem;
  --s-9: 4rem;    --s-10: 5rem;   --s-11: 7rem;

  --section-y:   clamp(4.5rem, 9vw, 8.5rem);
  --container:   1280px;
  --gutter:      clamp(1.25rem, 4vw, 2.75rem);

  /* — Radius — */
  --r-xs: 6px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-pill: 999px;

  /* — Shadows — */
  --sh-1: 0 1px 2px rgba(0, 0, 0, .3);
  --sh-2: 0 10px 30px -12px rgba(0, 0, 0, .7);
  --sh-3: 0 30px 70px -30px rgba(0, 0, 0, .85);
  --glow-cyan:   0 0 0 1px rgba(34, 211, 238, .22), 0 12px 40px -18px rgba(34, 211, 238, .35);
  --glow-violet: 0 0 0 1px rgba(139, 92, 246, .22), 0 12px 40px -18px rgba(139, 92, 246, .3);

  /* — Motion — */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --dur:  .5s;

  /* Constantes del sistema de interaccion. Van aqui y no repartidas por el
     fichero para que cambiar el caracter del movimiento sea tocar un sitio.
     Los tres tramos son deliberados: los controles responden rapido, las
     entradas se toman su tiempo y lo ambiental es lento de verdad. */
  --dur-ui:     .22s;   /* hover, foco, pestanas */
  --dur-ui-lg:  .38s;   /* paneles y acordeones */
  --dur-in:     .72s;   /* entradas */
  --float-t:    8.5s;   /* ciclo de flotacion ambiental */
  --tilt-max:   1.2deg; /* inclinacion maxima con el cursor */
  /* Diagrama del hero. Se probo contenido en su columna, hasta 640 px, y se
     quedaba pequeno frente al titular: unos 530 px en una pantalla de 1588.
     Ahora crece hacia la DERECHA, hacia el espacio libre que queda entre el
     contenedor y el borde de la ventana, sin quitarle un pixel al titular.
     --obs-der es ese espacio real -margen del contenedor mas lo que sobra
     fuera de el en pantallas anchas- menos 1rem por la barra de
     desplazamiento, que 100vw incluye. Asi nunca llega a recortarse contra el
     overflow del hero. --obs-izq es un respiro pequeno hacia el hueco entre
     columnas, que nunca alcanza al texto. */
  --obs-max: 780px;
  --obs-izq: clamp(0rem, 1.6vw, 1.5rem);
  --obs-der: min(8rem, calc(var(--gutter) + max(0px, (100vw - var(--container)) / 2) - 1rem));

  /* — Cristal —
     Un solo juego de tokens para todas las superficies de cristal. El
     desenfoque se queda en 18px a proposito: por encima no se gana lectura y
     `backdrop-filter` obliga al navegador a recomponer el fondo en cada
     fotograma. */
  --glass-bg:        rgba(10, 20, 34, .58);
  --glass-bg-strong: rgba(9, 18, 31, .78);
  --glass-border:    rgba(82, 210, 255, .18);
  --glass-highlight: rgba(255, 255, 255, .08);
  --glass-shadow:    0 24px 70px rgba(0, 0, 0, .38);
  --glass-blur:      18px;
}

/* ---------- Cristal ------------------------------------------------------
   Se aplica por JERARQUIA, no por decoracion: superficies que flotan sobre
   otra cosa -cabecera al desplazarse, paneles de evidencia, selectores,
   tooltips-. Nunca sobre parrafos largos, tablas ni capturas del producto,
   donde lo unico que hace es restar lectura.
   ----------------------------------------------------------------------- */

/* `hidden` NO puede perder contra un `display` del autor, y perdia.
   El atributo se aplica con `display: none` desde la hoja del navegador, asi
   que cualquier regla propia que declare `display` lo anula en silencio: el
   panel sigue marcado como oculto -y asi lo reportan el DOM y los lectores de
   pantalla- pero se ve. Paso con `.upanel { display: grid }` en casos de uso,
   donde se veian los seis paneles apilados a la vez.

   Va aqui, global y con `!important`, porque el fallo no se ve al escribir la
   regla que lo causa: se ve seis secciones mas abajo. */
[hidden] { display: none !important; }

.glass-panel {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    var(--glass-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur)) saturate(130%);
}

/* Sin soporte de `backdrop-filter` el panel se queda transparente y el texto
   cae sobre lo que haya debajo. El respaldo es opacidad, no desenfoque. */
@supports not (backdrop-filter: blur(1px)) {
  .glass-panel { background: var(--glass-bg-strong); }
}

/* ============================================================
   01. RESET & BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* Compensacion de la cabecera fija al saltar a un ancla: la cabecera mas un
   respiro, para que el titulo de la seccion no quede debajo.
   Va en scroll-margin-top del destino y no en scroll-padding-top del html.
   Los dos no pueden convivir -se suman-, y el margen tiene una ventaja real:
   tambien lo respeta el desplazamiento que provoca mover el foco con el
   teclado, asi que un control enfocado no acaba escondido tras la cabecera.
   Cabecera medida: 69 px en escritorio, 61 px por debajo de 1024. */
:root { --ancla: 88px; }
[id] { scroll-margin-top: var(--ancla); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-weight: 400;
  letter-spacing: -.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.026em; line-height: 1.1; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
code { font-family: var(--font-mono); font-size: .92em; }

::selection { background: rgba(34, 211, 238, .28); color: #fff; }

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon {
  width: 1.15rem; height: 1.15rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--xs { width: .95rem; height: .95rem; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; top: -100px; left: var(--s-4); z-index: 200;
  background: var(--surface-2); color: var(--text);
  padding: .7rem 1.1rem; border: 1px solid var(--line-2);
  border-radius: var(--r-sm); font-size: var(--fs-sm);
  transition: top .2s var(--ease);
}
.skip-link:focus { top: var(--s-4); }

/* ============================================================
   02. TYPOGRAPHY & UTILITIES
   ============================================================ */
h1 { font-size: var(--fs-display); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -.015em; }

.lead {
  font-size: var(--fs-lead);
  color: var(--text-2);
  line-height: 1.6;
  font-weight: 400;
}

.mono-label {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0;
}
.mono-label--green { color: var(--green); }

.grad-text {
  background: linear-gradient(96deg, var(--cyan) 0%, #6EA8FF 48%, var(--violet) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* ============================================================
   03. LAYOUT
   ============================================================ */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); position: relative; }
/* El fondo alterno tiene que ALTERNAR: dos secciones --alt seguidas suman sus
   bordes y dejan una linea doble. Paso al reordenar el recorrido -Casos y
   Seguridad, FAQ y Contacto quedaron juntas-. Si se mueve una seccion, se
   revisa el orden de los fondos. */
.section--alt { background: var(--bg-2); border-block: 1px solid var(--line); }

.section-head { max-width: 44rem; margin-bottom: clamp(2.5rem, 5vw, 4.5rem); }
.section-head .mono-label { margin-bottom: var(--s-4); }
.section-head__lead { margin-top: var(--s-5); }
.section-head--center { margin-inline: auto; text-align: center; }

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: center;
}
.split--reverse .split__copy { order: 2; }
.split__copy .mono-label { margin-bottom: var(--s-4); }
.split__copy h2 { margin-bottom: var(--s-5); }
.split__copy > p + p { margin-top: var(--s-4); }
.split__copy p:not(.lead):not(.mono-label) { color: var(--text-2); }
/* Una lista de etiquetas detras del texto necesita aire: sin esto las
   pastillas de Column-level lineage quedaban pegadas al parrafo. */
.split__copy > .tag-list { margin-top: var(--s-6); }

/* ============================================================
   04. BUTTONS, CHIPS, TAGS
   ============================================================ */
.btn {
  --btn-bg: transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .7rem 1.15rem;
  font-size: var(--fs-sm); font-weight: 500; letter-spacing: -.01em;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--btn-bg);
  cursor: pointer;
  white-space: nowrap;
  transition: background .22s var(--ease), border-color .22s var(--ease),
              transform .22s var(--ease), box-shadow .22s var(--ease), color .22s var(--ease);
}
.btn .icon { transition: transform .25s var(--ease); }
.btn:hover .icon { transform: translateX(3px); }
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: linear-gradient(180deg, #EDF3FF 0%, #D6E4FB 100%);
  color: #071021;
  border-color: transparent;
  font-weight: 600;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .35) inset, 0 10px 30px -14px rgba(120, 180, 255, .6);
}
.btn--primary:hover {
  background: linear-gradient(180deg, #FFFFFF 0%, #E4EEFF 100%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .5) inset, 0 14px 36px -14px rgba(120, 190, 255, .8);
}

.btn--ghost { color: var(--text); background: rgba(255, 255, 255, .02); }
.btn--ghost:hover { border-color: var(--line-3); background: rgba(255, 255, 255, .05); }

.btn--sm { padding: .5rem .85rem; font-size: var(--fs-xs); }
.btn--lg { padding: .85rem 1.4rem; font-size: 1rem; border-radius: var(--r-md); }
.btn--block { width: 100%; }

.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .32rem .7rem;
  font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: .04em;
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
  background: var(--surface); color: var(--text-2);
  white-space: nowrap;
}
.chip--green  { color: var(--green);  border-color: rgba(52, 211, 153, .3);  background: var(--green-soft); }
.chip--violet { color: #B79BFF;       border-color: rgba(139, 92, 246, .32); background: var(--violet-soft); }
.chip--cyan   { color: var(--cyan);   border-color: rgba(34, 211, 238, .3);  background: var(--cyan-soft); }

.tag {
  display: inline-block;
  padding: .18rem .5rem;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  border-radius: var(--r-xs); border: 1px solid var(--line-2);
  color: var(--text-3); background: rgba(255, 255, 255, .03);
  vertical-align: middle;
}
.tag--green { color: var(--green); border-color: rgba(52, 211, 153, .3); background: var(--green-soft); }
.tag--amber { color: var(--amber); border-color: rgba(245, 158, 11, .3); background: var(--amber-soft); }
.tag--dim   { color: var(--text-3); }
.tag--cyan   { color: var(--cyan);   border-color: rgba(34, 211, 238, .3);  background: var(--cyan-soft); }
.tag--violet { color: #B79BFF;       border-color: rgba(139, 92, 246, .3);  background: var(--violet-soft); }
.tag--roadmap {
  color: #B79BFF; border-color: rgba(139, 92, 246, .3); background: var(--violet-soft);
  margin-left: .5rem; text-transform: none; letter-spacing: .04em;
}

.tag-list { display: flex; flex-wrap: wrap; gap: .5rem; }
.tag-list li {
  padding: .34rem .7rem;
  font-family: var(--font-mono); font-size: var(--fs-mono);
  color: var(--text-2); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
.tag-list--lg li { font-family: var(--font-sans); font-size: var(--fs-sm); padding: .42rem .85rem; }

.check-list { display: grid; gap: .7rem; }
.check-list li {
  display: flex; align-items: flex-start; gap: .6rem;
  font-size: var(--fs-sm); color: var(--text-2);
}
.check-list .icon { margin-top: .3rem; color: var(--text-3); }
.check-list--green .icon { color: var(--green); }

/* Cierre de seccion con pregunta y boton. Uno solo, igual en todas partes:
   centrado y SIN raya encima. Hubo dos variantes -a los lados en Casos,
   centrado en Adopcion- y las dos con una raya que, pegada a la tarjeta o al
   desplegable de encima, se leia como un borde suelto. El espacio ya separa. */
.cta-inline {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: var(--s-4) var(--s-5);
  margin-top: clamp(3rem, 6vw, 4.5rem);
  text-align: center;
}
.cta-inline p { font-size: var(--fs-lead); color: var(--text); }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 2.4rem; height: 2.4rem;
  background: transparent; border: 1px solid var(--line-2);
  border-radius: var(--r-sm); cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.icon-btn:hover { background: rgba(255, 255, 255, .05); border-color: var(--line-3); }

/* ============================================================
   05. HEADER, NAV, DRAWER
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease), backdrop-filter .3s var(--ease);
}
/* Al desplazarse pasa a cristal. Ya se comportaba asi; lo que cambia es que
   los valores salen de los tokens en lugar de estar escritos aqui sueltos, que
   era la unica forma de que la cabecera y el resto de superficies de cristal se
   fueran separando sin que nadie lo notara. */
.site-header.is-scrolled {
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  border-bottom-color: var(--glass-border);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-5);
  height: 68px;
}

.brand { display: inline-flex; align-items: center; gap: .65rem; }
.brand__mark { display: block; width: 32px; height: 32px; }
/* Hueco entre nombre y lema: con solo el interlineado, las dos lineas se
   tocaban. El conjunto sigue midiendo lo mismo que el icono, 32 px. */
.brand__text { display: flex; flex-direction: column; gap: .28rem; line-height: 1.05; }
.brand__name { font-size: .94rem; font-weight: 600; letter-spacing: -.02em; }
.brand__tag {
  font-family: var(--font-mono); font-size: .62rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-3);
}

.nav { display: flex; align-items: center; gap: var(--s-6); }
.nav__list { display: flex; align-items: center; gap: var(--s-5); }
.nav__link {
  position: relative;
  font-size: var(--fs-sm); color: var(--text-2);
  padding-block: .35rem;
  transition: color .2s var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 1px; background: var(--cyan);
  transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease);
}
.nav__link:hover { color: var(--text); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="true"] { color: var(--text); }
.nav__link[aria-current="true"]::after { transform: scaleX(1); }

/* — Selector de idioma —
   Dos enlaces reales, no un conmutador: cada idioma es una URL indexable. El
   activo se marca con aria-current="page", que sirve a la vez de estado visual
   y de anuncio para el lector de pantalla. */
.lang {
  display: flex; align-items: center; gap: 1px;
  padding: 2px;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
}
.lang__opt {
  padding: .2rem .45rem;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .06em;
  color: var(--text-3); text-decoration: none;
  border-radius: calc(var(--r-sm) - 3px);
  transition: color .2s var(--ease), background .2s var(--ease);
}
.lang__opt:hover { color: var(--text); background: var(--surface-2); }
.lang__opt[aria-current="page"] { color: var(--text); background: var(--surface-3); }

/* En el drawer ocupa su propia fila, alineado con el resto del menú. */
.lang--drawer { align-self: flex-start; }

.nav-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem;
  background: transparent; border: 1px solid var(--line-2);
  border-radius: var(--r-sm); cursor: pointer;
}

.drawer { position: fixed; inset: 0; z-index: 150; background: rgba(3, 5, 10, .72); backdrop-filter: blur(4px); }
.drawer[hidden] { display: none; }
.drawer__panel {
  position: absolute; inset: 0 0 auto auto;
  width: min(88vw, 340px); height: 100%;
  display: flex; flex-direction: column; gap: var(--s-5);
  padding: var(--s-5);
  background: var(--surface);
  border-left: 1px solid var(--line-2);
  animation: drawerIn .28s var(--ease);
}
@keyframes drawerIn { from { transform: translateX(18px); opacity: .4; } to { transform: none; opacity: 1; } }
.drawer__head { display: flex; align-items: center; justify-content: space-between; }
.drawer__nav { display: flex; flex-direction: column; flex: 1; }
.drawer__nav a {
  padding: .95rem 0; font-size: 1.05rem; font-weight: 500;
  border-bottom: 1px solid var(--line);
  transition: color .2s var(--ease), padding-left .2s var(--ease);
}
.drawer__nav a:hover { color: var(--cyan); padding-left: 4px; }

/* ============================================================
   06. HERO + LINEAGE VISUAL
   ============================================================ */
.hero { position: relative; padding-block: clamp(3rem, 7vw, 6rem) clamp(4rem, 8vw, 7rem); overflow: hidden; }

.hero__glow {
  position: absolute; inset: -30% 0 auto -10%;
  height: 120%; pointer-events: none;
  background:
    radial-gradient(52rem 34rem at 22% 18%, rgba(34, 211, 238, .10), transparent 65%),
    radial-gradient(46rem 30rem at 78% 8%,  rgba(139, 92, 246, .10), transparent 62%);
}
.hero__grid {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(70% 55% at 50% 22%, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(70% 55% at 50% 22%, #000 0%, transparent 78%);
}

.hero__inner {
  position: relative;
  display: grid;
  /* Dos columnas iguales. Con el titular nuevo -mas largo- y el diagrama
     limitado a 640 px, la columna de texto necesita tanto sitio como la
     imagen; el hueco entre ambas baja un poco para que las dos lleguen a
     unos 568 px a 1440 y 564 a 1280, dentro del rango del diagrama. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 3.8vw, 3.5rem);
  align-items: center;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-2);
  padding: .38rem .8rem .38rem .7rem;
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .025);
}
.eyebrow__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--cyan); box-shadow: 0 0 0 3px rgba(34, 211, 238, .18);
}

/* Titular del hero. Es el doble de largo que el anterior -60 caracteres en
   espanol y 78 en ingles, frente a 31-, asi que con la escala de --fs-display
   (73 px a 1440) ocupaba cinco lineas en espanol y seis en ingles y empujaba
   los botones por debajo del pliegue. Se baja la escala sin perder
   contundencia, y cada idioma lleva la suya: el ingles es un 30 % mas largo.

   Contra las palabras sueltas en la ultima linea no se confia solo en
   `text-wrap: balance`: el contenido une las dos ultimas palabras con un
   espacio de no separacion (si&nbsp;cambia / it&nbsp;changes), que funciona
   en cualquier navegador. */
.hero__title {
  margin-top: var(--s-5); line-height: 1.04; text-wrap: balance;
  font-size: clamp(2.4rem, 4.1vw, 3.6rem);
}
/* La regla inglesa va acotada a partir de 761 px. Es mas especifica que las
   de movil (clase + :lang), asi que sin acotarla pisaria el tamano de movil
   en /en/. */
@media (min-width: 761px) {
  .hero__title:lang(en) { font-size: clamp(2.3rem, 3.8vw, 3.3rem); }
}
/* La palabra destacada es UNA unidad y no se puede partir por dentro. Se partia:
   a 1440 el titular caia como «Entiende como / se mueve tu / dato.», con «dato.»
   sola en su linea y la unidad rota justo por la mitad. Vale para los dos
   idiomas, porque en ingles el span es «your data» y tiene el mismo problema.
   `text-wrap: balance` de arriba reparte el resto de lineas; donde no hay
   soporte se ignora y no rompe nada. */
.hero__title .grad-text { white-space: nowrap; }
.hero__sub { margin-top: var(--s-5); max-width: 34rem; }

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-7); }

/* Los cuatro conceptos. Lista y no parrafo con puntos medios: son cuatro
   elementos de la misma clase, que es justo lo que describe una lista, y asi el
   separador es cosa del CSS y no un caracter que un lector de pantalla tenga
   que leer en voz alta.

   Cada uno lleva su punto luminoso y un divisor tenue entre ellos, para que
   dejen de parecer una linea de texto sobrante. Cuatro puntos, no cuatro
   botones: siguen siendo respaldo del titular, no acciones. */
.hero__trust {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .4rem 1rem;
  margin-top: var(--s-6);
  padding: 0; list-style: none;
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .08em; color: var(--text-3);
}
.hero__trust li {
  display: inline-flex; align-items: center; gap: .5rem;
}
.hero__trust li::before {
  content: ""; flex: none;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 0 2.5px rgba(34, 211, 238, .16);
}
/* SIN divisor vertical. Se probo con `border-left` en `li + li` y el resultado
   fue peor que el problema: cuando la lista envuelve -y a 1440 envuelve, con
   «Human validation» sola en la segunda linea- el elemento que abre la linea
   nueva arrastra su borde y aparece una raya suelta a la izquierda, colgando de
   nada. El CSS no sabe cual es el primero de CADA linea, solo el primero de la
   lista, asi que no hay forma de apagarlo ahi.
   Los puntos luminosos ya separan de sobra. */

/* ---------- Observatorio del hero ---------------------------------------
   El recurso es un PNG/WebP con transparencia REAL, asi que no lleva caja ni
   fondo propio: lo que hay detras -el resplandor del hero y la reticula- se ve
   a traves del cristal del dibujo. Meterle un panel opaco detras destruiria
   justo lo que lo hace bueno.
   ----------------------------------------------------------------------- */

.observatory {
  position: relative;
  margin: 0;
  width: calc(100% + var(--obs-izq) + var(--obs-der));
  max-width: var(--obs-max);
  margin-right: calc(var(--obs-der) * -1);
  justify-self: end;
}

.observatory__img {
  display: block;
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  /* `contain` y no `cover`: recortar este dibujo se come las tarjetas laterales
     o la banda inferior, que son parte del argumento. */
  object-fit: contain;
}

/* Sin resplandor detras del diagrama. Hubo dos degradados radiales
   difuminados (.observatory__aura) para que el cristal se leyera sobre el
   negro; se retiraron a peticion de Gregorio, tras verlo sin ellos: los
   brillos de las tarjetas ya vienen dibujados en la imagen, y el halo solo
   anadia una mancha rectangular alrededor. */
.observatory__note {
  position: relative;
  z-index: 1;
  margin-top: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: .06em;
  color: var(--text-3);
}


/* ---------- Movimiento del observatorio ---------------------------------
   Tres capas separadas a proposito, porque se apagan por separado:

     1. ENTRADA. Una vez, al cargar. Opacidad, 16px de subida y 0.98 de escala.
        Sin rebote: la imagen representa infraestructura de datos y tiene que
        transmitir estabilidad, no elasticidad.
     2. FLOTACION. Continua, 4px y un ciclo de 8.5s. Al limite de lo
        perceptible, que es el punto: si se nota, distrae de leer el titular.
     3. INCLINACION con el cursor. La pone el JS en --tilt-x / --tilt-y.

   Las tres viven en `transform` y `opacity`, que no provocan relayout. La
   flotacion va en un envoltorio distinto de la inclinacion para que no se
   pisen: si compartieran `transform`, la ultima en escribirse ganaria.
   ----------------------------------------------------------------------- */

.observatory {
  /* Valores neutros. El JS solo los sobrescribe si hay puntero preciso. */
  --tilt-x: 0deg;
  --tilt-y: 0deg;
  perspective: 1400px;
}

.observatory__img {
  transform-style: preserve-3d;
  transform: rotateX(var(--tilt-x)) rotateY(var(--tilt-y));
  transition: transform .9s var(--ease);
  animation:
    obsEntrada var(--dur-in) var(--ease) both,
    obsFlota var(--float-t) ease-in-out 1.2s infinite;
}

@keyframes obsEntrada {
  from { opacity: 0; transform: translateY(16px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes obsFlota {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -4px; }
}

/* Movimiento reducido: se apaga lo continuo y la entrada, y se conserva el
   estado visual. El recurso NO se oculta, que seria peor que animarlo. */
@media (prefers-reduced-motion: reduce) {
  .observatory__img {
    animation: none;
    transform: none;
    transition: none;
  }
}

/* edges */
.edges .edge { stroke: url(#edgeCyan); stroke-dasharray: 5 6; opacity: .9; }
.edges .edge--out { stroke: url(#edgeViolet); }
.edges .edge--far { stroke: url(#edgeCyan); opacity: .7; }

/* nodes */
.node { cursor: default; }
.node__box {
  fill: var(--surface-2);
  stroke: var(--line-2);
  stroke-width: 1;
  transition: stroke .25s var(--ease), fill .25s var(--ease);
}
.node__type {
  font-family: var(--font-mono); font-size: 7.5px;
  letter-spacing: .12em; fill: var(--text-3);
}
.node__name {
  font-family: var(--font-mono); font-size: 9.5px;
  fill: var(--text); letter-spacing: -.01em;
}
.node__meta { font-family: var(--font-mono); font-size: 7.5px; fill: var(--green); }

.node--s3       .node__accent { fill: var(--green); }
.node--table    .node__accent { fill: var(--blue); }
.node--glue     .node__accent { fill: var(--violet); }
.node--lambda   .node__accent { fill: var(--amber); }
.node--redshift .node__accent { fill: var(--cyan); }
.node--athena   .node__accent { fill: #6EA8FF; }

.node:hover .node__box,
.node:focus-visible .node__box { fill: var(--surface-3); stroke: rgba(34, 211, 238, .5); }
.node:focus-visible { outline: none; }

/* Nodo seleccionado: es el que describe el panel de detalle de debajo. */
.node.is-selected .node__box {
  fill: var(--surface-3);
  stroke: rgba(34, 211, 238, .75);
  stroke-width: 1.4;
}

/* ============================================================
   07. TRUST BAND
   ============================================================ */
.band { border-block: 1px solid var(--line); background: var(--bg-2); }
.band__inner { padding-block: var(--s-5); }
.band__list {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-4) clamp(1.5rem, 4vw, 3.5rem);
  justify-content: space-between;
}
.band__list li {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-3);
  transition: color .25s var(--ease);
}
.band__list li:hover { color: var(--text-2); }

.logo-band { display: flex; flex-wrap: wrap; gap: var(--s-6); align-items: center; }
.logo-band img { height: 26px; width: auto; opacity: .65; filter: grayscale(1); }

/* ============================================================
   09. PROBLEM
   ============================================================ */
.questions {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
.questions__list { display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }

/* Las preguntas son BOTONES, no elementos de lista: al pulsarlas pasa algo.
   Eso obliga a deshacer los estilos que trae el navegador -tipografia propia,
   centrado, borde- porque si no cada una parece un boton de formulario. */
.question {
  /* `relative` es obligatorio, no decorativo: `.question__n` va en absoluto y
     es hermano de `.question__q`, asi que sin esto se anclaba al primer
     antepasado posicionado -muy arriba en el arbol- y los seis numeros
     aparecian amontonados en una esquina de la pagina. */
  position: relative;
  display: block; width: 100%;
  margin: 0; padding: 0;
  font: inherit; text-align: left;
  background: var(--bg); border: 0; cursor: pointer;
  transition: background var(--dur-ui) var(--ease);
}
.question:hover { background: var(--surface); }
.question:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

.question__q {
  display: block; padding: 1.05rem var(--s-4) 1.05rem 0;
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  font-weight: 500; color: var(--text-2);
  position: relative; padding-left: 3.1rem;
  transition: color var(--dur-ui) var(--ease), padding-left var(--dur-ui) var(--ease);
}
/* El numero sustituye al interrogante suelto que habia antes: con seis
   opciones seleccionables, saber en cual estas importa mas que decorar. */
.question__n {
  position: absolute; left: .85rem; top: 1.25rem;
  font-family: var(--font-mono); font-size: .72rem;
  color: var(--text-3); transition: color var(--dur-ui) var(--ease);
}
.question:hover .question__q { color: var(--text); padding-left: 3.35rem; }

/* El estado activo NO se comunica solo con color: lleva ademas una barra a la
   izquierda y el numero encendido. Quien no distinga el matiz de gris sigue
   viendo cual esta elegida. */
.question[aria-selected="true"] { background: var(--surface); }
.question[aria-selected="true"] .question__q {
  color: var(--text);
  box-shadow: inset 2px 0 0 var(--cyan);
}
.question[aria-selected="true"] .question__n { color: var(--cyan); }

/* — Panel de respuesta — */
.qanswer { animation: qaEntra var(--dur-ui-lg) var(--ease) both; }
@keyframes qaEntra {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.qanswer__label {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-3);
}
.qanswer__text { margin-top: var(--s-3); color: var(--text-2); line-height: 1.65; }

.qanswer__feature {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem .75rem;
  margin-top: var(--s-4); padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}
.qanswer__feature-label {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-3);
}
.qanswer__feature-name { font-size: var(--fs-sm); color: var(--cyan); }

/* — La ruta de linaje —
   Un solo SVG por panel, y lo que cambia es que tramo se enciende. El estado
   base es apagado: asi «encendido» significa algo. */
.qroute { margin-top: var(--s-4); }
.qroute__svg { display: block; width: 100%; height: auto; }
.qroute__node rect { fill: var(--surface); stroke: var(--line-2); stroke-width: 1; }
.qroute__node text { fill: var(--text-3); font-family: var(--font-mono); font-size: 9px; }
.qroute__col { font-size: 8px !important; opacity: .75; }
.qroute__edge { stroke: var(--line-2); stroke-dasharray: 4 5; }

.qroute__node rect, .qroute__node text, .qroute__edge {
  transition: fill var(--dur-ui-lg) var(--ease), stroke var(--dur-ui-lg) var(--ease), opacity var(--dur-ui-lg) var(--ease);
}

/* Que se enciende con cada pregunta. El atributo lo pone el JS en el
   contenedor; aqui solo esta escrito que significa cada valor. */
.qanswer[data-focus="upstream"] .qroute__node--source rect,
.qanswer[data-focus="process"] .qroute__node--process rect,
.qanswer[data-focus="runs"]    .qroute__node--process rect,
.qanswer[data-focus="column"]  .qroute__node--table rect,
.qanswer[data-focus="downstream"] .qroute__node--sink rect,
.qanswer[data-focus="trust"]   .qroute__node--process rect {
  stroke: var(--cyan); fill: rgba(34, 211, 238, .08);
}
.qanswer[data-focus="upstream"] .qroute__node--source text,
.qanswer[data-focus="process"] .qroute__node--process text,
.qanswer[data-focus="runs"]    .qroute__node--process text,
.qanswer[data-focus="column"]  .qroute__node--table text,
.qanswer[data-focus="downstream"] .qroute__node--sink text,
.qanswer[data-focus="trust"]   .qroute__node--process text { fill: var(--text); }

.qanswer[data-focus="upstream"] .qroute__edge--in,
.qanswer[data-focus="process"] .qroute__edge--out,
.qanswer[data-focus="column"] .qroute__edge--out,
.qanswer[data-focus="downstream"] .qroute__edge--far,
.qanswer[data-focus="trust"] .qroute__edge--in { stroke: var(--cyan); stroke-dasharray: none; }

/* La columna solo se destaca en la pregunta que va de columnas. */
.qanswer[data-focus="column"] .qroute__col { fill: var(--violet); opacity: 1; }

/* — La misma ruta en CASOS DE USO —
   Cada caso enciende SU tramo, y ninguno repite el de otro: si dos casos
   encendieran lo mismo, al pasar de uno a otro no cambiaria nada y pareceria
   roto. Asi estuvo: los paneles traian data-focus pero solo habia reglas
   para EL PROBLEMA, y el diagrama no se movia nunca.

     impact        la tabla que se toca y todo lo que cuelga de ella
     governance    de donde sale el dato hasta la tabla que se gobierna
     discovery     todo: que hay montado y como se relaciona
     troubleshoot  del dato malo al proceso que lo escribio
     migrate       el proceso que se migra y todo lo que depende de el
     evidence      las relaciones, no las cajas, y la columna en violeta

   Al elegir un caso el tramo se enciende en el sentido en que corre el dato,
   caja a caja: el retardo va por posicion en la ruta, no por caso. */
.qroute__node--source  { --d: 0s; }
.qroute__edge--in      { --d: .08s; }
.qroute__node--process { --d: .16s; }
.qroute__edge--out     { --d: .24s; }
.qroute__node--table   { --d: .32s; }
.qroute__edge--far     { --d: .40s; }
.qroute__node--sink    { --d: .48s; }

.upanel[data-focus="impact"]       :is(.qroute__node--table, .qroute__node--sink) rect,
.upanel[data-focus="governance"]   :is(.qroute__node--source, .qroute__node--process, .qroute__node--table) rect,
.upanel[data-focus="discovery"]    .qroute__node rect,
.upanel[data-focus="troubleshoot"] :is(.qroute__node--process, .qroute__node--table) rect,
.upanel[data-focus="migrate"]      :is(.qroute__node--process, .qroute__node--table, .qroute__node--sink) rect {
  stroke: var(--cyan); fill: rgba(34, 211, 238, .08);
  animation: qrNodo .45s var(--ease) var(--d, 0s) both;
}
.upanel[data-focus="impact"]       :is(.qroute__node--table, .qroute__node--sink) text,
.upanel[data-focus="governance"]   :is(.qroute__node--source, .qroute__node--process, .qroute__node--table) text,
.upanel[data-focus="discovery"]    .qroute__node text,
.upanel[data-focus="troubleshoot"] :is(.qroute__node--process, .qroute__node--table) text,
.upanel[data-focus="migrate"]      :is(.qroute__node--process, .qroute__node--table, .qroute__node--sink) text {
  fill: var(--text);
  animation: qrTexto .45s var(--ease) var(--d, 0s) both;
}
.upanel[data-focus="impact"]       .qroute__edge--far,
.upanel[data-focus="governance"]   :is(.qroute__edge--in, .qroute__edge--out),
.upanel[data-focus="discovery"]    .qroute__edge,
.upanel[data-focus="troubleshoot"] .qroute__edge--out,
.upanel[data-focus="migrate"]      :is(.qroute__edge--out, .qroute__edge--far),
.upanel[data-focus="evidence"]     .qroute__edge {
  stroke: var(--cyan); stroke-dasharray: 80;
  animation: qrArista .5s var(--ease) var(--d, 0s) both;
}
.upanel[data-focus="evidence"] .qroute__col { fill: var(--violet); opacity: 1; }

/* Los keyframes solo dicen de donde parte: el final es el estado encendido
   de arriba. La arista se dibuja de izquierda a derecha -raya de 80 sobre
   tramos de 56, desplazada hasta cero-. */
@keyframes qrNodo   { from { stroke: var(--line-2); fill: var(--surface); } }
@keyframes qrTexto  { from { fill: var(--text-3); } }
@keyframes qrArista { from { stroke-dashoffset: 80; } to { stroke-dashoffset: 0; } }

/* Las cuatro notas bajan a una banda propia: antes ocupaban la columna derecha,
   que ahora es de las respuestas. */
/* ---------- Como funciona: recorrido de cinco etapas --------------------
   Stepper horizontal en escritorio, vertical en movil. La escena es UNA y las
   cinco etapas la encienden por zonas: `data-active` lo pone el selector
   generico en la raiz y aqui solo esta escrito que significa cada valor.
   ----------------------------------------------------------------------- */

.flow { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

.flow__tabs {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
.fstep {
  display: flex; flex-direction: column; gap: .3rem;
  padding: var(--s-4) var(--s-3);
  font: inherit; text-align: left; cursor: pointer;
  background: var(--bg); border: 0;
  /* La barra superior marca la etapa activa ADEMAS del color. Sin ella, el
     estado se comunicaria solo por matiz. */
  box-shadow: inset 0 2px 0 transparent;
  transition: background var(--dur-ui) var(--ease), box-shadow var(--dur-ui) var(--ease);
}
.fstep:hover { background: var(--surface); }
.fstep:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }
.fstep__num { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-3); }
.fstep__title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.fstep[aria-selected="true"] {
  background: var(--surface);
  box-shadow: inset 0 2px 0 var(--cyan);
}
.fstep[aria-selected="true"] .fstep__num { color: var(--cyan); }
.fstep[aria-selected="true"] .fstep__title { color: var(--text); }

.flow__stage {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
  margin-top: clamp(2rem, 4vw, 3rem);
}

.flow__svg { display: block; width: 100%; height: auto; }

/* Estado base: todo apagado. Que una zona se encienda significa algo solo si
   las demas no lo estan. */
.flow__z { opacity: .32; transition: opacity var(--dur-ui-lg) var(--ease); }
.flow__cap { fill: var(--text-3); font-family: var(--font-mono); font-size: 8px; letter-spacing: .1em; }
.flow__chip rect { fill: var(--surface); stroke: var(--line-2); }
.flow__chip text { fill: var(--text-2); font-family: var(--font-mono); font-size: 9px; }
.flow__card { fill: var(--surface); stroke: var(--line-2); }
.flow__code { fill: var(--text-3); font-family: var(--font-mono); font-size: 8.5px; }
.flow__track { fill: var(--line-2); }
.flow__fill { fill: var(--cyan); opacity: .5; }
.flow__ok { fill: var(--green, #34D399); font-family: var(--font-mono); font-size: 9px; }
.flow__edges { stroke: var(--line-2); stroke-dasharray: 4 5; }
.flow__gnode rect { fill: var(--surface); stroke: var(--line-2); }
.flow__gnode text { fill: var(--text-2); font-family: var(--font-mono); font-size: 8.5px; }
.flow__chip rect, .flow__card, .flow__edges, .flow__gnode rect, .flow__fill {
  transition: stroke var(--dur-ui-lg) var(--ease), fill var(--dur-ui-lg) var(--ease), opacity var(--dur-ui-lg) var(--ease);
}

/* 01 Discover — se enciende el inventario. */
[data-flow][data-active="0"] .flow__z--inv { opacity: 1; }
[data-flow][data-active="0"] .flow__chip rect { stroke: var(--cyan); }

/* 02 Select — el inventario sigue, pero solo los elegidos destacan. */
[data-flow][data-active="1"] .flow__z--inv { opacity: 1; }
[data-flow][data-active="1"] .flow__chip[data-pick] rect { stroke: var(--cyan); fill: rgba(34, 211, 238, .1); }
[data-flow][data-active="1"] .flow__chip[data-pick] text { fill: var(--text); }

/* 03 Analyze — el codigo. */
[data-flow][data-active="2"] .flow__z--proc { opacity: 1; }
[data-flow][data-active="2"] .flow__card { stroke: var(--cyan); }
[data-flow][data-active="2"] .flow__code { fill: var(--text-2); }

/* 04 Validate — confianza y evidencia. */
[data-flow][data-active="3"] .flow__z--conf { opacity: 1; }
[data-flow][data-active="3"] .flow__fill { opacity: 1; }

/* 05 Explore — el grafo publicado, con las aristas ya firmes. */
[data-flow][data-active="4"] .flow__z--graph { opacity: 1; }
[data-flow][data-active="4"] .flow__edges { stroke: var(--cyan); stroke-dasharray: none; }
[data-flow][data-active="4"] .flow__gnode rect { stroke: var(--cyan); }
[data-flow][data-active="4"] .flow__gnode text { fill: var(--text); }

.fpanel { animation: qaEntra var(--dur-ui-lg) var(--ease) both; }
.fpanel__progress {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .1em; color: var(--text-3);
}
.fpanel__progress b { color: var(--cyan); font-weight: 400; }
.fpanel__title { margin-top: var(--s-3); font-size: 1.35rem; }
.fpanel__body { margin-top: var(--s-3); color: var(--text-2); line-height: 1.65; }

@media (prefers-reduced-motion: reduce) {
  .fpanel, .qanswer { animation: none; }
}

/* Movil y tablet: el stepper se apila y la escena baja. Sin sticky, sin hover y
   sin bloquear el scroll: en una pantalla estrecha una seccion pegada de esta
   altura secuestra la pagina. */
@media (max-width: 860px) {
  .flow__tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow__stage { grid-template-columns: 1fr; }
  .flow__viz { order: 2; }
  .flow__panels { order: 1; }
}
@media (max-width: 480px) {
  .flow__tabs { grid-template-columns: 1fr; }
}

.problem-notes {
  display: grid; gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  margin-top: clamp(3rem, 6vw, 5rem);
}
/* Sin raya encima del bloque: la lista de preguntas ya cierra con la suya a
   un palmo, y cada nota lleva su propia linea izquierda. Con las tres quedaba
   una linea doble en la mitad izquierda. */
.problem-note { padding-left: var(--s-4); border-left: 2px solid var(--line-2); transition: border-color .25s var(--ease); }
.problem-note:hover { border-left-color: var(--cyan); }
.problem-note h3 { font-size: 1rem; margin-bottom: .3rem; }
.problem-note p { font-size: var(--fs-sm); color: var(--text-2); }

/* ============================================================
   10. HOW IT WORKS
   ============================================================ */
.steps {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--s-5);
  position: relative;
}
.steps::before {
  content: ""; position: absolute; left: 0; right: 0; top: 15px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-2) 8%, var(--line-2) 92%, transparent);
}
.step { position: relative; padding-top: var(--s-7); }
.step__num {
  position: absolute; top: 0; left: 0;
  display: inline-grid; place-items: center;
  width: 31px; height: 31px;
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .02em;
  color: var(--text-2);
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 50%;
  transition: color .25s var(--ease), border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.step:hover .step__num { color: var(--cyan); border-color: rgba(34, 211, 238, .5); box-shadow: 0 0 0 4px rgba(34, 211, 238, .08); }
.step__title { margin-bottom: .45rem; }
.step p { font-size: var(--fs-sm); color: var(--text-2); }

/* ============================================================
   11. PRODUCT SHOWCASE + UI MOCKUPS
   ============================================================ */
.showcase__tabs {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-bottom: var(--s-5);
}
.tab {
  padding: .5rem .9rem;
  font-size: var(--fs-xs); font-weight: 500; color: var(--text-3);
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
.tab:hover { color: var(--text-2); border-color: var(--line-2); }
.tab[aria-selected="true"] {
  color: var(--text); background: var(--surface-2); border-color: var(--line-3);
}

.showcase__note {
  margin-top: var(--s-4);
  font-family: var(--font-mono); font-size: var(--fs-mono);
  line-height: 1.6; color: var(--text-3); max-width: 44rem;
}

.showcase__layout {
  display: grid;
  grid-template-columns: minmax(0, 2.05fr) minmax(0, 1fr);
  gap: var(--s-5);
  align-items: start;
}
.showcase__side { display: grid; gap: var(--s-5); }

/* — Frame chrome — */
.frame {
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-3);
}
.frame--lg { box-shadow: var(--sh-3), var(--glow-cyan); }
.frame__bar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: .6rem .85rem;
  background: rgba(255, 255, 255, .022);
  border-bottom: 1px solid var(--line);
}
.frame__dots { display: inline-flex; gap: 5px; }
.frame__dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line-3); }
.frame__title {
  font-family: var(--font-mono); font-size: .66rem;
  letter-spacing: .04em; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.frame__body { padding: var(--s-4); }
.frame[hidden] { display: none; }
.frame:focus-visible { outline-offset: 2px; }

/* — Explorer mock — */
.mock-toolbar { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: var(--s-4); }
.mock-chip {
  padding: .28rem .6rem;
  font-family: var(--font-mono); font-size: .64rem; color: var(--text-3);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-xs);
}
.mock-chip--active { color: var(--text-2); border-color: var(--line-2); }
.mock-chip--violet { color: #B79BFF; border-color: rgba(139, 92, 246, .3); background: var(--violet-soft); }

.mock-explorer {
  display: grid; grid-template-columns: minmax(0, 1fr) 200px; gap: var(--s-4);
  align-items: start;
}
.mock-graph { width: 100%; height: auto; }
.mock-nodes .mn { fill: var(--surface-2); stroke: var(--line-2); stroke-width: 1; }
.mock-nodes .mn--table    { stroke: rgba(59, 130, 246, .45); }
.mock-nodes .mn--s3       { stroke: rgba(52, 211, 153, .4); }
.mock-nodes .mn--glue     { stroke: rgba(139, 92, 246, .5); fill: var(--surface-3); }
.mock-nodes .mn--lambda   { stroke: rgba(245, 158, 11, .4); fill: var(--surface-3); }
.mock-nodes .mn--redshift { stroke: rgba(34, 211, 238, .45); }

.mock-labels .lb { fill: rgba(255, 255, 255, .22); }
.mock-labels .lb--dim { fill: rgba(255, 255, 255, .1); }
.mock-labels .ld--table    { fill: var(--blue); }
.mock-labels .ld--s3       { fill: var(--green); }
.mock-labels .ld--glue     { fill: var(--violet); }
.mock-labels .ld--lambda   { fill: var(--amber); }
.mock-labels .ld--redshift { fill: var(--cyan); }

.mock-inspector {
  padding: var(--s-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.mock-inspector__title { margin-top: .6rem; font-family: var(--font-mono); font-size: .8rem; color: var(--text); }
.mock-inspector__sub { font-size: .68rem; color: var(--text-3); margin-top: .15rem; }
.mock-inspector__label { margin-top: var(--s-4); }

.meter { margin-top: var(--s-4); }
.meter__head {
  display: flex; justify-content: space-between;
  font-size: .68rem; color: var(--text-3); margin-bottom: .35rem;
}
.meter__val { color: var(--green); font-family: var(--font-mono); }
.meter__track { height: 4px; background: rgba(255, 255, 255, .07); border-radius: var(--r-pill); overflow: hidden; }
.meter__fill { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--green)); border-radius: inherit; }

.mock-evidence { display: grid; gap: .4rem; margin-top: .5rem; }
.mock-evidence li { font-size: .64rem; color: var(--text-2); line-height: 1.45; }
.mock-evidence code { color: var(--cyan); font-size: .62rem; }

.mock-actions { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: var(--s-4); }
.mock-btn {
  padding: .28rem .55rem; font-size: .62rem;
  border: 1px solid var(--line-2); border-radius: var(--r-xs); color: var(--text-2);
}
.mock-btn--green { color: var(--green); border-color: rgba(52, 211, 153, .35); background: var(--green-soft); }
.mock-btn--muted { color: var(--text-3); }

/* — Dashboard mock — */
.mock-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); }
.kpi { padding: var(--s-3); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md); }
.kpi__label { font-size: .64rem; color: var(--text-3); line-height: 1.3; }
.kpi__value { margin-top: .3rem; font-size: 1.55rem; font-weight: 600; letter-spacing: -.03em; }
.kpi__value--green { color: var(--green); }

.mock-dash { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); margin-top: var(--s-3); }
.mock-panel { padding: var(--s-4); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md); }

.mock-bars { display: grid; gap: .55rem; margin-top: var(--s-3); }
.mock-bars li { display: grid; grid-template-columns: 66px 1fr 18px; align-items: center; gap: .5rem; font-size: .66rem; color: var(--text-3); }
.mock-bars b { color: var(--text-2); font-weight: 500; text-align: right; font-family: var(--font-mono); font-size: .64rem; }
.bar { height: 4px; background: rgba(255, 255, 255, .07); border-radius: var(--r-pill); overflow: hidden; }
.bar i { display: block; height: 100%; background: linear-gradient(90deg, rgba(59, 130, 246, .8), var(--cyan)); }

.mock-status { display: grid; gap: .45rem; margin-top: var(--s-3); }
.mock-status li { display: flex; align-items: center; gap: .5rem; font-size: .68rem; color: var(--text-2); }
.mock-status b { margin-left: auto; font-family: var(--font-mono); font-size: .66rem; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); flex: none; }
.dot--green { background: var(--green); }
.dot--amber { background: var(--amber); }
.dot--dim   { background: var(--text-3); }
.dot--red   { background: #F87171; }

.spark { width: 100%; height: 46px; margin-top: .5rem; }
.spark__line { stroke: var(--cyan); stroke-width: 1.4; stroke-linecap: round; }

/* — Discovery mock — */
.mock-stepper { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: var(--s-4); }
.mock-step {
  padding: .3rem .6rem; font-family: var(--font-mono); font-size: .62rem;
  color: var(--text-3); border: 1px solid var(--line); border-radius: var(--r-xs);
}
.mock-step.is-active { color: var(--cyan); border-color: rgba(34, 211, 238, .4); background: var(--cyan-soft); }

.mock-services { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }
.svc {
  display: grid; grid-template-columns: 1fr auto; gap: .15rem .5rem;
  padding: .55rem .65rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm);
}
.svc__name { font-size: .68rem; color: var(--text-2); }
.svc__n { font-family: var(--font-mono); font-size: .68rem; color: var(--text); }
.svc__ok { grid-column: 1 / -1; font-family: var(--font-mono); font-size: .58rem; color: var(--green); letter-spacing: .06em; }
.svc__ok--muted { color: var(--text-3); }
.svc--empty { opacity: .6; }

.mock-summary {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3);
  margin-top: var(--s-3); padding-top: var(--s-4); border-top: 1px solid var(--line);
}
.mock-summary__v { font-size: 1.25rem; font-weight: 600; letter-spacing: -.02em; margin-top: .2rem; }
.mock-summary__v--sm { font-size: .82rem; color: var(--cyan); font-family: var(--font-mono); }

.mock-kpis--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.mock-kpis--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
/* Ocho KPI en la pantalla de Linaje. A este ancho las etiquetas son de dos
   lineas, asi que el valor baja de cuerpo: caben los ocho sin que ninguno se
   parta. */
.mock-kpis--8 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.mock-kpis--8 .kpi { padding: .5rem .55rem; }
.mock-kpis--8 .kpi__value { font-size: 1rem; margin-top: .15rem; }
.mock-kpis--8 .kpi__label { font-size: .58rem; }

/* Rotulo del grupo ADMINISTRACION dentro de la tira de pestanas. No es un
   tab: no se pulsa, no entra en el recorrido con flechas y va oculto a
   lectores, porque el menu del producto lo usa como separador visual. */
.showcase__tabs-group {
  align-self: center;
  padding-left: .55rem;
  margin-left: .2rem;
  border-left: 1px solid var(--line);
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3);
}

/* Pestanas del inspector. Son cinco en el producto; aqui solo se muestran para
   que se vea que la evidencia es UNA de ellas y no todo lo que hay. */
.mock-subtabs { display: flex; flex-wrap: wrap; gap: .3rem; margin: .35rem 0 .5rem; }
.mock-subtab {
  font-family: var(--font-mono); font-size: .55rem; color: var(--text-3);
  padding: .12rem .3rem; border-bottom: 1px solid transparent;
}
.mock-subtab--active { color: var(--text-2); border-bottom-color: var(--line-2); }

.mock-inspector__explore {
  margin-top: .5rem; font-family: var(--font-mono);
  font-size: .55rem; color: var(--text-3);
}

/* Preguntas que propone el Copilot. Van como lista y no como botones falsos:
   no se puede pulsar nada en una maqueta, y fingir lo contrario invita a
   intentarlo. */
.mock-suggest { display: grid; gap: .4rem; margin-top: var(--s-3); }
.mock-suggest li {
  font-size: .66rem; color: var(--text-3);
  padding: .3rem .5rem;
  background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r-xs);
}

/* Aviso de validacion de cuenta. Ambar y no rojo: la cuenta ES valida, solo
   que con menos permisos de los ideales, y el escaneo puede lanzarse. Pintarlo
   de error diria que algo se ha roto, y no se ha roto nada. */
.mock-notice {
  margin-top: var(--s-3);
  padding: .5rem .65rem;
  font-size: .66rem; line-height: 1.5; color: var(--text-2);
  background: rgba(245, 158, 11, .06);
  border: 1px solid rgba(245, 158, 11, .25);
  border-radius: var(--r-xs);
}
.kpi__pct { font-size: .58rem; color: var(--text-3); margin-top: .1rem; }

.mock-stages { display: grid; gap: .45rem; margin-top: var(--s-3); }
.mock-stages li {
  display: flex; align-items: center; justify-content: space-between;
  padding: .35rem .55rem;
  font-size: .68rem; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xs);
}
.mock-stages b { font-family: var(--font-mono); font-size: .66rem; color: var(--text); }
/* Las relaciones ENTRE etapas: el mapa sin ellas es una lista de servicios. */
.mock-stages__rel {
  margin-top: var(--s-3);
  font-family: var(--font-mono); font-size: .6rem; color: var(--text-3); line-height: 1.5;
}

/* — Connections mock — */
.mock-conns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
.mock-conns--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mock-conn {
  padding: var(--s-4);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md);
}
.mock-conn__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.mock-conn__name { font-family: var(--font-mono); font-size: .8rem; color: var(--text); }
.mock-conn__mode {
  margin-top: .2rem;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--cyan);
}
.mock-conn .mock-kv { margin-top: var(--s-3); }
.mock-caps { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: var(--s-3); }
.mock-chip--warn { color: var(--amber); border-color: rgba(245, 158, 11, .35); background: var(--amber-soft); }
.mock-chip--ok   { color: var(--green); border-color: rgba(52, 211, 153, .35); background: var(--green-soft); }

@media (max-width: 1100px) {
  .mock-kpis--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .mock-kpis--5,
  .mock-kpis--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-conns,
  .mock-conns--3 { grid-template-columns: 1fr; }
}

/* — Validation mock — */
.mock-table { width: 100%; border-collapse: collapse; }
.mock-table th {
  text-align: left; padding: .45rem .5rem;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-3); font-weight: 400;
  border-bottom: 1px solid var(--line-2);
}
.mock-table td {
  padding: .6rem .5rem; font-size: .7rem; color: var(--text-2);
  border-bottom: 1px solid var(--line);
}
.mock-table code { color: var(--text); font-size: .68rem; }
.mock-table tr:hover td { background: rgba(255, 255, 255, .018); }
.pct { font-family: var(--font-mono); font-size: .68rem; }
.pct--high { color: var(--green); }
.pct--mid  { color: var(--amber); }
.pct--low  { color: var(--text-3); }
.mock-foot { margin-top: var(--s-3); font-size: .68rem; color: var(--text-3); }

/* — Copilot mock — */
/* El chat es un HILO: una sola columna donde los mensajes se apilan y cada uno
   se alinea a su lado -la pregunta a la derecha, la respuesta a la izquierda-
   con `justify-self`. Eso es lo que hace que se lea como una conversacion.

   Estaba declarado como rejilla de dos columnas, `1fr 200px`, que era un resto
   de una version anterior con barra lateral propia. El resultado: la pregunta
   caia en la primera columna y la respuesta en la segunda, una al lado de la
   otra y la respuesta estrangulada a 200px. La barra lateral que justificaba
   esa segunda columna -.mock-chat__side- ya no existe en el marcado, como
   tampoco .mock-chat__thread ni ninguna .chat-msg: se retiran, que llevaban
   ahi sosteniendo un layout que nadie usaba. */
.mock-chat { display: grid; gap: var(--s-3); align-content: start; }

/* Cada afirmación del Copilot se acompaña de la relación en la que se apoya:
   es la misma promesa de evidencia que en la revisión, no una respuesta suelta. */
.chat-src { display: grid; gap: .3rem; margin-top: var(--s-3); }
.chat-src li { display: flex; align-items: center; gap: .4rem; font-size: .66rem; color: var(--text-2); }
.chat-src__k {
  flex: none;
  font-family: var(--font-mono); font-size: .54rem; letter-spacing: .08em; text-transform: uppercase;
  padding: .1rem .35rem; border-radius: var(--r-xs);
  color: var(--green); background: var(--green-soft); border: 1px solid rgba(52, 211, 153, .28);
}
.chat-src__k--amber { color: var(--amber); background: var(--amber-soft); border-color: rgba(245, 158, 11, .28); }
.chat-sugs { display: grid; gap: .3rem; margin-top: var(--s-3); }
.chat-sugs li {
  padding: .3rem .45rem;
  font-size: .64rem; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xs);
}

/* — Matriz de permisos — */
.mock-table--matrix { margin-top: var(--s-3); }
.mock-table--matrix th:not(:first-child),
.mock-table--matrix td:not(:first-child) { text-align: center; width: 5.5rem; }
.mock-table--matrix .si { color: var(--green); font-size: .8rem; }

/* Sin ajuste responsive propio: el hilo ya es de una sola columna en todos los
   anchos, asi que no hay nada que apilar. Lo que habia aqui deshacia la rejilla
   de dos columnas y colocaba la barra lateral que ya no existe. */

/* — Copilot mock — */
.chat { display: grid; gap: var(--s-3); }
.chat__q {
  justify-self: end; max-width: 92%;
  padding: .55rem .75rem; font-size: .72rem;
  background: var(--surface-3); border: 1px solid var(--line-2);
  border-radius: var(--r-md) var(--r-md) 4px var(--r-md);
}
.chat__q code { color: var(--cyan); font-size: .68rem; }
.chat__a {
  max-width: 96%;
  padding: .65rem .8rem; font-size: .72rem; color: var(--text-2);
  background: var(--violet-soft); border: 1px solid rgba(139, 92, 246, .22);
  border-radius: var(--r-md) var(--r-md) var(--r-md) 4px;
}
.chat__a ul { margin: .4rem 0 0; display: grid; gap: .25rem; }
.chat__a li { padding-left: .7rem; position: relative; }
.chat__a li::before { content: ""; position: absolute; left: 0; top: .55em; width: 3px; height: 3px; border-radius: 50%; background: #B79BFF; }
.chat__a code { color: var(--text); font-size: .68rem; }
.chat__src { margin-top: .5rem; font-size: .62rem; color: var(--text-3); }

/* — Process detail mock — */
.mock-tabs { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: var(--s-3); }
.mock-tabs span {
  padding: .25rem .5rem; font-size: .62rem; color: var(--text-3);
  border-bottom: 1px solid transparent;
}
.mock-tabs .is-active { color: var(--text); border-bottom-color: var(--cyan); }
.mock-kv { display: grid; gap: .45rem; }
.mock-kv li { display: flex; justify-content: space-between; gap: var(--s-3); font-size: .68rem; color: var(--text-3); }
.mock-kv b { color: var(--text-2); font-weight: 500; text-align: right; }

/* ============================================================
   12. PILLARS
   ============================================================ */
.pillars {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
}
.pillar {
  padding: 0 clamp(1rem, 2vw, 2rem);
  border-left: 1px solid var(--line);
}
.pillar:first-child { padding-left: 0; border-left: 0; }
.pillar:last-child { padding-right: 0; }
.pillar__icon {
  display: inline-grid; place-items: center;
  width: 2.4rem; height: 2.4rem; margin-bottom: var(--s-4);
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  background: var(--surface);
}
.pillar__icon--cyan   { color: var(--cyan);   border-color: rgba(34, 211, 238, .28);  background: var(--cyan-soft); }
.pillar__icon--blue   { color: #6EA8FF;       border-color: rgba(59, 130, 246, .28);  background: var(--blue-soft); }
.pillar__icon--green  { color: var(--green);  border-color: rgba(52, 211, 153, .28);  background: var(--green-soft); }
.pillar__icon--violet { color: #B79BFF;       border-color: rgba(139, 92, 246, .28);  background: var(--violet-soft); }
.pillar h3 { margin-bottom: .5rem; }
.pillar > p { font-size: var(--fs-sm); color: var(--text-2); }
.pillar ul { margin-top: var(--s-4); display: grid; gap: .4rem; }
.pillar ul li {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  color: var(--text-3); padding-left: .85rem; position: relative;
}
.pillar ul li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 4px; height: 1px; background: var(--line-3);
}

/* ============================================================
   13. COLUMN-LEVEL LINEAGE
   ============================================================ */
/* ---------- Column-level lineage: una relacion cada vez ------------------
   El bloque `.col-map` anterior mostraba las cuatro relaciones a la vez, que
   era exactamente lo que impedia leerlas. Se sustituye por filas
   seleccionables: origen, conexion, destino, y debajo el tipo y por que.
   ----------------------------------------------------------------------- */

.colrel {
  padding: clamp(1.1rem, 2vw, 1.8rem);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
}
/* La nota esta SIEMPRE, con o sin JavaScript, con o sin movimiento: la seccion
   tiene que decir algo aunque nadie toque nada. */
.colrel__note {
  font-size: var(--fs-sm); color: var(--text-3); line-height: 1.55;
  margin-bottom: var(--s-4);
}

/* Rejilla y no float: los dos nombres de tabla tienen que compartir linea
   base. Con el destino flotado quedaba unos pixeles mas alto que el origen. */
.colrel__map {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline;
  column-gap: var(--s-4);
}
.colrel__table {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .06em; color: var(--text-3);
  overflow-wrap: anywhere;
}
.colrel__table--dst { text-align: right; }

.colrel__list { grid-column: 1 / -1; display: grid; gap: .4rem; margin-top: var(--s-3); }

.colrel__row {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: .5rem;
  width: 100%; padding: .48rem .65rem;
  font: inherit; text-align: left; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-xs);
  transition: border-color var(--dur-ui) var(--ease), background var(--dur-ui) var(--ease);
}
.colrel__row:hover { border-color: var(--line-2); }
.colrel__row:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.colrel__src, .colrel__dst {
  font-family: var(--font-mono); font-size: .72rem; color: var(--text-2);
  transition: color var(--dur-ui) var(--ease);
  overflow-wrap: anywhere;
}
.colrel__dst { text-align: right; }

/* La conexion: una linea apagada con un punto que solo se enciende en la
   relacion activa. Es lo que hace que «se dibuja la conexion» signifique algo. */
.colrel__link { position: relative; display: block; width: 3.2rem; height: 1px; background: var(--line-2); }
.colrel__dot {
  position: absolute; top: 50%; left: 0;
  width: 5px; height: 5px; margin-top: -2.5px; border-radius: 50%;
  background: var(--cyan); opacity: 0;
  transition: opacity var(--dur-ui) var(--ease);
}

.colrel__row[aria-selected="true"] {
  background: rgba(34, 211, 238, .06);
  border-color: rgba(34, 211, 238, .45);
}
.colrel__row[aria-selected="true"] .colrel__src,
.colrel__row[aria-selected="true"] .colrel__dst { color: var(--text); }
.colrel__row[aria-selected="true"] .colrel__link { background: rgba(34, 211, 238, .55); }
.colrel__row[aria-selected="true"] .colrel__dot { opacity: 1; animation: crRecorre 1.1s var(--ease) both; }

/* El punto recorre la conexion una vez, de origen a destino. Una vez y no en
   bucle: es un gesto que explica la direccion, no un adorno que late. */
@keyframes crRecorre {
  from { left: 0; }
  to   { left: calc(100% - 5px); }
}

.colrel__panels { margin-top: var(--s-4); padding-top: var(--s-4); border-top: 1px solid var(--line); }
.colrel__panel { animation: qaEntra var(--dur-ui-lg) var(--ease) both; }
.colrel__head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.colrel__type {
  padding: .12rem .45rem;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .04em;
  color: var(--cyan); background: var(--surface); border: 1px solid rgba(34, 211, 238, .28);
  border-radius: var(--r-pill);
}
.colrel__pair { font-family: var(--font-mono); font-size: .72rem; color: var(--text-3); }
.colrel__detail { margin-top: var(--s-3); font-size: var(--fs-sm); color: var(--text-2); line-height: 1.6; }

@media (prefers-reduced-motion: reduce) {
  .colrel__panel { animation: none; }
  .colrel__row[aria-selected="true"] .colrel__dot { animation: none; left: calc(100% - 5px); }
}

/* ============================================================
   14. USE CASES
   ============================================================ */
/* ---------- Recorridos del explorador ---------------------------------- */

.journeys { margin: 0 0 var(--s-5); }
.journeys__lead { margin-bottom: var(--s-3); font-size: var(--fs-sm); color: var(--text-2); }
.journeys__tabs { display: flex; flex-wrap: wrap; gap: .5rem; }
.journey {
  display: inline-flex; align-items: center; gap: .55rem;
  min-height: 44px; padding: .55rem 1.05rem;
  font: inherit; cursor: pointer; color: var(--text-2);
  background: var(--glass-bg); border: 1px solid var(--line-2); border-radius: var(--r-pill);
  transition: color var(--dur-ui) var(--ease), border-color var(--dur-ui) var(--ease), background var(--dur-ui) var(--ease);
}
.journey:hover { color: var(--text); border-color: var(--line-3); }
.journey__n { font-family: var(--font-mono); font-size: .66rem; color: var(--text-3); }
.journey__title { font-size: var(--fs-sm); font-weight: 600; }
/* Activo: fondo, borde y numero encendido. No solo color. */
.journey[aria-selected="true"] {
  color: var(--text); background: rgba(34, 211, 238, .08); border-color: rgba(34, 211, 238, .5);
}
.journey[aria-selected="true"] .journey__n { color: var(--cyan); }
.journey__panel { margin-top: var(--s-4); animation: qaEntra var(--dur-ui) var(--ease) both; }
.journey__body { font-size: var(--fs-sm); color: var(--text-2); }
.journey__items { display: flex; flex-wrap: wrap; gap: .4rem .5rem; margin: var(--s-3) 0 0; padding: 0; list-style: none; }
.journey__items li {
  padding: .22rem .6rem; font-size: .72rem; color: var(--text-2);
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
}
/* Boton secundario, no enlace: cambia lo que se ve en el explorador y no
   lleva a ninguna parte. Pulsado se enciende como un recorrido activo, porque
   es un conmutador. */
.journeys__all { min-height: 44px; margin-top: var(--s-4); padding-inline: 1rem; font-size: var(--fs-sm); }
.journeys__all .icon { color: var(--cyan); }
.journeys__all:hover .icon { transform: none; }
.journeys__all[aria-pressed="true"] {
  color: var(--text); background: rgba(34, 211, 238, .08); border-color: rgba(34, 211, 238, .5);
}

/* En movil el menu del explorador pasa a fila: las pestanas necesitan alto
   tactil. */
@media (max-width: 900px) {
  .tlapp__nav .tab { min-height: 40px; padding-block: .6rem; }
}

/* ---------- Detalles del formulario ------------------------------------ */

.form__more { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.form__more-summary {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: .15rem var(--s-4);
  min-height: 44px; padding: var(--s-3) 0; cursor: pointer; list-style: none;
  font-size: var(--fs-sm); font-weight: 600; color: var(--text);
}
.form__more-summary::-webkit-details-marker { display: none; }
.form__more-summary::marker { content: ""; }
.form__more-hint { grid-column: 1; font-size: var(--fs-xs); font-weight: 400; color: var(--text-3); }
.form__more-chevron {
  grid-column: 2; grid-row: 1 / span 2; width: 1rem; height: 1rem; color: var(--text-3);
  transition: transform var(--dur-ui-lg) var(--ease);
}
.form__more[open] .form__more-chevron { transform: rotate(180deg); color: var(--cyan); }
.form__more::details-content {
  block-size: 0; overflow: hidden;
  transition: block-size var(--dur-ui-lg) var(--ease), content-visibility var(--dur-ui-lg) allow-discrete;
}
.form__more[open]::details-content { block-size: auto; }
.form__more-body { display: grid; gap: var(--s-4); padding-bottom: var(--s-4); }

/* ---------- Roadmap: lista completa plegada ----------------------------- */

.rmmore { margin-top: var(--s-2); }
.rmmore__summary {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 44px; cursor: pointer; list-style: none;
  font-size: var(--fs-sm); color: var(--cyan);
}
.rmmore__summary::-webkit-details-marker { display: none; }
.rmmore__summary::marker { content: ""; }
/* Indicador de estado con signo, no solo con color. */
.rmmore__summary::before { content: "+"; font-family: var(--font-mono); width: 1ch; }
.rmmore[open] > .rmmore__summary::before { content: "\2212"; }
.rmmore > ul { margin-top: var(--s-3); }

/* ---------- Adopcion: detalle de Customize ------------------------------ */

.adopt__details { margin-top: clamp(2rem, 4vw, 3rem); }
.platform { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); }
.platform__title { margin-bottom: var(--s-3); font-size: 1rem; }
.platform__conf { display: flex; flex-wrap: wrap; gap: .4rem .5rem; margin: 0; padding: 0; list-style: none; }
.platform__conf li {
  padding: .22rem .6rem; font-size: .75rem; color: var(--text-2);
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
}
.platform__note { grid-column: 1 / -1; font-size: var(--fs-sm); color: var(--text-3); }
@media (max-width: 760px) { .platform { grid-template-columns: 1fr; } }

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

/* ---------- Seguridad e IA: tres garantias y el detalle ------------------ */

.guarantees {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-5);
  margin: clamp(2rem, 4vw, 2.75rem) 0 0; padding: 0; list-style: none;
}
.guarantee { padding: clamp(1.25rem, 2.4vw, 1.75rem); border-radius: var(--r-lg); }
.guarantee__icon { width: 1.35rem; height: 1.35rem; color: var(--cyan); }
.guarantee__title { margin-top: var(--s-4); font-size: 1.05rem; }
.guarantee__body { margin-top: var(--s-3); color: var(--text-2); font-size: var(--fs-sm); line-height: 1.6; }

/* Todo el detalle tecnico, en un solo acordeon. Nativo: funciona sin JS, con
   teclado y lo anuncian los lectores de pantalla. */
.secdetails {
  margin-top: var(--s-6);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
/* Si es lo ultimo de la seccion, su raya de cierre caia a unos centimetros
   del borde de la propia seccion: dos lineas para cerrar lo mismo. */
.secdetails:last-child { border-bottom: 0; }
/* Si detras viene el CTA de cierre, el desplegable tampoco lleva raya
   inferior: quedaba suelta encima del boton. Cerrado se lee como una fila
   con su raya de arriba, igual que una pregunta frecuente. */
.secdetails:has(+ .cta-inline) { border-bottom: 0; }
.secdetails__summary {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: .25rem var(--s-4);
  padding: var(--s-5) 0; cursor: pointer; list-style: none;
}
.secdetails__summary::-webkit-details-marker { display: none; }
.secdetails__summary::marker { content: ""; }
.secdetails__summary:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; border-radius: var(--r-xs); }
.secdetails__label { font-weight: 600; color: var(--text); grid-column: 1; }
.secdetails__hint { grid-column: 1; font-size: var(--fs-sm); color: var(--text-3); }
.secdetails__chevron {
  grid-column: 2; grid-row: 1 / span 2;
  width: 1.15rem; height: 1.15rem; color: var(--text-3);
  transition: transform var(--dur-ui-lg) var(--ease), color var(--dur-ui) var(--ease);
}
.secdetails__summary:hover .secdetails__label { color: var(--cyan); }
/* Abierto: el chevron gira Y cambia de color. No depende de un solo rasgo. */
.secdetails[open] .secdetails__chevron { transform: rotate(180deg); color: var(--cyan); }
.secdetails::details-content {
  block-size: 0; overflow: hidden;
  transition: block-size var(--dur-ui-lg) var(--ease), content-visibility var(--dur-ui-lg) allow-discrete;
}
.secdetails[open]::details-content { block-size: auto; }
.secdetails__body { padding-bottom: var(--s-6); }
.secdetails__body .secblock:first-child { margin-top: var(--s-2); }

@media (max-width: 900px) {
  .guarantees { grid-template-columns: 1fr; }
}

/* ---------- Seguridad: tres bloques ------------------------------------- */

.secblock { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.secblock__title {
  font-size: 1.05rem;
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--s-5);
}
.secblock__sub { margin: var(--s-7) 0 var(--s-4); font-size: .95rem; color: var(--text-2); }
.secblock__one { max-width: 46rem; }
.secblock__one .sec__icon { color: var(--cyan); margin-bottom: var(--s-3); }
.secblock__one h4 { margin-bottom: .4rem; }
.secblock__one p { color: var(--text-2); font-size: var(--fs-sm); }

/* ---------- Detalle tecnico: cinco temas en pestanas ------------------------
   Mismo aspecto que los recorridos del producto -pastillas, la activa con
   fondo, borde y texto encendidos- para que se reconozca como el mismo gesto.
   Cada panel es un .secblock; aqui solo se le quita el margen grande que lo
   separaba del bloque anterior, porque ya no hay bloque anterior a la vista. */
.sectopics__tabs { display: flex; flex-wrap: wrap; gap: .5rem; }
.sectopic {
  min-height: 44px; padding: .55rem 1.05rem;
  font: inherit; font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
  color: var(--text-2);
  background: var(--glass-bg); border: 1px solid var(--line-2); border-radius: var(--r-pill);
  transition: color var(--dur-ui) var(--ease), border-color var(--dur-ui) var(--ease), background var(--dur-ui) var(--ease);
}
.sectopic:hover { color: var(--text); border-color: var(--line-3); }
.sectopic:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.sectopic[aria-selected="true"] {
  color: var(--text); background: rgba(34, 211, 238, .08); border-color: rgba(34, 211, 238, .5);
}
.sectopics__panel { margin-top: var(--s-6); animation: qaEntra var(--dur-ui-lg) var(--ease) both; }
/* Sin JavaScript nadie puede cambiar de pestana: se ven los cinco temas
   seguidos y las pastillas, que no harian nada, no se ensenan. */
html:not(.js) .sectopics__panel[hidden] { display: block !important; }
html:not(.js) .sectopics__tabs { display: none; }
@media (prefers-reduced-motion: reduce) { .sectopics__panel { animation: none; } }

/* Los dos modelos de conexion son EXCLUYENTES: o asumes un rol o despliegas
   dentro. Por eso van en selector y no en dos columnas iguales, que sugerian
   que hay que leerse las dos para decidir. */
.connsel { margin-top: var(--s-6); }
.connsel__tabs {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r-md) var(--r-md) 0 0; overflow: hidden;
}
.connsel__tab {
  display: flex; flex-direction: column; gap: .3rem;
  padding: var(--s-4);
  font: inherit; text-align: left; cursor: pointer;
  background: var(--bg-2); border: 0;
  box-shadow: inset 0 -2px 0 transparent;
  transition: background var(--dur-ui) var(--ease), box-shadow var(--dur-ui) var(--ease);
}
.connsel__tab:hover { background: var(--surface); }
.connsel__tab:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }
.connsel__label {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-3);
}
.connsel__name { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.connsel__tab[aria-selected="true"] { background: var(--surface); box-shadow: inset 0 -2px 0 var(--cyan); }
.connsel__tab[aria-selected="true"] .connsel__label { color: var(--cyan); }
.connsel__tab[aria-selected="true"] .connsel__name { color: var(--text); }

/* Cristal solo en el MARCO del panel. Dentro va texto que hay que leer, asi
   que el desenfoque se queda detras y no debajo de las palabras. */
/* Sin la sombra exterior del cristal: el panel cuelga de las pestanas, no
   flota, y la sombra dejaba una franja oscura debajo que parecia un fallo. */
.connsel__panel {
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  padding: clamp(1.1rem, 2.2vw, 1.6rem);
  border-radius: 0 0 var(--r-md) var(--r-md);
  border-top: 0;
  animation: qaEntra var(--dur-ui-lg) var(--ease) both;
}
.connsel__panel p { color: var(--text-2); font-size: var(--fs-sm); line-height: 1.65; }

.secnote { margin-top: var(--s-6); padding-left: var(--s-4); border-left: 2px solid var(--line-2); }
.secnote h4 { margin: .25rem 0 .4rem; font-size: .95rem; }
.secnote p { color: var(--text-2); font-size: var(--fs-sm); line-height: 1.6; }

.secegress__lead { color: var(--text-2); font-size: var(--fs-sm); }
.secegress {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin: var(--s-4) 0 0; padding: 0; list-style: none;
}
.secegress__item {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .4rem .7rem;
  font-size: var(--fs-sm); color: var(--text);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-pill);
}
.secegress__x { color: var(--green, #34D399); font-size: .9rem; line-height: 1; }
.secegress__more { margin-top: var(--s-4); font-size: var(--fs-sm); }

/* ---------- Roadmap: tres estados --------------------------------------- */

.rmstates { margin-top: clamp(2rem, 4vw, 3rem); }
.rmstates__tabs {
  display: flex; flex-wrap: wrap; gap: .5rem;
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--line);
}
.rmtab {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .48rem .9rem;
  font: inherit; cursor: pointer;
  background: transparent; color: var(--text-3);
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
  transition: color var(--dur-ui) var(--ease), border-color var(--dur-ui) var(--ease), background var(--dur-ui) var(--ease);
}
.rmtab:hover { color: var(--text-2); border-color: var(--line-3); }
.rmtab:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.rmtab__name { font-size: var(--fs-sm); }
/* El contador no es decoracion: dice cuanto hay en cada estado antes de
   abrirlo, que es la pregunta real -cuanto existe frente a cuanto se promete-. */
.rmtab__n {
  font-family: var(--font-mono); font-size: .62rem;
  padding: .1rem .35rem; border-radius: var(--r-pill);
  background: var(--surface); color: var(--text-3);
}
.rmtab[aria-selected="true"] {
  color: var(--text); background: rgba(34, 211, 238, .08); border-color: rgba(34, 211, 238, .45);
}
.rmtab[aria-selected="true"] .rmtab__n { background: var(--cyan); color: #04151b; }

.rmstates__panel { margin-top: var(--s-6); animation: qaEntra var(--dur-ui-lg) var(--ease) both; }
.rmstates__today { columns: 2; column-gap: var(--s-7); }
.rmstates__today li { break-inside: avoid; }

@media (prefers-reduced-motion: reduce) {
  .connsel__panel, .rmstates__panel { animation: none; }
}
@media (max-width: 720px) {
  .connsel__tabs { grid-template-columns: 1fr; }
  .rmstates__today { columns: 1; }
}

/* ---------- Casos de uso: selector con escena compartida ----------------
   La cuadricula de seis tarjetas iguales se sustituye por seis pestanas y un
   panel. La ruta de linaje es la MISMA pieza que usa EL PROBLEMA
   (src/partials/ruta.mjs), y por eso hereda sus estilos `.qroute__*`: lo unico
   propio de aqui es el marco.
   ----------------------------------------------------------------------- */

.usecases { margin-top: clamp(2rem, 4vw, 3rem); }

.usecases__tabs {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r-lg) var(--r-lg) 0 0; overflow: hidden;
}
.ucase {
  display: flex; flex-direction: column; gap: .55rem;
  padding: clamp(.9rem, 1.8vw, 1.25rem);
  font: inherit; text-align: left; cursor: pointer;
  background: var(--bg-2); border: 0;
  box-shadow: inset 0 -2px 0 transparent;
  transition: background var(--dur-ui) var(--ease), box-shadow var(--dur-ui) var(--ease);
}
.ucase:hover { background: var(--surface); }
.ucase:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }
.ucase__icon { color: var(--text-3); transition: color var(--dur-ui) var(--ease); }
.ucase__title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); line-height: 1.3; }
/* Activo: fondo, barra inferior e icono encendido. Tres senales, no solo color. */
.ucase[aria-selected="true"] { background: var(--surface); box-shadow: inset 0 -2px 0 var(--cyan); }
.ucase[aria-selected="true"] .ucase__icon { color: var(--cyan); }
.ucase[aria-selected="true"] .ucase__title { color: var(--text); }

.usecases__stage {
  padding: clamp(1.4rem, 2.6vw, 2.2rem);
  background: var(--bg-2);
  border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}
.upanel {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.5rem, 3vw, 2.5rem); align-items: center;
  animation: qaEntra var(--dur-ui-lg) var(--ease) both;
}
.upanel__label {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-3);
}
.upanel__question { margin-top: var(--s-3); font-size: 1.15rem; color: var(--text); line-height: 1.4; }
.upanel__body { margin-top: var(--s-3); font-size: var(--fs-sm); color: var(--text-2); line-height: 1.6; }

.link-arrow {
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--cyan); text-decoration: none;
  border-bottom: 1px solid rgba(34, 211, 238, .35);
  transition: border-color var(--dur-ui) var(--ease);
}
.link-arrow:hover { border-bottom-color: var(--cyan); }
.link-arrow:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

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

@media (max-width: 900px) {
  .usecases__tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .upanel { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .usecases__tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   15. FLEXIBILITY
   ============================================================ */
.flex-grid {
  display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: var(--s-5);
}
.flex-core, .flex-conf {
  padding: clamp(1.4rem, 2.5vw, 2.2rem);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-lg);
}
.flex-core { background: linear-gradient(180deg, rgba(34, 211, 238, .05), transparent 55%), var(--surface); }
.flex-core h3, .flex-conf h3 { margin: var(--s-4) 0 var(--s-5); }
.flex-conf__note { margin-top: var(--s-5); font-size: var(--fs-sm); color: var(--text-3); }

/* ============================================================
   16. AI DIFFERENTIATOR
   ============================================================ */
.ia-badges { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: var(--s-6); }

.ai-pipeline { display: grid; gap: 0; }
.ai-step {
  --accent: var(--line-3);
  position: relative;
  padding: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-md);
  transition: border-color .25s var(--ease);
}
.ai-step + .ai-step { margin-top: 1.6rem; }
.ai-step + .ai-step::before {
  content: ""; position: absolute; left: 50%; top: -1.6rem;
  width: 1px; height: 1.6rem;
  background: linear-gradient(180deg, transparent, var(--line-3));
}
.ai-step + .ai-step::after {
  content: ""; position: absolute; left: 50%; top: -.42rem;
  width: 5px; height: 5px; margin-left: -2px;
  border-right: 1px solid var(--line-3); border-bottom: 1px solid var(--line-3);
  transform: rotate(45deg);
}
.ai-step__label {
  display: block; font-size: .95rem; font-weight: 600; letter-spacing: -.015em;
}
.ai-step__desc { display: block; margin-top: .2rem; font-size: var(--fs-sm); color: var(--text-2); }
.ai-step:hover { border-top-color: var(--line-3); border-right-color: var(--line-3); border-bottom-color: var(--line-3); }

.ai-step--ai     { --accent: var(--violet); background: linear-gradient(90deg, var(--violet-soft), transparent 45%), var(--surface); }
.ai-step--cyan   { --accent: var(--cyan);   background: linear-gradient(90deg, var(--cyan-soft), transparent 45%), var(--surface); }
.ai-step--blue   { --accent: var(--blue); }
.ai-step--green  { --accent: var(--green);  background: linear-gradient(90deg, var(--green-soft), transparent 45%), var(--surface); }

/* — Modelo de IA local: el argumento fuerte, así que se destaca — */
.llm-local {
  margin-top: var(--s-7);
  padding: clamp(1.3rem, 2.2vw, 1.9rem);
  background: linear-gradient(180deg, rgba(52, 211, 153, .06), transparent 55%), var(--surface);
  border: 1px solid rgba(52, 211, 153, .22);
  border-radius: var(--r-lg);
}
.llm-local h3 { margin: var(--s-3) 0 var(--s-4); font-size: 1.1rem; }
.llm-local > p { font-size: var(--fs-sm); color: var(--text-2); }
.llm-local__opts { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: var(--s-5); }
.llm-local__opt {
  display: flex; align-items: center; gap: .5rem;
  padding: .45rem .8rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-pill);
}
.llm-local__opt--on { border-color: rgba(52, 211, 153, .45); background: var(--green-soft); }
.llm-local__name { font-size: var(--fs-sm); font-weight: 500; }
.llm-local__tag {
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3);
}
.llm-local__opt--on .llm-local__tag { color: var(--green); }
.llm-local__note { margin-top: var(--s-4); font-size: var(--fs-xs); color: var(--text-3); }

/* Política de salida de datos. El color codifica la regla: verde sale tal cual,
   ámbar sale transformado, apagado no sale. */
.egress { display: grid; gap: .3rem; margin-top: var(--s-4); }
.egress__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: .4rem .6rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xs);
  border-left: 2px solid var(--green);
}
.egress__row--mid { border-left-color: var(--amber); }
.egress__row--no  { border-left-color: var(--line-3); }
.egress__what { font-size: var(--fs-xs); color: var(--text-2); }
.egress__rule {
  flex: none;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--green);
}
.egress__row--mid .egress__rule { color: var(--amber); }
.egress__row--no  .egress__rule { color: var(--text-3); }

@media (max-width: 640px) {
  .egress__row { flex-direction: column; align-items: flex-start; gap: .25rem; }
}

/* — Modelos de conexión — */
.conn {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5);
  margin-top: var(--s-6);
}
.conn__opt {
  padding: var(--s-5);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md);
  border-top: 2px solid var(--cyan);
}
.conn__opt:nth-child(2) { border-top-color: var(--violet); }
.conn__opt:nth-child(3) { border-top-color: var(--green); }
.conn__opt h3 { margin: var(--s-3) 0 var(--s-3); font-size: 1.02rem; }
.conn__opt p { font-size: var(--fs-sm); color: var(--text-2); }
.conn__opt em { color: var(--text); font-style: normal; }

@media (max-width: 900px) {
  .conn { grid-template-columns: 1fr; }
}

/* ============================================================
   17. ROADMAP
   ============================================================ */
.roadmap {
  display: grid; grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}
.roadmap__today {
  position: sticky; top: 100px;
  padding: clamp(1.3rem, 2.2vw, 1.9rem);
  background: linear-gradient(180deg, rgba(52, 211, 153, .06), transparent 50%), var(--surface);
  border: 1px solid rgba(52, 211, 153, .2);
  border-radius: var(--r-lg);
}
.roadmap__today .check-list { margin-top: var(--s-5); }
/* Decir en voz alta lo que NO hay, dentro del bloque de lo que sí: un comprador
   enterprise pregunta por el SSO en la primera reunión, y descubrirlo tarde cuesta
   más que leerlo aquí. */
.roadmap__gap {
  margin-top: var(--s-5); padding-top: var(--s-4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--text-3);
}
.roadmap__next > .mono-label { margin-bottom: var(--s-5); }

.roadmap-list { display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.rm {
  display: grid; grid-template-columns: 2.1rem 1fr; gap: var(--s-4);
  padding: var(--s-5) 0;
  background: var(--bg);
  transition: background .25s var(--ease);
}
.rm:hover { background: var(--surface); }
.rm__letter {
  display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem;
  font-family: var(--font-mono); font-size: .74rem; color: var(--text-3);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.rm:hover .rm__letter { color: #B79BFF; border-color: rgba(139, 92, 246, .4); }
.rm__body h3 { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; margin-bottom: .35rem; }
.rm__body p { font-size: var(--fs-sm); color: var(--text-2); }
.roadmap__note { margin-top: var(--s-5); font-size: var(--fs-sm); color: var(--text-3); max-width: 40rem; }

/* ============================================================
   18. SECURITY
   ============================================================ */
.security { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5); }
.sec {
  padding: var(--s-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  transition: border-color .25s var(--ease);
}
.sec:hover { border-color: var(--line-2); }
.sec__icon { color: var(--green); margin-bottom: var(--s-4); }
.sec h3 { font-size: 1rem; margin-bottom: .35rem; }
.sec p { font-size: var(--fs-sm); color: var(--text-2); }
/* Sin linea propia: justo debajo va la del desplegable de detalles, y con
   las dos la nota quedaba enjaulada entre dos rayas. */
.security__note {
  margin-top: var(--s-6);
  font-size: var(--fs-sm); color: var(--text-3); max-width: 52rem;
}

/* ============================================================
   19. ADOPTION
   ============================================================ */
.adopt { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; }
.adopt__col { padding: 0 clamp(1rem, 2.5vw, 2.4rem); border-left: 1px solid var(--line); }
.adopt__col:first-child { padding-left: 0; border-left: 0; }
.adopt__step {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .14em;
  color: var(--cyan); margin-bottom: var(--s-3);
}
.adopt__col h3 { font-size: 1.2rem; margin-bottom: .5rem; }
.adopt__col p { font-size: var(--fs-sm); color: var(--text-2); }

.quote { margin: 0; }

/* ============================================================
   20. CONTACT FORM
   ============================================================ */
.section--contact {
  background:
    radial-gradient(46rem 30rem at 82% 12%, rgba(34, 211, 238, .07), transparent 62%),
    var(--bg-2);
  border-top: 1px solid var(--line);
}
.contact {
  display: grid; grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
.contact__copy .mono-label { margin-bottom: var(--s-4); }
.contact__copy h2 { margin-bottom: var(--s-5); }
.contact__points { margin-top: var(--s-6); display: grid; gap: .6rem; }
.contact__points li { display: flex; align-items: flex-start; gap: .6rem; font-size: var(--fs-sm); color: var(--text-2); }
.contact__points .icon { color: var(--green); margin-top: .3rem; }

/* Cristal en el MARCO, y solo en el marco. Los campos de texto conservan su
   fondo solido: desenfocar por detras de algo que se esta escribiendo resta
   lectura justo donde mas hace falta, y no gana nada. */
.form {
  display: grid; gap: var(--s-4);
  padding: clamp(1.4rem, 2.6vw, 2.2rem);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--sh-2);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur)) saturate(130%);
}
@supports not (backdrop-filter: blur(1px)) {
  .form { background: var(--glass-bg-strong); }
}
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }

.field { display: grid; gap: .4rem; }
.field label { font-size: var(--fs-xs); font-weight: 500; color: var(--text-2); letter-spacing: .01em; }
.req { color: var(--cyan); }

.field input, .field textarea, .field select {
  width: 100%;
  padding: .7rem .8rem;
  font: inherit; font-size: var(--fs-sm);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.field textarea { resize: vertical; min-height: 6rem; line-height: 1.55; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-3); opacity: .75; }
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--line-3); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: rgba(34, 211, 238, .6);
  box-shadow: 0 0 0 3px rgba(34, 211, 238, .12);
  background: var(--surface);
}
.field input[aria-invalid="true"], .field select[aria-invalid="true"] {
  border-color: rgba(245, 158, 11, .7);
}
.field input[aria-invalid="true"]:focus, .field select[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(245, 158, 11, .14);
}
.field__error {
  font-size: var(--fs-xs); color: var(--amber); min-height: 0;
}
.field__error:empty { display: none; }

.select { position: relative; }
.select select { appearance: none; -webkit-appearance: none; padding-right: 2.4rem; cursor: pointer; }
.select select option { background: var(--surface-2); color: var(--text); }
.select__chevron {
  position: absolute; right: .75rem; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none;
}

.check { display: flex; align-items: center; gap: .6rem; }
.check input {
  appearance: none; -webkit-appearance: none;
  width: 1.05rem; height: 1.05rem; flex: none;
  border: 1px solid var(--line-3); border-radius: var(--r-xs);
  background: var(--bg); cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
  position: relative;
}
.check input:hover { border-color: var(--cyan); }
.check input:checked { background: var(--cyan); border-color: var(--cyan); }
.check input:checked::after {
  content: ""; position: absolute; inset: 0;
  background: no-repeat center/.7rem url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23050710' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E");
}
/* Contenedor de Turnstile. Reserva altura para que la aparición del widget no
   desplace los botones (evita CLS y clics accidentales). */
.turnstile { min-height: 65px; }
.turnstile[hidden] { display: none; min-height: 0; }

/* Trampa antispam: invisible pero presente en el DOM. No se usa display:none
   ni visibility:hidden porque algunos bots omiten los campos ocultos así. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.check label { font-size: var(--fs-sm); color: var(--text-2); cursor: pointer; }
.check--required { align-items: flex-start; }
.check--required input { margin-top: .22rem; }
.check input[aria-invalid="true"] { border-color: rgba(245, 158, 11, .85); background: var(--amber-soft); }

.check label a, .form__legal a {
  color: var(--cyan);
  text-decoration: underline;
  text-decoration-color: rgba(34, 211, 238, .45);
  text-underline-offset: 3px;
  transition: text-decoration-color .2s var(--ease);
}
.check label a:hover, .form__legal a:hover { text-decoration-color: var(--cyan); }

.form__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-2); }

.form__status {
  font-size: var(--fs-sm); line-height: 1.5;
  padding: 0; color: var(--text-2);
}
.form__status[data-state="idle"]:empty { display: none; }
.form__status[data-state="error"],
.form__status[data-state="pending-config"],
.form__status[data-state="sent"] {
  padding: .75rem .9rem; border-radius: var(--r-sm); border: 1px solid var(--line-2);
}
.form__status[data-state="error"] { color: var(--amber); border-color: rgba(245, 158, 11, .35); background: var(--amber-soft); }
.form__status[data-state="pending-config"] { color: var(--text-2); border-color: var(--line-2); background: var(--surface-2); }
.form__status[data-state="sent"] { color: var(--green); border-color: rgba(52, 211, 153, .32); background: var(--green-soft); }

.form__legal { font-size: var(--fs-xs); color: var(--text-3); }

/* ============================================================
   20b. ACENTO DE COLOR EN TARJETAS
   ============================================================ */
/* Un solo lenguaje para todas las tarjetas, sacado del que ya tenian las de
   IDENTIDAD / AUTORIZACION / ALCANCE (arriba) y la secuencia de la IA y la
   matriz de salida (a la izquierda). Gustaba mas que el resto, que eran
   rectangulos iguales entre si.

   La regla: ARRIBA para tarjetas que se leen en paralelo, una junto a otra;
   A LA IZQUIERDA para lo que se lee de arriba abajo -una secuencia, una
   lista, el panel que sale de una pestana-.

   El color no es decoracion, repite el codigo del resto de la pagina: cian lo
   principal, violeta lo que hace la IA, verde lo que protege o no sale, ambar
   lo que sale transformado. En una fila de tarjetas paralelas va en el mismo
   orden que ya tenian las de conexion: cian, violeta, verde.

   Va aqui, detras de cada componente, porque tiene que ganar a sus `border`
   abreviados -el de .glass-panel, el de .form- sin subir especificidad. */
.guarantee,
.sec,
.colrel,
.form { border-top: 2px solid var(--acento, var(--cyan)); }

.guarantee:nth-child(2),
.sec:nth-child(2) { --acento: var(--violet); }
.guarantee:nth-child(3) { --acento: var(--green); }

/* Las dos cajas del modelo local y de la salida de datos ya iban enmarcadas
   en verde; el acento sigue ese mismo color. */
.llm-local { border-top: 2px solid var(--green); }

/* Panel del selector de conexion: cuelga de las pestanas, asi que su acento
   va a la izquierda, como el de una lista. */
.connsel__panel { border-left: 2px solid var(--cyan); }

/* Notas sueltas dentro del detalle de seguridad: ya tenian la linea
   izquierda, pero gris; ahora lleva color, como la de la secuencia. */
.secnote { border-left-color: var(--cyan); }

/* ============================================================
   21. FOOTER
   ============================================================ */
.site-footer { border-top: 1px solid var(--line); background: var(--bg); }
.site-footer__inner {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: var(--s-5);
  padding-block: var(--s-7);
}
.site-footer__name { font-size: .95rem; font-weight: 600; letter-spacing: -.02em; }
.site-footer__claim { margin-top: .25rem; font-size: var(--fs-sm); color: var(--text-3); }
.site-footer__nav { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.site-footer__nav a { font-size: var(--fs-sm); color: var(--text-2); transition: color .2s var(--ease); }
.site-footer__nav a:hover { color: var(--text); }

/* ============================================================
   22. MOTION / REVEAL
   ============================================================

   EL CONTENIDO ES VISIBLE POR DEFECTO. El JavaScript puede animar su entrada,
   pero nunca es necesario para verlo.

   Antes era al reves, y ese era el origen de la pantalla negra al navegar por
   el menu: 74 bloques nacian con opacity 0 y solo aparecian cuando el
   IntersectionObserver avisaba de que se veian, seguido de una transicion de
   600 ms con retrasos de hasta 280 ms. Al pulsar un enlace, el desplazamiento
   suave atravesaba 16.000 px de pagina -23.000 en movil- de contenido
   invisible, y al llegar, lo que se veia dependia de cuanto tardara ese
   aviso. Cualquier cosa que lo retrasara -fotogramas perdidos por el
   desenfoque de la cabecera y los paneles, las animaciones del hero- se
   convertia directamente en segundos de pantalla negra.

   Ahora solo se oculta lo que el script marca como pendiente (`.is-pending`),
   y el script solo marca lo que al cargar esta por DEBAJO del pliegue. Lo que
   ya se ve no se toca, al llegar por un ancla no se oculta nada, y al pulsar un
   enlace interno se suelta todo antes de que empiece el desplazamiento.
   ============================================================ */
.reveal { transition: opacity .3s var(--ease), transform .3s var(--ease); }
/* Escalonado de 60 ms entre elementos: se percibe la secuencia sin que nadie
   espere. El total no pasa de 240 ms. */
.reveal[data-reveal-delay="1"] { transition-delay: .06s; }
.reveal[data-reveal-delay="2"] { transition-delay: .12s; }
.reveal[data-reveal-delay="3"] { transition-delay: .18s; }
.reveal[data-reveal-delay="4"] { transition-delay: .24s; }
.reveal.is-pending { opacity: 0; transform: translateY(10px); }

/* El hero no espera a ningun observer: entra con CSS al cargar, en 400 ms. */
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.hero .reveal { animation: riseIn .4s var(--ease) both; }
.hero .reveal[data-reveal-delay="1"] { animation-delay: .06s; }
.hero .reveal[data-reveal-delay="2"] { animation-delay: .12s; }
.hero .reveal[data-reveal-delay="3"] { animation-delay: .18s; }
.hero .reveal[data-reveal-delay="4"] { animation-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Sin desplazamientos Y sin retrasos. Antes se acortaba la duracion pero
     se conservaba el delay, asi que algunos bloques seguian esperando 280 ms
     para aparecer de golpe. */
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
  .reveal, .reveal.is-pending { opacity: 1; transform: none; }
}

/* ============================================================
   23. RESPONSIVE
   ============================================================ */

/* — Laptop 1280–1440 — */
@media (max-width: 1200px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .mock-explorer { grid-template-columns: minmax(0, 1fr) 180px; }
  .brand__tag { display: none; }
  .nav__list { gap: var(--s-4); }
}

/* — Movil: el diagrama usa todo el ancho de la columna — */
@media (max-width: 560px) {
  /* El margen lateral del contenedor se conserva: es el padding seguro que
     evita que el brillo exterior de las tarjetas toque el borde. Mas
     especifico que la regla de tablet, que tambien aplica a este ancho. */
  .hero .observatory { max-width: 100%; }
}

/* — Tablet 768–1024 — */
@media (max-width: 1024px) {
  :root { --ancla: 76px; }

  .hero__inner { grid-template-columns: 1fr; gap: var(--s-8); }
  /* Apilado: centrado y algo mas pequeno, entre 460 y 520 px. */
  .observatory { justify-self: center; width: 100%; max-width: min(100%, 560px); margin-right: 0; }
  .hero__sub { max-width: 42rem; }

  .split, .split--reverse { grid-template-columns: 1fr; }
  .split--reverse .split__copy { order: 0; }

  .questions { grid-template-columns: 1fr; }
  .problem-notes { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6) var(--s-5); }
  .steps::before { display: none; }
  .step { padding-top: 0; padding-left: 2.6rem; }
  .step__num { top: -2px; }

  .showcase__layout { grid-template-columns: 1fr; }
  .showcase__side { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-7) 0; }
  .pillar:nth-child(3) { padding-left: 0; border-left: 0; }
  .pillar { padding-right: clamp(1rem, 3vw, 2rem); }

  /* Con 6 conceptos que envuelven, space-between deja huecos raros. */
  .band__list { justify-content: flex-start; gap: .65rem clamp(1.25rem, 3.5vw, 2.5rem); }

  .flex-grid { grid-template-columns: 1fr; }
  .security { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .roadmap { grid-template-columns: 1fr; }
  .roadmap__today { position: static; }
  .adopt { grid-template-columns: 1fr; gap: var(--s-6); }
  .adopt__col { padding: 0 0 0 var(--s-4); border-left: 1px solid var(--line); }
  .adopt__col:first-child { padding-left: var(--s-4); border-left: 1px solid var(--line); }
  /* minmax(0, 1fr) y no 1fr: 1fr deja crecer la columna hasta el ancho
     minimo de su contenido, y el widget de Turnstile mide 300 px fijos. A
     360 px de pantalla empujaba la pagina 7 px de lado. */
  .contact { grid-template-columns: minmax(0, 1fr); }

  .nav__list { display: none; }
  .nav__cta { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* — Mobile ≤ 760 — */
@media (max-width: 760px) {
  :root { --section-y: clamp(3.5rem, 12vw, 5rem); }

  .site-header__inner { height: 60px; }

  .hero { padding-block: var(--s-7) var(--s-8); }
  /* Recalculado para el titular nuevo, el doble de largo que el anterior. */
  .hero__title { font-size: clamp(2rem, 8.2vw, 2.6rem); }
  .hero__title:lang(en) { font-size: clamp(1.9rem, 7.4vw, 2.4rem); }
  .hero__actions { gap: var(--s-2); }
  .hero__actions .btn { flex: 1 1 100%; }
  .hero__trust { gap: .4rem; font-size: .66rem; }


  .band__list { gap: .5rem 1.25rem; justify-content: flex-start; }
  .band__list li { font-size: .62rem; }

  .problem-notes { grid-template-columns: 1fr; gap: var(--s-5); }
  .question__q { font-size: 1rem; }

  .steps { grid-template-columns: 1fr; gap: var(--s-5); }

  .showcase__tabs { overflow-x: auto; flex-wrap: nowrap; padding-bottom: .25rem; }
  .tab { flex: none; }
  .showcase__side { grid-template-columns: 1fr; }
  .mock-explorer { grid-template-columns: 1fr; }
  .mock-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-dash { grid-template-columns: 1fr; }
  .mock-services { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .frame__body { padding: var(--s-3); }
  .mock-table { display: block; overflow-x: auto; white-space: nowrap; }

  .pillars { grid-template-columns: 1fr; gap: var(--s-7); }
  .pillar { padding: 0 0 0 var(--s-4); border-left: 1px solid var(--line); }
  .pillar:first-child { padding-left: var(--s-4); border-left: 1px solid var(--line); }

  /* Las filas de relacion se estrechan, pero NO se apilan: origen, conexion y
     destino tienen que seguir leyendose como una sola linea, que es lo que
     cuenta la relacion. Lo que cede es el ancho de la conexion. */
  .colrel__link { width: 1.6rem; }
  .colrel__src, .colrel__dst { font-size: .68rem; }

  .security { grid-template-columns: 1fr; }

  .rm { grid-template-columns: 1.9rem 1fr; gap: var(--s-3); }

  .form__row { grid-template-columns: 1fr; }
  .form__actions .btn { flex: 1 1 100%; }

  .cta-inline { flex-direction: column; }
  .cta-inline .btn { width: 100%; }

  .site-footer__inner { flex-direction: column; align-items: flex-start; }
}

/* — Mobile pequeño 390 y menos — */
@media (max-width: 400px) {
  .brand__name { font-size: .86rem; }
  .eyebrow { font-size: .68rem; letter-spacing: .1em; }
  .hero__title { font-size: 1.9rem; }
  .hero__title:lang(en) { font-size: 1.8rem; }
  .mock-kpis { grid-template-columns: 1fr 1fr; }
  .mock-services { grid-template-columns: 1fr; }
}

/* — Pantallas grandes 1920+ — */
@media (min-width: 1600px) {
  :root { --container: 1360px; }
}

/* ============================================================
   24. PÁGINA LEGAL (aviso legal + privacidad)
   ============================================================ */
.nav--legal .nav__list { display: flex; }
/* En movil no caben en una fila la marca, Volver, el idioma y el boton de
   Contacto: a 360 px la cabecera se salia 64 px y el boton quedaba fuera de
   la pantalla, con desplazamiento lateral en las nueve paginas secundarias.
   Se va el boton; el contacto sigue a un toque, porque Volver lleva a la
   portada. */
@media (max-width: 560px) {
  .nav--legal { gap: var(--s-4); }
  .nav--legal .btn { display: none; }
}

.legal { padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(3.5rem, 8vw, 6rem); }
.legal__inner { max-width: 48rem; }

.legal__head { padding-bottom: var(--s-6); border-bottom: 1px solid var(--line); }
.legal__head .mono-label { margin-bottom: var(--s-4); }
.legal__head h1 {
  font-size: clamp(1.9rem, 4vw, 2.9rem);
  margin-bottom: var(--s-5);
}
.legal__updated {
  margin-top: var(--s-5);
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .06em; color: var(--text-3);
}

.legal__toc {
  margin-block: var(--s-6);
  padding: var(--s-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
}
.legal__toc ol {
  margin-top: var(--s-4);
  columns: 2; column-gap: var(--s-6);
  list-style: decimal; padding-left: 1.2rem;
}
.legal__toc li { font-size: var(--fs-sm); color: var(--text-3); margin-bottom: .35rem; break-inside: avoid; }
.legal__toc a { color: var(--text-2); transition: color .2s var(--ease); }
.legal__toc a:hover { color: var(--cyan); }

.prose { margin-top: clamp(2rem, 4vw, 3rem); scroll-margin-top: 96px; }
.prose h2 {
  font-size: clamp(1.25rem, 2vw, 1.55rem);
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
}
.prose h3 { font-size: 1rem; margin: var(--s-5) 0 var(--s-3); color: var(--text); }
.prose p { color: var(--text-2); }
.prose p + p, .prose ul + p, .prose p + ul, .prose dl + p { margin-top: var(--s-4); }
.prose ul { display: grid; gap: .5rem; margin-top: var(--s-3); }
.prose ul li {
  position: relative; padding-left: 1.1rem;
  font-size: var(--fs-sm); color: var(--text-2);
}
.prose ul li::before {
  content: ""; position: absolute; left: 0; top: .68em;
  width: 5px; height: 1px; background: var(--line-3);
}
.prose strong { color: var(--text); font-weight: 600; }
.prose a:not(.ph) {
  color: var(--cyan);
  text-decoration: underline;
  text-decoration-color: rgba(34, 211, 238, .4);
  text-underline-offset: 3px;
  transition: text-decoration-color .2s var(--ease);
}
.prose a:not(.ph):hover { text-decoration-color: var(--cyan); }

.legal__dl {
  margin: var(--s-5) 0 0;
  display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden;
}
.legal__dl dt, .legal__dl dd {
  margin: 0; padding: .8rem 1rem;
  background: var(--surface); font-size: var(--fs-sm);
}
.legal__dl dt { color: var(--text-3); }
.legal__dl dd { color: var(--text); }

.legal__callout {
  margin-top: var(--s-5); padding: var(--s-4);
  border-left: 2px solid var(--cyan);
  background: var(--cyan-soft);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: var(--fs-sm);
}

.legal__disclaimer {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--text-3);
}

/* — Guías — */
.miga {
  margin-bottom: var(--s-5);
  font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-3);
}
.miga a { color: var(--text-2); transition: color .2s var(--ease); }
.miga a:hover { color: var(--cyan); }
.miga span[aria-hidden] { margin: 0 .35rem; color: var(--line-3); }

.prose__ol { list-style: decimal; padding-left: 1.3rem; margin-top: var(--s-3); display: grid; gap: .6rem; }
.prose__ol li { font-size: var(--fs-sm); color: var(--text-2); padding-left: .2rem; }
.prose__ol li::before { content: none; }

.guias { margin-top: var(--s-7); display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.guia { background: var(--bg); transition: background .25s var(--ease); }
.guia:hover { background: var(--surface); }
.guia a { display: block; padding: var(--s-5) 0; }
.guia h2 { font-size: 1.1rem; line-height: 1.35; margin-bottom: var(--s-3); }
.guia p { font-size: var(--fs-sm); color: var(--text-2); max-width: 46rem; }
.guia__mas {
  display: inline-block; margin-top: var(--s-3);
  font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--cyan);
}
.guia a:hover h2 { color: var(--cyan); }

.guia-cta {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding: clamp(1.4rem, 2.6vw, 2.2rem);
  background: linear-gradient(180deg, rgba(34, 211, 238, .06), transparent 55%), var(--surface);
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
}
.guia-cta h2 { font-size: 1.15rem; margin-bottom: var(--s-3); }
.guia-cta p { font-size: var(--fs-sm); color: var(--text-2); max-width: 42rem; margin-bottom: var(--s-5); }

/* Dato legal pendiente de completar: debe verse a la primera. */
.ph {
  display: inline-block;
  padding: .05rem .4rem;
  font-family: var(--font-mono); font-size: .82em;
  color: var(--amber);
  background: var(--amber-soft);
  border: 1px dashed rgba(245, 158, 11, .5);
  border-radius: var(--r-xs);
}
.ph::before { content: "⌗ "; opacity: .7; }

/* Pie con copyright */
.site-footer__legal {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-3) var(--s-5);
  padding-bottom: var(--s-6);
  border-top: 1px solid var(--line);
  padding-top: var(--s-5);
}
.site-footer__legal p { font-size: var(--fs-xs); color: var(--text-3); }

@media (max-width: 760px) {
  .legal__toc ol { columns: 1; }
  .legal__dl { grid-template-columns: 1fr; }
  .legal__dl dt { padding-bottom: 0; background: var(--surface); color: var(--text-3); }
  .legal__dl dd { padding-top: .3rem; }
  .site-footer__legal { flex-direction: column; }
}

/* ============================================================
   25. PREGUNTAS FRECUENTES
   ============================================================ */
/* Título a la izquierda, acordeón a la derecha. */
.faq-layout {
  display: grid;
  grid-template-columns: minmax(0, .78fr) minmax(0, 1.55fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.faq-layout__head { position: sticky; top: 104px; }
.faq-layout__head .mono-label { margin-bottom: var(--s-4); }

.faq { border-top: 1px solid var(--line); }

.faq__item { border-bottom: 1px solid var(--line); }

/* <summary>: quitar el triángulo nativo en todos los navegadores. */
.faq__q {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ""; }

.faq__q h3 {
  font-size: 1.02rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -.012em;
  transition: color .2s var(--ease);
}
.faq__q:hover h3 { color: var(--cyan); }

.faq__chevron {
  flex: none;
  width: 1.15rem; height: 1.15rem;
  color: var(--text-3);
  transition: transform .3s var(--ease), color .2s var(--ease);
}
.faq__item[open] .faq__chevron { transform: rotate(180deg); color: var(--cyan); }
.faq__item[open] .faq__q h3 { color: var(--text); }

/* Apertura suave. `<details>` no anima de serie: pasa de cerrado a abierto de
   golpe. `::details-content` permite transicionar la altura, y el
   `interpolate-size` de :root es lo que hace animable el salto a `auto`.

   Va como MEJORA PROGRESIVA a proposito: donde no hay soporte, el acordeon se
   abre instantaneo, que es exactamente como se comportaba hasta ahora. Nada
   depende de esto para funcionar. */
.faq__item::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size var(--dur-ui-lg) var(--ease), content-visibility var(--dur-ui-lg) allow-discrete;
}
.faq__item[open]::details-content { block-size: auto; }

/* El foco tiene que VERSE, y sobre el acordeon no bastaba con el offset: no
   habia color declarado, asi que quedaba el de por defecto del navegador. */
.faq__q:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

.faq__a { padding-bottom: var(--s-5); max-width: 46rem; }
.faq__a p { font-size: var(--fs-sm); color: var(--text-2); }
.faq__a em { color: var(--text); font-style: normal; }

@media (max-width: 900px) {
  .faq-layout { grid-template-columns: 1fr; }
  .faq-layout__head { position: static; }
}

/* ============================================================
   26. PANEL INTERNO (/admin)
   ============================================================ */
/* Pantalla de entrada */
.entrar { display: grid; place-items: center; min-height: 100vh; padding: var(--s-5); }
.entrar__caja {
  width: 100%; max-width: 24rem;
  padding: clamp(1.5rem, 4vw, 2.2rem);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
}
.entrar__caja h1 { font-size: 1.5rem; margin: var(--s-3) 0 var(--s-5); }
.entrar__caja .form { padding: 0; background: none; border: 0; box-shadow: none; }
.field__ayuda { font-size: var(--fs-xs); color: var(--text-3); line-height: 1.5; }

.admin { padding-block: clamp(2rem, 5vw, 3.5rem) var(--s-9); }
.admin__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: var(--s-4);
  padding-bottom: var(--s-5); border-bottom: 1px solid var(--line);
}
.admin__head h1 { font-size: clamp(1.5rem, 3vw, 2rem); margin-top: var(--s-3); }
.admin__stats { display: flex; gap: .5rem; }

.admin__2fa {
  margin-top: var(--s-5);
  padding: clamp(1.2rem, 2.2vw, 1.8rem);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md);
}
.admin__2fa h2 { font-size: 1.05rem; margin-bottom: var(--s-3); }
.admin__2fa-estado { font-size: var(--fs-sm); color: var(--text-2); }
.admin__2fa-ayuda { margin-top: var(--s-4); font-size: var(--fs-sm); color: var(--text-2); max-width: 40rem; }
.admin__qr { margin-top: var(--s-4); width: 240px; max-width: 100%; background: #fff; padding: 10px; border-radius: var(--r-sm); }
.admin__qr svg { width: 100%; height: auto; display: block; }
.admin__secreto { margin-top: var(--s-3); }
.admin__secreto code { font-size: .8rem; color: var(--cyan); letter-spacing: .08em; }
.admin__2fa-form { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-4); align-items: center; }
.admin__2fa-form input {
  padding: .55rem .7rem; font: inherit; font-size: var(--fs-sm); color: var(--text);
  background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  max-width: 14rem;
}
.admin__codigos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: .4rem; margin-top: var(--s-4);
}
.admin__codigos li {
  padding: .4rem .6rem;
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .06em; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--r-xs);
  text-align: center;
}

.admin__bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--s-4);
  margin-top: var(--s-5);
}
.admin__bar .check span { font-size: var(--fs-sm); color: var(--text-2); }

.admin__status { margin-top: var(--s-4); font-size: var(--fs-sm); color: var(--text-3); }
.admin__status:empty { display: none; }
.admin__status[data-tipo="error"] {
  color: var(--amber); padding: .7rem .9rem;
  border: 1px solid rgba(245, 158, 11, .35); background: var(--amber-soft);
  border-radius: var(--r-sm);
}

.admin__tabla-wrap { margin-top: var(--s-5); overflow-x: auto; }
.admin__tabla { width: 100%; border-collapse: collapse; min-width: 62rem; }
.admin__tabla th {
  text-align: left; padding: .6rem .7rem;
  font-family: var(--font-mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-3); font-weight: 400;
  border-bottom: 1px solid var(--line-2);
}
.admin__tabla td {
  padding: .8rem .7rem; font-size: var(--fs-sm); color: var(--text-2);
  border-bottom: 1px solid var(--line); vertical-align: top;
}
.admin__tabla tr.is-spam td { opacity: .5; }
.admin__tabla tr:hover td { background: rgba(255, 255, 255, .018); }

.admin__fecha { font-family: var(--font-mono); font-size: .7rem; white-space: nowrap; }
.admin__sub, .admin__mail { display: block; font-size: var(--fs-xs); }
.admin__sub { color: var(--text-3); margin-top: .15rem; }
.admin__mail { color: var(--cyan); margin-top: .2rem; }
.admin__msg { max-width: 26rem; color: var(--text-3); }

.admin__sel, .admin__notas {
  width: 100%; padding: .4rem .5rem;
  font: inherit; font-size: var(--fs-xs); color: var(--text);
  background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-xs);
  transition: border-color .2s var(--ease);
}
.admin__notas { min-width: 12rem; }
.admin__sel:focus, .admin__notas:focus {
  outline: none; border-color: rgba(34, 211, 238, .6);
  box-shadow: 0 0 0 3px rgba(34, 211, 238, .12);
}
.is-saving { opacity: .5; }
.is-saved { border-color: rgba(52, 211, 153, .7) !important; }
.is-error { border-color: rgba(245, 158, 11, .7) !important; }

/* ============================================================
   27. PÁGINA 404
   ============================================================ */
.notfound {
  display: grid; place-items: center;
  min-height: 70vh;
  padding-block: var(--section-y);
  background: radial-gradient(46rem 30rem at 50% 0%, rgba(34, 211, 238, .07), transparent 62%);
}
.notfound__inner { max-width: 34rem; text-align: center; }
.notfound__inner .mono-label { margin-bottom: var(--s-4); }
.notfound__inner h1 { font-size: clamp(2rem, 5vw, 3.2rem); margin-bottom: var(--s-5); }
.notfound__actions {
  display: flex; flex-wrap: wrap; gap: var(--s-3); justify-content: center;
  margin-top: var(--s-7);
}
@media (max-width: 560px) {
  .notfound__actions .btn { flex: 1 1 100%; }
}

/* ============================================================
   28. TIPOGRAFÍAS AUTO-ALOJADAS (opcional)
   ------------------------------------------------------------
   La página se sirve hoy sin ninguna petición a terceros, lo que permite
   afirmar en la política de privacidad que no se comunican datos a
   proveedores externos por el simple hecho de visitarla.

   Para usar Inter y JetBrains Mono con su diseño original:
     1. Ejecuta scripts/get-fonts.ps1 (descarga los .woff2 a assets/fonts/).
     2. Descomenta el bloque siguiente.
     3. Añade en el <head> de cada página, antes de styles.css:
        <link rel="preload" href="assets/fonts/inter.woff2" as="font"
              type="font/woff2" crossorigin>

   NO descomentar sin los archivos: provocaría un 404 por carga de página.
   ============================================================ */
/*
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono.woff2") format("woff2-variations");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
}
*/

/* ============================================================
   PRINT
   ============================================================ */
@media print {
  .site-header, .drawer, .hero__glow, .hero__grid, .showcase__tabs { display: none !important; }
  body { background: #fff; color: #000; }
  .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   ARMAZON DE LA APLICACION
   --------------------------------------------------------------------------
   Reproduce la interfaz real de AI Data Lineage Mapper: barra superior, barra
   lateral con las nueve secciones y area de contenido.

   Antes esto eran nueve recuadros sueltos con pestanas encima, y esas pestanas
   eran un invento de la web: en el producto no existen, existe un menu lateral.
   Quien ha visto una demo tiene que reconocer esta pantalla.

   El menu ES el tablist. No se duplica el armazon por pantalla: hay UNA barra
   lateral y nueve paneles dentro del area principal, que es como se comporta
   la aplicacion.
   ========================================================================== */

/* — Aviso de que la seccion se recorre —
   Sin esto el bloque se lee como una captura fija y el visitante pasa de largo
   sin descubrir las otras ocho pantallas, que es justo lo que hay que ensenar.
   Va pegado al marco, no bajo el titular, porque senala al menu lateral. */
.tlhint {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .4rem .6rem;
  margin: 0 0 .75rem;
  font-family: var(--font-mono); font-size: .6875rem;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--cyan);
}
.tlhint__arrow {
  display: inline-block; font-size: .875rem;
  /* Apunta al menu, abajo a la izquierda. Se detiene en cuanto la persona
     interactua: entonces ya no hay nada que senalar. */
  animation: hintNudge 1.9s var(--ease) infinite;
}
.tlhint__count {
  padding: .1rem .4rem;
  border: 1px solid var(--line-2);
  letter-spacing: .14em; color: var(--text-3);
}

@keyframes hintNudge {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(-3px, 3px); }
}

/* El texto se adapta al dispositivo desde CSS, no desde JavaScript. Por debajo
   de 900px el menu deja de estar a la izquierda (ver .tlapp__body), asi que la
   redaccion y la direccion de la flecha cambian con el. */
.tlhint__narrow { display: none; }

/* Un halo tenue en el menu mientras nadie lo ha tocado: es la senal de donde
   hay que ir. En cuanto se usa, sobra. */
[data-showcase]:not(.has-interacted) .tlapp__nav {
  animation: menuPulse 2.4s var(--ease) infinite;
}
@keyframes menuPulse {
  0%, 100% { box-shadow: inset 2px 0 0 rgba(34, 211, 238, 0); }
  50%      { box-shadow: inset 2px 0 0 rgba(34, 211, 238, .55); }
}

/* Variantes para cuando el menu es una fila sobre los paneles. */
@keyframes hintNudgeDown {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(0, 3px); }
}
@keyframes menuPulseDown {
  0%, 100% { box-shadow: inset 0 -2px 0 rgba(34, 211, 238, 0); }
  50%      { box-shadow: inset 0 -2px 0 rgba(34, 211, 238, .55); }
}

/* Al usarse, el aviso deja de moverse pero NO se atenua. Atenuarlo parecia el
   gesto elegante y lo dejaba por debajo de AA de contraste: un texto que sigue
   en pantalla tiene que seguir siendo legible. Si estorbara, lo correcto seria
   quitarlo, no dejarlo a medio ver. */
[data-showcase].has-interacted .tlhint__arrow { animation: none; }

/* Quien pide menos movimiento suele tener una razon medica: se quita el
   movimiento, no el aviso. El texto y el halo estatico siguen ahi. */
@media (prefers-reduced-motion: reduce) {
  .tlhint__arrow { animation: none; }
  [data-showcase]:not(.has-interacted) .tlapp__nav {
    animation: none;
    box-shadow: inset 2px 0 0 rgba(34, 211, 238, .4);
  }
}

/* Con el menu en fila, la flecha apunta hacia abajo y el halo pasa al borde
   inferior, que es el que marca la pestana activa en esa disposicion.
   Va condicionado a `no-preference` y no dentro del bloque de 900px: ahi
   aparece mas abajo en la hoja y le habria devuelto la animacion a quien pidio
   no tenerla. */
@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  .tlhint__arrow { animation-name: hintNudgeDown; }
  [data-showcase]:not(.has-interacted) .tlapp__nav { animation-name: menuPulseDown; }
}
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  [data-showcase]:not(.has-interacted) .tlapp__nav {
    box-shadow: inset 0 -2px 0 rgba(34, 211, 238, .4);
  }
}

.tlapp {
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
  /* El halo azul verdoso del sistema visual, que se conserva, mas el reflejo
     superior del sistema de cristal para que el marco tenga la misma
     profundidad que el resto de superficies flotantes. Solo el MARCO: dentro
     van capturas del producto y ahi no entra ningun desenfoque. */
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    0 0 0 1px rgba(34, 211, 238, .07),
    0 24px 70px -30px rgba(34, 211, 238, .18);
}

/* Indicador de posicion entre las nueve pantallas. */
.tlapp__pos {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: .1em; color: var(--text-3);
  padding: var(--s-3) var(--s-4) 0;
  margin: 0;
}
.tlapp__pos b { color: var(--cyan); font-weight: 400; }

/* Entrada progresiva de la pantalla elegida. Muy corta y sin desplazamiento
   lateral: son capturas densas y moverlas de lado marea. */
.tlapp__body [role="tabpanel"]:not([hidden]) {
  animation: tlappEntra var(--dur-ui-lg) var(--ease) both;
}
@keyframes tlappEntra {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .tlapp__body [role="tabpanel"]:not([hidden]) { animation: none; }
}

/* ---- Barra superior ---- */
.tlapp__top {
  display: flex; align-items: center; gap: var(--s-3);
  padding: .5rem .75rem;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.tlapp__brand { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.tlapp__logo {
  display: grid; place-items: center;
  width: 26px; height: 26px; flex: none;
  border-radius: var(--r-xs);
  background: var(--blue); color: #fff;
  font-family: var(--font-mono); font-size: .6rem; font-weight: 700;
}
.tlapp__name { font-size: .72rem; font-weight: 600; color: var(--text); line-height: 1.15; }
.tlapp__tag  { font-size: .55rem; color: var(--text-3); line-height: 1.15; }

.tlapp__search {
  flex: 1 1 auto; min-width: 0;
  padding: .32rem .6rem;
  font-family: var(--font-mono); font-size: .6rem; color: var(--text-3);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xs);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tlapp__topright { display: flex; align-items: center; gap: .45rem; flex: none; }
.tlapp__mini { font-family: var(--font-mono); font-size: .55rem; color: var(--text-3); }
.tlapp__pill {
  padding: .18rem .45rem; border-radius: var(--r-xs);
  font-family: var(--font-mono); font-size: .55rem;
  color: var(--text-2); background: var(--surface); border: 1px solid var(--line);
}
.tlapp__pill--ai { color: #B79BFF; background: var(--violet-soft); border-color: rgba(139, 92, 246, .3); }

/* ---- Cuerpo: lateral + contenido ---- */
.tlapp__body { display: grid; grid-template-columns: 186px minmax(0, 1fr); }

.tlapp__nav {
  display: flex; flex-direction: column; gap: 1px;
  padding: .5rem .4rem;
  background: var(--surface-2);
  border-right: 1px solid var(--line);
}
.tlapp__nav .tab {
  display: block; width: 100%; text-align: left;
  padding: .4rem .55rem;
  border: 0; border-left: 2px solid transparent; border-radius: var(--r-xs);
  background: none; color: var(--text-2);
  font: inherit; font-size: .68rem; cursor: pointer;
}
.tlapp__nav .tab:hover { color: var(--text-2); background: var(--surface-3); }
.tlapp__nav .tab[aria-selected="true"] {
  color: var(--text); background: var(--surface-3);
  border-left-color: var(--blue);
}
.tlapp__nav-group {
  margin: .5rem 0 .2rem; padding: .4rem .55rem 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: .52rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3);
}

.tlapp__main { padding: var(--s-4); min-width: 0; background: var(--surface); }

/* ---- Cabecera de pantalla ---- */
.tlscreen__head {
  display: flex; align-items: flex-start; gap: .6rem;
  flex-wrap: wrap; margin-bottom: var(--s-3);
}
.tlscreen__icon {
  display: grid; place-items: center; width: 30px; height: 30px; flex: none;
  border-radius: var(--r-sm); background: var(--blue-soft); color: #7FB0FF; font-size: .8rem;
}
.tlscreen__titles { flex: 1 1 12rem; min-width: 0; }
.tlscreen__title { font-size: 1rem; font-weight: 600; color: var(--text); letter-spacing: -.02em; }
.tlscreen__sub   { font-size: .64rem; color: var(--text-3); margin-top: .1rem; }
.tlscreen__acts  { display: flex; gap: .35rem; flex-wrap: wrap; }
.tlact {
  padding: .28rem .55rem; border-radius: var(--r-xs);
  font-size: .6rem; color: var(--text-2);
  background: var(--surface-2); border: 1px solid var(--line);
}
.tlact--primary { color: #fff; background: var(--blue); border-color: var(--blue); }

/* ---- Tira de contexto ---- */
.tlctx {
  display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .9rem;
  padding: .4rem .6rem; margin-bottom: var(--s-3);
  font-size: .6rem; color: var(--text-3);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-xs);
}
.tlctx b { color: var(--text-2); font-weight: 600; }
.tlctx__end { margin-left: auto; display: flex; align-items: center; gap: .4rem; }

/* ---- Rejillas de contenido ---- */
.tlgrid { display: grid; gap: .6rem; margin-bottom: .6rem; }
.tlgrid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.tlgrid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tlgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tlgrid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* La tarjeta es columna flexible para que el enlace del pie pueda empujarse
   al fondo. Sin esto, «Ver detalle» y «Ver historial» quedaban pegados al
   ultimo dato y cada tarjeta de la fila los dejaba a una altura distinta; en
   el producto estan todos alineados abajo. */
.tlcard {
  display: flex; flex-direction: column;
  padding: .6rem .65rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  min-width: 0;
}
.tlcard__title { font-size: .68rem; font-weight: 600; color: var(--text); margin-bottom: .45rem; }

/* Cabecera de tarjeta: titulo a la izquierda y, a la derecha, lo que en el
   producto vive ahi y no abajo —«Ver todos», «Ver mapa completo», el numero de
   alertas o el selector de rango—. */
.tlcard__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .45rem;
}
.tlcard__head .tlcard__title { margin-bottom: 0; }
.tlcard__aside { font-size: .55rem; color: var(--text-3); white-space: nowrap; }
.tlcard__aside--link { color: #7FB0FF; }
.tlcard__sel {
  padding: .12rem .35rem; border-radius: var(--r-xs);
  font-size: .55rem; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--line); white-space: nowrap;
}

.tlcard__link { display: block; margin-top: auto; padding-top: .55rem; font-size: .58rem; color: #7FB0FF; }

/* Tarjeta anidada: el escaneo dentro de «Ultimos escaneos» tiene su propio
   marco en el producto, no es una lista suelta. */
.tlscan {
  padding: .45rem .5rem; border-radius: var(--r-xs);
  background: var(--surface); border: 1px solid var(--line-2);
}
.tlscan__top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.tlscan__date { font-size: .58rem; color: var(--text); font-weight: 600; }
.tlscan__meta { font-size: .5rem; color: var(--text-3); margin: .2rem 0 .35rem; }
.tlscan__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem; }
.tlscan__k { font-size: .5rem; color: var(--text-3); }
.tlscan__v { font-size: .8rem; font-weight: 600; color: var(--text); }

/* KPI con icono, como en el producto */
.tlkpi__top { display: flex; align-items: center; gap: .35rem; }
.tlkpi__ico { width: 16px; height: 16px; flex: none; border-radius: 4px; display: grid; place-items: center; font-size: .5rem; }
.tlkpi__ico--blue { background: var(--blue-soft); color: #7FB0FF; }
.tlkpi__ico--violet { background: var(--violet-soft); color: #B79BFF; }
.tlkpi__ico--green { background: var(--green-soft); color: var(--green); }
.tlkpi__ico--amber { background: var(--amber-soft); color: var(--amber); }
.tlkpi__label { font-size: .55rem; color: var(--text-3); line-height: 1.25; }
.tlkpi__val { font-size: 1.25rem; font-weight: 600; letter-spacing: -.03em; margin-top: .2rem; }
.tlkpi__val--green { color: var(--green); }
.tlkpi__sub { font-size: .5rem; color: var(--text-3); margin-top: .05rem; }

/* Anillo de Estado del linaje.

   Se apila —anillo arriba, leyenda debajo— y no en fila. En la aplicacion van
   uno al lado del otro, pero alli la tarjeta mide 380px; aqui es una de cuatro
   columnas dentro de un marco de ~1050px, o sea unos 230px. Con el anillo
   robando 84, a la leyenda le quedaban 130 y «Con linaje validado» se partia en
   tres lineas. Apilado entra en una. */
.tlring { display: grid; justify-items: center; gap: .55rem; }
.tlring__fig { text-align: center; }
.tlring__svg { display: block; width: 84px; height: 84px; }
.tlring .tllist { width: 100%; }

/* El cuerpo del numero va en UNIDADES DEL viewBox, no en rem.

   Estaba en `.95rem` y salia enorme: dentro de un SVG la medida se interpreta
   en el sistema de coordenadas del `viewBox` —42 unidades— y despues se escala
   al tamano real, asi que un valor pensado para pixeles se multiplicaba por
   dos. En unidades, 9 de 42 dan ~18px reales, que es lo que se busca.

   La etiqueta va FUERA del anillo. Dentro no cabe: el hueco mide 26,8 unidades
   de ancho y «Procesos totales» necesita mas, asi que se salia por encima del
   trazo. Debajo se lee bien y el anillo queda limpio. */
.tlring__n { font-size: 9px; font-weight: 700; fill: var(--text); }
.tlring__cap { margin-top: .15rem; font-size: .5rem; color: var(--text-3); }

.tllist { display: grid; gap: .3rem; min-width: 0; }
.tllist li { display: flex; align-items: center; gap: .35rem; font-size: .58rem; color: var(--text-2); }
.tllist b { margin-left: auto; color: var(--text); font-weight: 600; }
.tllist small { color: var(--text-3); font-size: .92em; }

.tlalert { display: flex; align-items: center; gap: .4rem; font-size: .58rem; color: var(--text-2); }
.tlalert b {
  margin-left: auto; padding: .04rem .3rem; border-radius: var(--r-pill);
  font-size: .52rem; font-weight: 600;
}
.tlalert b.is-red   { background: rgba(239, 68, 68, .15); color: #FCA5A5; }
.tlalert b.is-amber { background: var(--amber-soft); color: #FBBF24; }

.tlchat__in {
  padding: .35rem .5rem; font-size: .58rem; color: var(--text-3);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xs);
}
.tlchat__q {
  margin-top: .3rem; padding: .3rem .5rem; font-size: .56rem; color: var(--text-2);
  background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r-xs);
}

@media (max-width: 900px) {
  /* El menu no desaparece: es el unico control de la seccion. Pasa a fila
     desplazable, que es lo que hace la propia aplicacion cuando no cabe. */
  .tlapp__body { grid-template-columns: minmax(0, 1fr); }
  .tlapp__nav {
    flex-direction: row; overflow-x: auto; gap: .25rem;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  .tlapp__nav .tab { width: auto; white-space: nowrap; border-left: 0; border-bottom: 2px solid transparent; }
  .tlapp__nav .tab[aria-selected="true"] { border-left: 0; border-bottom-color: var(--blue); }
  .tlapp__nav-group { display: none; }

  /* Aqui el menu ya no esta a la izquierda: cambia la redaccion del aviso. */
  .tlhint__wide { display: none; }
  .tlhint__narrow { display: inline; }
  .tlgrid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tlgrid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tlapp__search, .tlapp__topright { display: none; }
}
@media (max-width: 560px) {
  .tlgrid--6, .tlgrid--4, .tlgrid--3, .tlgrid--2 { grid-template-columns: minmax(0, 1fr); }
}

/* Inventario y Catalogo: panel de filtros estrecho a la izquierda y tabla
   ancha a la derecha, como en el producto. */
.tlsplit { grid-template-columns: 200px minmax(0, 1fr); align-items: start; }
@media (max-width: 900px) { .tlsplit { grid-template-columns: minmax(0, 1fr); } }

/* Copilot: historial estrecho, chat ancho y contexto a la derecha, que es como
   se reparte la pantalla en el producto. */
.tlcop { grid-template-columns: 170px minmax(0, 1fr) 200px; align-items: start; }
@media (max-width: 900px) { .tlcop { grid-template-columns: minmax(0, 1fr); } }

/* ---- Hero: etiquetas de relacion, estado y tarjeta de evidencia ---------- */

/* Que significa cada arista. En mono y muy pequeno: tiene que leerse al
   acercarse, no competir con los nombres de los nodos. */
.edge-tag text {
  font-family: var(--font-mono); font-size: 7px;
  letter-spacing: .06em; fill: var(--text-3);
}

/* Marca de relacion ya revisada por una persona. */
.node__ok { font-family: var(--font-mono); font-size: 8px; fill: var(--green); }

/* Panel de detalle del nodo seleccionado.

   Va acoplado debajo del grafo, no flotando encima. Flotando se leia como el
   inspector de la aplicacion, que es lo que es, pero la columna del hero solo
   da ~530px: la tarjeta tapaba entera la columna de destinos. Acoplado no
   esconde nada y sigue leyendose como producto porque el nodo que describe
   queda marcado con .is-selected.

   Es ademas lo unico de toda la pagina que ningun competidor puede ensenar,
   porque exige haber leido el codigo. */
.lineage-evd {
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: .5rem .9rem;
  margin-top: var(--s-3); padding: .6rem .7rem;
  background: var(--surface-2);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
}
/* Si en algun ancho no caben nombre y etiqueta, la etiqueta baja de linea. Antes
   de eso preferimos eso a recortar el identificador. */
.lineage-evd__head {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .4rem;
}
/* El nombre del recurso no se parte: partido deja de leerse como identificador. */
.lineage-evd__name {
  font-family: var(--font-mono); font-size: .66rem; color: var(--text);
  white-space: nowrap;
}
.lineage-evd__head .tag { flex: none; }
.lineage-evd__sub { font-size: .58rem; color: var(--text-3); margin-top: .15rem; }

.lineage-evd__meter {
  display: grid; grid-template-columns: 1fr auto; gap: .2rem .4rem;
  margin-top: .5rem; font-size: .58rem; color: var(--text-3);
}
.lineage-evd__meter b { color: var(--green); font-size: .6rem; }
.lineage-evd__track {
  grid-column: 1 / -1; height: 3px; border-radius: 2px;
  background: var(--line); overflow: hidden;
}
.lineage-evd__track i { display: block; height: 100%; background: var(--green); }

.lineage-evd__label {
  font-family: var(--font-mono); font-size: .55rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-3);
}
.lineage-evd__list { display: grid; gap: .25rem; margin-top: .35rem; }
.lineage-evd__list li { font-size: .58rem; color: var(--text-2); line-height: 1.45; }
.lineage-evd__list code { color: #B79BFF; font-size: .95em; }

/* En estrecho el grafo ya hace scroll horizontal; el panel se apila. */
@media (max-width: 760px) {
  .lineage-evd { grid-template-columns: 1fr; }
}
