/* Portal del cliente — la capa de acabado.
 *
 * Vive aparte de tailwind.css porque solo la cargan las dos páginas que ve un
 * cliente (el login y el portal). El portal interno de los empleados no tiene
 * por qué pagar la fuente ni heredar estos ajustes.
 */

/* ============================================================
   El azul de la casa
   ============================================================ */

/* Los dos azules son los del logo, sacados del propio PNG: el índigo del óvalo
 * grande es #240094 y el celeste del pequeño es #7ebfff. Lo que había antes
 * —un azul marino #003366 con su escala— no aparece en el logo por ningún
 * lado: se parecía lo justo para que nadie lo mirara dos veces.
 *
 * Redefinir aquí estas variables repinta de golpe todas las clases bg-brand,
 * text-brand-500, ring-brand… del portal del cliente, sin tocar una sola clase
 * del HTML: en tailwind.config.cjs el color de marca es rgb(var(--brand-…))
 * con el azul marino como respaldo. Y como cliente.css solo lo cargan las
 * páginas del cliente, el portal interno se queda exactamente como estaba.
 *
 * Van en "R G B" y no en # porque es lo que necesita esa forma de declararlas
 * para que sigan funcionando las transparencias (bg-brand/10).
 *
 * La escala mantiene el tono del logo (255°) y solo mueve la luz. Ojo con el
 * orden, que no es el que parece: el 500 es MÁS claro que el DEFAULT, y así
 * estaba antes — DEFAULT es el botón, 500 el texto y los iconos sobre blanco,
 * 600 el botón al pasar por encima. */
:root {
  --brand-50:  243 240 253;  /* #f3f0fd — veladuras */
  --brand-100: 216 205 249;  /* #d8cdf9 */
  --brand-300: 157 132 240;  /* #9d84f0 — texto de marca en modo oscuro */
  --brand-500:  74  31 208;  /* #4a1fd0 — enlaces e iconos sobre blanco */
  --brand-600:  46   0 176;  /* #2e00b0 — el botón al pasar por encima */
  --brand-700:  23   0  94;  /* #17005e */
  --brand:      36   0 148;  /* #240094 — el índigo exacto del logo */

  /* El celeste del logo. En claro es el acento (la franja, los degradados);
   * en oscuro hace de azul principal, porque el índigo sobre negro se apaga. */
  --pc-cielo:  126 191 255;  /* #7ebfff */

  /* EL FILO DE LA CASA
   *
   * Todos los marcos del portal —el buscador, los desplegables, las cajas, las
   * tarjetas, los campos del login— van del mismo color, y el color es el de
   * marca. Antes cada uno llevaba su gris con su transparencia (0.06, 0.08,
   * 0.09, 0.12, 0.14) y la página parecía cinco páginas: el buscador se
   * encendía en morado al entrar en él y todo lo demás seguía gris.
   *
   * `--pc-filo` es el marco: lo que rodea algo. `--pc-filo-suave` es la raya
   * que separa dos filas DENTRO de una lista, que no es un marco y a plena
   * intensidad convertía la tabla en una reja.
   *
   * Los dos cambian con el tema, así que quien los use no tiene que escribir
   * una regla `.dark` de acompañamiento. */
  --pc-filo:       rgb(var(--brand-500));
  --pc-filo-suave: rgb(var(--brand-500) / 0.16);
}
html.dark {
  --pc-filo:       rgb(var(--pc-cielo));
  --pc-filo-suave: rgb(var(--pc-cielo) / 0.20);
}

/* Inter, servida desde aquí. La CSP de la app solo admite 'self' y data: como
 * origen de fuentes, así que nada de CDN. Sin esto la tipografía caía en Segoe
 * UI o en lo que hubiera instalado, y de ahí venía buena parte del aire de
 * plantilla: la misma letra que cualquier panel de administración.
 *
 * Es la variable (un solo archivo, 48 KB, todo el rango de pesos), así que
 * pesa menos que las dos estáticas que harían falta para lo mismo. */
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/inter-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   Tipografía
   ============================================================ */

/* Los tamaños grandes necesitan menos espacio entre letras del que llevan por
 * defecto: a 60px el interletrado normal se ve suelto y barato. */
.pc-display {
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.02;
}

/* Cifras de ancho fijo. Sin esto, un contador que sube de 9 a 10 mientras se
 * anima da un salto lateral en toda la fila. */
.pc-cifra {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
}

