/* ==========================================================================
   Sistema de diseño IPS H&L — la fuente única de toda la plataforma.
   Cuatro capas: 1 tokens · 2 reset · 3 carcasa · 4 componentes.
   Se sirve en /css/ips.css (app.mount("/css", ...) en backend/app/main.py).
   Ninguna plantilla declara :root: lo impide tests/test_diseno_ips.py.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');

/* ---- 1 · TOKENS ---------------------------------------------------------
   Canónicos: los del módulo Clínica de Heridas, que es el que fijó la
   paleta. Debajo, la capa de alias con los nombres que board.html ya usa en
   unas 800 líneas: así la Entrega 2 alinea la imagen sin reescribir cada
   regla. Color nuevo: arriba el canónico y, si hace falta, su alias abajo.
   -------------------------------------------------------------------- */
:root{
  --brand:#3BA3DE; --brand-h:#2E8FC5; --navy:#1B4B7A; --tint:#E8F4FC;
  --text:#1E293B; --text-2:#64748B; --text-3:#94A3B8;
  --border:#E2E8F0; --bg:#F8FAFC; --surface:#FFFFFF;
  --ok:#10B981; --ok-bg:#ECFDF5;
  --warn:#F59E0B; --warn-bg:#FFFBEB;
  --danger-strong:#EF4444; --danger-bg:#FEF2F2;
  --mono:'JetBrains Mono',ui-monospace,Menlo,monospace;
  --font:'Inter',system-ui,-apple-system,sans-serif;

  /* alias heredados */
  --primary:var(--navy);
  --primary-light:var(--brand);
  --secondary:var(--tint);
  --teal:var(--ok);
  --surface-sec:#F1F5F9;
  --surface-tert:var(--border);
  --text-sec:var(--text-2);
  --text-tert:var(--text-3);
  --success:#047857;  --success-bg:var(--ok-bg);   --success-border:var(--ok);
  --warning:#B45309;  --warning-bg:var(--warn-bg); --warning-border:var(--warn);
  --danger:#B91C1C;   --danger-border:var(--danger-strong);
  --info:var(--navy); --info-bg:var(--tint);
  --purple:#6D28D9;   --purple-bg:#F5F3FF;
  --font-heading:var(--font);
  --font-body:var(--font);
  --card-shadow:0 1px 2px rgba(15,23,42,.04);
  --radius:12px;

  /* la carcasa */
  --rail:320px;
  --rail-min:72px;
  --rail-bg:linear-gradient(160deg,#1B4B7A,#0E3357);
  --rail-text:#BBD9F0;
  --rail-rotulo:#9BC7E8;
  --rail-danger:#FCA5A5;
}

/* ---- 2 · RESET Y BASE ------------------------------------------------ */
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:var(--font-body); background:var(--bg); color:var(--text);
  line-height:1.55; -webkit-font-smoothing:antialiased;
}
a{color:var(--navy); text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit; color:inherit; cursor:pointer; background:none; border:0}
input,select,textarea{font:inherit; color:inherit}
img{max-width:100%}
:focus-visible{outline:2px solid var(--brand); outline-offset:2px}
/* El juego de iconos va en un <svg hidden> y el atributo NO basta: medido en
   Chrome, un <svg hidden> computa display:inline y ocupa su tamaño intrinseco
   de 300x150 — la regla [hidden] de la hoja del navegador no alcanza a un
   elemento del espacio de nombres de SVG. Sin esto el sprite empuja la
   carcasa entera 157px hacia abajo, en todas las paginas. */
svg[hidden]{display:none}
@media (prefers-reduced-motion: reduce){*{transition:none !important}}

/* ---- 3 · CARCASA ----------------------------------------------------- */
.ips{display:grid; grid-template-columns:var(--rail) 1fr; min-height:100vh}

.ips-rail{
  /* overflow-x:clip, no el `auto` implicito que arrastra overflow-y: si no,
     cualquier hijo mas ancho que el rail colapsado abre una franja de
     scroll horizontal dentro del propio rail. */
  position:sticky; top:0; height:100vh; overflow-y:auto; overflow-x:clip;
  background:var(--rail-bg); color:#fff;
  padding:32px 24px; display:flex; flex-direction:column;
  justify-content:space-between; gap:24px;
}

