/* =====================================================================
   FS - Pantallas propias
   Lo que es de una pantalla sola y de ninguna otra: la pared, la ficha de
   reparacion, el telefono, el ingreso, los permisos del perfil y las colas
   de Logistica. Va despues de componentes.css a proposito: asi una pantalla
   ajusta un componente sin tener que ganarle por especificidad.

   Parte de la hoja de estilos de FS, que se sirve en varios archivos
   enlazados en orden desde src/views/_estilos.php. El orden importa:
   la cascada es la concatenacion de todos ellos.
   ===================================================================== */
/* --------------------------------------------------------------------
   Pantalla de pared (quiosco)
   Letra grande para leer de lejos en un TV; color por semáforo al costado.
   -------------------------------------------------------------------- */
/* La pared ocupa la pantalla y no scrollea: nadie va a arrastrar un televisor
   colgado. Todo lo que esta fuera de servicio tiene que entrar en una sola
   pantalla, asi que si no entra pared.js achica hasta que entra -en la pared
   de todas, cada sala por su cuenta-. Solo si ni al minimo legible entra, lo
   parte en paginas que rotan.

   Antes se recortaba: la grilla fijaba tres filas y las tarjetas quedaban
   cortadas a la mitad de un renglon, con la zona y la prioridad tapadas. */
.pared {
  --pared-pendiente-fondo: #f2c94c;
  --pared-pendiente-texto: #352500;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: var(--fondo);
  color: var(--texto);
  margin: 0;
  padding: 18px 24px 12px;
  height: 100vh;
  overflow: hidden;
}
.pared-cab {
  display: flex;
  align-items: baseline;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  border-bottom: 2px solid var(--borde);
  padding-bottom: 10px;
}
.pared-cab h1 { font-size: 2rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; line-height: 1.1; }
.pared-sala { font-size: 1.3rem; color: var(--texto-suave); }

/* El titulo con la sala debajo, y a su lado -separado por una linea- el total.
   Los recortes van en el renglon de la sala, que es lo que acotan. */
.pared-titulo { align-self: center; display: flex; flex-direction: column; gap: 2px; }
.pared-titulo .pared-recorte { margin-left: 8px; vertical-align: middle; }
.pared-separador { align-self: stretch; width: 2px; border-radius: 1px; background: var(--borde-fuerte); }
.pared-total.pared-total-principal { margin-left: 0; }

/* Las cuentas, con el color de sus franjas y su rotulo abajo: cuantas en
   reparacion, cuantas trabadas y el total. Es lo primero que se mira al
   pasar, asi que manda el numero; el rotulo va chico. */
.pared-total { margin-left: auto; align-self: center; display: flex; gap: 10px; }
.pared-total > span {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 6.5rem;
  padding: 2px 14px 4px;
  border-radius: 10px;
}
.pared-total b { font-size: 2.2rem; font-weight: 700; line-height: 1.1; }
.pared-total > span > span { font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
/* Reparación sigue el rojo del tema; pendientes comparte el amarillo y la
   tinta de sus títulos para reconocer el mismo estado desde lejos. */
.pared-total-rep  { background: var(--rojo);  color: var(--fondo); }
.pared-total-pend { background: var(--pared-pendiente-fondo); color: var(--pared-pendiente-texto); }
.pared-total-todo { background: var(--fondo-panel); color: var(--texto); box-shadow: inset 0 0 0 2px var(--borde-fuerte); }

/* Lo que recorta la URL, al lado de la sala: un TV que muestra una parte
   tiene que decirlo, o se lee como si fuera todo. */
.pared-recorte {
  align-self: center;
  padding: 2px 12px;
  border-radius: 999px;
  background: var(--acento-suave);
  border: 1px solid var(--acento);
  font-size: 1.1rem;
  font-weight: 700;
}

/* La fecha de hoy, grande, y la hora debajo, antes de los totales. El margen
   empuja reloj y totales juntos a la derecha. */
.pared-reloj {
  margin-left: auto;
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.05;
}
.pared-reloj + .pared-total { margin-left: 0; }
.pared-reloj-fecha { font-size: 2.2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.pared-reloj-hora { font-size: 1.1rem; color: var(--texto-suave); font-variant-numeric: tabular-nums; }

.pared-vacio { font-size: 2rem; color: var(--verde); padding: 3rem 0; }

/* Aviso de que lo que se ve esta viejo: el servidor no contesta y la pantalla
   quedo con la ultima foto buena. Lo pone y lo saca pared.js.

   Franja roja, ancho completo y letra grande: el televisor esta lejos y nadie
   lo mira de cerca, asi que tiene que gritar. Sin esto, una pared congelada se
   ve exactamente igual que una al dia, que es la peor forma de fallar. */
.pared-aviso {
  margin: 0 0 12px;
  padding: 10px 18px;
  border-radius: 8px;
  background: var(--rojo);
  color: #fff;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-align: center;
}

/* El bloque que pared.js achica cuando no entra. El zoom se aplica aca y no en
   el <body> para que el encabezado y el pie queden a su tamaño: lo que sobra
   son las tarjetas, no los rotulos.

   Una columna vertical por sala, lado a lado. Antes era una grilla sola con
   las salas una debajo de la otra, y una sala con una sola maquina se comia un
   renglon entero: quedaban tarjetas enormes al lado de huecos. */
.pared-salas {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(var(--pared-salas, 1), minmax(0, 1fr));
  align-items: start;
  gap: 18px;
}

.pared-sala-grupo { min-width: 0; }

/* La pared de todas: columnas fijas, del alto de la pantalla, y cada una con
   un cuerpo que se achica por su cuenta (pared.js). La fila mide lo que la
   zona y no lo que el contenido, o el cuerpo no tendria contra que medirse. */
.pared-salas[data-pared-por-sala] { grid-template-rows: minmax(0, 1fr); align-items: stretch; }
.pared-salas[data-pared-por-sala] .pared-sala-grupo { display: flex; flex-direction: column; min-height: 0; }
.pared-salas[data-pared-por-sala] .pared-sala-cuerpo { flex: 1; min-height: 0; overflow: hidden; }

.pared-sala-ok {
  margin: 2.5rem 0 0;
  text-align: center;
  color: var(--verde);
  font-size: 1.8rem;
  font-weight: 700;
}

/* El indicador de pagina de una sala que rota sola, al lado de su cuenta. */
.pared-sala-pagina { margin-left: auto; min-width: 0; font-size: 1.1rem; letter-spacing: 0; }
.pared-sala-pagina .pared-pagina-barra { width: 70px; min-width: 16px; flex-shrink: 1; }
.pared-sala-titulo > .pared-sala-cuenta,
.pared-sala-pagina > [data-pared-pagina-texto] { flex-shrink: 0; }
.pared-sala-pagina:not([hidden]) + .pared-sala-cuenta { margin-left: 0; }

/* El rotulo de la sala manda: en la pared de todas, lo primero que hace el ojo
   es ubicar de que sala esta mirando. Antes era un texto gris chico y las tres
   franjas se leian como una sola grilla. Ahora es una banda con fondo propio,
   letra grande y una linea azul abajo que cierra la columna. */
.pared-sala-titulo {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 10px;
  padding: 5px 14px;
  border-radius: 8px 8px 0 0;
  /* Azul y no el fondo de panel: en el tema oscuro el panel es el MISMO color
     que las tarjetas, asi que la banda se confundia con ellas. */
  background: var(--acento-suave);
  border-bottom: 3px solid var(--acento);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--texto);
}
/* El nombre de la sala lleva a su propia pared, y el titulo al listado de
   reparaciones. Se dibujan igual que antes -son rotulos, no botones- y solo se
   subrayan al pasar por encima. */
.pared-sala-enlace,
.pared-titulo-enlace { color: inherit; text-decoration: none; }
.pared-sala-enlace:hover,
.pared-titulo-enlace:hover { color: var(--texto); text-decoration: underline; }
.pared-sala-enlace:focus-visible,
.pared-titulo-enlace:focus-visible { outline: 2px solid var(--acento); outline-offset: 3px; }

/* Cuantas hay en esa sala. Es el numero que se lee cruzando el laboratorio -"que
   tan mal esta cada una"-, asi que va grande y no como una etiqueta chica al
   costado del nombre. */
.pared-sala-cuenta {
  margin-left: auto;
  padding: 1px 16px;
  border-radius: 999px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde-fuerte);
  color: var(--texto);
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0;
}