/* La etiqueta pequeña en versalitas. Abre mucho el interletrado a propósito:
 * es lo que separa un rótulo de un texto y hace que se lea como jerarquía. */
.pc-etiqueta {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* ============================================================
   Piezas
   ============================================================ */

/* Regla de un píxel de verdad. `border` de Tailwind pinta 1px opaco, que a
 * este tamaño se ve como una raya; esto es una insinuación. */
.pc-regla {
  height: 1px;
  background: rgb(15 23 42 / 0.09);
}
.dark .pc-regla { background: rgb(255 255 255 / 0.09); }

/* Cada cifra del Inicio. Sin caja, sin borde y sin sombra: lo que la separa de
 * la de al lado es el aire, no una línea. El enlace entero es la zona pulsable
 * aunque no lo parezca. */
.pc-dato {
  display: block;
  position: relative;
  transition: transform .25s cubic-bezier(.2,.8,.2,1);
}
.pc-dato:hover { transform: translateY(-2px); }
.pc-dato .pc-cifra { transition: color .2s; }
.pc-dato:hover .pc-cifra { color: rgb(var(--brand-500)); }
.dark .pc-dato:hover .pc-cifra { color: rgb(var(--pc-cielo)); }

/* "Ver todos →" aparece al pasar por encima. En una pantalla táctil no hay
 * hover, así que ahí se deja siempre visible: si no, nadie sabría que la cifra
 * lleva a algún sitio. */
.pc-dato-ir {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin-top: .6rem;
  font-size: .75rem;
  font-weight: 500;
  color: rgb(var(--brand-500));
  opacity: 1;
  transform: none;
  transition: opacity .25s, transform .25s;
}
.dark .pc-dato-ir { color: rgb(var(--pc-cielo)); }
@media (hover: hover) {
  .pc-dato-ir { opacity: 0; transform: translateX(-4px); }
  .pc-dato:hover .pc-dato-ir { opacity: 1; transform: none; }
}

/* Aviso del Inicio (inspección o próximo trabajo). En vez del rectángulo de
 * color saturado de antes, una barra fina a la izquierda: se ve igual de
 * rápido y no compite con el saludo, que es lo que tiene que mandar. */
.pc-aviso {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem 1rem 1.5rem;
  border-left: 3px solid;
  border-radius: 0 .75rem .75rem 0;
  transition: background-color .2s;
}
.pc-aviso-normal { border-color: rgb(var(--brand-500)); background: rgb(var(--brand-500) / 0.04); }
.pc-aviso-normal:hover { background: rgb(var(--brand-500) / 0.08); }
.dark .pc-aviso-normal { border-color: rgb(var(--pc-cielo)); background: rgb(var(--pc-cielo) / 0.07); }
.dark .pc-aviso-normal:hover { background: rgb(var(--pc-cielo) / 0.12); }
.pc-aviso-ojo { border-color: #d97706; background: rgb(217 119 6 / 0.05); }
.pc-aviso-ojo:hover { background: rgb(217 119 6 / 0.1); }
.dark .pc-aviso-ojo { border-color: #fbbf24; background: rgb(251 191 36 / 0.08); }
.pc-aviso-mal { border-color: #e11d48; background: rgb(225 29 72 / 0.05); }
.pc-aviso-mal:hover { background: rgb(225 29 72 / 0.1); }
.dark .pc-aviso-mal { border-color: #fb7185; background: rgb(251 113 133 / 0.08); }

/* Fila de las listas de "últimos". Solo una línea de separación y un realce
 * discreto al pasar por encima. */
.pc-fila {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .7rem 0;
  border-top: 1px solid var(--pc-filo-suave);
}
.pc-fila:first-child { border-top: 0; }

/* ============================================================
   Secciones interiores
   ============================================================ */

/* Mismo ritmo vertical que el Inicio: el título entra con aire por arriba y
 * deja aire por abajo antes del contenido. Es lo que hace que las siete
 * secciones se lean como el mismo sitio y no como siete listados. */
.pc-seccion { padding-top: 1.5rem; padding-bottom: 2rem; }
@media (min-width: 640px) { .pc-seccion { padding-top: 3rem; padding-bottom: 2.5rem; } }

.pc-h2 { font-weight: 600; letter-spacing: -0.03em; line-height: 1.05; }

/* El buscador de las listas. Sin fondo propio: se apoya en el de la página y
 * solo se marca con el filo. Un campo blanco sobre blanco con borde gris era
 * lo que hacía que estas pantallas parecieran un formulario. */
.pc-buscador {
  width: 100%;
  padding: 0.6rem 0.9rem 0.6rem 2.3rem;
  font-size: 0.875rem;
  border-radius: 0.7rem;
  border: 1px solid var(--pc-filo);
  background: transparent;
  transition: border-color .15s, box-shadow .15s;
}
.pc-buscador:focus {
  outline: none;
  border-color: rgb(var(--brand-500));
  box-shadow: 0 0 0 3px rgb(var(--brand-500) / 0.12);
}
.dark .pc-buscador:focus { border-color: rgb(var(--pc-cielo)); box-shadow: 0 0 0 3px rgb(var(--pc-cielo) / 0.16); }

/* El filtro por instalación, al lado del buscador en Informes y Archivos.
 * Mismo filo, mismo alto y mismo radio que él: son dos mandos de la misma
 * barra, y si uno lleva fondo propio y el otro no, la barra se ve torcida.
 * Sin la flecha del sistema —la pintamos nosotros— porque la nativa cambia de
 * forma en cada navegador y rompía la simetría con la lupa de al lado. */
.pc-filtro {
  width: 100%;
  padding: 0.6rem 2.2rem 0.6rem 0.9rem;
  font-size: 0.875rem;
  border-radius: 0.7rem;
  border: 1px solid var(--pc-filo);
  background: transparent;
  color: inherit;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.pc-filtro:focus {
  outline: none;
  border-color: rgb(var(--brand-500));
  box-shadow: 0 0 0 3px rgb(var(--brand-500) / 0.12);
}
.dark .pc-filtro:focus { border-color: rgb(var(--pc-cielo)); box-shadow: 0 0 0 3px rgb(var(--pc-cielo) / 0.16); }
/* Las opciones sí quieren fondo propio: el desplegable lo pinta el sistema y
 * un `transparent` heredado dejaba, en oscuro, texto claro sobre claro. */
.pc-filtro option { background: #fff; color: rgb(15 23 42); }
.dark .pc-filtro option { background: rgb(15 23 42); color: rgb(226 232 240); }

/* Las listas no viven dentro de una tarjeta con borde y sombra. Una regla
 * arriba basta para decir dónde empiezan, igual que las cifras del Inicio: el
 * contenido se sostiene solo. */
.pc-panel { border-top: 1px solid var(--pc-filo); }

/* …salvo donde la lista es una tabla. Ahí manda la caja de la cabecera, que
 * está justo debajo, y las dos juntas eran una raya y un recuadro pegados.
 * Solo de tablet para arriba: en el móvil la tabla no se enseña —se cambia por
 * tarjetas, que no llevan cabecera— y la regla vuelve a hacer su papel. */
@media (min-width: 640px) { .pc-panel-tabla { border-top: 0; } }

/* LA CABECERA DE LA TABLA, EN SU PROPIA CAJA
 *
 * Cerrada y con las esquinas redondeadas, del filo de la casa. Antes era una
 * raya arriba y otra debajo del título de las columnas; en gris se sostenía,
 * pero en morado dos líneas sueltas quedaban colgando.
 *
 * `border-collapse: separate` no es opcional: con `collapse` —lo que pone
 * Tailwind— el navegador ignora el radio de las celdas y las esquinas salen en
 * pico. Y tiene un peaje, que es la regla de abajo: con `separate` los bordes
 * puestos en el <tr> no se dibujan, así que la raya entre filas se muda a las
 * celdas. Por eso los <tbody> de estas dos tablas ya no llevan `divide-y`. */
.pc-tabla { border-collapse: separate; border-spacing: 0; }
.pc-tabla .pc-thead th {
  border-top: 1px solid var(--pc-filo);
  border-bottom: 1px solid var(--pc-filo);
}
.pc-tabla .pc-thead th:first-child {
  border-left: 1px solid var(--pc-filo);
  border-top-left-radius: 0.75rem;
  border-bottom-left-radius: 0.75rem;
}
.pc-tabla .pc-thead th:last-child {
  border-right: 1px solid var(--pc-filo);
  border-top-right-radius: 0.75rem;
  border-bottom-right-radius: 0.75rem;
}
.pc-tabla tbody tr + tr > td { border-top: 1px solid var(--pc-filo-suave); }

/* "Aquí no hay nada" no necesita un recuadro alrededor para entenderse. */
.pc-vacio { text-align: center; padding: 4rem 1.5rem; }

/* Lo que sí sigue pidiendo caja —el chat y el explorador de archivos, que son
 * superficies con vida dentro— la lleva finísima y sin sombra. */
.pc-caja {
  border: 1px solid var(--pc-filo);
  border-radius: 1rem;
  background: #fff;
}
.dark .pc-caja { background: rgb(15 23 42 / 0.35); }

/* ============================================================
   Chat: lista de conversaciones al lado
   ============================================================ */

/* Con 40 obras, una pastilla por conversación son siete filas que empujan el
 * chat fuera de la pantalla y obligan a leerlas todas para encontrar una. La
 * lista lateral cabe siempre, se busca y deja la conversación arriba. */
.pc-chat { display: flex; gap: 1.25rem; align-items: stretch; }
@media (max-width: 1023px) { .pc-chat { flex-direction: column; gap: 0.6rem; } }

.pc-canales { width: 17rem; flex: 0 0 17rem; display: flex; flex-direction: column; gap: 0.5rem; min-height: 0; }
@media (max-width: 1023px) { .pc-canales { width: auto; flex: none; } }

.pc-canal {
  display: flex; align-items: center; gap: 0.5rem;
  width: 100%; text-align: left;
  padding: 0.5rem 0.7rem;
  border-radius: 0.6rem;
  font-size: 0.8125rem;
  color: rgb(71 85 105);
  transition: background-color .15s, color .15s;
}
.dark .pc-canal { color: rgb(148 163 184); }
.pc-canal:hover { background: rgb(var(--brand-500) / 0.06); color: rgb(var(--brand-500)); }
.dark .pc-canal:hover { background: rgb(255 255 255 / 0.06); color: rgb(var(--pc-cielo)); }
.pc-canal.activo { background: rgb(var(--brand-500) / 0.10); color: rgb(var(--brand-500)); font-weight: 600; }
.dark .pc-canal.activo { background: rgb(var(--pc-cielo) / 0.14); color: rgb(var(--pc-cielo)); }

/* El globo de sin leer no debe encogerse ni empujar el nombre: el nombre se
 * recorta y el número se queda entero, que es el que urge. */
.pc-canal-globo {
  flex: none;
  min-width: 1.15rem; height: 1.15rem; padding: 0 0.3rem;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: #e11d48; color: #fff;
  font-size: 0.625rem; font-weight: 700;
}

/* ============================================================
   Login
   ============================================================ */

/* Antes esto era un degradado azul con dos manchas naranjas encima y la
 * tarjeta en cristal esmerilado. Llamaba mucho la atención, pero de la manera
 * en que la llama una plantilla descargada. Ahora el fondo casi no existe —una
 * veladura de marca muy abierta— y todo el peso lo lleva la tarjeta. */
.pc-fondo { background: #f5f6f8; }
.dark .pc-fondo { background: #050810; }
.pc-fondo::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(60rem 40rem at 50% -15%, rgb(var(--brand-500) / 0.10), transparent 70%),
    radial-gradient(40rem 30rem at 110% 110%, rgb(255 102 0 / 0.05), transparent 70%);
}
.dark .pc-fondo::before {
  background:
    radial-gradient(60rem 40rem at 50% -15%, rgb(var(--brand-500) / 0.22), transparent 70%),
    radial-gradient(40rem 30rem at 110% 110%, rgb(255 102 0 / 0.07), transparent 70%);
}

/* Dos sombras: una corta que asienta la tarjeta sobre el fondo y otra larga y
 * muy abierta que la levanta. Con una sola o queda pegada o queda flotando. */
.pc-tarjeta {
  position: relative;
  background: #fff;
  border: 1px solid var(--pc-filo);
  border-radius: 1.25rem;
  padding: 2.75rem 2rem;
  box-shadow: 0 1px 2px rgb(15 23 42 / 0.04), 0 24px 48px -20px rgb(15 23 42 / 0.18);
}
.dark .pc-tarjeta {
  background: #0b1120;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 24px 56px -20px rgb(0 0 0 / 0.8);
}
@media (min-width: 640px) { .pc-tarjeta { padding: 3rem 2.75rem; } }

.pc-campo {
  width: 100%;
  margin-top: 0.4rem;
  padding: 0.8rem 1rem;
  font-size: 0.9375rem;
  border-radius: 0.7rem;
  border: 1px solid var(--pc-filo);
  background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
.dark .pc-campo { background: rgb(15 23 42 / 0.6); }
.pc-campo:focus {
  outline: none;
  border-color: rgb(var(--brand-500));
  box-shadow: 0 0 0 3px rgb(var(--brand-500) / 0.14);
}
.dark .pc-campo:focus { border-color: rgb(var(--pc-cielo)); box-shadow: 0 0 0 3px rgb(var(--pc-cielo) / 0.18); }

.pc-boton {
  width: 100%;
  padding: 0.85rem 1rem;
  border-radius: 0.7rem;
  font-weight: 600;
  font-size: 0.9375rem;
  color: #fff;
  background: linear-gradient(180deg, rgb(var(--brand-500)) 0%, rgb(var(--brand)) 100%);
  box-shadow: 0 1px 2px rgb(var(--brand-700) / 0.4), 0 8px 20px -8px rgb(var(--brand-700) / 0.6);
  transition: transform .15s, box-shadow .2s, filter .2s;
}
.pc-boton:hover { filter: brightness(1.08); box-shadow: 0 2px 4px rgb(var(--brand-700) / 0.4), 0 12px 26px -8px rgb(var(--brand-700) / 0.7); }
.pc-boton:active { transform: translateY(1px); }
.pc-boton:disabled { opacity: .65; filter: none; transform: none; cursor: default; }

/* ============================================================
   Cabecera del portal
   ============================================================ */

/* Clara, no azul. El azul corporativo a toda anchura era lo que más gritaba
 * "panel de administración"; puesto solo en la sección activa y en los enlaces
 * marca igual y deja respirar al contenido, que es de quien va la página.
 * Además el logo, que es una elipse oscura, se lee mejor sobre blanco. */
.pc-cabecera {
  position: relative;
  background: rgb(255 255 255 / 0.85);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--pc-filo-suave);
}
.dark .pc-cabecera {
  background: rgb(2 6 23 / 0.85);
}

/* La franja de marca: los dos azules del logo, del índigo al celeste, cruzando
 * la cabecera. Es lo único de color a toda anchura de la página, y con 3px
 * basta — la cabecera sigue siendo clara, que es lo que deja respirar al
 * contenido y lo que hace que el logo se lea.
 *
 * Va a la altura del área segura y no a top:0: en un iPhone con muesca, la
 * cabecera se extiende por detrás de ella, y una franja pegada al borde del
 * todo se partiría en dos al girar el móvil. */
.pc-cabecera::before {
  content: "";
  position: absolute;
  top: env(safe-area-inset-top, 0px);
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg,
    rgb(var(--brand)) 0%,
    rgb(var(--brand-500)) 42%,
    rgb(var(--pc-cielo)) 100%);
}

.pc-nav {
  padding: 0.45rem 0.8rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: rgb(71 85 105);
  border-radius: 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  position: relative;
  transition: color .15s, background-color .15s;
}
.dark .pc-nav { color: rgb(148 163 184); }
.pc-nav:hover { color: rgb(var(--brand-500)); background: rgb(var(--brand-500) / 0.06); }
.dark .pc-nav:hover { color: rgb(var(--pc-cielo)); background: rgb(255 255 255 / 0.06); }
.pc-nav.active { color: rgb(var(--brand-500)); background: transparent; }
.dark .pc-nav.active { color: rgb(var(--pc-cielo)); }
/* El subrayado de la activa se pinta pegado al borde inferior de la cabecera,
 * no al del enlace: así queda una línea continua con el borde. */
.pc-nav.active::after {
  content: "";
  position: absolute;
  left: 0.8rem; right: 0.8rem; bottom: -0.5rem;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}

/* ============================================================
   El filo, en clase
   ============================================================ */

/* Lo que en el HTML llevaba `border-slate-200 dark:border-slate-700` y sus
 * ocho variantes. Se cambió por esto para que el color del marco se decida en
 * un sitio y no en treinta atributos class: cambiar el de arriba los cambia
 * todos, y ya no hace falta acordarse de escribir la pareja clara/oscura.
 *
 * `pc-filo` sigue necesitando la utilidad `border` (o `border-t`, `border-l`…)
 * al lado: aquí solo va el color, el grosor lo pone Tailwind como siempre. */
.pc-filo       { border-color: var(--pc-filo); }
.pc-filo-suave { border-color: var(--pc-filo-suave); }
/* La raya entre filas de una lista. Tailwind pone el grosor con `divide-y` y
 * el color lo ponía `divide-slate-100`; esto es lo segundo, del color de casa
 * y sin pareja para el modo oscuro. */
.pc-divide > :not([hidden]) ~ :not([hidden]) { border-color: var(--pc-filo-suave); }
