/* ═══════════════════════════════════════════════════════════════════════════
   login-cloud.css — pantalla de ingreso del modo gestionado
   ───────────────────────────────────────────────────────────────────────────
   Hoja propia, no un tema de `auth-backdrop.css`. La razón es la condición de
   diseño del revamp: lo del modo gestionado tiene que ser ARCHIVOS QUE SE
   PUEDAN DEJAR AFUERA del paquete público. Una rama dentro de la hoja
   compartida de los logins no se puede excluir, y además le cambiaría la
   pantalla a Cervepar y a Indufar, que comparten ese shell.

   Las tres pantallas de ingreso del producto (`login.html`, `login-editor`,
   `login-console`) son navy oscuro. Esta es clara a propósito: es la
   diferenciación que se pidió, y no es decorativa — alguien que entra desde su
   casa por navegador tiene que ver de una que no está frente a la HMI de la
   sala de control.

   ── Los tokens ─────────────────────────────────────────────────────────────
   Levantados tal cual del bloque `:root` de `Induxa Cloud Edition.html`, sin
   reinterpretar, como pide el punto 1 del spec. Van prefijados `--c-` y
   declarados en `.cloud-login`, no en `:root`: así no se pisan con los tokens
   del Editor o del Viewer si algún día esta hoja se carga en una página que ya
   los trae.

   ── La regla invariante ────────────────────────────────────────────────────
   Verde, ámbar y rojo saturados —`--c-run`, `--c-warn`, `--c-crit`— SÓLO para
   estado. En esta pantalla eso significa: el punto del chip de servicio y el
   cartel de error. En ningún borde, ningún encabezado, ninguna marca.
   `--c-info` (azul) es el único color que se usa para foco y enlaces, y no
   pertenece al eje verde-ámbar-rojo justamente para no gastarlo.

   ── Las fuentes ────────────────────────────────────────────────────────────
   El mockup pide Barlow y Barlow Condensed desde `fonts.googleapis.com`.
   NINGUNA vista servida del producto pide una fuente a un CDN — están todas
   empaquetadas en `app/assets/fonts/` y declaradas en `app/css/fonts.css`
   (30 bloques `@font-face`, verificado) — y esta pantalla no va a ser la
   primera: un login que se queda esperando a un CDN es un login que no abre
   cuando el DNS del cliente filtra Google.

   Barlow no está empaquetada. Así que la cadena arranca en Barlow —para que
   el día que se agreguen los `.woff2` entre sin tocar una línea— y cae en
   Roboto, que SÍ está empaquetada con los pesos 100/300/400/500/700 que esta
   pantalla usa, y que es la que el propio `--sans` del mockup lista como
   siguiente opción. No es la misma letra; es la misma intención, con los pesos
   completos y sin red.
   ═══════════════════════════════════════════════════════════════════════════ */

.cloud-login {
  /* Registro Brückner: cromo gris, contenido blanco, color reservado a estado */
  --c-paper:     #e8eaec;
  --c-surface:   #ffffff;
  --c-surface-2: #f6f7f8;
  --c-chrome:    #34383c;
  --c-chrome-2:  #4a4f54;
  --c-ink:       #1b1f23;
  --c-ink-2:     #656d75;
  --c-ink-3:     #98a0a8;
  --c-line:      #d8dcdf;
  --c-line-2:    #e9ecee;

  /* estado — único lugar donde hay color saturado */
  --c-run:  #3d9e37;
  --c-warn: #eda400;
  --c-crit: #dc3226;
  --c-info: #1b7fc0;

  --c-sans: 'Barlow', 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --c-cond: 'Barlow Condensed', 'Barlow', 'Roboto Condensed', 'Roboto', sans-serif;

  color-scheme: light;
}

/* ── Lienzo ────────────────────────────────────────────────────────────── */