/* Adentro de cada sala, las tarjetas apiladas. Con una sola sala -un televisor
   dedicado, /pared?sala=rebisco- no hay columnas que llenar, asi que las
   reparte en las que decida pared.js. */
.pared-grid {
  display: grid;
  grid-template-columns: repeat(var(--pared-cols, 1), minmax(0, 1fr));
  gap: 8px;
}

/* La tarjeta es apaisada: en una columna angosta y alta, apilar cinco
   renglones deja tarjetas altisimas y pocas por pantalla. Tres zonas en una
   fila -quien es, que le pasa, como esta- entran en la mitad del alto.

   Las columnas de los costados se miden por su contenido y no en ch: con un
   ancho fijo, el UID se partia en dos renglones y "En reparacion" quedaba en
   "En repara...". El medio se queda con lo que sobra y ahi si se corta con
   puntos, porque una falla puede tener 255 caracteres. */
.pared-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 14px;
  min-width: 0;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-left: 8px solid var(--borde-fuerte);
  border-radius: 8px;
  padding: 8px 12px;
  /* Red de seguridad: si por lo que fuera la columna quedara mas angosta que
     la tarjeta, se corta adentro y no se desborda por el costado. */
  overflow: hidden;
}

/* El color dice el ESTADO, no la demora: rojo lo que esta en reparacion, ambar
   lo que quedo trabado esperando un repuesto o una autorizacion. Es la
   pregunta que se hace mirando la pared desde lejos: que se esta trabajando y
   que esta parado. La demora sigue estando, en dias, adentro de la tarjeta. */
/* La tarjeta entera es un enlace a la ficha. Hereda el color y no se subraya:
   en la pared tiene que verse igual que antes; lo que cambia es que desde una
   computadora se puede entrar de un clic. */
a.pared-card { color: inherit; text-decoration: none; }
a.pared-card:hover { border-color: var(--borde-fuerte); background: var(--fondo-hover); }
a.pared-card:focus-visible { outline: 3px solid var(--acento); outline-offset: 2px; }

.pared-card.franja-reparacion { border-left-color: var(--rojo); }
.pared-card.franja-pendiente  { border-left-color: var(--ambar); }
.pared-card.franja-reparacion .pared-dias,
.pared-card.franja-reparacion .pared-estado { color: var(--rojo); }
.pared-card.franja-pendiente .pared-dias,
.pared-card.franja-pendiente .pared-estado { color: var(--ambar); }
.pared-pieza { color: var(--texto-suave); font-weight: 600; }

/* Cada sala en dos franjas: lo que se trabaja y lo que esta trabado. El rotulo
   lleva el color de sus tarjetas, asi la division se ve antes de leerla. */
.pared-franja + .pared-franja { margin-top: 12px; }
.pared-franja-titulo {
  --pared-franja-texto: var(--fondo-panel);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 6px;
  padding: 6px 12px;
  border-radius: 6px;
  background: var(--pared-franja-color);
  color: var(--pared-franja-texto);
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.franja-reparacion > .pared-franja-titulo { --pared-franja-color: var(--rojo); }
/* El ámbar oscuro lleno se acerca al rojo desde lejos: el pendiente lleva
   amarillo y tinta oscura en ambos temas para separar las dos bandas. */
.franja-pendiente > .pared-franja-titulo {
  --pared-franja-color: var(--pared-pendiente-fondo);
  --pared-franja-texto: var(--pared-pendiente-texto);
}
.pared-franja-etiqueta { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pared-franja-etiqueta .icono { width: 1.2em; height: 1.2em; flex-shrink: 0; stroke-width: 2.2; }
.pared-franja-cuenta {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  min-width: 1.45em;
  height: 1.45em;
  padding: 0 .15em;
  box-sizing: border-box;
  border-radius: 999px;
  background: var(--pared-franja-texto);
  color: var(--pared-franja-color);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.pared-franja-vacia { margin: 0 0 4px; padding: 2px 12px; color: var(--texto-tenue); font-size: 1rem; }

/* Los cinco pasos de una reparacion, de la sala a instalada. Ocupa el ancho
   entero de la tarjeta, abajo: es un dato de un vistazo, no un renglon mas. */
.pared-pasos {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
}
.pared-paso { height: 6px; border-radius: 3px; background: var(--borde); }
.pared-paso.es-hecho  { background: var(--rojo); opacity: .45; }
.pared-paso.es-actual { background: var(--rojo); }

/* Al llegar una actualización SSE, sólo titila la tarjeta afectada. El borde
   lateral conserva el color del estado; el halo azul señala el cambio sin
   confundir reparación con pendiente. Cinco pulsos duran algo más de 3 s. */
@keyframes pared-card-actualizada {
  0%, 100% {
    background: var(--fondo-panel);
    box-shadow: none;
  }
  50% {
    background: var(--acento-suave);
    box-shadow: 0 0 0 4px var(--acento), 0 0 22px var(--acento);
  }
}

.pared-card.es-actualizada {
  position: relative;
  z-index: 1;
  animation: pared-card-actualizada .65s ease-in-out 5;
}

/* Adornos de los cambios, que pone pared.js al comparar una foto con la
   anterior. Cortos y solo con transform y opacity, que los televisores mas
   viejos mueven sin trabarse.

   Una maquina que sale de servicio entra desde arriba. */
@keyframes pared-card-entra {
  0%   { opacity: 0; transform: translateY(-16px) scale(.97); }
  60%  { opacity: 1; transform: translateY(2px); }
  100% { opacity: 1; transform: none; }
}
.pared-card.es-nueva { animation: pared-card-entra .6s ease-out; }

/* La que se va de la pared -casi siempre porque volvio a servicio- se pinta
   de verde un instante y se corre al costado: es la buena noticia de la
   pantalla, y antes simplemente desaparecia. Dura lo mismo que SALIDA_MS. */
@keyframes pared-card-sale {
  0%   { opacity: 1; transform: none; }
  30%  { opacity: 1; transform: none; background: var(--verde-bg); border-left-color: var(--verde); }
  100% { opacity: 0; transform: translateX(40px); background: var(--verde-bg); border-left-color: var(--verde); }
}
.pared-card.es-saliente { animation: pared-card-sale 1.4s ease-in forwards; }

/* El numero que cambio sube desde abajo, como un contador mecanico. La
   casilla recorta, para que no se vea pasar por debajo. */
@keyframes pared-numero-sube {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: none; }
}
.pared-total > span,
.pared-sala-cuenta { overflow: hidden; }
.pared-total b.es-cambiada,
.pared-sala-cuenta.es-cambiada { animation: pared-numero-sube .45s ease-out; }

/* Cuando una sala rota de pagina, sus tarjetas entran con un deslizamiento
   corto en vez de aparecer de golpe. */
@keyframes pared-pagina-entra {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: none; }
}
.pared-card.es-pagina-nueva { animation: pared-pagina-entra .65s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .pared-card.es-pagina-nueva { animation: none; }
  .pared-card.es-actualizada {
    animation: none;
    background: var(--acento-suave);
    box-shadow: 0 0 0 4px var(--acento);
  }
  .pared-card.es-nueva,
  .pared-card.es-saliente,
  .pared-total b.es-cambiada,
  .pared-sala-cuenta.es-cambiada { animation: none; }
}

.pared-quien { min-width: 0; }
.pared-que { display: flex; flex-direction: column; min-width: 0; }
.pared-como { display: flex; flex-direction: column; align-items: flex-end; min-width: 0; }

.pared-uid { font-size: 1.5rem; font-weight: 700; line-height: 1.1; white-space: nowrap; }
.pared-dias { font-size: 1.2rem; font-weight: 700; white-space: nowrap; }

/* Una linea cada uno, cortado con puntos: dos tarjetas con textos de distinto
   largo tienen que medir lo mismo. */
.pared-equipo,
.pared-estado,
.pared-datos > span,
.pared-meta > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* El equipo comparte renglon con la zona: se corta el primero, que es el que
   trae nombres larguisimos, y no la zona, que es una palabra. */
.pared-equipo { min-width: 0; flex: 0 1 auto; }
.pared-estado { font-size: .85rem; font-weight: 700; }

/* Primer renglon: que maquina es. Es el dato que se busca junto con el UID,
   asi que va grande. */
.pared-datos {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
  align-items: baseline;
  gap: 4px 12px;
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--texto);
  white-space: nowrap;
}