/* zona 1 — identidad */
.ips-logo{height:52px; width:auto; display:block; margin-bottom:14px}
.ips-modulo{font-weight:700; font-size:24px; line-height:1.15; color:#fff}
.ips-lema{font-size:13px; color:var(--rail-text); max-width:34ch; margin-top:6px}
.ips-area{
  display:flex; align-items:center; gap:6px; margin-top:8px; font-size:11px;
  text-transform:uppercase; letter-spacing:.08em; color:var(--rail-rotulo);
}
.ips-area-punto{width:8px; height:8px; border-radius:50%; flex:none; display:inline-block}

/* El selector de sede. Vive en la zona 1 porque la sede es parte de QUIEN
   eres dentro del modulo, no de a donde vas: cambiarla recarga todas las
   secciones. Dos modulos lo usan (CDH y Terapias) y por eso esta aqui y no
   en ninguna de las dos plantillas.
   `appearance:none` quita la flecha del sistema, que sobre el navy sale
   negra; la que se ve es la del fondo, en SVG embebido y del color del
   rail. */
.ips-sede{
  width:100%; margin-top:14px; padding:8px 30px 8px 10px;
  border:1px solid rgba(255,255,255,.2); border-radius:9px;
  background:rgba(255,255,255,.08); color:#fff;
  font-family:inherit; font-size:13px; appearance:none;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23BFD6E8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 8px center;
  background-size:16px 16px;
}
/* La lista desplegada la pinta el sistema operativo, no la pagina: sin esto
   sale texto blanco sobre fondo blanco en Chrome de Windows. */
.ips-sede option{color:var(--text); background:var(--surface)}

/* zona 2 — navegación */
.ips-nav{display:flex; flex-direction:column; gap:2px}
.ips-nav-rotulo{
  font-family:var(--mono); font-size:11px; text-transform:uppercase;
  letter-spacing:.08em; color:var(--rail-rotulo); margin:14px 0 4px 12px;
}
.ips-nav-item{
  position:relative; display:flex; align-items:center; gap:12px;
  height:40px; padding:0 12px; border-radius:8px; width:100%;
  font-size:14px; color:var(--rail-text); text-align:left;
}
.ips-nav-item:hover{background:rgba(255,255,255,.06); color:#fff; text-decoration:none}
.ips-nav-item.activa{background:rgba(255,255,255,.10); color:#fff; font-weight:600}
.ips-nav-item.activa::before{
  content:""; position:absolute; left:0; top:8px; bottom:8px;
  width:3px; border-radius:2px; background:var(--brand);
}
.ips-nav-contador{
  margin-left:auto; font-family:var(--mono); font-size:11px;
  background:rgba(255,255,255,.12); border-radius:999px; padding:2px 8px;
}
/* Una seccion urgente. El aviso va por partida doble a proposito: el
   contador lo enseña en el rail ancho y en la hoja movil, pero los dos
   bloques de colapso lo esconden — asi que a 72px el que queda es el
   icono, y sin teñirlo la alarma no se veria en ningun portatil por
   debajo de 1280px. El icono se apoya DIRECTAMENTE en el navy del rail,
   sin chip que lo separe: --danger-strong da 2.39:1 ahi (por debajo del
   3:1 de WCAG para un objeto grafico), asi que usa --rail-danger, medido
   en 4.74:1 contra el extremo mas claro del degradado. */
.ips-nav-item.urgente .ips-nav-contador{
  background:var(--danger-bg); color:var(--danger-strong); font-weight:600;
}
.ips-nav-item.urgente .ico{color:var(--rail-danger)}
.ico{width:18px; height:18px; flex:none}

/* zona 3 — pie */
.ips-pie{display:flex; flex-direction:column; gap:16px}
.ips-cifras{display:flex; gap:20px; flex-wrap:wrap}
.ips-cifra b{font-family:var(--mono); font-size:32px; font-weight:500; color:#fff; display:block}
.ips-cifra span{
  font-size:11px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--rail-rotulo);
}
.ips-dominio{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  color:var(--rail-rotulo);
}
/* Sin usuario el hueco esta vacio de verdad (carcasa.html recorta los
   espacios): sin esto seguiria contando como hijo del pie y abriria su gap. */
.ips-hueco-usuario:empty{display:none}
.ips-usuario{display:flex; align-items:center; gap:10px; color:#fff}
.ips-usuario:hover{text-decoration:none; opacity:.85}
.ips-avatar{
  width:32px; height:32px; border-radius:50%; flex:none;
  background:rgba(255,255,255,.14); display:grid; place-items:center;
  font-weight:600; font-size:13px;
}
.ips-usuario-nombre{font-size:13px; line-height:1.2}
.ips-usuario-rol{font-size:11px; color:var(--rail-rotulo)}
.ips-usuario .ico{margin-left:auto}

/* área de contenido */
.ips-main{min-width:0; padding:32px 40px}
.ips-cabecera{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:24px;
}
.ips-etiqueta{
  font-family:var(--mono); font-size:11px; text-transform:uppercase;
  letter-spacing:.08em; color:var(--brand);
}
.ips-cabecera h1{font-size:26px; font-weight:600; color:var(--text); margin-top:4px}
.ips-cabecera p{font-size:14px; color:var(--text-2); margin-top:4px}
.ips-estrecho{max-width:900px}

/* sin autenticar.
   No basta con esconder el rail: la rejilla le seguiria reservando su
   columna de 320px y la caja de acceso saldria descentrada. Lo enciende
   IPS.anonimo(true) — ver frontend/js/ips.js. */
.ips.anonima{grid-template-columns:1fr}
.ips.anonima .ips-rail{display:none}
.ips-movil.anonima{display:none}
/* Sin sesion no hay modulo al que dar nombre: la cabecera lo repetia
   justo encima del titular de la caja de acceso, y el margen de .ips-main
   cortaba el fondo antes de los bordes. */
.ips.anonima .ips-cabecera{display:none}
.ips.anonima .ips-main{padding:0}

/* colapsado.
   El colapso manual (.ips.colapsada) y el automatico (@media 1280) tienen
   que dar EXACTAMENTE el mismo resultado: las mismas doce ocultaciones, el
   mismo padding, la misma alineacion y el mismo logo. Si tocas uno, toca el
   otro — lo vigila tests/test_diseno_ips.py. */
.ips.colapsada{grid-template-columns:var(--rail-min) 1fr}
.ips.colapsada .ips-rail{padding:24px 12px; align-items:center}
.ips.colapsada .ips-modulo,
.ips.colapsada .ips-lema,
.ips.colapsada .ips-area,
.ips.colapsada .ips-nav-item span,
.ips.colapsada .ips-nav-rotulo,
.ips.colapsada .ips-cifras,
.ips.colapsada .ips-dominio,
.ips.colapsada .ips-avatar,
.ips.colapsada .ips-usuario-nombre,
.ips.colapsada .ips-usuario-rol,
.ips.colapsada .ips-sede,
.ips.colapsada .ips-nav-contador{display:none}
/* A 72px de rail con 12px de padding quedan 48px utiles, y el logo maestro
   (462:191) necesita 68px para 28px de alto: no cabe. En colapsado se
   cambia por el emblema cuadrado, que a 28x28 si cabe y no se deforma.
   El margen lo baja por debajo del boton de colapsar, que en 72px de ancho
   le caia encima — medido en Chrome, 10x18px de solape. */
.ips.colapsada .ips-logo{
  content:url("/static/marca/hyl-emblema-192.png"); width:28px; height:28px;
  margin-top:20px;
}
.ips.colapsada .ips-nav-item{justify-content:center; padding:0}
.ips.colapsada .ips-usuario{justify-content:center}
/* Dentro del rail, no fuera: .ips-rail lleva overflow-y:auto, asi que su
   overflow-x computa a auto y cualquier cosa asomada por la derecha queda
   recortada y abre una franja de scroll horizontal. */
.ips-colapsar{
  position:absolute; top:18px; right:8px; width:24px; height:24px;
  border-radius:50%; background:var(--navy); color:#fff;
  display:grid; place-items:center; border:1px solid rgba(255,255,255,.2);
}
.ips.colapsada .ips-colapsar .ico{transform:rotate(180deg)}

/* movil */
.ips-movil{display:none}
/* Asi en escritorio no se pinta nunca, aunque .ips-movil cambie. */
.ips-movil-cifras{display:none}
@media (max-width:1280px){
  .ips{grid-template-columns:var(--rail-min) 1fr}
  .ips .ips-rail{padding:24px 12px; align-items:center}
  .ips .ips-modulo,
  .ips .ips-lema,
  .ips .ips-area,
  .ips .ips-nav-item span,
  .ips .ips-nav-rotulo,
  .ips .ips-cifras,
  .ips .ips-dominio,
  .ips .ips-avatar,
  .ips .ips-usuario-nombre,
  .ips .ips-usuario-rol,
  .ips .ips-nav-contador,
  .ips .ips-sede{display:none}
  .ips .ips-logo{
    content:url("/static/marca/hyl-emblema-192.png"); width:28px; height:28px;
    margin-top:20px;
  }
  .ips .ips-nav-item{justify-content:center; padding:0}
  .ips .ips-usuario{justify-content:center}
}
@media (max-width:900px){
  .ips.ips{grid-template-columns:1fr}
  .ips .ips-rail{display:none}
  .ips .ips-rail.abierta{
    display:flex; position:fixed; inset:0; height:100vh; z-index:200;
    padding:24px; align-items:stretch;
  }
  /* El bloque de 1280 tambien casa aqui y no lo deshace nadie: sin esto la
     "hoja a pantalla completa" del spec §1 se abre con el logo y tres
     iconos mudos. La hoja es el rail entero, no el rail colapsado. */
  .ips-rail.abierta .ips-modulo,
  .ips-rail.abierta .ips-lema,
  .ips-rail.abierta .ips-nav-rotulo,
  .ips-rail.abierta .ips-dominio,
  .ips-rail.abierta .ips-usuario-nombre,
  .ips-rail.abierta .ips-usuario-rol{display:block}
  .ips-rail.abierta .ips-area{display:flex}
  .ips-rail.abierta .ips-avatar{display:grid}
  .ips-rail.abierta .ips-usuario{justify-content:flex-start}
  .ips-rail.abierta .ips-nav-item span{display:inline}
  .ips-rail.abierta .ips-nav-contador{display:inline-block}
  .ips-rail.abierta .ips-cifras{display:flex}
  .ips-rail.abierta .ips-sede{display:block}
  .ips-rail.abierta .ips-logo{content:normal; width:auto; height:52px}
  .ips-rail.abierta .ips-nav-item{justify-content:flex-start; padding:0 12px}
  /* La cabecera movil es HERMANA de .ips, no descendiente: con el prefijo
     ".ips " el selector no casaba nunca y el telefono se quedaba sin ningun
     control de navegacion. Estas reglas ya viven dentro del @media. */
  /* flex-wrap y height:auto (en vez de los 56px fijos de antes): con
     cifras la cabecera pasa a dos filas, la barra azul arriba y las
     cifras debajo. Van juntas en esta regla porque asi se leen mejor, no
     porque ningun test lo obligue: desde la revision final,
     test_la_cabecera_movil_no_lleva_degradado fusiona las declaraciones
     por selector (`_mapa`), asi que da igual en cuantas reglas se parta
     .ips-movil dentro del @media. */
  .ips-movil{
    display:flex; align-items:center; flex-wrap:wrap; gap:12px;
    height:auto; padding:10px 16px;
    background:#1B4B7A; color:#fff; position:sticky; top:0; z-index:100;
  }
  .ips-movil img{height:28px}
  .ips-movil-modulo{font-weight:600; font-size:15px}
  .ips-movil button{margin-left:auto; color:#fff}
  .ips .ips-main{padding:20px 16px}

  /* Las cifras, en el telefono. Hasta CUATRO (medicina pasa cuatro), asi
     que reparten el ancho en vez de fijarlo. `flex-wrap` es inofensivo
     para 2 o 3 (ya caben en una fila, nunca desbordan) y necesario para
     4: sin el, una fila desbordada recorta en vez de bajar de linea. */
  .ips-movil-cifras{
    display:flex; flex-wrap:wrap; width:100%; gap:12px; margin-top:8px;
    border-top:1px solid rgba(255,255,255,.18); padding-top:8px;
  }
  .ips-movil-cifra{flex:1 1 0; min-width:0; text-align:center}
  .ips-movil-cifra b{
    font-family:var(--mono); font-size:20px; font-weight:500;
    color:#fff; display:block; line-height:1.1;
  }
  .ips-movil-cifra span{
    font-size:10px; text-transform:uppercase; letter-spacing:.06em;
    color:rgba(255,255,255,.72); display:block;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }

  /* Con CUATRO cifras (Medicina), una sola fila da 80px de columna y
     "Les toca este mes" (111px con esta tipografia) no cabe -- Ronda de
     arreglo 1 de la Task 6, medido en Chrome real. La correccion: min-width
     mayor que (358-24)/3=111.34px para que NINGUNA fila quepa con tres
     cifras (asi la de cuatro rompe en 2+2, no en 3+1 con medio pixel de
     margen), y como mucho (328-12)/2=158px para que dos SIGAN cabiendo en
     una fila a 360px (iPhone SE). 130px cae comodo en medio de ese rango.
     Solo en `--4`: la misma regla en TODAS partiria tambien la fila de
     tres de sonda, que hoy cabe de sobra sin ella (medido: se rompe en
     2+1 sin necesidad). */
  .ips-movil-cifras--4 .ips-movil-cifra{min-width:130px}
}

/* ---- 4 · COMPONENTES ------------------------------------------------- */
.btn{
  border-radius:9px; padding:10px 18px; font-weight:600; font-size:14px;
  background:var(--brand); color:#fff; border:1px solid transparent;
  display:inline-flex; align-items:center; gap:8px;
}
.btn:hover{background:var(--brand-h); text-decoration:none}
.btn:disabled{opacity:.5; cursor:not-allowed}
.btn-fantasma{background:var(--surface); color:var(--text); border-color:var(--border)}
.btn-fantasma:hover{background:var(--surface); border-color:var(--brand)}
.btn-peligro{background:var(--danger-bg); color:var(--danger); border-color:var(--danger-border)}
.btn-peligro:hover{background:var(--danger-bg)}
.btn .ico{width:16px; height:16px}

.etiqueta{
  display:block; font-size:11px; font-weight:600; text-transform:uppercase;
  letter-spacing:.06em; color:var(--text-2); margin-bottom:4px;
}
.campo{
  border-radius:9px; border:1px solid var(--border); padding:9px 11px;
  background:var(--surface); font-size:14px; width:100%;
}
.campo:focus{outline:2px solid var(--tint); border-color:var(--brand)}

.card{
  background:var(--surface); border:1px solid var(--border); border-radius:12px;
  padding:18px; box-shadow:var(--card-shadow);
}

.cifras{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px}
.cifra{
  background:var(--surface); border:1px solid var(--border); border-radius:12px;
  padding:14px 16px;
}
.cifra b{font-family:var(--mono); font-size:28px; font-weight:500; display:block}
.cifra span{font-size:12px; color:var(--text-2)}
.cifra.pide-accion{border-color:var(--danger-strong)}
.cifra.pide-accion b{color:var(--danger-strong)}

.tabla-marco{overflow-x:auto; border:1px solid var(--border); border-radius:12px; background:var(--surface)}
.tabla{border-collapse:collapse; width:100%; font-size:14px}
.tabla th{
  text-align:left; font-size:11px; font-weight:600; text-transform:uppercase;
  letter-spacing:.06em; color:var(--text-3); padding:12px 14px;
  border-bottom:1px solid var(--border); white-space:nowrap;
}
.tabla td{padding:12px 14px; border-bottom:1px solid var(--border)}
.tabla tr:last-child td{border-bottom:none}
.tabla tbody tr:hover{background:var(--bg)}

.insignia{
  display:inline-block; border-radius:999px; font-size:11px; font-weight:600;
  padding:3px 10px;
}
.insignia.ok{background:var(--ok-bg); color:var(--success)}
.insignia.warn{background:var(--warn-bg); color:var(--warning)}
.insignia.peligro{background:var(--danger-bg); color:var(--danger)}
.insignia.info{background:var(--tint); color:var(--navy)}
.insignia.morada{background:var(--purple-bg); color:var(--purple)}

.aviso{
  background:var(--tint); border-left:4px solid var(--brand); border-radius:12px;
  padding:12px 16px; font-size:13px; line-height:1.6;
}
.aviso strong{font-weight:600; color:var(--navy)}

/* ---- 5 · LA PUERTA DE ENTRADA ---------------------------------------- */
/* `.hide` no es solo de la puerta -- la usan practicamente todas las
   pantallas para esconder cualquier cosa, no solo #login -- pero
   `partials/puerta.html` depende de ella (`class="login-box hide"`), y
   antes de esta entrada vivia declarada en once de las catorce plantillas
   migradas (identidad/buscar.html, mipres/board.html y mipres/uploader.html
   usaban `style="display:none;"` en linea, no la clase). Con la puerta
   fuera en un partial comun, `.hide` tiene que vivir en la hoja comun --
   mismo argumento que las otras cuatro clases de la Task 1: una clase de
   la que depende una pieza compartida no puede vivir en la mitad de las
   pantallas que la usan. */
.hide{display:none !important}

/* Una sola vez para toda la plataforma. Antes de la Entrega 4 esto estaba
   copiado en catorce plantillas: doce declaraban .login-box, diez .gsi,
   once .err y trece .loading -- y otras dos USABAN .loading sin
   declararla, asi que se pintaban sin estilo y nadie lo vio.
   (.err son once, no trece: identidad/buscar.html y mipres/uploader.html
   usan .msg.err, un selector compuesto de su propio sistema de mensajes,
   no el .err suelto de la puerta -- no cuentan.)
   El HTML va en partials/puerta.html; el JS, en IPS.puerta (ips.js). */
.login-box{
  max-width:420px; margin:80px auto; background:var(--surface);
  border:1px solid var(--border); border-radius:var(--radius);
  padding:32px; box-shadow:var(--card-shadow); text-align:center;
}
/* Solo la altura, nunca alto y ancho a la vez: la proporcion 462:191
   se respeta sola (ver el comentario de cabecera de carcasa.html --
   ya se estiro una vez en la Entrega 3c). El de color, no el blanco:
   el fondo de la caja es var(--surface), claro. */
.login-logo{height:52px; width:auto; margin-bottom:16px}
.login-box h2{font-size:18px; font-weight:600; color:var(--navy); margin-bottom:6px}
.login-box p{font-size:14px; color:var(--text-2)}
.gsi{display:flex; justify-content:center; margin-top:18px}
/* `#gsi-button{margin-bottom:14px}` vivia solo en el <style> de
   cdh/app.html y no se trajo aqui: separaba el boton de Google del
   `.note` de instrucciones que colgaba siempre visible debajo ("Si tu
   cuenta no tiene acceso..."), y ese `.note` no sobrevivio a la mudanza
   de la puerta a partials/puerta.html (Task 2) -- el partial comun no
   lleva ese texto en ninguna de las catorce pantallas. Lo unico que
   sigue #gsi-button hoy es `.err`, que ya trae su propio margin-top de
   14px (la misma cifra) y solo ocupa espacio cuando se muestra. */
.err{
  background:var(--danger-bg); border:1px solid var(--danger-border);
  color:var(--danger); border-radius:9px; padding:10px 14px;
  font-size:13px; margin-top:14px;
}
.loading{color:var(--text-2); padding:20px; text-align:center; font-size:13px}