html, body.cloud-login {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body.cloud-login {
  background: var(--c-paper);
  color: var(--c-ink);
  font-family: var(--c-sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  display: flex;
  align-items: stretch;
}

.cloud-login *, .cloud-login *::before, .cloud-login *::after { box-sizing: border-box; }

/* El `min-width: 1160px` del mockup NO va a producción — el punto 1 del spec
   lo dice: existe sólo para que el marco de demostración se vea completo. */
.cl-shell {
  flex: 1;
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  min-height: 100vh;
  background: var(--c-surface);
}

/* ── Columna izquierda · marca, promesa y estado del servicio ──────────── */

.cl-left {
  position: relative;
  overflow: hidden;
  background: linear-gradient(158deg, #eef4f7 0%, #f8fafb 46%, #ffffff 100%);
  padding: 40px 44px 34px;
  display: flex;
  flex-direction: column;
}

.cl-left > * { position: relative; z-index: 1; }

/* El gráfico de fondo es telemetría, no nubes: dos señales con un punto
   viajando. Decorativo y `aria-hidden`; nada de lo que dice es dato. */
.cl-sig {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.cl-mark { display: flex; align-items: center; gap: 12px; }
.cl-mark svg { width: 34px; height: 34px; flex: 0 0 auto; }
.cl-wordmark { font-size: 20px; font-weight: 600; letter-spacing: -.015em; line-height: 1; }
.cl-wordmark em { font-style: normal; font-weight: 300; color: var(--c-ink-2); }

.cl-mid { margin-top: auto; max-width: 36ch; }
.cl-mid h1 {
  margin: 0;
  font-size: clamp(27px, 3.3vw, 36px);
  font-weight: 300;
  line-height: 1.14;
  letter-spacing: -.025em;
  text-wrap: balance;
}
.cl-mid h1 b { font-weight: 600; }
.cl-mid p { margin: 14px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--c-ink-2); }

.cl-props { margin-top: 30px; display: flex; flex-direction: column; gap: 13px; }
.cl-prop { display: flex; align-items: flex-start; gap: 11px; }
.cl-prop .cl-pi {
  width: 28px; height: 28px; flex: 0 0 auto;
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  display: grid; place-items: center;
  color: var(--c-ink-2);
}
.cl-prop .cl-pt b { display: block; font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.cl-prop .cl-pt span { display: block; font-size: 12.5px; color: var(--c-ink-2); margin-top: 1px; }

/* ── Chip de estado del servicio ───────────────────────────────────────────
   Lo único de la instalación que esta pantalla muestra antes de autenticar, y
   sólo porque el punto 7 del spec lo permite explícitamente: el estado del
   servicio no revela nada de ningún cliente.

   Dos estados y no tres. `GET /api/v1/health` contesta, a un llamador no
   local, `{ok:true}` con 200 o `{ok:false}` con 503 — eso es todo lo que hay
   medido, así que eso es todo lo que se dibuja. El ámbar de «degradado» que
   pide el spec necesita una fuente que todavía no existe, y la regla del punto
   6 es que lo que no se mide no se muestra. Cuando haya una señal de
   degradación real se agrega `.cl-status.deg` y nada más. */
.cl-status {
  margin-top: 30px;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  padding: 8px 13px;
  font-size: 12.5px;
  color: var(--c-ink-2);
}
.cl-status b { color: var(--c-ink); font-weight: 600; }

.cl-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c-ink-3); flex: 0 0 auto; }
.cl-status.ok   .cl-dot { background: var(--c-run);  animation: cl-pulse 2.4s ease-in-out infinite; }
.cl-status.deg  .cl-dot { background: var(--c-warn); }
.cl-status.down .cl-dot { background: var(--c-crit); }

@keyframes cl-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(61, 158, 55, .5); }
  50%      { box-shadow: 0 0 0 6px rgba(61, 158, 55, 0); }
}

/* `prefers-reduced-motion` apaga el pulso y el punto viajero del gráfico. El
   pulso es refuerzo del color, nunca el único portador del estado: la palabra
   del chip dice lo mismo. */
@media (prefers-reduced-motion: reduce) {
  .cl-status.ok .cl-dot { animation: none; }
  .cl-sig animateMotion { display: none; }
}

/* ── Columna derecha · el formulario ──────────────────────────────────── */

.cl-right {
  padding: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-left: 1px solid var(--c-line);
  background: var(--c-surface);
}

.cl-form-wrap { width: 100%; max-width: 380px; margin: 0 auto; }

.cl-h { margin-bottom: 26px; }
.cl-h b { display: block; font-size: 19px; font-weight: 600; letter-spacing: -.015em; }
.cl-h span { display: block; font-size: 13.5px; color: var(--c-ink-2); margin-top: 4px; }

.cl-fg + .cl-fg { margin-top: 17px; }

.cl-fl {
  display: block;
  font-family: var(--c-cond);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--c-ink-2);
  margin-bottom: 6px;
}

.cl-field {
  width: 100%;
  background: var(--c-surface);
  border: 1px solid #c4cace;
  padding: 11px 12px;
  font-family: var(--c-sans);
  font-size: 15px;
  color: var(--c-ink);
}
.cl-field::placeholder { color: var(--c-ink-3); }
.cl-field:focus { outline: 0; border-color: var(--c-info); box-shadow: 0 0 0 3px rgba(27, 127, 192, .14); }
.cl-field:disabled { background: var(--c-surface-2); color: var(--c-ink-3); }

.cl-pw { position: relative; }
.cl-pw .cl-field { padding-right: 44px; }
.cl-pw-eye {
  position: absolute; top: 0; right: 0; height: 100%; width: 40px;
  background: none; border: 0; cursor: pointer; color: var(--c-ink-3);
  display: grid; place-items: center;
}
.cl-pw-eye:hover { color: var(--c-ink-2); }
.cl-pw-eye:focus-visible { outline: 2px solid var(--c-info); outline-offset: -2px; }