/* Segundo renglon: donde esta parada y con que urgencia. La falla no esta en
   la pared -es texto libre de 255 caracteres y esta a un clic, en la ficha-,
   asi que este renglon es el que dice para donde salir a caminar. */
.pared-meta {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
  align-items: center;
  gap: 10px;
  font-size: .95rem;
  font-weight: 700;
  color: var(--texto-suave);
  white-space: nowrap;
}
.pared-zona { color: var(--texto); }

/* Un punto entre la zona y la prioridad: de lejos, dos textos pegados por un
   espacio se leen como uno solo. */
.pared-meta > span + span::before { content: '· '; color: var(--texto-tenue); }
.pared-meta > .pared-prioridad.es-alta::before { content: none; }
/* La prioridad normal es la de casi todas: se dice, pero en gris y sin
   pastilla. La ALTA es la excepcion y por eso grita. */
.pared-prioridad.es-alta {
  padding: 0 7px;
  border-radius: 999px;
  background: var(--rojo);
  color: #fff;
}

.pared-pie {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 12px;
  color: var(--texto-tenue);
  font-size: 1rem;
}
.pared-pie > :first-child { margin-right: auto; }

/* Lo que pared.js saca de la vista porque va en otra pagina. Con clase y no
   con hidden: la tarjeta y la franja tienen su propio display. */
.pared .es-otra-pagina { display: none; }

/* Solo cuando pared.js tuvo que partir la pared en paginas: cual se ve y
   cuanto falta para la siguiente. */
.pared-pagina { display: flex; align-items: center; gap: 10px; color: var(--texto); font-weight: 700; }
.pared-pagina[hidden] { display: none; }
.pared-pagina-barra { width: 120px; height: 6px; border-radius: 3px; background: var(--borde); overflow: hidden; }
.pared-pagina-barra > span { display: block; height: 100%; width: 0; background: var(--texto-suave); }
.pared-pagina-barra > span.es-corriendo { animation: pared-pagina-avance var(--pared-rotacion, 10s) linear forwards; }
@keyframes pared-pagina-avance { from { width: 0; } to { width: 100%; } }

/* El TV queda limpio. La franja aparece sobre el borde inferior al acercar
   el mouse; nunca participa del alto disponible para repartir las tarjetas. */
.pared-controles {
  position: fixed;
  z-index: 10;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 14px 24px;
  padding: 18px 24px;
  background: var(--fondo-panel);
  border-top: 1px solid var(--borde-fuerte);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(100%);
  transition: transform .3s ease, opacity .3s ease, visibility .3s;
}
.pared.es-controles-visible .pared-controles {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
}
.pared-controles label { display: grid; gap: 6px; margin: 0; font-size: 1rem; }
.pared-controles input[type="range"] { width: 210px; max-width: 100%; margin: 0; accent-color: var(--acento); }
.pared-controles output { font-variant-numeric: tabular-nums; }
.pared-controles-abrir {
  position: fixed;
  z-index: 9;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 54px;
  opacity: 0;
  border: 0;
  background: transparent;
}
.pared-controles-abrir:focus-visible { opacity: 1; background: var(--fondo-panel); }
@media (pointer: coarse) {
  .pared-controles-abrir { left: auto; right: 12px; bottom: 8px; width: auto; height: 44px; opacity: 1; background: var(--fondo-panel); border: 1px solid var(--borde-fuerte); }
  .pared.es-controles-visible .pared-controles-abrir { visibility: hidden; }
  .pared-controles button, .pared-controles select { min-height: 44px; }
}
@media (max-width: 460px) {
  .pared-controles { padding: 14px 12px; gap: 12px; }
  .pared-controles label { width: 100%; }
  .pared-controles input[type="range"] { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .pared-controles { transition: none; }
}

/* --------------------------------------------------------------------
   Ficha de reparacion: la cabecera

   El titulo con el UID, el equipo y el bloque de estado con los dias.
   Estaba metido adentro de la seccion de la pared, sin encabezado: son
   dos pantallas distintas que no comparten nada.
   -------------------------------------------------------------------- */

/* El nombre de la sala al lado del titulo, con el MISMO estilo: hereda tamaño,
   peso y color del h1. Va en <small> por semantica, pero se ve igual. */
.titulo-sala { font-size: inherit; font-weight: inherit; color: inherit; margin-left: 8px; }

/* --------------------------------------------------------------------
   La cabecera de las OTRAS fichas: la del slot y el alta de una reparacion

   Es la que tenia tambien la ficha de reparacion hasta que paso a
   .ficha-cab, mas abajo. Se queda porque esas dos vistas la siguen usando,
   y pasarlas es su propio paso: cada una muestra cosas distintas en la
   barra de la derecha.
   -------------------------------------------------------------------- */
.titulo-ficha {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 18px;
  flex-wrap: wrap;
}

.ficha-uid {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--acento);
}

.ficha-titulo {
  margin: 0 0 6px;
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--texto);
  line-height: 1.15;
}

