/* ============================================================================
   pibiCo Auth — landing pública (se sirve en "/" solo cuando no hay marcadores
   de SSO; con `?app=`, `?redirect=`… `web.py` devuelve el formulario de login).

   Aislamiento: TODO lo que repinta la cáscara compartida va bajo
   `html:has(.auth-landing)`, de modo que /login, /account, /admin y /guia no se
   enteran. `pibico.css`, `collab.css` y `auth.css` NO se tocan: son comunes.

   Marca: tokens de `pibico.css` — degradado, glass blanco, Raleway/Montserrat/
   Inter. La libertad se gasta en composición y movimiento, no en la paleta.
   ========================================================================= */

/* ── Cáscara ──────────────────────────────────────────────────────────────
   El degradado se toma de `--bg-gradient` en vez de reescribirlo. La versión
   anterior declaraba `linear-gradient(140deg, … 52% …)`: dos grados y un stop
   de diferencia con el canon, lo justo para que la landing no casara con
   /login, que es literalmente la página siguiente.                          */
html:has(.auth-landing) {
  background: var(--bg-gradient);
  background-attachment: fixed;
  color: #f5f9fc;
}
html:has(.auth-landing) body { min-height: 100vh; }

/* El navbar medía 33 px de alto con un botón de 32 px dentro: cero holgura
   arriba y abajo, y los controles pegados a los bordes. El canon de la casa son
   48 px. Se corrige acotado a la landing para no alterar /login, /account ni
   /admin, que comparten la cáscara — allí el mismo apretón sigue, y conviene
   arreglarlo, pero es un cambio de otro alcance. */
html:has(.auth-landing) .app-header {
  min-height: 48px;
  padding-top: 6px;
  padding-bottom: 6px;
  box-sizing: border-box;
  background: rgba(20, 40, 64, 0.42);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}
html:has(.auth-landing) .app-header-title #brandName { color: #fff; }
html:has(.auth-landing) .pibico-lang-btn { color: #eaf2fa; }

/* La landing crece; la app no. `collab.css` da `.app-main { overflow: hidden }`
   para que las tarjetas scrolleen por dentro, y aquí hace lo contrario. */
html:has(.auth-landing) main.app-main {
  padding: 0;
  display: block;
  overflow: visible;
  flex: none;
  min-height: auto;
}

html:has(.auth-landing) .app-footer {
  background: transparent;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.72);
}
html:has(.auth-landing) .app-footer a { color: rgba(255, 255, 255, 0.88); }

/* ── Retícula ─────────────────────────────────────────────────────────── */
.auth-landing { width: 100%; }
.lnd-wrap {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 28px;
}
.lnd-wrap-narrow { max-width: 800px; }

/* El aire entre secciones eran 168 px fijos entre cada par (84 + 84): un 14 %
   de la página en vacío, y sin escalar con la ventana — el mismo hueco en un
   portátil que en un monitor de 27". Ahora es fluido y con un techo más bajo. */
.lnd-band { padding: clamp(46px, 4.8vw, 68px) 0; }
.lnd-band--tight { padding: clamp(34px, 3.4vw, 48px) 0; }

/* Banda oscura: una capa de tinta sobre el degradado, no un color plano, para
   que el fondo de marca siga leyéndose por debajo. */
.lnd-band--ink {
  background: linear-gradient(180deg, rgba(10, 24, 40, 0.55), rgba(10, 24, 40, 0.35));
}
.lnd-band--close {
  background: linear-gradient(180deg, rgba(10, 24, 40, 0.0), rgba(10, 24, 40, 0.45));
  padding-bottom: clamp(56px, 5.4vw, 78px);
}

/* ── Tipografía ────────────────────────────────────────────────────────────
   Montserrat llega hasta 700 en `fonts.css`. La versión anterior pedía 800 en
   el wordmark del hero, así que el navegador lo sintetizaba: falso negrita
   emborronado a 5rem. Aquí no se pide ningún peso que no exista.            */