.cl-btn {
  width: 100%;
  margin-top: 24px;
  background: var(--c-chrome);
  color: #fff;
  border: 1px solid var(--c-chrome);
  padding: 13px 16px;
  font-family: var(--c-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
}
.cl-btn:hover:not(:disabled) { background: #23272a; }
.cl-btn:focus-visible { outline: 2px solid var(--c-info); outline-offset: 2px; }
.cl-btn:disabled { background: var(--c-ink-3); border-color: var(--c-ink-3); cursor: not-allowed; }

.cl-sub {
  display: block;
  margin-top: 15px;
  text-align: center;
  font-size: 13.5px;
  color: var(--c-info);
  text-decoration: none;
  background: none;
  border: 0;
  width: 100%;
  font-family: var(--c-sans);
  cursor: pointer;
}
.cl-sub:hover { text-decoration: underline; }

.cl-foot {
  margin-top: 28px;
  padding-top: 15px;
  border-top: 1px solid var(--c-line-2);
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--c-ink-3);
}
.cl-foot a { color: var(--c-ink-3); text-decoration: none; }
.cl-foot a:hover { color: var(--c-ink-2); text-decoration: underline; }

/* ── Carteles ──────────────────────────────────────────────────────────────
   Dos cosas distintas y por eso dos componentes:

   `.cl-alert` es el resultado del intento que el operador acaba de hacer —
   credenciales incorrectas, cuenta bloqueada. Es un `role="alert"`, así que un
   lector de pantalla lo anuncia solo.

   `.cl-reason` es el motivo por el que lo mandaron de vuelta acá — sesión
   vencida, bloqueo por inactividad, cambio de clave pendiente. Ya está en
   pantalla cuando el operador llega, así que NO es un `role="alert"`: anunciar
   algo que el usuario no provocó al momento de cargar interrumpe sin motivo. */

.cl-alert, .cl-reason {
  display: none;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 12px;
  margin-bottom: 18px;
  font-size: 13px;
  line-height: 1.45;
  border: 1px solid;
}
.cl-alert.visible, .cl-reason.visible { display: flex; }

.cl-alert     { border-color: #f0b4ae; background: #fdf2f1; color: #8a1d14; }
.cl-alert.ok  { border-color: #b4ddb1; background: #f1f9f0; color: #1f5a1b; }

.cl-reason      { border-color: #cfdbe4; background: var(--c-surface-2); color: var(--c-ink-2); }
.cl-reason.warn { border-color: #f0dcae; background: #fdf8ec; color: #6b4e05; }

.cl-alert .cl-ico, .cl-reason .cl-ico { flex: 0 0 auto; line-height: 1.45; }

/* ── Cambio de contraseña obligatorio ─────────────────────────────────────
   El punto 7 del spec: una contraseña vencida LLEVA al cambio, no rebota al
   login. El servidor contesta `force_password_change` en el `user` del login
   exitoso, igual que en la pantalla estándar. */

.cl-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(27, 31, 35, .55);
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.cl-overlay.visible { display: flex; }

.cl-modal {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  padding: 30px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 20px 50px -20px rgba(27, 31, 35, .5);
}
.cl-modal h2 { margin: 0 0 6px; font-size: 18px; font-weight: 600; letter-spacing: -.015em; }
.cl-modal > p { margin: 0 0 22px; font-size: 13.5px; line-height: 1.5; color: var(--c-ink-2); }
.cl-modal .cl-who { font-weight: 600; color: var(--c-ink); }

/* ── Responsive ────────────────────────────────────────────────────────────
   El punto 8 del spec define cuatro anchos para el shell de la consola. Esta
   pantalla tiene una sola decisión: dos columnas o una. Se apila a 900 px
   —donde la columna del formulario baja de 360 px y los campos empiezan a
   apretarse—, y el panel de marca queda arriba con su alto natural para que el
   formulario no se vaya abajo del pliegue en un celular. */

@media (max-width: 900px) {
  .cl-shell { grid-template-columns: 1fr; min-height: 100vh; }
  .cl-left  { padding: 28px 24px 26px; min-height: auto; }
  .cl-mid   { margin-top: 24px; }
  .cl-mid h1 { font-size: clamp(24px, 6.5vw, 30px); }
  .cl-props { margin-top: 22px; }
  .cl-right { border-left: 0; border-top: 1px solid var(--c-line); padding: 32px 24px 40px; }
}

@media (max-width: 560px) {
  /* Las tres promesas son argumento de venta, no operación: en un celular
     ocupan la pantalla entera y empujan el formulario fuera de vista. El
     titular y el chip de estado se quedan. */
  .cl-props { display: none; }
  .cl-left  { padding: 22px 18px; }
  .cl-right { padding: 26px 18px 34px; }
  .cl-status { margin-top: 22px; }
}

/* Alto chico y apaisado (un portátil de 1366×768 con el navegador a media
   pantalla, una tablet acostada): el bloque de marca no puede comerse el
   formulario. */
@media (max-height: 560px) and (min-width: 901px) {
  .cl-left { padding: 24px 32px; }
  .cl-props { display: none; }
  .cl-right { padding: 24px 32px; }
}