/* Subtitulo de equipo: UID destacado y modelo. */
.titulo-equipo {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.titulo-equipo small {
  font-size: 1rem;
  font-weight: 500;
  color: var(--texto-suave);
  letter-spacing: 0;
}

/* Contra un titulo grande el marcador queda diminuto: se agranda un poco y
   se alinea con el UID en vez de con la base de la linea. */
.titulo-equipo .reincide {
  margin-left: 0;
  font-size: .8rem;
  padding: 4px 8px;
  align-self: center;
}

/* --------------------------------------------------------------------
   La cabecera de la ficha de reparacion

   Dos renglones: arriba quien es -el UID, el marcador de reincidencia y la
   prioridad-, abajo que es y como esta -marca y modelo, estado y dias-.

   NO HAY PASTILLAS, y es a proposito. El estado y los dias son texto, y el
   color se lo dan ellos mismos. Sale de la pantalla de la pared, que es la
   que esta familia visual vino a copiar: ver .pared-estado y .pared-dias
   mas abajo en este archivo. Lo unico que encierra algo es la regla de la
   izquierda, que tambien viene de ahi -la tarjeta de la pared lleva el
   color del estado en su borde-.

   DOS COLORES, DOS COSAS. La regla dice en que ESTADO esta el caso; el
   numero de dias dice hace CUANTO, por semaforo, con los umbrales que se
   configuran en Ajustes. No se unifican porque no dicen lo mismo: una
   maquina en reparacion -ambar- puede llevar 69 dias -rojo-, y ese es
   justamente el caso que hay que ver.

   El tono del estado se resuelve UNA vez, en --tono-estado, y lo usan la
   regla y el texto. Los valores son los mismos que los de .etq-<estado> en
   componentes.css; si alla se agrega un estado, aca va su linea.
   -------------------------------------------------------------------- */
/* SE QUEDA A LA VISTA mientras se recorre la ficha.

   La ficha es larga -los datos, la bitacora, las partes con su via, los
   adjuntos- y al bajar se perdia de vista de que maquina se estaba hablando.
   Ahora el UID, el estado y los dias acompanian todo el recorrido.

   Se cuelga de --alto-cabecera, la medida de la barra de la aplicacion, que
   es exactamente lo mismo que hace .cabecera-pegajosa en los listados. En el
   telefono esa medida vale cero porque alla la barra no se pega, asi que esta
   se pega contra el borde de la ventana: sale bien sin ninguna regla aparte.

   El fondo es obligatorio. Un sticky transparente deja ver el contenido pasar
   por atras, y aca abajo pasan paneles enteros. Por lo mismo el margen de
   .titulo-pagina pasa a padding: un margen no se pinta, y el contenido se
   colaba por ese hueco.

   POR QUE NO SE PEGA ELLA MISMA
   -----------------------------
   La primera version la hizo `sticky` a secas y funcionaba, pero ocupaba
   117px en escritorio y 143 en el telefono: arriba de la barra de la
   aplicacion, un quinto de la ventana. Achicarla al pegarse NO se puede
   hacer sobre ella misma: un sticky sigue ocupando su lugar en el FLUJO, asi
   que si se achica 70px, los 70px se los come todo lo que tiene debajo y el
   contenido pega un salto hacia arriba justo en el momento en que uno esta
   bajando.

   Por eso se queda quieta y, cuando se va de la pantalla, aparece en su
   lugar .ficha-cab-fija: otra barra, mas chica, en position: fixed. Una
   fija no esta en el flujo, asi que no mueve nada. Es el mismo patron que
   .slots-encabezado-flotante, en componentes.css. */
.ficha-cab {
  --tono-estado: var(--texto-suave);
  border-left: 4px solid var(--tono-estado);
  padding-left: 14px;
  padding-bottom: 12px;
  margin-bottom: 4px;
  /* La linea que marca donde termina la cabecera y empieza el contenido. */
  border-bottom: 1px solid var(--borde);
}

/* En tema claro, la cabecera es una tarjeta blanca como los paneles de abajo,
   con la regla del estado en su borde izquierdo: sobre el piedra de la
   pagina, el UID y el estado se leian como sueltos, y la barra compacta que
   aparece al bajar ya era blanca. En el oscuro queda como estaba: ahi el
   fondo de la pagina y el de los paneles casi no se distinguen. Vale para el
   telefono tambien; angosto.css sólo le achica el relleno. */
:root:not([data-tema="oscuro"]) .ficha-cab {
  padding: 14px 18px 14px 16px;
  margin-bottom: 12px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-left: 4px solid var(--tono-estado);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
}

/* --------------------------------------------------------------------
   La barra compacta: lo que queda de la cabecera cuando la cabecera se fue

   Es la cabecera entera menos una linea: la del rotulo "Ficha de
   reparacion". Es lo unico que sobra al bajar, porque quien ya recorrio
   media ficha sabe en que pantalla esta. El UID, el estado, los dias, la
   marca y el modelo siguen haciendo falta a mano.

   El fondo va de lado a lado de la ventana y el contenido adentro repite la
   caja de .contenido. Asi no hay que medir ni el ancho ni la posicion desde
   JavaScript: el navegador la centra igual que al resto.

   La arma fs.js clonando el renglon, y el clon va con aria-hidden: para un
   lector de pantalla la cabecera de verdad sigue estando una sola vez, mas
   arriba en el documento.
   -------------------------------------------------------------------- */
.ficha-cab-fija {
  position: fixed;
  top: var(--alto-cabecera);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--fondo-panel);
  border-bottom: 1px solid var(--borde-fuerte);
  box-shadow: var(--sombra);
}
.ficha-cab-fija[hidden] { display: none; }

.ficha-cab-fija-int {
  max-width: 1500px;
  margin: 0 auto;
  padding: 7px 18px;
  border-left: 4px solid var(--tono-estado);
}

/* Adentro se ve igual que la cabecera de arriba: mismos cuerpos, mismos
   colores. Lo unico que cambia es que no esta el rotulo, asi que el primer
   renglon no necesita separarse de nada. */
.ficha-cab-fija .ficha-cab-quien { margin-top: 0; }

.ficha-cab.est-en_reparacion   { --tono-estado: var(--ambar); }
.ficha-cab.est-pendiente       { --tono-estado: var(--rojo); }
.ficha-cab.est-sin_reparacion  { --tono-estado: var(--rojo); }
.ficha-cab.est-reparada_lab    { --tono-estado: var(--violeta); }
.ficha-cab.est-reemplazada     { --tono-estado: var(--violeta); }
.ficha-cab.est-reparada_sala   { --tono-estado: var(--verde); }
.ficha-cab.est-en_servicio     { --tono-estado: var(--verde); }
.ficha-cab.est-rep_sin_recibir { --tono-estado: var(--acento); }
.ficha-cab.est-retirada        { --tono-estado: var(--texto-suave); }

/* "Ficha de reparacion" baja a rotulo: sigue estando -dice donde estas y
   encabeza la pagina- pero deja de ser lo mas grande de la pantalla. Misma
   condensada en mayuscula que los titulos de seccion. */
.ficha-rotulo {
  display: block;
  font-family: var(--fuente-display);
  font-size: 1.05rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--texto);
}

/* El renglon de un vistazo: quien es, como esta y hace cuanto.

   Los tramos se separan con una BARRA vertical, el mismo recurso con el que
   la barra de arriba encierra el nombre de la sala. Dice "esto es otro dato"
   sin encerrar nada en una caja de color, que es de lo que se trataba.

   align-items: stretch y no baseline: la barra tiene que medir el alto del
   renglon entero para leerse como una barra. Con baseline cada tramo mide lo
   suyo -el UID va a 1.7rem y el estado a .95- y las barras quedaban de
   alturas distintas. Cada tramo se centra por dentro. */
.ficha-cab-quien {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  margin-top: 4px;
  min-height: 2.1rem;
}

/* El UID y su marcador de reincidencia son la misma cosa -la maquina-, asi
   que van juntos y sin barra en el medio. */
.ficha-quien-uid {
  display: flex;
  align-items: center;
  gap: 9px;
  padding-right: 14px;
}

.ficha-tramo {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border-left: 1px solid var(--borde-fuerte);
}

/* El titular. Va en mono porque un UID es un codigo: en la sala se lee de a
   grupos -038, 7022- y la mono los alinea. */