.lnd-eyebrow,
.lnd-kicker {
  font-family: var(--font-brand, 'Raleway', sans-serif);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.72rem;
  font-weight: 700;
  margin: 0 0 14px;
  color: rgba(255, 255, 255, 0.72);
}
.lnd-h1 {
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 700;
  font-size: clamp(2.1rem, 5.4vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin: 0;
  max-width: 16ch;
  color: #fff;
}
.lnd-h1 em {
  display: block;
  font-style: normal;
  color: #bfe0ff;
}
.lnd-h2 {
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 700;
  font-size: clamp(1.45rem, 3.4vw, 2.1rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
  color: #fff;
  max-width: 22ch;
}
.lnd-sec-head { margin-bottom: 34px; }
.lnd-sec-sub {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.74);
  margin: 10px 0 0;
}
.mono { font-family: var(--font-mono, 'JetBrains Mono', monospace); }

/* ── Hero: recorrido por scroll ────────────────────────────────────────────
   La sección mide varias pantallas de alto y su contenido se queda pegado
   (`position: sticky`) mientras se recorre: ese desplazamiento es el que
   `landing.js` traduce a fotograma del pasillo. El canvas evita el parpadeo de
   cambiar el `src` de un <img> 40 veces. Si no hay JS —o el usuario pidió menos
   movimiento— se ve `.lnd-hero-fallback`, un fotograma fijo.               */
.lnd-hero {
  position: relative;
  /* 240vh eran 2,4 pantallas: el 55 % de TODA la página se iba en el hero.
     El recorrido útil es `alto - track` (landing.js:60), o sea 140vh para 40
     fotogramas: sobraba. A 185vh quedan 85vh de recorrido, que siguen siendo
     dos pantallas largas de scrub y quitan casi 700 px de scroll. */
  height: 185vh;               /* recorrido; la vista real es el track pegado */
}
.lnd-hero-track {
  position: sticky; top: 0;
  height: 100vh; min-height: 560px;
  display: flex; align-items: center;
  overflow: hidden;
}
.lnd-hero-media { position: absolute; inset: 0; z-index: 0; }
.lnd-hero-media canvas,
.lnd-hero-fallback {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.lnd-hero-media canvas { display: none; }
html.lnd-scrub .lnd-hero-media canvas { display: block; }
html.lnd-scrub .lnd-hero-fallback { display: none; }

/* El vídeo tiene el tercio izquierdo en sombra: la cortina lo refuerza para que
   el texto blanco tenga contraste garantizado en cualquier fotograma. */
.lnd-hero-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(8, 20, 34, 0.90) 0%, rgba(8, 20, 34, 0.66) 42%, rgba(8, 20, 34, 0.20) 78%, rgba(8, 20, 34, 0.36) 100%),
    linear-gradient(180deg, rgba(8, 20, 34, 0.48) 0%, rgba(8, 20, 34, 0) 30%, rgba(8, 20, 34, 0.58) 100%);
}
/* La luz que se cuela por la puerta, seguida por el cursor. Es el mismo gesto
   que el metraje, no un efecto de adorno: refuerza de dónde viene la luz. */
.lnd-hero-spill {
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(420px circle at var(--luz-x, 70%) var(--luz-y, 45%),
              rgba(255, 214, 160, 0.16), rgba(255, 214, 160, 0) 62%);
  opacity: 0; transition: opacity 0.5s ease;
}
html.lnd-scrub .lnd-hero-spill { opacity: 1; }

.lnd-hero-inner { position: relative; z-index: 1; padding-top: 40px; padding-bottom: 40px; }

.lnd-hero-sub {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: clamp(0.98rem, 1.7vw, 1.12rem);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.84);
  max-width: 52ch;
  margin: 20px 0 0;
}

.lnd-cta-row {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: 28px;
}

.lnd-facts {
  display: flex; flex-wrap: wrap; gap: 34px;
  margin: 44px 0 0;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}
.lnd-facts div { display: flex; flex-direction: column; gap: 4px; }
.lnd-fact-n {
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 1.7rem; font-weight: 400; line-height: 1;
  color: #fff;
}
.lnd-fact-l {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.78);
  margin: 0; max-width: 18ch;
}

/* Marca de que hay recorrido por delante: una línea que baja, nada más. */
.lnd-scroll-hint {
  position: absolute; left: 50%; bottom: 26px; z-index: 1;
  width: 1px; height: 46px;
  background: rgba(255, 255, 255, 0.22);
  overflow: hidden;
}
.lnd-scroll-line {
  display: block; width: 100%; height: 40%;
  background: rgba(255, 255, 255, 0.85);
  animation: lndBaja 2.4s cubic-bezier(0.6, 0, 0.4, 1) infinite;
}
@keyframes lndBaja {
  0% { transform: translateY(-120%); }
  100% { transform: translateY(280%); }
}

/* ── Botones ──────────────────────────────────────────────────────────── */
.lnd-btn {
  display: inline-flex; align-items: center; gap: 9px;
  text-decoration: none;
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 0.95rem; line-height: 1.2;
  padding: 13px 24px;
  border-radius: var(--radius-sm, 8px);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.lnd-btn svg {
  width: 17px; height: 17px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform 0.15s ease;
}
.lnd-btn:hover svg { transform: translateX(3px); }
.lnd-btn-primary {
  background: #fff; color: var(--accent-color, #2c5171);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.24);
}
.lnd-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 14px 38px rgba(0, 0, 0, 0.32); }
/* Regla de la casa: botón claro sobre fondo claro lleva línea. Estos van sobre
   fondo oscuro, así que la línea es la que les da cuerpo. */
.lnd-btn-ghost {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.34);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.lnd-btn-ghost:hover { background: rgba(255, 255, 255, 0.16); transform: translateY(-2px); }
.lnd-btn-outline {
  background: transparent; color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
}
.lnd-btn-outline:hover { background: rgba(255, 255, 255, 0.1); }