.ficha-uid {
  margin: 0;
  font-family: var(--fuente-mono);
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.1;
  color: var(--texto);
}

/* Solo aparece en ALTA. En NORMAL no se dibuja nada: es el 99 % de los
   casos y no merece un renglon que diga "todo normal". */
.ficha-prioridad {
  display: flex;
  align-items: center;
  padding-left: 14px;
  font-family: var(--fuente-display);
  font-size: .82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--rojo);
}

/* Debajo de la cabecera de un caso pendiente por repuesto: qué pieza lo traba.
   En la ficha cada pieza va en su renglón, con el REQUI con el que se reclama. */
/* Tan ancho como lo que dice: a todo el ancho se leía como un cartel de la
   página y no como un dato del caso. */
.ficha-traban {
  width: fit-content;
  max-width: 100%;
  box-sizing: border-box;
  margin: 12px 0 6px;
  padding: 10px 14px 10px 12px;
  border: 1px solid var(--ambar);
  border-left-width: 6px;
  border-radius: var(--radio);
  background: var(--ambar-bg);
}
.ficha-traban-rotulo {
  font-family: var(--fuente-display);
  font-size: .95rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ambar);
}
.ficha-traban .partes-pendientes { flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 8px; }
.ficha-traban .parte-pendiente  { font-size: .95rem; padding: 4px 5px 4px 10px; border-color: var(--ambar); }
.ficha-traban .parte-pendiente-tramo { font-size: .8rem; }
.ficha-traban-pie {
  display: block;
  margin-top: 6px;
  font-size: .8rem;
  color: var(--texto-suave);
}

.ficha-cab-como {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 7px;
}

.ficha-equipo { font-size: .95rem; font-weight: 600; color: var(--texto); }

.ficha-estado-txt {
  font-family: var(--fuente-display);
  font-size: .95rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tono-estado);
}

/* El estado acaba de cambiar (fs.js, «Lo nuevo desde la última vez que se
   miró esta ficha»): se ilumina con su propio color y aparece una tilde al
   costado, que se va sola. Es la respuesta a "¿se guardó?" sin leer nada.
   La tilde va en absoluto para que al irse no corra el renglón. El fondo es
   un ::before con opacidad y no un color mezclado: así sirve el color de
   cualquier estado sin escribir uno por cada uno. */
.ficha-estado-cambio { position: relative; isolation: isolate; }
.ficha-estado-cambio::before {
  content: "";
  position: absolute;
  inset: -3px -6px;
  z-index: -1;
  border-radius: var(--radio-chico);
  background: var(--tono-estado);
  opacity: 0;
  animation: ficha-estado-luz 2.2s ease;
}
.ficha-estado-cambio::after {
  content: "✓";
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: .5em;
  opacity: 0;
  animation: ficha-estado-tilde 2.2s ease;
}
@keyframes ficha-estado-luz { 0%, 50% { opacity: .16; } }
@keyframes ficha-estado-tilde {
  0%   { opacity: 1; transform: translateY(-50%) scale(0); }
  15%  { opacity: 1; transform: translateY(-50%) scale(1.3); }
  25%, 75% { opacity: 1; transform: translateY(-50%) scale(1); }
  100% { opacity: 0; transform: translateY(-50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .ficha-estado-cambio::after { animation-name: ficha-estado-tilde-quieta; }
  @keyframes ficha-estado-tilde-quieta {
    0%, 75% { opacity: 1; transform: translateY(-50%); }
    100% { opacity: 0; transform: translateY(-50%); }
  }
}

/* El numero grande de la cabecera. Las clases sem-* traen el color del
   semaforo; aca se les saca el fondo, que es lo que las hacia pastilla. */
.ficha-dias {
  font-size: 1.15rem;
  font-weight: 700;
  background: none;
  padding: 0;
}

.ficha-nota,
.ficha-sala { font-size: .88rem; color: var(--texto-tenue); }
.ficha-sala { font-family: var(--fuente-display); font-weight: 600; letter-spacing: .06em; }
.ficha-sep  { color: var(--borde-fuerte); }

.ficha-quien-uid .reincide { margin-left: 0; }

/* Desde cuándo está en el estado actual: un renglón propio debajo del estado,
   en el mismo tramo. Al costado no entraba en el teléfono, donde el estado ya
   ocupa dos o tres renglones. */
.ficha-tramo:has(.ficha-desde) { flex-direction: column; align-items: flex-start; gap: 0; }
.ficha-desde { font-weight: 600; white-space: nowrap; margin-top: 2px; }

/* La barra de estado de una ficha: la pastilla, el contador de días y la
   aclaración al lado. Son los tres datos que contestan "¿cómo está esto?" y se
   leen de una sola pasada, así que se dibujan como un conjunto y no como tres
   elementos que quedaron juntos.

   Lo que los unifica es la ALTURA y no el tamaño de letra: el número va en
   mono y la etiqueta en la tipografía del texto, y a igual font-size la caja
   del número se ve más chica. Con una altura mínima común y el padding solo
   horizontal, las dos cajas miden lo mismo y cada texto puede tener el tamaño
   que le corresponde. El radio redondo es el de la pastilla, que es la forma
   con la que esta app dice "estado".

   Vale para las tres fichas que tienen esta barra —la de la reparación, la del
   slot y el alta—, que hasta ahora se parecían pero no coincidían. */
.ficha-estado {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.ficha-estado .etq-grande,
.ficha-estado .dias-grande {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  line-height: 1;
}

.ficha-estado .etq-grande  { font-size: 1.02rem; font-weight: 700; }
.ficha-estado .dias-grande { font-size: 1.2rem; }
.ficha-estado > .tenue     { font-size: .95rem; }

@media (max-width: 700px) {
  /* Un punto menos de alto y de letra: en el teléfono la barra comparte
     renglón con el UID y con la sala, y a tamaño completo empujaba el resto de
     la cabecera fuera de la primera pantalla. */
  .ficha-estado .etq-grande,
  .ficha-estado .dias-grande {
    min-height: 32px;
    padding: 0 13px;
  }

  .ficha-estado .etq-grande  { font-size: .95rem; }
  .ficha-estado .dias-grande { font-size: 1.1rem; }
  .ficha-estado > .tenue     { font-size: .9rem; }
}

.grilla-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  gap: 16px;
}

/* ---------------------------------------------------------------------
   Cada REQUI, su caja

   La primera version ponia un rotulo suelto entre las partes. No alcanzaba:
   sin caja ni fondo, las siete partes seguian leyendose como una sola lista
   y el rotulo parecia un renglon mas. Ahora cada requisicion es un bloque
   cerrado -borde, encabezado con fondo y una barra de color a la izquierda-,
   y lo que se ve primero es cuantos pedidos distintos hay.
   --------------------------------------------------------------------- */
.partes-grupo {
  margin-bottom: 14px;
  border: 1px solid var(--borde);
  border-left: 4px solid var(--acento);
  border-radius: var(--radio-chico);
  overflow: hidden;
}

.partes-grupo:last-child { margin-bottom: 0; }

.partes-grupo-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0;
  padding: 8px 12px;
  background: var(--fondo-suave);
  border-bottom: 1px solid var(--borde);
  font-size: .85rem;
}

.partes-grupo-requi {
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
}

.partes-grupo-rotulo {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--texto-suave);
}

/* El numero es el dato que se busca, asi que es lo mas grande del encabezado.
   El rotulo "REQUI" se lee una vez y despues se saltea. */
.partes-grupo-requi .mono {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--texto);
}

/* El punto rojo de SIN REPARACIÓN, al lado del número: avisa que adentro de
   esa requisición hay una pieza sin arreglo, que plegado no se ve porque el
   resumen la cuenta como resuelta.

   El encabezado alinea por línea base y un punto vacío quedaría colgado del
   piso de la cifra: se lo sube al medio, y se lo agranda apenas, porque acá
   compite con un número de 1.05rem y no con el texto chico del dashboard. */
.partes-grupo-requi .etq-punto {
  align-self: center;
  width: 9px;
  height: 9px;
}

.partes-grupo-cuenta { color: var(--texto-suave); font-size: .8rem; }

/* Lo que dice el encabezado cuando el grupo esta plegado: cuantas partes hay
   y si queda trabajo adentro. Sin esto habria que abrir cada requisicion para
   saber si tiene algo pendiente, que es justo lo que se quiere evitar. */
.partes-grupo-resumen {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.partes-grupo-pendientes {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--ambar-bg);
  color: var(--ambar);
  font-size: .72rem;
  font-weight: 700;
}

.partes-grupo-listas {
  color: var(--verde);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* El grupo se abre y se cierra: es un <details>. Se le saca el triangulito
   propio del navegador y se usa uno propio, que ademas se da vuelta al abrir,
   como en el menu "Mas" de las pestañas. */
.partes-grupo > summary { cursor: pointer; list-style: none; }
.partes-grupo > summary::-webkit-details-marker { display: none; }
.partes-grupo > summary:hover { background: var(--fondo-hover); }
.partes-grupo > summary:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: -2px;
}

.partes-grupo-flecha {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: 1px solid var(--borde-fuerte);
  border-radius: 50%;
  background: var(--fondo-panel);
  color: var(--acento);
  font-size: .85rem;
  line-height: 1;
  transition: transform .15s ease, background .15s ease, border-color .15s ease;
}

/* Con todos los grupos plegados, esta flecha es el unico control a la vista de
   la seccion: tiene que leerse como un boton y no como un adorno. Por eso el
   circulo con borde y el azul de los controles, y no un triangulito gris. */
.partes-grupo > summary:hover .partes-grupo-flecha,
.partes-grupo > summary:focus-visible .partes-grupo-flecha {
  border-color: var(--acento);
  background: var(--acento-suave);
}

.partes-grupo[open] > summary .partes-grupo-flecha { transform: scaleY(-1); }

/* Abierto, el encabezado se pinta del acento lleno, el relleno de los botones
   primarios, con letra blanca: con varios REQUI en la ficha, la barra igual
   abierta que plegada no decía cuál se estaba mirando, y al bajar entre las
   partes se perdía de qué pedido eran. Sigue el color de la sala, y el
   acento lleno aguanta letra blanca en los dos temas. */
.partes-grupo[open] { border-color: var(--acento-fuerte); }
.partes-grupo[open] > .partes-grupo-cab,
.partes-grupo[open] > summary:hover {
  background: var(--acento-fuerte);
  border-bottom: none;
}
.partes-grupo[open] > summary:hover { background: var(--acento-hover); }
.partes-grupo[open] .partes-grupo-rotulo,
.partes-grupo[open] .partes-grupo-cuenta { color: rgba(255, 255, 255, .8); }
.partes-grupo[open] .partes-grupo-requi .mono { color: #fff; font-size: 1.2rem; }
.partes-grupo[open] .partes-grupo-listas { color: #fff; }

/* Plegado, la caja es solo su encabezado: sin el borde de abajo queda una
   linea suelta debajo del titulo. */
.partes-grupo:not([open]) > .partes-grupo-cab { border-bottom: none; }

/* La lista de partes vive adentro de la caja: el aire se lo da el grupo. */
.partes-grupo > .partes-reparacion { padding: 0 12px; }

/* Entre las partes de un mismo REQUI, una línea fuerte, como la que separa
   los días de la bitácora: con la vía y los botones de cada una en el medio,
   la línea fina no alcanzaba para ver dónde terminaba una parte y empezaba la
   otra. Es el color del texto, así que en el tema oscuro la línea es clara. */
.partes-grupo > .partes-reparacion > li { border-bottom: 2px solid var(--texto); }
.partes-grupo > .partes-reparacion > li:last-child { border-bottom: none; }

/* "PARTE 2 DE 4", en negativo para que se encuentre al bajar. */
.parte-num {
  display: inline-block;
  margin-right: 8px;
  padding: 1px 8px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  vertical-align: 1px;
  color: var(--fondo-panel);
  background: var(--texto);
  border-radius: 4px;
}

.parte-reparacion-cab,
.parte-reparacion-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}

.parte-reparacion-cab > div {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.parte-reparacion-meta { margin-top: 5px; font-size: .8rem; }

.parte-envio-editor { margin-top: 10px; }
.parte-envio-editor > summary { width: fit-content; list-style: none; }
.parte-envio-editor > summary::-webkit-details-marker { display: none; }
.parte-envio-editor form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 10px;
  margin-top: 9px;
  padding: 10px;
  border-left: 3px solid var(--acento);
  background: var(--fondo-suave);
}
.parte-envio-editor .campo { margin: 0; }

.parte-requi-editor { margin-top: 10px; }
.parte-requi-editor > summary { width: fit-content; list-style: none; }
.parte-requi-editor > summary::-webkit-details-marker { display: none; }
.parte-requi-editor form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 10px;
  margin-top: 9px;
  padding: 10px;
  border-left: 3px solid var(--acento);
  background: var(--fondo-suave);
}
.parte-requi-editor .campo { margin: 0; }

/* El sello de carga de la parte, que solo ve el administrador. Se dibuja como
   los otros desplegables de la fila para que no se lea como algo aparte. */
.parte-fecha-carga-editor { margin-top: 10px; }
.parte-fecha-carga-editor > summary { width: fit-content; list-style: none; }
.parte-fecha-carga-editor > summary::-webkit-details-marker { display: none; }
.parte-fecha-carga-editor form {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 10px;
  margin-top: 9px;
  padding: 10px;
  border-left: 3px solid var(--acento);
  background: var(--fondo-suave);
}
.parte-fecha-carga-editor .campo { margin: 0; }

.parte-reparacion-acciones {
  display: flex;
  align-items: center;
  gap: 7px;
  /* La marca de recepcion ahora dice fecha y demora, y con el estado al lado
     no entra en un telefono. Las etiquetas no se parten -son pildoras-, asi
     que se pasa la que sobra al renglon siguiente. */
  flex-wrap: wrap;
  justify-content: flex-end;
}

.form-quitar-parte { margin: 0; }

/* --------------------------------------------------------------------
   Pantalla del telefono: subir una foto por QR
   Estaba al final de fs.css, despues de la impresion y sin encabezado.
   -------------------------------------------------------------------- */

/* ====================================================================
   "Usar el movil": QR en la compu y pagina de subida en el telefono
   ==================================================================== */

/* Lo que fs.js esconde cuando hay JavaScript (queda como respaldo sin el). */
html.js .solo-sin-js { display: none; }

/* --- Enlace en la ficha, junto a la subida de adjuntos --- */
.adjuntos-movil {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px dashed var(--borde);
}
.btn-movil { white-space: nowrap; }