/* ── Pilares (glass canónico blanco) ───────────────────────────────────────
   La versión anterior usaba glass OSCURO (`rgba(13,30,48,.36)`), que no es el
   de la casa y además obliga a texto blanco sobre un fondo semitransparente
   encima de un degradado: el contraste depende de qué haya detrás. El glass
   canónico es blanco 0.85 con tinta `--accent-color`, que es exactamente la
   tarjeta que el visitante ve un clic después en /login.                    */
.lnd-pillars {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}
@media (min-width: 780px) { .lnd-pillars { grid-template-columns: 1fr 1fr; } }

.lnd-pillar {
  background: var(--glass-bg, rgba(255, 255, 255, 0.85));
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--glass-border, rgba(255, 255, 255, 0.3));
  border-radius: var(--radius-card, 24px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  padding: 26px 26px 24px;
}
.lnd-pillar-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  border-radius: var(--radius, 12px);
  margin-bottom: 14px;
  background: rgba(70, 130, 180, 0.14);
  color: var(--accent-color, #2c5171);
}
.lnd-pillar-ico svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.lnd-pillar h3 {
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 1.06rem; line-height: 1.25;
  margin: 0 0 8px;
  color: var(--accent-color, #2c5171);
}
.lnd-pillar p {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.9rem; line-height: 1.55;
  margin: 0;
  color: var(--text-color, #333);
}

/* ── El pasillo ────────────────────────────────────────────────────────────
   Seis puertas en fila; la abierta se ensancha. Es la misma figura que el
   vídeo del hero, convertida en navegación: un pasillo, muchas puertas, una
   llave. Funciona SIN JavaScript (`:hover` y `:focus-within` abren), así que
   `landing.js` solo añade fijar con clic y mover con flechas.               */
.lnd-corridor {
  display: flex;
  gap: 6px;
  height: 264px;
  border-radius: var(--radius-card, 24px);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(8, 20, 34, 0.32);
}
.lnd-door {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
  font-family: var(--font-body, 'Inter', sans-serif);
  overflow: hidden;
  transition: flex-grow 0.42s cubic-bezier(0.2, 0.8, 0.2, 1),
              background 0.3s ease;
}
.lnd-door:hover,
.lnd-door:focus-within,
.lnd-door.is-open { flex-grow: 4.2; background: rgba(255, 255, 255, 0.1); }

/* El control cubre la puerta entera: se pulsa en cualquier punto. Su nombre
   accesible es solo el rótulo —el cuerpo vive fuera del botón—, y `aria-expanded`
   dice si está abierta. */
.lnd-door-btn {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: stretch; justify-content: flex-start;
  margin: 0; padding: 0; border: 0;
  background: transparent;
  color: inherit; font: inherit; text-align: left;
  cursor: pointer;
}
.lnd-door-btn:focus-visible { outline: 2px solid #bfe0ff; outline-offset: -2px; }

/* La jamba: una línea cálida que se enciende al abrir, el mismo gesto que la
   luz que se cuela por la puerta entreabierta del vídeo. */
.lnd-door-spine {
  position: absolute; left: 0; top: 0; bottom: 0; z-index: 3;
  width: 2px;
  background: linear-gradient(180deg, rgba(255, 220, 170, 0), rgba(255, 220, 170, 0.85), rgba(255, 220, 170, 0));
  opacity: 0;
  transition: opacity 0.35s ease;
}
.lnd-door:hover .lnd-door-spine,
.lnd-door:focus-within .lnd-door-spine,
.lnd-door.is-open .lnd-door-spine { opacity: 1; }

/* Cara cerrada: icono arriba y rótulo en vertical, como el lomo de una carpeta
   en una estantería de archivo. */
.lnd-door-face {
  display: flex; flex-direction: column; align-items: center;
  gap: 14px;
  padding: 20px 0;
  width: 62px;
  flex: 0 0 62px;
  transition: opacity 0.25s ease;
}
.lnd-door-ico { color: rgba(255, 255, 255, 0.9); }
.lnd-door-ico svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.lnd-door-title {
  writing-mode: vertical-rl;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.78);
  white-space: nowrap;
}
.lnd-door:hover .lnd-door-face,
.lnd-door:focus-within .lnd-door-face,
.lnd-door.is-open .lnd-door-face { opacity: 0; }

/* Habitación: lo que hay detrás de la puerta. */
.lnd-door-room {
  position: absolute;
  inset: 0; z-index: 1;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 8px;
  padding: 24px 24px 26px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s ease 0.08s, transform 0.3s ease 0.08s;
  pointer-events: none;
}
.lnd-door:hover .lnd-door-room,
.lnd-door:focus-within .lnd-door-room,
.lnd-door.is-open .lnd-door-room { opacity: 1; transform: none; }
.lnd-door-h {
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 1.04rem; line-height: 1.2;
  color: #fff;
}
.lnd-door-b {
  font-size: 0.86rem; line-height: 1.5;
  color: rgba(255, 255, 255, 0.78);
  max-width: 42ch;
}

/* ── Ecosistema ───────────────────────────────────────────────────────── */
/* Puertas, no tarjetas. La página entera va de un pasillo y de puertas que se
   abren con la misma llave; esta sección es el desenlace, así que usa el mismo
   lenguaje en vez de una fila de fichas de cristal.
   La norma de la casa prohíbe las franjas de canto en las tarjetas y admite
   SOLO tinte de fondo, sombra y glow. La primera versión de esto llevaba una
   junta luminosa de 3 px en el borde izquierdo: eso es una franja, por mucho
   que se llame «rendija de puerta». La luz se hace ahora con un halo radial
   anclado al canto —glow puro, sin línea—, que además queda más cerca de lo que
   hace la luz de verdad: no dibuja un filo, se derrama. */
/* El pasillo y sus puertas, en una sola composición.
   `--luz-pasillo` es el vínculo entre las dos mitades: cada puerta declara su
   color y, al pasar por encima, `:has()` lo sube hasta este contenedor, que es
   quien tiñe el halo del vídeo. Sin JS. */
.lnd-leads {
  --luz-pasillo: rgba(120, 170, 215, 0.16);
  display: grid; grid-template-columns: 1fr; gap: 22px;
}
@media (min-width: 980px) {
  /* `stretch`, no `start`: el spot es 16:9 y la lista de puertas es más alta,
     así que dejaba un vacío de 184 px bajo el vídeo. Estirado y recortado con
     `object-fit: cover` las dos columnas acaban a la misma altura — y el
     pasillo, más vertical, se parece más a lo que es. */
  .lnd-leads { grid-template-columns: 1.06fr 0.94fr; gap: 30px; align-items: stretch; }
  .lnd-spot { height: 100%; }
  .lnd-spot video { height: 100%; object-fit: cover; }
}
.lnd-leads:has(.lnd-app--t2d:hover), .lnd-leads:has(.lnd-app--t2d:focus-visible) { --luz-pasillo: rgba(106, 180, 240, 0.34); }
.lnd-leads:has(.lnd-app--scr:hover), .lnd-leads:has(.lnd-app--scr:focus-visible) { --luz-pasillo: rgba(168, 142, 240, 0.34); }
.lnd-leads:has(.lnd-app--cat:hover), .lnd-leads:has(.lnd-app--cat:focus-visible) { --luz-pasillo: rgba(142, 150, 168, 0.26); }

/* Un solo paquete, no tres fichas sueltas: las puertas van pegadas y el
   redondeo vive en el CONTENEDOR, con `overflow: hidden`, así que los cantos
   de arriba y de abajo salen curvos y los de la de en medio, rectos — sin
   tener que darle un radio distinto a cada hija.
   La juntura es un hueco de 1 px por el que se ve el fondo del `<ul>`: es una
   rendija, no una línea dibujada, así que no hay ninguna franja de canto. */
.lnd-doors {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: var(--radius, 12px);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: 0 16px 38px rgba(3, 9, 17, 0.34);
}
.lnd-app {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; height: 100%;
  padding: 18px 20px 16px 24px;
  text-decoration: none;
  /* Sin borde ni radio propios: los pone el paquete. Y sin `translateY` al
     pasar por encima — levantar una hoja rompería la pila; lo que cambia es la
     luz, que es el lenguaje de toda la página. */
  border: 0; border-radius: 0;
  background:
    linear-gradient(158deg, rgba(13, 28, 45, 0.90) 0%, rgba(7, 15, 26, 0.97) 100%);
  transition: background 0.42s ease;
}
/* El halo: la luz de la habitación de detrás, derramándose por el canto. Sin
   filo, sin línea — un radial que nace fuera del panel y se apaga hacia dentro.
   Se ve ya en reposo, porque si no la hoja parece una tarjeta vacía, y sube al
   acercarse. Va en `::after` sobre el fondo, que es lo que la norma admite. */
.lnd-app-halo {
  position: absolute; left: -34px; top: 12%; bottom: 12%; width: 96px;
  pointer-events: none;
  background: radial-gradient(closest-side,
              var(--luz-tenue, rgba(106, 180, 240, 0.26)) 0%, transparent 100%);
  filter: blur(9px);
  opacity: 0.85;
  transition: opacity 0.42s ease, transform 0.42s ease;
}
.lnd-app::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(128% 82% at -6% 44%, var(--luz-tenue, rgba(106, 180, 240, 0.26)) 0%, transparent 60%);
  opacity: 0.55; transition: opacity 0.45s ease;
}
.lnd-app:hover, .lnd-app:focus-visible {
  background:
    linear-gradient(158deg, rgba(18, 36, 56, 0.92) 0%, rgba(9, 19, 32, 0.97) 100%);
}
/* El foco de teclado necesita verse sin depender del color de fondo. */
.lnd-app:focus-visible { outline: 2px solid var(--luz, #6AB4F0); outline-offset: -3px; }
.lnd-app:hover .lnd-app-halo,
.lnd-app:focus-visible .lnd-app-halo { opacity: 1; transform: translateX(9px); }
.lnd-app:hover::after, .lnd-app:focus-visible::after { opacity: 1; }

.lnd-app-cuerpo { display: flex; flex-direction: column; gap: 6px; }
.lnd-app h3 {
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 700; font-size: 1.06rem; margin: 0;
  color: #fff; letter-spacing: -0.01em;
}
.lnd-app-que {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.88rem; line-height: 1.5; margin: 0;
  color: rgba(255, 255, 255, 0.82);
}
/* La línea que ata la sección con la tesis de la página: qué te da la llave
   una vez dentro. Va marcada con la luz de la puerta. */
/* Se distingue por color y cuerpo, no por un filo lateral: la misma norma
   que vale para la tarjeta vale para lo que va dentro. */
.lnd-app-llave {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.78rem; line-height: 1.45; font-weight: 500;
  color: var(--luz, #6AB4F0);
  letter-spacing: 0.005em;
}
/* El pie se separa con aire, no con un filo: ninguna línea de canto dentro de
   la tarjeta. */
.lnd-app-pie {
  margin-top: auto; padding-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.lnd-app-host {
  font-size: 0.72rem;
  color: rgba(197, 214, 230, 0.9);
  padding-top: 0; margin-top: 0;
}
.lnd-app-flecha {
  width: 17px; height: 17px; flex-shrink: 0;
  fill: none; stroke: var(--luz, #6AB4F0); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.55;
  transition: transform 0.42s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.42s ease;
}
.lnd-app:hover .lnd-app-flecha,
.lnd-app:focus-visible .lnd-app-flecha { opacity: 1; transform: translateX(4px); }

/* El catálogo se lee más apagado: es una promesa, no una puerta abierta. */
.lnd-app--cat { background: linear-gradient(158deg, rgba(11, 23, 38, 0.86) 0%, rgba(6, 13, 23, 0.95) 100%); }
.lnd-app--cat:hover, .lnd-app--cat:focus-visible {
  background: linear-gradient(158deg, rgba(15, 30, 47, 0.90) 0%, rgba(8, 17, 28, 0.96) 100%);
}
.lnd-app--cat .lnd-app-halo { opacity: 0.3; }
.lnd-app--cat h3 { color: rgba(255, 255, 255, 0.9); font-size: 1.06rem; }
.lnd-app--cat .lnd-app-llave { color: rgba(186, 199, 216, 0.95); }

@media (prefers-reduced-motion: reduce) {
  .lnd-app, .lnd-app-halo, .lnd-app::after, .lnd-app-flecha { transition: none; }
  .lnd-app:hover .lnd-app-flecha,
  .lnd-app:hover .lnd-app-halo { transform: none; }
}

/* ── Spot: ya no es una banda aparte, es la mitad izquierda de «a dónde
   llevan». El halo que lo rodea toma el color de la puerta sobre la que esté
   el cursor (`--luz-pasillo`), que es lo que ata las dos mitades. ── */
.lnd-spot { position: relative; margin: 0; }
.lnd-spot::before {
  content: ""; position: absolute; inset: -26px; z-index: 0;
  pointer-events: none;
  background: radial-gradient(closest-side, var(--luz-pasillo, rgba(120,170,215,0.16)) 0%, transparent 100%);
  filter: blur(16px);
  transition: background 0.5s ease;
}
.lnd-spot video {
  position: relative; z-index: 1;
  width: 100%; display: block;
  border-radius: var(--radius, 12px);
  background: #0a1828;
  box-shadow: 0 22px 52px rgba(3, 9, 17, 0.42);
}
.lnd-spot-play { z-index: 2; }
.lnd-spot-play {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 22px;
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 999px;
  background: rgba(10, 24, 40, 0.55);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  color: #fff; cursor: pointer;
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 0.9rem;
  transition: background 0.2s ease, transform 0.15s ease, opacity 0.25s ease;
}
.lnd-spot-play:hover { background: rgba(10, 24, 40, 0.75); transform: translate(-50%, -50%) scale(1.04); }
.lnd-spot-play svg { width: 18px; height: 18px; fill: currentColor; stroke: none; }
.lnd-spot-play.is-hidden { opacity: 0; pointer-events: none; }

/* ── Cierre ───────────────────────────────────────────────────────────── */
.lnd-close { text-align: center; }
.lnd-close .lnd-h2 { max-width: none; margin: 0 auto; }
.lnd-close > p {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 1rem; line-height: 1.55;
  color: rgba(255, 255, 255, 0.8);
  margin: 14px auto 0; max-width: 52ch;
}
.lnd-close .lnd-cta-row { justify-content: center; }
.lnd-legal {
  margin-top: 26px;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.6);
}
.lnd-legal a { color: rgba(255, 255, 255, 0.8); text-decoration: none; }
.lnd-legal a:hover { text-decoration: underline; }
.lnd-legal-sep { margin: 0 8px; opacity: 0.5; }

/* ── Aparición al hacer scroll ────────────────────────────────────────────
   Clase-gancho sin CSS propio hasta que `landing.js` marca `.lnd-ready` en
   <html>. Así, si el JS no llega a ejecutarse, el contenido se ve: nunca se
   oculta nada que dependa de un script para volver a aparecer.              */
html.lnd-ready .lnd-rv {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s cubic-bezier(0.2, 0, 0.2, 1), transform 0.6s cubic-bezier(0.2, 0, 0.2, 1);
}
html.lnd-ready .lnd-rv.is-in { opacity: 1; transform: none; }

/* ── Panel de solicitud ───────────────────────────────────────────────────
   El shell (`.slide-panel`, `.panel-header`, `.panel-body`, `.sp-field`) lo
   pone `auth.css` y NO se redefine: solo se añade lo que el panel de la
   landing tiene de más — el pie de acciones y el texto introductorio.       */
.lnd-req-form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.lnd-req-lede {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.85rem; line-height: 1.55;
  color: var(--text-light, #666);
  margin: 0 0 16px;
}
.lnd-req-legal {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.72rem; line-height: 1.5;
  color: var(--text-light, #666);
  margin: 4px 0 0;
}
.lnd-req-legal a { color: var(--primary-color, #4682b4); }
.lnd-req-actions {
  display: flex; gap: 8px; justify-content: flex-end; align-items: center;
  padding: 12px 20px;
  border-top: 1px solid #e5e7eb;
  background: #fff;
  flex-shrink: 0;
}
.lnd-btn-sm {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-weight: 600; font-size: 0.875rem; line-height: 1.2;
  padding: 8px 16px;
  border-radius: var(--radius-sm, 8px);
  cursor: pointer;
  transition: all 0.2s;
}
.lnd-btn-sm:disabled { opacity: 0.55; cursor: not-allowed; }
.lnd-btn-sm-primary {
  background: var(--primary-color, #4682b4); color: #fff;
  border: 1px solid var(--primary-color, #4682b4);
}
.lnd-btn-sm-primary:hover:not(:disabled) {
  background: var(--accent-color, #2c5171); border-color: var(--accent-color, #2c5171);
  transform: translateY(-1px);
}
/* Botón claro sobre fondo claro: línea obligatoria, o no se lee como control. */
.lnd-btn-sm-ghost {
  background: transparent; color: var(--text-light, #666);
  border: 1px solid rgba(44, 81, 113, 0.22);
}
.lnd-btn-sm-ghost:hover { background: rgba(0, 0, 0, 0.05); border-color: rgba(44, 81, 113, 0.4); }

/* ── Móvil ────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  .lnd-wrap { padding: 0 20px; }
  .lnd-band { padding: 60px 0; }
  .lnd-hero { min-height: 78vh; }
  .lnd-h1 { max-width: none; }
  .lnd-facts { gap: 22px; }

  /* El pasillo se pone de pie: seis filas que se despliegan hacia abajo. La
     misma idea, girada, porque en 360 px seis columnas no caben. */
  .lnd-corridor { flex-direction: column; height: auto; gap: 4px; }
  .lnd-door { flex: 0 0 auto; min-height: 56px; }
  .lnd-door:hover,
  .lnd-door:focus-within,
  .lnd-door.is-open { flex-grow: 0; }
  .lnd-door-face {
    flex-direction: row; align-items: center; gap: 12px;
    width: auto; flex: 1 1 auto;
    padding: 0 18px;
  }
  .lnd-door-title { writing-mode: horizontal-tb; }
  .lnd-door-btn { position: static; inset: auto; }
  .lnd-door-room {
    position: static; inset: auto;
    padding: 0 18px 18px;
    max-height: 0; overflow: hidden;
    transform: none;
    transition: max-height 0.35s ease, opacity 0.25s ease, padding 0.35s ease;
  }
  .lnd-door:hover .lnd-door-face,
  .lnd-door:focus-within .lnd-door-face,
  .lnd-door.is-open .lnd-door-face { opacity: 1; }
  .lnd-door.is-open { padding-bottom: 0; }
  /* Esta era la ÚNICA regla que devolvía altura por debajo de 760 px y solo
     miraba `.is-open`, que sin JS es estática: cinco de las seis puertas no se
     podían abrir en móvil sin JavaScript. */
  .lnd-door:hover .lnd-door-room,
  .lnd-door:focus-within .lnd-door-room,
  .lnd-door.is-open .lnd-door-room { max-height: 340px; padding-top: 12px; }
  .lnd-door:not(.is-open):not(:hover):not(:focus-within) .lnd-door-room { opacity: 0; }
  .lnd-door { flex-direction: column; align-items: stretch; }
  .lnd-door-face { min-height: 56px; }
}

/* ── Movimiento reducido ──────────────────────────────────────────────────
   Con `prefers-reduced-motion` no se esconde nada detrás de una animación:
   las seis puertas quedan abiertas en rejilla y las apariciones se anulan.  */
@media (prefers-reduced-motion: reduce) {
  .auth-landing *,
  .auth-landing *::before,
  .auth-landing *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
  html.lnd-ready .lnd-rv { opacity: 1; transform: none; }

  .lnd-corridor {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    height: auto;
    gap: 1px;
  }
  .lnd-door { min-height: 150px; }
  /* El botón se oculta ENTERO, no solo su cara: `.lnd-door-face` era su único
     contenido, así que esconderla dejaba seis botones sin nombre accesible
     (WCAG 4.1.2) y seis paradas de tabulación invisibles con el anillo de foco
     recortado a 0 px (WCAG 2.4.7). Con las habitaciones ya abiertas en rejilla
     el control no aporta nada. */
  .lnd-door-btn { display: none; }
  .lnd-door-btn { position: static; inset: auto; height: 0; overflow: hidden; }
  .lnd-door-room {
    position: static; inset: auto;
    opacity: 1; transform: none;
    justify-content: flex-start;
    max-height: none; overflow: visible;
  }
  .lnd-hero-media video { display: none; }
}

/* ── La demostración del acceso sin contraseña ────────────────────────────
   Tres estados en el mismo hueco: formulario → correo con el código → dentro.
   Se superponen en la misma caja para que la altura no salte al cambiar de
   paso, que es lo que convierte una demo en un tirón visual.               */
.lnd-band--demo {
  background: linear-gradient(180deg, rgba(10, 24, 40, 0.42), rgba(10, 24, 40, 0.18));
}
/* La caja medía 804 px de ancho para un solo campo de correo: una barra vacía,
   no una pantalla. Acotada a 440 px y con la composición centrada, la demo pasa
   a leerse como lo que imita —la pantalla de acceso— y los seis dígitos del
   código, que es el momento bueno, dejan de perderse en el vacío. */
.lnd-demo { display: grid; gap: 22px; }
@media (min-width: 900px) {
  .lnd-demo {
    grid-template-columns: 176px minmax(0, 440px);
    /* A la izquierda, no centrada: el kicker, el H2 y la entradilla de la
       sección van alineados a la izquierda y una demo centrada quedaba
       desplazada 200 px respecto a su propio titular. */
    justify-content: start;
    gap: 46px; align-items: start;
  }
}

.lnd-demo-steps {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}
/* Sin filos entre pasos: el estado ya lo dicen el número y el color, que es
   para lo que sirven. Las líneas solo añadían peso a una columna que no lo
   necesitaba. */
.lnd-demo-steps li {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 0;
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.42);
  transition: color 0.35s ease;
}
.lnd-demo-steps li.is-now { color: #fff; }
.lnd-demo-steps li.is-done { color: rgba(255, 255, 255, 0.62); }
.lnd-step-n {
  width: 22px; height: 22px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 0.68rem; line-height: 1;
  transition: all 0.35s ease;
}
.lnd-demo-steps li.is-now .lnd-step-n {
  background: #fff; color: var(--accent-color, #2c5171); border-color: #fff;
}
.lnd-demo-steps li.is-done .lnd-step-n { border-color: rgba(255, 255, 255, 0.5); }

/* El escenario tenía `min-height: 236px` a ojo, con las tres tarjetas
   superpuestas en `position:absolute; inset:0`. Medido: los pasos miden 195,
   157 y 278 px, así que el 1 —el que ve todo el mundo al llegar— dejaba 41 px
   de hueco muerto y el 3 se salía de su caja por 42.
   Ahora la tarjeta activa vuelve al flujo y es ella la que da la altura, de
   modo que el escenario se ajusta solo a cada paso. `landing.js` fija además
   la altura en píxeles antes de cambiar de paso para que el cambio se anime en
   vez de dar un salto; sin JS la regla de abajo ya deja la caja correcta. */
.lnd-demo-stage {
  position: relative;
  transition: height 0.42s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.lnd-demo-card {
  position: absolute; inset: 0 0 auto 0;
  background: var(--glass-bg, rgba(255, 255, 255, 0.85));
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--glass-border, rgba(255, 255, 255, 0.3));
  border-radius: var(--radius-card, 24px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  padding: 26px 28px;
  display: flex; flex-direction: column; gap: 10px;
  opacity: 0; visibility: hidden;
  transform: translateY(14px);
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), visibility 0.4s;
}
.lnd-demo-card.is-now {
  opacity: 1; visibility: visible; transform: none;
  position: relative; inset: auto;   /* en flujo: es quien da la altura */
}

.lnd-demo-tag {
  font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--text-light, #666);
}
.lnd-demo-label {
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--accent-color, #2c5171);
}
.lnd-demo-row { display: flex; flex-direction: column; gap: 9px; }
.lnd-demo-row input {
  /* `flex: 1 1 220px` venía de cuando la fila era horizontal y el 220 era ANCHO.
     Al pasarla a columna, ese mismo valor es ALTO: el campo de correo se estiraba
     a 220 px y el marcador de posición quedaba flotando abajo, con pinta de área
     de texto. En columna el campo no crece: lo alto lo pone su propio padding. */
  flex: 0 0 auto; min-width: 0;
  padding: 11px 14px;
  border: 1px solid #94a3b8; border-radius: var(--radius-sm, 8px);
  font-family: var(--font-body, 'Inter', sans-serif); font-size: 0.95rem;
  background: #fff; color: var(--text-color, #333);
}
.lnd-demo-row input:focus {
  outline: none; border-color: var(--primary-color, #4682b4);
  box-shadow: 0 0 0 3px rgba(70, 130, 180, 0.14);
}
.lnd-demo-go {
  width: 100%;
  padding: 12px 22px; border: 1px solid var(--primary-color, #4682b4);
  border-radius: var(--radius-sm, 8px);
  background: var(--primary-color, #4682b4); color: #fff;
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 0.9rem; cursor: pointer;
  transition: all 0.2s;
}
.lnd-demo-go:hover { background: var(--accent-color, #2c5171); transform: translateY(-1px); }
.lnd-demo-none {
  margin: 4px 0 0; font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.8rem; line-height: 1.5; color: var(--text-light, #666);
}

/* El correo: se dibuja como un correo, no como una tarjeta de web. */
.lnd-demo-mail { gap: 6px; }
.lnd-mail-head {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding-bottom: 9px; border-bottom: 1px solid rgba(44, 81, 113, 0.12);
  font-size: 0.7rem;
}
.lnd-mail-de { color: var(--accent-color, #2c5171); font-weight: 700; }
.lnd-mail-para { color: var(--text-light, #666); }
.lnd-mail-asunto {
  margin: 10px 0 2px;
  font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 600; font-size: 0.98rem; color: var(--accent-color, #2c5171);
}
.lnd-mail-codigo {
  display: flex; gap: 8px; margin: 8px 0 4px;
}
.lnd-mail-codigo span {
  width: 42px; height: 52px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(44, 81, 113, 0.2); border-radius: var(--radius-sm, 8px);
  background: rgba(70, 130, 180, 0.07);
  font-family: var(--font-mono, 'JetBrains Mono', monospace);
  font-size: 1.4rem; color: var(--accent-color, #2c5171);
  opacity: 0; transform: translateY(6px);
  animation: lndDigito 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes lndDigito { to { opacity: 1; transform: none; } }
.lnd-mail-pie {
  margin: 2px 0 0; font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.78rem; color: var(--text-light, #666);
}

.lnd-demo-dentro { align-items: flex-start; justify-content: center; }
.lnd-demo-check {
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(16, 185, 129, 0.14); color: #059669;
}
.lnd-demo-check svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.lnd-dentro-h {
  margin: 8px 0 0; font-family: var(--font-heading, 'Montserrat', sans-serif);
  font-weight: 700; font-size: 1.5rem; color: var(--accent-color, #2c5171);
}
.lnd-dentro-b {
  margin: 0; font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.9rem; line-height: 1.5; color: var(--text-color, #333); max-width: 46ch;
}
.lnd-dentro-apps { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 4px; }
.lnd-dentro-apps span { font-size: 0.74rem; color: var(--text-light, #666); }
.lnd-demo-otra {
  margin-top: 8px; align-self: flex-start;
  padding: 8px 16px;
  border: 1px solid rgba(44, 81, 113, 0.22); border-radius: var(--radius-sm, 8px);
  background: transparent; color: var(--text-light, #666);
  font-family: var(--font-body, 'Inter', sans-serif); font-weight: 600; font-size: 0.82rem;
  cursor: pointer; transition: all 0.2s;
}
.lnd-demo-otra:hover { background: rgba(0, 0, 0, 0.05); border-color: rgba(44, 81, 113, 0.4); }

.lnd-demo-aviso {
  grid-column: 1 / -1;
  margin: 0; font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 0.74rem; color: rgba(255, 255, 255, 0.62);
}

@media (max-width: 899px) {
  /* Sin superposición: en columna la caja crece y encoge, pero el salto se nota
     mucho menos que tener 268 px vacíos bajo el formulario. */
  .lnd-demo-stage { min-height: 0; }
  .lnd-demo-card { position: static; inset: auto; display: none; }
  .lnd-demo-card.is-now { display: flex; }
  .lnd-demo-steps { flex-direction: row; gap: 10px; }
  .lnd-demo-steps li { border: 0; padding: 0; font-size: 0.78rem; }
  .lnd-demo-steps li:last-child { border: 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin animación no hay demo que valga: los tres estados se enseñan a la vez,
     en vertical, para que la información no dependa del movimiento. */
  .lnd-demo-stage { min-height: 0; display: grid; gap: 12px; }
  .lnd-demo-card { position: static; inset: auto; opacity: 1; visibility: visible; transform: none; }
  .lnd-mail-codigo span { opacity: 1; transform: none; animation: none; }
  .lnd-scroll-line { animation: none; }
  .lnd-hero { height: auto; }
  .lnd-hero-track { position: static; height: auto; min-height: 88vh; }
}