/* --- Pantalla del QR (compu) --- */
.movil-qr-grid {
  display: flex;
  gap: 22px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.movil-qr-svg {
  flex: 0 0 auto;
  width: 240px;
  max-width: 60vw;
  padding: 12px;
  background: #fff;                 /* el QR siempre sobre blanco, aun en oscuro */
  border: 1px solid var(--borde);
  border-radius: var(--radio);
}
.movil-qr-svg .qr { display: block; width: 100%; height: auto; }
.movil-qr-texto { flex: 1 1 260px; min-width: 240px; }
.movil-pasos { margin: 0 0 14px; padding-left: 22px; line-height: 1.7; }
.movil-vence { margin: 0 0 14px; }
.movil-url-det summary { cursor: pointer; color: var(--acento); }
.movil-url {
  word-break: break-all;
  background: var(--fondo-suave);
  border: 1px solid var(--borde);
  border-radius: var(--radio-chico);
  padding: 8px 10px;
  font-size: .85rem;
}

.movil-recibido {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--borde);
}
.movil-recibido-titulo {
  color: var(--verde);
  font-size: 1.05rem;
  margin: 0 0 12px;
}
.movil-recibido-lista {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.movil-recibido-lista li {
  width: 96px;
  height: 96px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-chico);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--fondo-suave);
}
.movil-recibido-lista img { width: 100%; height: 100%; object-fit: cover; }
.movil-recibido-lista .adj-doc { font-size: .75rem; padding: 6px; text-align: center; }

/* --- Pagina en el telefono (documento autonomo, fuera del layout) --- */
.movil-pagina {
  min-height: 100dvh;
  margin: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: max(24px, env(safe-area-inset-top)) 18px 24px;
  background: var(--fondo);
  color: var(--texto);
}
.movil-card {
  width: 100%;
  max-width: 460px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 22px 20px 26px;
  text-align: center;
}
.movil-titulo { margin: 0 0 16px; font-size: 1.3rem; }
.movil-maquina {
  margin: 0 0 20px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.movil-uid { font-size: 1.5rem; font-weight: 700; }
.movil-form { display: flex; flex-direction: column; gap: 12px; }
.movil-form [data-comentario-simple] { text-align: left; }
.movil-form [data-comentario-simple] label { display: block; margin-bottom: 5px; font-weight: 600; }
.movil-form [data-comentario-simple] textarea {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  font: inherit;
  color: var(--texto);
  background: var(--fondo-panel);
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-chico);
  padding: 8px 10px;
}
.movil-form [data-comentario-simple] button { margin-top: 12px; }
.movil-o { margin: 2px 0; }
.movil-nota { margin-top: 14px; }
.movil-estado {
  font-size: 1.05rem;
  font-weight: 600;
  padding: 12px 14px;
  border-radius: var(--radio-chico);
  margin: 0 0 14px;
}
.movil-estado-ok  { color: var(--verde); background: var(--verde-bg); }
.movil-estado-mal { color: var(--ambar); background: var(--ambar-bg); }

/* Botones grandes, para el pulgar. */
.btn-grande {
  display: block;
  width: 100%;
  padding: 16px;
  font-size: 1.1rem;
  box-sizing: border-box;
}

/* ====================================================================
   Visor de adjuntos (lightbox)

   Fondo oscuro siempre, independiente del tema: una foto se mira mejor
   sobre negro. fs.js lo crea y lo muestra; sin JavaScript no existe.
   ==================================================================== */

/* --------------------------------------------------------------------
   Login
   -------------------------------------------------------------------- */
.pagina-login {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--fondo);
}

.caja-login {
  width: 100%;
  max-width: 380px;
  margin: auto;
  padding: 30px 28px 34px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
}

.caja-login h1 { font-size: 1.25rem; text-align: center; }
.caja-login .sub {
  text-align: center;
  color: var(--texto-tenue);
  font-size: .86rem;
  margin: 5px 0 20px;
}

.caja-login label {
  display: block;
  font-size: .82rem;
  font-weight: 600;
  color: var(--texto-suave);
  margin: 12px 0 4px;
}

.caja-login .btn { margin-top: 20px; }

.caja-login .login-recordar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}
.caja-login .login-recordar input {
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--acento);
}

/* --------------------------------------------------------------------
   Lista de permisos del perfil
   -------------------------------------------------------------------- */
.lista-permisos { list-style: none; margin: 0; padding: 0; font-size: .89rem; }
.lista-permisos li { padding: 3px 0; }
.lista-permisos .permitido { color: var(--texto); }
.lista-permisos .negado { color: var(--texto-tenue); }

/* --------------------------------------------------------------------
   Logística: las dos colas

   Las dos listas se agrupan por sala porque el recorrido se hace sala por
   sala. La fila de la sala es un encabezado adentro de la tabla y no una
   tabla por sala: así el "marcar todo" sigue alcanzando a todas las piezas
   de la pantalla, que es como se trabaja cuando se sale a buscar.
   -------------------------------------------------------------------- */
.fila-sala td {
  background: var(--fondo-suave);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--texto-suave);
  border-top: 2px solid var(--borde-fuerte);
}
.fila-sala-n {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--texto-tenue);
  margin-left: 8px;
}

/* Esperan repuesto: el bloque de las que nadie pidió va arriba y es lo que
   más se ve; el de las que están en compra, debajo y apagado. Antes era al
   revés -la que faltaba tenía sólo una rayita y la que ya estaba pedida una
   pastilla de color- y lo único de la cola que depende de Logística era lo
   que menos se leía. */
.fila-grupo td {
  font-family: var(--fuente-display);
  font-size: .9rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-top: 2px solid var(--borde-fuerte);
}
.fila-grupo .fila-sala-n { font-family: var(--fuente); }
.fila-grupo-sin td { background: var(--rojo-bg); color: var(--rojo); border-top-color: var(--rojo); }
.fila-grupo-sin .fila-sala-n { color: var(--rojo); }
.fila-grupo-compra td { background: var(--fondo-suave); color: var(--texto-suave); }

.tabla tbody tr.fila-sin-gestionar { background: var(--rojo-bg); }
.fila-sin-gestionar td:first-child { box-shadow: inset 5px 0 0 var(--rojo); }
.fila-sin-gestionar .celda-parte { font-weight: 600; }
.fila-sala-chica {
  margin-left: 6px;
  color: var(--texto-tenue);
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.etq-sin-gestionar { background: var(--rojo); color: var(--fondo-panel); }

.fila-en-compra td { color: var(--texto-suave); }
.compra-hecha { color: var(--texto-tenue); font-size: .85rem; white-space: nowrap; }

/* La marca de compra y su "Quitar" conviven en la celda sin saltar de
   renglón: son una sola cosa leída de un vistazo. */
.celda-compra { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.form-linea { display: inline; }

/* Deshacer no se ofrece con el mismo peso que hacer. */
.btn-plano {
  background: none;
  border-color: transparent;
  color: var(--texto-tenue);
  padding-left: 4px;
  padding-right: 4px;
}
.btn-plano:hover { color: var(--rojo); border-color: var(--borde); }

/* --------------------------------------------------------------------
   Logística: el renglón de Sala con lo que va en camino
   Un enlace con forma de renglón, no un aviso: no hay nada mal, es la
   puerta a la pestaña donde esas piezas se reciben. El número en el color
   de la sala, como en el menú.
   -------------------------------------------------------------------- */
.aviso-en-camino {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  padding: 10px 14px;
  background: var(--fondo-panel);
  border: 1px solid var(--borde);
  border-left: 3px solid var(--acento);
  color: var(--texto);
}
.aviso-en-camino:hover { background: var(--fondo-hover); text-decoration: none; }
.aviso-en-camino-n {
  min-width: 24px;
  padding: 0 7px;
  border-radius: 12px;
  background: var(--acento-fuerte);
  color: #fff;
  font-family: var(--fuente-mono);
  font-weight: 600;
  line-height: 22px;
  text-align: center;
}
.aviso-en-camino-ver { margin-left: auto; color: var(--acento); font-weight: 600; }

/* ---------------------------------------------------------------------
   Panel: "Fuera de servicio ahora" en el teléfono

   La tabla del panel tiene nueve columnas y en el teléfono había que
   correrla de costado para llegar al estado. Ahí se cambia por esta lista,
   que se desliza por dentro y deja ver siempre seis máquinas: el panel no
   se alarga aunque sean cuarenta. En pantalla ancha no se muestra; el
   cambio lo hace angosto.css.

   Seis justas porque cada fila mide lo mismo: dos renglones que no se
   parten -el equipo largo termina en «…»-, así que el alto de la lista es
   seis veces el de una fila, sin medir nada con JavaScript.
   --------------------------------------------------------------------- */
.abiertas-lista { display: none; margin: 0 -14px; }
.abiertas-marco { position: relative; }
.abiertas {
  --alto-abierta: 56px;
  position: relative;
  max-height: calc(6 * var(--alto-abierta));
  margin: 0;
  padding: 0 8px 0 14px;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* La barra a la vista siempre, con su riel, y no la que el teléfono esconde
   hasta que se toca la lista: es la que dice que hay más de seis. */
.abiertas::-webkit-scrollbar { width: 8px; }
.abiertas::-webkit-scrollbar-track { background: var(--fondo); border-radius: 4px; }
.abiertas::-webkit-scrollbar-thumb { background: var(--texto-tenue); border-radius: 4px; }

.abierta {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  column-gap: 10px;
  align-items: center;
  height: var(--alto-abierta);
  margin-right: 6px;
  border-bottom: 1px solid var(--borde);
}
.abierta:last-child { border-bottom: 0; }
.abierta-dias {
  grid-row: 1 / 3;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: center;
}
.abierta-fecha {
  font-family: var(--fuente-mono);
  font-size: .68rem;
  color: var(--texto-tenue);
  white-space: nowrap;
}
.abierta-uid {
  font-family: var(--fuente-mono);
  font-weight: 600;
  white-space: nowrap;
}
.abierta .etq { justify-self: end; font-size: .74rem; padding: 1px 8px; }
.abierta-equipo {
  grid-column: 2 / 4;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: .86rem;
  color: var(--texto-suave);
}

/* El esfumado al pie mientras queda algo abajo. Lo prende panel.js y lo
   apaga al llegar al final. */
.abiertas-lista.hay-mas .abiertas-marco::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 34px;
  pointer-events: none;
  background: linear-gradient(rgba(255, 255, 255, 0), var(--fondo-panel) 90%);
}

.abiertas-pie {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin: 2px 14px 0;
  padding-top: 10px;
  border-top: 1px solid var(--borde);
  font-size: .9rem;
}
.abiertas-cuenta { font-family: var(--fuente-mono); font-size: .82rem; color: var(--texto-tenue); }
.abiertas-pie a { margin-left: auto; font-weight: 600; }

/* ---------------------------------------------------------------------
   Compartir una reparación

   La ventana de la ficha y la página de solo lectura que abre el enlace.
   Las dos sirven igual en el teléfono y en la compu: la ventana usa el
   ancho de los modales, y la lectura es una columna angosta y centrada,
   que en el teléfono ocupa toda la pantalla. Ver
   src/controllers/compartir.php.
   --------------------------------------------------------------------- */
.modal-compartir { width: min(520px, calc(100vw - 32px)); }
.modal-compartir .formulario { padding: 0; }

/* Sin JavaScript, en línea, como los modales de Personal. */
html:not(.js) .modal-compartir { display: block; position: static; width: auto; margin: 0 0 14px; }
html:not(.js) [data-abrir-modal="modal-compartir"],
html:not(.js) .modal-compartir [data-cerrar-modal] { display: none; }

.compartir-quien { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; font-size: .92rem; line-height: 1.35; }

.compartir-crear { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; padding-top: 12px; border-top: 1px solid var(--borde); }
/* Con .formulario adelante para ganarle al recuadro que llevan los fieldset
   de los formularios: acá las pastillas ya se agrupan solas. */
.formulario .compartir-vence { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; border: 0; }
.compartir-vence legend {
  width: 100%;
  margin-bottom: 6px;
  padding: 0;
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--texto-suave);
}
/* Los plazos como pastillas: el radio queda escondido y la pastilla elegida
   se pinta llena. Siguen siendo radios, así que el teclado anda igual. */
.compartir-chip { position: relative; cursor: pointer; }
.compartir-chip input { position: absolute; opacity: 0; pointer-events: none; }
.compartir-chip span {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--borde-fuerte);
  border-radius: 999px;
  background: var(--fondo-panel);
  font-size: .88rem;
}
.compartir-chip input:checked + span { background: var(--texto); border-color: var(--texto); color: var(--fondo-panel); }
.compartir-chip input:focus-visible + span { outline: 2px solid var(--acento); outline-offset: 2px; }

.compartir-enlaces { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--borde); }
.compartir-enlaces h3 {
  margin: 0 0 8px;
  font-size: .8rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--texto-suave);
}
.compartir-enlace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 10px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--borde);
}
.compartir-enlace:last-child { border-bottom: 0; }
.compartir-url {
  grid-column: 1 / -1;
  width: 100%;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-chico);
  background: var(--fondo);
  color: var(--texto-suave);
  font-size: .8rem;
}
.compartir-enlace-ultimo .compartir-url { border-color: var(--acento); color: var(--texto); }
.compartir-dato { font-size: .82rem; }
.compartir-botones { display: flex; gap: 6px; justify-content: flex-end; }

/* La página que abre el enlace. */
.compartido-pagina { background: var(--fondo); }
.compartido-cab {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--banda);
  border-bottom: 3px solid var(--acento-barra);
}
.compartido-marca { font-family: var(--fuente-titulo); font-size: 1.25rem; font-weight: 700; }
.compartido-sala {
  padding-left: 10px;
  border-left: 1px solid var(--banda-linea);
  font-family: var(--fuente-titulo);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.compartido-ingresar { margin-left: auto; font-weight: 600; }
.compartido-franja {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 16px;
  background: var(--acento-suave);
  color: var(--acento);
  font-size: .88rem;
}
.compartido-main { max-width: 640px; margin: 0 auto; padding: 14px 14px 32px; }
.compartido-titulo { margin: 0 0 8px; font-size: 1.2rem; }
.compartido-uid-fila { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.compartido-uid { margin: 0; font-size: 1.7rem; }
.compartido-equipo { margin: 4px 0 8px; color: var(--texto-suave); }
.compartido-main h2 {
  margin: 0 0 8px;
  font-family: var(--fuente-titulo);
  font-size: 1rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.compartido-lista { list-style: none; margin: 0; padding: 0; }
.compartido-lista li { padding: 8px 0; border-bottom: 1px solid var(--borde); }
.compartido-lista li:last-child { border-bottom: 0; }
.compartido-parte { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; align-items: center; }
.compartido-parte-falta { grid-column: 1 / -1; font-size: .85rem; }
.compartido-bit { display: grid; gap: 2px; line-height: 1.4; }
.compartido-bit-sello { font-size: .78rem; color: var(--texto-tenue); }
.compartido-fotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.compartido-fotos img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border: 1px solid var(--borde);
  border-radius: var(--radio-chico);
}
.compartido-entrar { text-align: center; }
.compartido-entrar p { margin: 0 0 10px; color: var(--texto-suave); }
.compartido-entrar .btn { width: 100%; }
