* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: #1f1f1f;
  color: #ddd;
  font-family: Arial, sans-serif;
  overflow: hidden;
}

#app {
  width: 100vw;
  height: 100vh;   /* fallback para navegadores que no soportan dvh */
  height: 100dvh;  /* alto visual REAL en tablets/moviles: evita que la
                      barra de direcciones dinamica (que se oculta/aparece
                      en Safari/Chrome moviles) desalinee el contenido
                      respecto a elementos position:fixed como .account-bar,
                      que es la causa de que el boton "Show Panels" se vea
                      bien en escritorio pero pegado/superpuesto en tablets. */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 64px 1fr;
}

.topbar {
  grid-column: 1 / 2;
  background: rgb(25,25,25);
  border-bottom: 1px solid #2c2c2c;
  display: flex;
  align-items: center;
  gap: 16px;
  height: 64px;
  min-height: 64px;
  min-width: 0;
  padding: 0 20px;
  box-sizing: border-box;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* IMPORTANTE: el header NO debe tener overflow:hidden/auto, porque el
     panel de resultados de busqueda (#globalSearchResults) se posiciona
     absolute y se extiende por debajo de esta barra; si el header recorta
     su propio overflow, recorta tambien ese panel aunque tenga z-index alto.
     En su lugar usamos min-width:0 (el item de grid/flex por defecto no se
     encoge mas alla del contenido minimo de sus hijos, lo que hacia que el
     header "reventara" su propio ancho en ciertos anchos intermedios aunque
     el navegador no lo reportara como scroll). Los breakpoints de mas abajo
     hacen el resto del ajuste. */
}

.topbar-spacer {
  flex: 1 1 auto;
}

button {
  background: #008f5a;
  color: white;
  border: 1px solid #00d37f;
  border-radius: 5px;
  padding: 6px 16px;
  cursor: pointer;
}

input {
  width: 80px;
  background: #111;
  color: #00d37f;
  border: 1px solid #444;
  padding: 6px;
  border-radius: 4px;
}

/* --- Ticker ------------------------------------------------------------ */
@keyframes topbarTickerMove {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.topbar-ticker {
  flex: none;
  width: 360px;
  height: 34px;
  display: flex;
  align-items: center;
  overflow: hidden;
  position: relative;
  background: rgba(255,255,255,.04);
  border-radius: 9px;
}

.topbar-ticker::before,
.topbar-ticker::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 36px;
  z-index: 2;
  pointer-events: none;
}

.topbar-ticker::before {
  left: 0;
  background: linear-gradient(90deg, rgba(255,255,255,.04), transparent);
}

.topbar-ticker::after {
  right: 0;
  background: linear-gradient(270deg, rgba(255,255,255,.04), transparent);
}

.topbar-ticker-track {
  display: flex;
  white-space: nowrap;
  will-change: transform;
  animation: topbarTickerMove 22s linear infinite;
}

.topbar-ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 22px;
  padding-right: 22px;
  font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
  font-size: 12.5px;
  font-weight: 500;
  color: #5fe0ab;
  letter-spacing: .3px;
}

.topbar-ticker-item b {
  color: #e9fbf3;
  font-weight: 600;
}

.topbar-ticker-dot {
  color: #3f6857;
}

/* --- Grupo de carga de proyecto ----------------------------------------- */
.topbar-project {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}

.topbar-project input#projectId {
  width: 60px;
  height: 30px;
  background: rgba(255,255,255,.04);
  color: #e9fbf3;
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 8px;
  padding: 0 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}

.topbar-project #status {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  color: #6b7478;
  white-space: nowrap;
}

.topbar-date {
  display: inline-flex;
  align-items: center;
  height: 30px;
  margin-left: 6px;
  padding: 0 12px;
  border-radius: 8px;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.09);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: #8fa89c;
  white-space: nowrap;
}

.topbar-time {
  margin-left: 8px;
  gap: 7px;
  color: #5fe0ab;
}

.topbar-time::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #5fe0ab;
  box-shadow: 0 0 6px 1px rgba(24,167,101,.7);
  animation: consolePulse 1.8s ease-in-out infinite;
}

/* --- Pill buttons (Global Files / Update List / Perfil / Logout) ------- */
.pill-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: 8px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  color: rgb(170,170,170);
  background: rgba(255,255,255,.05);
  border: 1px solid rgb(40,40,40);
  transition: all .16s ease;
}

.pill-btn:hover {
  color: #fff;
  background: linear-gradient(145deg,#3a3f3d,#2a2e2c);
  border-color: rgb(60,60,60);
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
}

.pill-btn-solid {
  color: #fff;
  background: #18a765;
  border: 1px solid #1ec27a;
}

.pill-btn-solid:hover {
  background: #14915a;
  border-color: #18a765;
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
}

/* Botón de Logout: naranja fuerte en vez del gris genérico de los
   demás botones tipo "pill", para que se distinga como una acción
   distinta (salir de la sesión). */
#btnLogout {
  color: #fff;
  background: #d9531e;
  border: 1px solid #e8672f;
}

#btnLogout:hover {
  background: #ed6a2f;
  border-color: #ff7e3f;
  color: #fff;
  box-shadow: 0 4px 14px rgba(217, 83, 30, 0.4);
}

.topbar-actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
}

#status {
  color: #00d37f;
}

.sidebar {
  position: fixed;
  top: 64px;
  left: 0;
  bottom: 100px;
  width: 340px;
  z-index: 50;
  background: rgb(25,25,25);
  border-right: 1px solid #333;
  padding: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.panel-title {
  background: #111;
  padding: 12px;
  text-align: center;
  border-radius: 4px;
  margin-bottom: 14px;
}

.side-btn {
  width: 100%;
  margin-bottom: 14px;
}

.list-title {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgb(24,24,24);
  border-bottom: 1px solid rgb(50,50,50);
  border-radius: 7px 7px 0 0;
  padding: 8px 12px;
  margin: 0;
  color: rgb(190,190,190);
  font-size: 13px;
  letter-spacing: .2px;
  flex: 0 0 auto;
}

.list-item {
  position: relative;
  padding: 5px 10px 5px 22px;
  background: #232323;
  margin-bottom: 4px;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: background .15s ease;
}

.list-item::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #777;
}

#categoriesList .list-item::before {
  background: #00d37f;
}

.list-item:hover {
  background: #2c2c2c;
}

.list-item.active {
  background: #008f5a;
  color: #fff;
}

.list-item.active::before {
  background: #fff;
}

.workspace {
  position: relative;
  grid-column: 1 / 2;
  grid-row: 2 / 3;
  overflow: hidden;
}

#viewer {
  width: 100%;
  height: 100%;
  display: block;
  background-color: #252525;
  /* Los gestos tactiles (pinch-zoom, pan con 1-2 dedos) sobre la placa
     los maneja nuestro propio JS (ver viewer.js). touch-action:none evita
     que el navegador le aplique su propio zoom/scroll nativo a este
     elemento cuando el gesto empieza aqui, sin afectar el mouse/escritorio. */
  touch-action: none;
}

.watermark-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  pointer-events: none;
  background-repeat: repeat;
  background-position: 0 0;
}

.cursor-info-panel {
  position: absolute;
  top: 8px;
  left: 348px;   /* .sidebar mide 340px + 8px, bien pegado a la esquina */
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(135deg, rgba(45,45,45,0.45), rgba(15,15,15,0.45));
  border: 1px solid rgba(50,50,50,0.6);
  border-radius: 10px;
  padding: 9px 16px;
  font-family: "Consolas", "Menlo", monospace;
  font-size: 12px;
  color: rgb(190,190,190);
  pointer-events: auto;
  backdrop-filter: blur(3px);
  transition: left .35s ease, background .2s ease, border-color .2s ease;
}

.cursor-info-panel:hover {
  border-color: #00d37f;
}

/* -------------------------------------------------------------------------*/
/*   JOYSTICK DE NAVEGACIÓN + ZOOM */

.nav-joystick {
  position: absolute;
  top: 8px;
  right: 338px;   /* .rightbar mide 330px + 8px, más pegado a esa esquina */
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  transition: right .35s ease;
}

#app.panels-hidden .nav-joystick {
  right: 14px;
}

.joy-dpad {
  position: relative;
  width: 92px;
  height: 92px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.joy-btn {
  position: absolute;
  z-index: 1;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px;
  background: linear-gradient(180deg, #3a3a3a, #191919);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.10), 0 2px 5px rgba(0,0,0,0.4);
  color: rgb(190,190,190);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}

.joy-btn:hover,
.joy-btn:active {
  background: linear-gradient(180deg, rgba(0,211,127,0.35), rgba(0,150,90,0.35));
  color: #fff;
}

.joy-up,
.joy-down {
  width: 34px;
  height: 20px;
}

.joy-left,
.joy-right {
  width: 20px;
  height: 34px;
}

.joy-up    { top: 2px;    left: 50%; transform: translateX(-50%); }
.joy-down  { bottom: 2px; left: 50%; transform: translateX(-50%); }
.joy-left  { left: 2px;   top: 50%; transform: translateY(-50%); }
.joy-right { right: 2px;  top: 50%; transform: translateY(-50%); }

.joy-center {
  position: relative;
  z-index: 2;
  width: 46px;
  height: 46px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.16);
  background: linear-gradient(180deg, #3f3f3f, #1b1b1b);
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.14), 0 3px 8px rgba(0,0,0,0.45);
  color: rgb(210,210,210);
  font-size: 10px;
  letter-spacing: .5px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.joy-center:hover {
  border-color: #00d37f;
  color: #fff;
}

.joy-zoom {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  padding: 0;
}

.joy-zoom-pct {
  color: rgb(190,190,190);
  font-size: 12px;
  font-family: "Consolas", "Menlo", monospace;
}

.joy-zoom-btn {
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 6px;
  background: rgba(255,255,255,0.08);
  color: rgb(200,200,200);
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}

.joy-zoom-btn:hover {
  background: rgba(0,211,127,0.22);
  color: #fff;
}

/* Contenedor que reserva el espacio VISUAL real (26x100) del slider en el
   flujo de la columna .joy-zoom. El <input> de adentro se rota con
   transform en vez de usar writing-mode: vertical-lr, porque Chrome en
   Android no orienta bien un <input type="range"> con writing-mode
   (aunque sí lo hace Safari en iPad/Mac y Chrome/Edge en Windows). Con
   transform:rotate el resultado es idéntico en TODOS los navegadores. */
.joy-zoom-range-wrap {
  width: 26px;
  height: 100px;
  position: relative;
}

.joy-zoom-range {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;   /* longitud del track, antes de rotar */
  height: 6px;    /* grosor del track */
  margin: 0;
  transform: translate(-50%, -50%) rotate(-90deg);
  transform-origin: center center;
  background: transparent;
  accent-color: #00d37f;
  cursor: pointer;
}

.cursor-info-panel.panel-dragging {
  background: linear-gradient(135deg, rgba(90,90,90,0.72), rgba(35,35,35,0.72));
}

#app.panels-hidden .cursor-info-panel {
  left: 8px;
}

.cursor-info-icon {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-right: 1px solid rgba(255,255,255,0.18);
  padding-right: 12px;
  margin-right: 4px;
  color: rgb(200,200,200);
  cursor: pointer;
  pointer-events: auto;
  transition: color .15s ease;
}

.cursor-info-icon:hover {
  color: #fff;
}

.cursor-info-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.cursor-info-row {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}

.cursor-info-label {
  color: #888;
  width: 44px;
  flex: 0 0 auto;
}

.cursor-info-coord {
  color: rgb(190,190,190);
}

.cursor-info-coord b {
  color: #fff;
  font-weight: 400;
}

.cursor-info-divider {
  width: 1px;
  height: 12px;
  background: rgba(255,255,255,0.15);
}

.cursor-info-hr {
  height: 1px;
  background: rgba(255,255,255,0.14);
  margin: 0;
}

.cursor-info-net-label {
  color: #00d37f;
  width: 44px;
  flex: 0 0 auto;
}

.cursor-info-net-value {
  color: rgb(190,190,190);
}

/*
.hint {
  position: absolute;
  right: 18px;
  bottom: 18px;
  color: #ddd;
  border: 1px solid #00d37f;
  padding: 8px 14px;
  border-radius: 8px;
  background: rgba(0,0,0,0.5);
}*/

.footer {
  position: fixed;
  left: 12px;
  bottom: 54px;      /* account-bar (46) + 8px de aire */
  width: min(500px, calc(100vw - 24px));
  height: 38px;
  z-index: 51;
  background: #161719;
  border: 1px solid #262a2d;
  border-radius: 10px;
  box-shadow: 0 8px 24px -10px rgba(0,0,0,.55);
  display: flex;
  align-items: stretch;
  overflow: hidden;
  box-sizing: border-box;
}

.console-label {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 100%;
  background: #18a765;
  color: #fff;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .2px;
  white-space: nowrap;
}

.console-prompt {
  opacity: .85;
  font-family: 'Courier New', monospace;
  font-weight: 700;
}

.console-badge {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,.22);
  border-radius: 9px;
  font-size: 11px;
  font-weight: 700;
  font-family: 'Courier New', monospace;
}

.console-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
}

.console-status-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #7dffc0;
  box-shadow: 0 0 8px 1px rgba(24,167,101,.7);
  animation: consolePulse 1.8s ease-in-out infinite;
}

@keyframes consolePulse {
  0%, 100% { opacity: .45; transform: scale(.85); }
  50%      { opacity: 1;   transform: scale(1); }
}

.console-time {
  flex: none;
  font-family: 'Courier New', monospace;
  font-size: 11px;
  color: #5f6a6f;
  letter-spacing: .3px;
}

.console-status-badge {
  flex: none;
  font-family: 'Courier New', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .5px;
  padding: 3px 7px;
  border-radius: 5px;
  color: #18a765;
  background: rgba(24,167,101,.13);
  border: 1px solid rgba(24,167,101,.3);
}

.console-status-badge.is-error {
  color: #ff6b6b;
  background: rgba(255,107,107,.12);
  border-color: rgba(255,107,107,.35);
}

.console-status-badge.is-loading {
  color: #ffcf5c;
  background: rgba(255,207,92,.12);
  border-color: rgba(255,207,92,.35);
}

.footer #consoleText {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 13px;
  color: #e7ebed;
}

/* .footer-panel eliminado: ya no se usa (era una franja vacía sin contenido) */

/* Console label ahora usa .console-label (ver más arriba) */

.topbar-search {
  position: relative;
  flex: 1 1 160px;
  min-width: 120px;
  max-width: 280px;
}

.login-body {
  background: #1f1f1f;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.login-card {
  width: 360px;
  background: #202020;
  border: 1px solid #00d37f;
  border-radius: 10px;
  padding: 28px;
  box-shadow: 0 0 30px rgba(0, 211, 127, 0.15);
}

.login-card h2 {
  margin: 0 0 8px;
  color: #00d37f;
  text-align: center;
}

.login-card p {
  text-align: center;
  color: #ccc;
  margin-bottom: 20px;
}

.login-card input {
  width: 100%;
  margin-bottom: 12px;
}

.login-card button {
  width: 100%;
}

#loginMsg {
  margin-top: 14px;
  color: #ffdf70;
  text-align: center;
  font-size: 13px;
}

/*-------------------------------------------------------------  */
.rightbar {
  position: fixed;
  top: 64px;
  right: 0;
  bottom: 100px;
  width: 330px;
  z-index: 50;
  background: #181818;
  border-left: 1px solid #333;
  padding: 8px;
  overflow: hidden;
}

.right-panel {
  background: #202020;
  border: 1px solid #333;
  border-radius: 6px;
  margin-bottom: 8px;
  overflow: hidden;
}

.right-panel-title {
  color: #00d37f;
  font-size: 13px;
  padding: 8px 10px;
  background: #151515;
  border-bottom: 1px solid #333;
}

.right-panel-body {
  color: #bbb;
  font-size: 12px;
  padding: 14px;
  min-height: 55px;
}

.tool-buttons {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  padding: 10px;
}

.tool-buttons button {
  height: 28px;
  font-size: 11px;
}

/* Estado activo (ej: "Animate" corriendo) — mismo verde de acento de la
   app pero con un resplandor pulsante, para que se note claramente que
   hay algo en curso y no es un botón más. */
.tool-buttons button.tool-btn-active {
  background: #00c77b;
  color: #06210f;
  font-weight: bold;
  animation: toolBtnPulse 1.4s ease-in-out infinite;
}

@keyframes toolBtnPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 199, 123, 0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(0, 199, 123, 0); }
}

.mini-pcb-fixed {
  position: fixed;
  right: 0;
  bottom: 54px;   /* mismo nivel que #imageControlPanel, encima de la account bar */
  width: 330px;
  padding: 8px;
  background: #181818;
  border-left: 1px solid #333;
  z-index: 55;
}

#netInfo {
  color: #fff;
  font-size: 18px;
  text-align: center;
  padding: 18px;
}

#btnHideRightPanels {
  float: right;
  padding: 2px 7px;
  font-size: 11px;
}

.toggle-panels-btn {
  position: fixed;
  right: 18px;
  bottom: 48px;
  z-index: 9999;
  background: #009f5a;
  color: white;
  border: 1px solid #00d37f;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 12px;
  cursor: pointer;
}

.sidebar,
.rightbar,
.footer,
.mini-pcb-fixed,
#imageControlPanel {
  transition: transform 0.35s ease, opacity 0.35s ease;
}

#app.panels-hidden .sidebar {
  transform: translateX(-110%);
  opacity: 0;
  pointer-events: none;
}

#app.panels-hidden .rightbar {
  transform: translateX(110%);
  opacity: 0;
  pointer-events: none;
}

#app.panels-hidden .mini-pcb-fixed {
  transform: translateX(110%);
  opacity: 0;
  pointer-events: none;
}

#app.panels-hidden .footer {
  transform: translateY(110%);
  opacity: 0;
  pointer-events: none;
}

#app.panels-hidden #imageControlPanel {
  transform: translateY(110%);
  opacity: 0;
  pointer-events: none;
}

/*-------------------------------------------------------------  */
/*                  css :  CATEGORIAS                                 */

.panel-group {
  background: rgb(35,35,35);
  border: 1px solid rgb(50,50,50);
  border-radius: 8px;
  margin-bottom: 12px;
  flex: 0 0 auto;
  transition: border-color .2s ease;
}

.panel-group:hover,
.panel-group:focus-within {
  border-color: #00d37f;
}

.panel-group-grow,
.panel-group-grow-small {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.panel-group-grow {
  flex: 3 1 110px;
}

.panel-group-grow-small {
  flex: 2 1 90px;
}

.side-list {
  overflow-y: scroll;
  overflow-x: hidden;
  padding: 6px;
  margin: 0;
  background: transparent;
  border: none;
  border-radius: 0 0 7px 7px;
  flex: 1 1 auto;
  min-height: 0;
  scrollbar-width: auto;
  scrollbar-color: rgb(95,95,95) rgb(45,45,45);
}

.control-panel-box {
  min-height: 56px;
  margin: 0;
  padding: 10px;
  background: transparent;
  border: none;
  border-radius: 0 0 7px 7px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.control-panel-placeholder {
  color: #555;
  font-size: 12px;
  font-style: italic;
}

.about-software {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}

.about-software-title {
  font-family: 'JetBrains Mono', 'Courier New', monospace;
  font-size: 15px;
  font-weight: 700;
  color: #5fe0ab;
  letter-spacing: .3px;
}

.about-software-subtitle {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 500;
  color: #6b7478;
  letter-spacing: .8px;
  text-transform: uppercase;
}

.side-list::-webkit-scrollbar {
  width: 16px;
}

.side-list::-webkit-scrollbar-track {
  background: rgb(45,45,45);
  border-radius: 8px;
}

.side-list::-webkit-scrollbar-thumb {
  background-color: rgb(95,95,95);
  border: 3px solid rgb(10,10,10);
  border-radius: 10px;
  background-clip: padding-box;
}

.side-list::-webkit-scrollbar-thumb:hover {
  background-color: rgb(120,120,120);
}

/*-------------------------------------------------------------  */
/*          CAPA LOADING / ECU   */
#loadingOverlay {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.68);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 95;
}

.loadingBox {
  width: 360px;
  text-align: center;
}

.loadingTitle {
  color: #fff;
  font-size: 26px;
  margin-bottom: 14px;
}

.loadingRow {
  display: flex;
  align-items: center;
  gap: 12px;
}

.loadingBar {
  flex: 1;
  height: 8px;
  background: #151515;
  border: 1px solid #333;
  border-radius: 10px;
  overflow: hidden;
}

#loadingProgress {
  width: 0%;
  height: 100%;
  background: #00d37f;
}

#loadingPercent {
  color: #fff;
  font-size: 18px;
  min-width: 48px;
}

/*-------------------------------------------------------------  */
/*          CAMPO BUSQUED */

#globalSearchInput {
  flex: 1;
  min-width: 0;
  width: auto;
  height: auto;
  background: transparent;
  color: #e9fbf3;
  border: none;
  border-radius: 0;
  padding: 0;
  font-family: 'Inter', sans-serif;
  font-size: 13.5px;
  font-weight: 500;
  outline: none;
}

#globalSearchInput::placeholder {
  color: #8a9297;
}

#globalSearchResults {
  position: absolute;
  top: 44px;
  left: auto;
  right: 0;
  width: 400px;
  max-width: calc(100vw - 40px);
  max-height: 320px;
  overflow-y: auto;
  background: #252525;
  border: 1px solid #333;
  border-radius: 14px;
  box-shadow: 0 18px 40px rgba(0,0,0,0.45);
  z-index: 200;
}

#globalSearchResults:empty {
  display: none;
  border: none;
  box-shadow: none;
}

.search-item {
  position: relative;
  padding: 18px 22px 18px 46px;
  cursor: pointer;
  border-bottom: 1px solid #343434;
  transition: 0.15s;
}

.search-item:nth-child(even) {
  background: #232323;
}

.search-item:nth-child(odd) {
  background: #292929;
}

.search-item:hover {
  background: #3a3a3a;
}

.search-main {
  color: #fff;
  font-size: 15px;
  margin-bottom: 4px;
}

.search-sub {
  color: #aaa;
  font-size: 12px;
}

.search-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border-radius: 9px;
  background: rgba(255,255,255,.09);
  border: 1px solid rgba(255,255,255,.18);
  transition: all .18s ease;
}

.search-input-wrap:hover {
  background: rgba(255,255,255,.12);
  border-color: rgba(255,255,255,.24);
}

.search-input-wrap:focus-within {
  background: rgba(16,185,129,.1);
  border-color: rgba(16,185,129,.6);
  box-shadow: 0 0 0 3px rgba(16,185,129,.15);
}

.search-icon-svg {
  flex: none;
  color: #8fa89c;
}

.search-kbd {
  flex: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  color: #5b7a6d;
  padding: 2px 6px;
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 5px;
  background: rgba(255,255,255,.02);
}

.search-highlight {
  color: #00d37f;
  font-weight: bold;
}

.search-item.selected {
  background: #008f5a;
}

.search-item.selected .search-sub {
  color: #e0e0e0;
}

.search-count {
  padding: 10px 14px;
  background: #1a1a1a;
  border-bottom: 1px solid #333;
  color: #00d37f;
  font-size: 12px;
  font-weight: bold;
  letter-spacing: 0.5px;
}

.search-item::before {
  content: "";
  position: absolute;
  left: 22px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #666;
  transform: translateY(-50%);
}


/* -------------------------------------------------------------------------*/
/*       PANEL TITULOS (sliders + título/descripción del proyecto) */

#imageControlPanel {
  position: absolute;
  right: 346px;   /* .rightbar mide 330px + 16px de separación, sin tocarlo */
  bottom: 54px;   /* account-bar (46px) + 8px de separación. */
  width: 620px;
  max-width: calc(100vw - 700px);
  z-index: 80;
  background: rgb(35,35,35);
  border: 1px solid #006f4a;
  border-radius: 8px;
  overflow: hidden;
  transition: opacity .25s ease, transform .25s ease;
}

.image-control-title {
  background: #00a85a;
  color: #eafff4;
  text-align: center;
  padding: 6px;
  font-size: 13px;
  transition: background .25s ease, color .25s ease;
}

.image-sliders {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  padding: 4px 14px;
}

.image-sliders label {
  color: #bbb;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.image-sliders input {
  width: 100%;
}

.image-sliders input[type="range"]{
  width:100%;
  accent-color:#00d37f;
}

.project-title-strip,
.project-subtitle-strip {
  padding: 9px 14px;
  border-top: 1px solid #222;
  transition: color .25s ease, background .25s ease;
}

.project-title-strip {
  color: #fff;
  background: rgba(0,0,0,0.85);
  text-align: right;
  font-size: 17px;
}

.project-subtitle-strip {
  color: #aaa;
  background: rgba(60,60,60,0.75);
  text-align: right;
  font-size: 14px;
}

/* -------------------------------------------------------------------------*/
/*   PANEL TITULOS "apagado" (sin proyecto cargado) */

#imageControlPanel.panel-off {
  background: rgba(20,20,20,0.45);
  border-color: #333;
  transition: background .25s ease, border-color .25s ease;
}

#imageControlPanel.panel-off .image-control-title {
  background: #2a2a2a;
  color: #777;
}

#imageControlPanel.panel-off .image-sliders input[type="range"] {
  accent-color: #555;
  opacity: 0.55;
  pointer-events: none;
}

#imageControlPanel.panel-off .project-title-strip {
  color: #6c6c6c;
  background: rgba(0,0,0,0.35);
}

#imageControlPanel.panel-off .project-subtitle-strip {
  color: #5a5a5a;
  background: rgba(40,40,40,0.3);
}

/* -------------------------------------------------------------------------*/
/*         TEXT BOX / REGION TOOL     */

.region-textbox{
  position:absolute;
  display:none;
  width:360px;
  max-height:260px;
  z-index:300;
  background:#101010;
  border:1px solid #007a55;
  border-radius:6px;
  box-shadow:0 18px 40px rgba(0,0,0,0.65);
  overflow:hidden;
  user-select:none;
  -webkit-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  pointer-events:auto;
}

.region-textbox-title{
  color:#00d37f;
  font-weight:bold;
  font-size:14px;
  padding:12px 16px;
  border-bottom:1px solid #222;
}

.region-textbox-body{
  color:#ddd;
  font-size:13px;
  line-height:1.45;
  padding:14px 16px;
  max-height:200px;
  overflow-y:auto;
  white-space:pre-wrap;
  user-select:none;
  -webkit-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
}

.region-textbox-body::-webkit-scrollbar{
  width:8px;
}

.region-textbox-body::-webkit-scrollbar-thumb{
  background:#008f5a;
  border-radius:10px;
}

.region-comment-bubble{
  position:absolute;
  display:none;
  z-index:320;
  pointer-events:none;
  width:max-content;
  min-width:120px;
  max-width:700px;
  text-align:center;
  font-family:Arial, sans-serif;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,0.55));
}

.region-comment-main,
.region-comment-sub{
  padding:7px 18px;
  font-size:14px;
  line-height:1.25;
  white-space:normal;
  overflow-wrap:break-word;
  word-break:normal;
}

.region-comment-main{
  color:#fff;
  background:#00aa42;
  border-radius:9px 9px 4px 4px;
}

.region-comment-sub{
  color:#fff;
  background:rgba(120,120,120,0.96);
  border-radius:4px 4px 9px 9px;
}

/* -------------------------------------------------------------------------*/
/*         COLITA BOCADILLO, COMENTARIO REGION SENALADA     */

.region-comment-bubble{
  transform: translate(-50%, calc(-100% - 34px));
}

.region-comment-bubble::after{
  content:"";
  position:absolute;
  left:50%;
  bottom:-11px;
  transform:translateX(-50%);
  width:0;
  height:0;
  border-left:12px solid transparent;
  border-right:12px solid transparent;
  border-top:12px solid rgba(120,120,120,0.92);
}

.region-comment-bubble.one-line::after{
  border-top-color:var(--bubble-main-color, #00d37f);
}

.region-comment-bubble.one-line{
  overflow: visible;
}

.region-comment-bubble.one-line .region-comment-main{
  border-radius:14px;
}

.region-comment-bubble.one-line .region-comment-sub{
  display:none;
}

/* -------------------------------------------------------------------------*/
/*         PANEL PCB MINIATURA    */

.mini-map-body{
  padding:8px;
}

#miniMapCanvas{
  width:100%;
  height:250px;
  display:block;
  background:#101010;
  border:2px solid #555;
  border-radius:6px;
  /* El arrastre tactil (tablets) para mover la placa grande desde aqui lo
     maneja nuestro JS (ver viewer.js); sin esto el navegador intenta
     hacer scroll/zoom nativo con el dedo en vez de mover la camara. */
  touch-action: none;
}

/* -------------------------------------------------------------------------*/
/*         boton ocultar paneles - panel pcb miniatura   */

.show-panels-btn{
      position:absolute;
      right:18px;
      /* La barra de cuenta (.account-bar) mide 46px y sigue visible aun
         cuando los paneles estan ocultos (ver captura del usuario), asi
         que el boton debe quedar POR ENCIMA de ella, no flotando sobre
         su contenido. */
      bottom:62px;
      z-index:9999;
      display:none;
      background:#009f5a;
      color:white;
      border:1px solid #00d37f;
      border-radius:9px;
      padding:10px 18px;
      font-size:15px;
      cursor:pointer;
}

#app.panels-hidden .show-panels-btn{
  display:block;
}

/* -------------------------------------------------------------------------*/
/*         Contributions - Aportes  */

.contributions-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 260px;
  overflow-y: auto;
}

.contribution-item {
  background: #2b2b2b;
  border: 1px solid #3a3a3a;
  border-radius: 10px;
  padding: 8px;
  cursor: pointer;
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

/* :active se activa mientras se mantiene presionado (dedo o mouse) y se
   quita limpio al soltar — a diferencia de :hover, no tiene el problema
   de "doble disparo" en táctil, así que funciona bien en cualquier
   dispositivo y le devuelve el resaltado verde al tocar en iPad/Android. */
.contribution-item:active {
  background: #333;
  border-color: #00c77b;
}

/* @media (hover:hover) excluye pantallas táctiles: en iPad/Android, sin
   mouse real, este :hover puede quedar "pegado" o parpadear al tocar
   (el navegador simula el estado hover brevemente en cada toque). En
   escritorio (mouse de verdad) el comportamiento queda igual que antes. */
@media (hover: hover) and (pointer: fine) {
  .contribution-item:hover {
    background: #333;
    border-color: #00c77b;
  }
}

.contribution-top {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
}

.contribution-user {
  font-weight: bold;
  color: #fff;
}

.contribution-level {
  background: #00c77b;
  color: #fff;
  border-radius: 10px;
  padding: 1px 8px;
}

.contribution-file {
  background: #d94b35;
  color: #fff;
  border-radius: 4px;
  padding: 1px 6px;
}

.contribution-like {
  margin-left: auto;
  color: #ddd;
}

.contribution-title {
  margin-top: 4px;
  font-size: 13px;
  color: #ddd;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.contribution-summary {
  font-size: 11px;
  color: #aaa;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}





.contribution-modal {
  position: fixed;
  inset: auto;
  background: transparent;
  display: none;
  z-index: 9999;
  pointer-events: none;
}

.contribution-modal-box {
  position: relative;
  width: 520px;
  max-height: 55vh;
  overflow: visible;
  background: #1f1f1f;
  border: 1px solid #00c77b;
  border-radius: 14px;
  box-shadow: 0 0 30px rgba(0,199,123,0.25);
  padding: 14px;
  pointer-events: auto;
}

.contribution-modal-box::after {
  content: "";
  position: absolute;
  left: var(--arrow-x, 50%);
  top: -16px;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 16px solid transparent;
  border-right: 16px solid transparent;
  border-bottom: 16px solid #00c77b;
  z-index: 10000;
}

.contribution-modal.viewer-above .contribution-modal-box::after {
  top: auto;
  bottom: -14px;
  border-bottom: none;
  border-top: 14px solid #00c77b;
}

.contribution-modal-header {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid #333;
  padding-bottom: 10px;
}

.contribution-modal-title {
  color: #fff;
  font-size: 18px;
  font-weight: bold;
}

.contribution-modal-meta,
.contribution-modal-body {
  color: #bbb;
  margin-top: 10px;
  font-size: 13px;
  line-height: 1.4;
}

.contribution-modal-summary {
  color: #ddd;
  margin-top: 10px;
  font-size: 13px;
  line-height: 1.4;
  background: rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 10px 12px;
}

.contribution-modal-files a {
  display: block;
  margin-top: 8px;
  color: #00c77b;
  text-decoration: none;
}

#btnCloseContributionDetail {
  width: 44px;
  height: 44px;
  background: #111;
  color: #fff;
  border: 1px solid #555;
  border-radius: 10px;
  cursor: pointer;
  font-size: 20px;
}





                    
.file-viewer-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 0;
  background: #111;
  border-top:1px solid transparent;
  overflow: hidden;
  z-index: 9000;
  display: flex;
  flex-direction: column;
  transition: none;
}
                    
.file-viewer-panel.open {
  height: 45%;
}

.file-viewer-header {
  height: 42px;
  background: #050505;
  color: #ddd;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px;
  border-bottom: 1px solid #222;
}

.file-viewer-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-viewer-actions button {
  background: #111;
  color: #ddd;
  border: 1px solid #444;
  border-radius: 6px;
  padding: 4px 8px;
  cursor: pointer;
}

.file-viewer-content {
  flex: 1;
  overflow: auto;
  background: #fff;
}

.file-viewer-content iframe,
.file-viewer-content img {
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: contain;
}

.file-viewer-content pre {
  margin: 0;
  padding: 16px;
  color: #111;
  font-size: 13px;
  white-space: pre-wrap;
}

.contribution-file-open {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  background: #00c77b;
  color: rgb(255, 255, 255);
  border: 0;
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  text-align: left;
  font-size: 13px;
  font-weight: bold;
  transition: background .12s;
}

/* Mismos colores que las etiquetas de tipo en las tarjetas del Panel A,
   para identificar el tipo de archivo de un vistazo. */
.contribution-file-open.type-pdf,
.contribution-file-open.type-txt {
  background: #d94b35;
}

.contribution-file-open.type-pdf:hover,
.contribution-file-open.type-txt:hover {
  background: #e8624c;
}

.contribution-file-open.type-img {
  background: #2563eb;
}

.contribution-file-open.type-img:hover {
  background: #3b76f6;
}

.contribution-file-open.type-comment {
  background: #555;
}

.contribution-file-open.type-comment:hover {
  background: #666;
}

.contribution-file-open:hover {
  background: #00e08a;
}

.workspace.file-viewer-open #imageControlPanel{
    opacity:0;
    pointer-events:none;
    transform:translateY(20px);
}

.tl-pdf-toolbar{
  height:44px;
  flex:0 0 44px;
  background:#263238;
  border-bottom:1px solid #1b2429;
  display:flex;
  align-items:center;
  gap:10px;
  padding:0 16px;
  color:#e5e7eb;
  font-size:14px;
  position:sticky;
  top:0;
  z-index:20;
}

.tl-pdf-btn{
  width:34px;
  height:32px;
  background:transparent;
  border:0;
  color:#d8dde0;
  font-size:22px;
  border-radius:7px;
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  line-height:1;
  padding:0;
}

.tl-pdf-btn:hover{
  background:#37474f;
}

.tl-pdf-reset-btn {
  min-width: 72px;
  height: 34px;
  padding: 0 16px;
  border-radius: 8px;
  background: #455a64;
  color: #fff;
  border: 1px solid #56707c;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;

  display: flex;
  align-items: center;
  justify-content: center;

  line-height: 1;
  white-space: nowrap;
  margin-left: 18px;
}

.tl-pdf-reset-btn:hover {
  background: #52707d;
}

.tl-pdf-pagebox{
  min-width:42px;
  height:32px;
  background:#1b2429;
  border-radius:9px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-weight:600;
  color:#fff;
}

.tl-pdf-zoom{
  min-width:52px;
  text-align:center;
  color:#f2f2f2;
  font-weight:500;
}

.tl-pdf-spacer{
  width:22px;
}

.tl-pdf-flex-spacer{
  flex:1 1 auto;
  min-width:8px;
}

.tl-pdf-search-nav{
  display:flex;
  align-items:center;
  gap:6px;
  margin-left:14px;
}

.tl-pdf-zoom-group{
  position:absolute;
  left:50%;
  top:50%;
  transform:translate(-50%, -50%);
  display:flex;
  align-items:center;
  gap:8px;
}

.tl-pdf-divider{
  width:1px;
  height:24px;
  background:#4b5560;
  margin:0 10px;
  flex:0 0 auto;
}

.tl-pdf-page-nav{
  display:flex;
  align-items:center;
  gap:10px;
  flex:0 0 auto;
}

.tl-pdf-stage{
  background:#2b2b2b;
  min-height:100%;
  padding:24px;
  display:flex;
  justify-content:center;
  align-items:flex-start;
  overflow:auto;
}

#tlPdfCanvas{
  background:white;
  box-shadow:0 8px 24px rgba(0,0,0,.35);
}
                    
.tl-pdf-stage{
  background:#2b2b2b;
  height:calc(100% - 44px);
  overflow:hidden;
  padding:24px;
  box-sizing:border-box;
  cursor:grab;
  /* Necesario para que .tl-pdf-canvas-wrap (position:absolute) se
     posicione respecto a ESTE contenedor y no respecto a algún ancestro
     más lejano. */
  position: relative;
  /* El pan (1 dedo) y pinch-zoom (2 dedos) tactiles sobre el PDF los
     maneja nuestro JS (ver pdfViewer.js); sin esto el navegador intenta
     hacer scroll/zoom nativo con el dedo en tablets. */
  touch-action: none;
}

.tl-pdf-stage.dragging{
  cursor:grabbing;
  user-select:none;
}


.tl-pdf-canvas-wrap{
  width:max-content;
  height:max-content;
  margin:0;
  padding:0;
  box-sizing:border-box;
}

                                
.tl-pdf-canvas-wrap{
  /* IMPORTANTE: position:absolute (en vez de relative) saca el wrap del
     flujo flex del .tl-pdf-stage (que lo centra con justify-content).
     Si se queda en flujo normal, cada vez que cambia de tamaño (al hacer
     zoom) el navegador reacomoda su posición para mantenerlo centrado
     por su cuenta — y esa reubicación no la sabe nuestro código, que
     asume que la única forma en que el wrap se mueve es a través de
     nuestro propio transform (tlPanX/tlPanY). Eso causaba el salto al
     achicar el zoom (con zoom grande el PDF se salía del visor y
     flexbox ya no tenía margen para recentrarlo, por eso no se notaba;
     al achicar sí lo recentraba, y ahí aparecía el salto). Con
     position:absolute, el wrap siempre parte del mismo punto (0,0) del
     stage, y el centrado inicial se hace a mano en el JS (ver
     openTechnovalabPdf), no con flexbox.
  */
  position: absolute;
  top: 0;
  left: 0;
  width: max-content;
  height: max-content;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  will-change: transform;
}

.tl-pdf-canvas{
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  background: white;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
  user-select: none;
}

.tl-pdf-canvas.active{
  opacity: 1;
}

#fileViewerResizeHandle{
    height:6px; 
    cursor:ns-resize; 
    background:transparent; 
}

#fileViewerResizeHandle:hover{
    background:#00d08455; 
}
                                
.file-viewer-header{
  position: relative;
  z-index: 50;
}

.file-viewer-actions{
  position: relative;
  z-index: 60;
}

#btnCloseFileViewer{
  position: relative;
  z-index: 70;
}

.tl-pdf-stage{
  z-index: 1;
}


.tl-pdf-search {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}
                        
.tl-pdf-search-input {
    width: 170px;
    height: 34px;
    padding: 0 12px;
    background: #111;
    color: #fff;
    border: 1px solid #00d37f;
    border-radius: 8px;
    outline: none;
    font-size: 14px;
}

.tl-pdf-search-btn{
    min-width:72px;
    height:34px;
    padding:0 16px;
    border-radius:8px;
    background:#00a86b;
    color:#fff;
    border:1px solid #00d37f;
    font-size:13px;
    font-weight:600;
    cursor:pointer;

    display:flex;
    align-items:center;
    justify-content:center;

    line-height:1;
    white-space:nowrap;
}

.tl-pdf-search-btn:hover{
    background:#00c47d;
 }
                                        
.tl-pdf-search-input:focus {
  border-color: #00d37f;
}

.tl-pdf-search-info {
  min-width: 42px;
  color: #00d37f;
  font-size: 12px;
  text-align: center;
}



.tl-pdf-theme-toggle {
  width: 86px;
  height: 32px;
  padding: 0;
  margin-left: 10px;
  border-radius: 999px;
  border: 1px solid #444;
  background: #e7e7e7;
  color: #111;
  display: flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.tl-pdf-theme-knob {
  width: 24px;
  height: 24px;
  margin-left: 4px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  transition: transform 0.2s ease;
}

.tl-pdf-theme-text {
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}

.tl-pdf-theme-toggle.dark {
  background: #101820;
  color: #00d37f;
  border-color: #00d37f;
}

.tl-pdf-theme-toggle.dark .tl-pdf-theme-knob {
  transform: translateX(48px);
  background: #00d37f;
}

.tl-pdf-theme-toggle.dark .tl-pdf-theme-text {
  transform: translateX(-26px);
}

.file-viewer-expand-btn {
  width: 32px;
  height: 28px;
  padding: 0;
  background: #111;
  border: 1px solid #444;
  border-radius: 6px;
  color: #ddd;
  font-size: 15px;
}

.file-viewer-expand-btn:hover {
  border-color: #00d37f;
  color: #00d37f;
}

.file-viewer-panel.pdf-focus-mode {
  height: 100vh !important;
  height: 100dvh !important;
  z-index: 99999;
}

.file-viewer-panel.pdf-focus-mode .file-viewer-header {
  height: 42px;
}

.file-viewer-title-wrap {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.file-viewer-brand-badge{
    color:#17e68b;
    font-size:15px;
    font-weight:700;
    letter-spacing:.4px;
    white-space:nowrap;
    padding:0;
    margin-right:10px;
    background:transparent;
    border:none;
    text-shadow:0 0 8px rgba(0,211,127,.25);
}


.file-viewer-info{
    display:flex;
    align-items:center;
    gap:12px;
    margin-left:22px;
}

.viewer-info-item{
    display:flex;
    align-items:center;
    gap:8px;

    padding:4px 12px;

    background:#171717;
    border:1px solid #2a2a2a;
    border-radius:8px;
}

.viewer-title-item{
    width:300px;
}
                    
.viewer-label{
    color:#6d6d6d;
    font-size:10px;
    text-transform:uppercase;
    letter-spacing:1px;
    font-weight:500;
}
    
#fileViewerAuthor,
#fileViewerTitle,
#fileViewerType{
    color:#c7c7c7;
    font-size:11px;
    font-weight:400;
    letter-spacing:.2px;
}


#fileViewerTitle{
    color:#d0d0d0;
    font-size:11px;
    font-weight:400;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
}

.tl-pdf-site-link {
  margin-left: auto;
  margin-right: 16px;
  padding: 5px 13px;
  border: 1px solid rgba(0, 211, 127, 0.65);
  border-radius: 999px;
  background: rgba(0, 211, 127, 0.08);
  color: #00d37f;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.2px;
  text-decoration: none;
  white-space: nowrap;
}

.tl-pdf-site-link:hover {
  background: rgba(0, 211, 127, 0.18);
  border-color: #00d37f;
  color: #ffffff;
}

.contribution-file.type-pdf {
  background: #d94b35;
}

.contribution-file.type-img {
  background: #2563eb;
}

.contribution-file.type-txt {
  background: #d94b35;
}

.contribution-file.type-comment {
  background: #555;
  color: #ddd;
}


.contribution-avatar{
    width:42px;
    height:42px;
    flex-shrink:0;
    display:flex;
    align-items:center;
    justify-content:center;
}
.contribution-avatar .material-icons{
    font-size:34px;
    color:#9b9b9b;
}

.contribution-content{
    flex:1;
    min-width:0;
}

.contribution-user-wrap{
    display:flex;
    align-items:center;
    gap:8px;
}

.contribution-avatar{
    width:22px;
    height:22px;
    object-fit:contain;
    flex-shrink:0;
    user-select:none;
    pointer-events:none;
}

.contribution-user{
    font-weight:600;
    color:#fff;
}







.tl-img-toolbar{
    height:46px;
    background:#27313b;
    display:flex;
    align-items:center;
    position:relative;
    gap:8px;
    padding:0 14px;
    border-bottom:1px solid #394651;
    user-select:none;
}

.tl-img-spacer{
    flex:1;
}

.tl-img-zoom-group{
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%, -50%);
    display:flex;
    align-items:center;
    gap:8px;
}

.tl-img-btn{
    width:30px;
    height:28px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    background:#1d2329;
    border:1px solid #4b5560;
    border-radius:6px;
    color:#dfe5ea;
    font-size:15px;
    font-weight:400;
    cursor:pointer;
    padding:0;
}

.tl-img-btn:hover{
    background:#2b333c;
}

.tl-img-action-btn{
    height:28px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    padding:0 11px;
    background:#1d2329;
    border:1px solid #4b5560;
    border-radius:6px;
    color:#e5e5e5;
    font-size:13px;
    font-weight:400;
    cursor:pointer;
}

.tl-img-action-btn:hover{
    background:#2b333c;
}

#tlImgReset{
    background:#00a86b;
    border-color:#16c784;
    color:#fff;
}

.tl-img-zoom-box{
    min-width:56px;
    height:28px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    background:#1b1f24;
    border:1px solid #16c784;
    border-radius:6px;
    color:#fff;
    font-size:13px;
    font-weight:400;
}

.tl-img-filter-box{
    min-width:96px;
    height:28px;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    background:#1b1f24;
    border:1px solid #394651;
    border-radius:6px;
    color:#d7d7d7;
    font-size:13px;
    font-weight:400;
}

.tl-img-stage{
    height:calc(100% - 46px);
    background:#2b2b2b;
    overflow:hidden;
    position:relative;
    cursor:grab;
    /* El pan (1 dedo) y pinch-zoom (2 dedos) tactiles sobre la imagen los
       maneja nuestro JS (ver fileViewer.js); sin esto el navegador intenta
       hacer zoom/scroll nativo con el dedo en tablets. */
    touch-action: none;
}

.tl-img-stage.dragging{
    cursor:grabbing;
}

.tl-img-wrap{
    position:absolute;
    left:0;
    top:0;
    transform-origin:0 0;
    will-change: transform;
}

#tlImgElement{
    display:block;
    user-select:none;
    pointer-events:none;
    transition:transform .2s ease, filter .2s ease;
}
/* -------------------------------------------------------------------------*/
/*  ACCOUNT BAR (pie de página: usuario, licencia, expiración, IP, config)  */

.account-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 46px;
  z-index: 52;
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 70px);
  padding: 0 22px;
  background: rgb(20,20,20);
  border-top: 1px solid #2c2c2c;
  box-sizing: border-box;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

.account-bar::-webkit-scrollbar {
  height: 4px;
}

.account-bar::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.15);
  border-radius: 4px;
}

.account-item {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.account-icon {
  flex: none;
  width: 22px;
  height: 22px;
  object-fit: contain;
}

.account-text {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}

.account-label {
  font-size: 11px;
  font-weight: 700;
  color: #18a765;
  letter-spacing: .2px;
}

.account-value {
  font-size: 12px;
  color: #9aa4a9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 8px;
}

.account-value b {
  color: #e7ebed;
  font-weight: 600;
}

.account-masked {
  font-family: 'Courier New', monospace;
  letter-spacing: 1px;
}

.account-show-btn {
  flex: none;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .3px;
  color: #18a765;
  background: rgba(24,167,101,.1);
  border: 1px solid rgba(24,167,101,.35);
  border-radius: 4px;
  padding: 2px 8px;
  cursor: pointer;
}

.account-show-btn:hover {
  background: rgba(24,167,101,.2);
}

.account-version {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: #6b7478;
  letter-spacing: .2px;
  white-space: nowrap;
}

.account-version-dot {
  color: #3f6857;
  font-size: 10px;
}

.account-version-link {
  color: #5fe0ab;
  font-weight: 600;
  text-decoration: none;
  transition: color .15s ease;
}

.account-version-link:hover {
  color: #8ff0c5;
  text-decoration: underline;
}

.account-version-link:visited {
  color: #5fe0ab;
}

/* -------------------------------------------------------------------------*/
/*  LATEST UPDATES MODAL (últimas ECUs cargadas, botón "Update List")       */

.latest-updates-modal {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,.6);
  backdrop-filter: blur(2px);
}

.latest-updates-modal.open {
  display: flex;
}

.latest-updates-box {
  position: relative;
  width: 1040px;
  max-width: calc(100vw - 60px);
  max-height: 60vh;
  display: flex;
  flex-direction: column;
  background: #131415;
  border: 1px solid #2c2c2c;
  border-radius: 14px;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.7);
  overflow: hidden;
}

.latest-updates-header {
  flex: none;
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 16px 20px;
  background: #232527;
  border-bottom: 1px solid #333638;
  font-family: 'Inter', sans-serif;
}

.latest-updates-header-side {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.latest-updates-header-side:first-child {
  justify-content: flex-start;
}

.latest-updates-header-title {
  justify-self: center;
  font-size: 15px;
  font-weight: 500;
  color: rgb(190,190,190);
  letter-spacing: .3px;
}

.latest-updates-close {
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.1);
  color: #aaa;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.latest-updates-close:hover {
  background: rgba(255,255,255,.12);
  color: #fff;
}

.latest-updates-body {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  overflow: hidden;
}

/* --- Fondo: la misma placa, en gris, cubriendo todo el panel, tipo Netflix --- */
@keyframes updatePreviewBgBounce {
  0%   { transform: translate(-3%, -2%) scale(1.22); }
  25%  { transform: translate(3%, -5%) scale(1.22); }
  50%  { transform: translate(5%, 3%) scale(1.22); }
  75%  { transform: translate(-5%, 4%) scale(1.22); }
  100% { transform: translate(-3%, -2%) scale(1.22); }
}

.update-bg-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) brightness(.42) contrast(1.05);
  opacity: 0;
  z-index: 0;
  animation: updatePreviewBgBounce 22s ease-in-out infinite;
  transition: opacity .6s ease;
}

.update-bg-layer.visible {
  opacity: .55;
}

.update-timeline {
  position: relative;
  z-index: 1;
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  padding: 30px 26px 14px;
  background: rgba(10,11,12,.5);
}

.update-empty {
  color: #6b7478;
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  text-align: center;
  padding: 30px 0;
}

.update-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  padding-bottom: 60px;
}

.update-item-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 13px;
  width: 2px;
  background: #2a3b33;
  z-index: 0;
}

.update-item:last-child .update-item-line {
  display: none;
}

.update-item-rail {
  position: relative;
  z-index: 1;
  width: 28px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.update-item-dot {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #1c231f;
  border: 3px solid #2f6b52;
  box-shadow: inset 0 0 0 4px #131415, inset 0 0 0 8px #3fdf94;
  transition: box-shadow .15s ease;
}

.update-item:hover .update-item-dot {
  box-shadow: inset 0 0 0 4px #131415, inset 0 0 0 8px #8ff0c5;
}

.update-item-content {
  flex: 1;
  min-width: 0;
}

.update-item-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}

.update-item-badge {
  color: #9aa4a9;
  font-weight: 400;
}

.update-item-date {
  color: #c9d3ce;
}

.update-item-author {
  color: #7a8a83;
}

.update-item-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 9px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
}

.update-item-cat {
  color: #e7ebed;
  font-weight: 400;
}

.update-item-link {
  color: #3fdf94;
  font-weight: 400;
  text-decoration: none;
  cursor: pointer;
}

.update-item-link:hover {
  color: #8ff0c5;
  text-decoration: underline;
}

.update-item-sub {
  color: #8a9297;
  font-weight: 400;
}

/* --- Placa a color, grande, en primer plano sobre el fondo gris --------- */
.update-preview {
  position: relative;
  z-index: 1;
  flex: none;
  width: 460px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 30px;
  text-align: center;
}

.update-preview-img {
  display: block;
  max-width: 100%;
  max-height: 72%;
  object-fit: contain;
  filter: drop-shadow(0 20px 34px rgba(0,0,0,.6));
  opacity: 0;
  transition: opacity .18s ease;
}

.update-preview-img.visible {
  opacity: 1;
}

.update-preview-title {
  font-family: 'Inter', sans-serif;
  font-size: 17px;
  font-weight: 700;
  color: #e7ebed;
}

.update-preview-sub {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  color: #8a9297;
}

/* ==========================================================================
   RESPONSIVE / ADAPTIVE LAYOUT
   Ajustes agregados para que la CABECERA (.topbar) y los PIES
   (.footer / .account-bar) se adapten a distintos anchos de ventana
   sin desbordar la pagina, sin esconder botones sin forma de alcanzarlos,
   y sin romper el resto del diseño (paneles laterales sin cambios).
   ========================================================================== */

/* Red de seguridad global: nunca debe aparecer scroll horizontal a nivel
   de pagina/documento; si algo se desborda, que se desborde de forma
   controlada dentro de su propio contenedor (topbar / account-bar). */
html {
  height: 100%;
  overflow-x: hidden;
}

/* Gestos tactiles a nivel de pagina (tablets / iPad): el zoom por
   pinch y por doble-tap del navegador quedan desactivados en toda la
   interfaz (cabecera, paneles, pies), que debe permanecer fija sin
   escalar. El scroll/tap normal con el dedo sigue funcionando igual
   (touch-action: manipulation permite pan, solo bloquea el zoom).
   El unico lugar donde SI debe responder el pinch-zoom/pan es dentro
   del canvas de la placa (#viewer), que tiene su propio touch-action:none
   y su propia logica de pinch/pan en viewer.js. Esto no afecta el
   comportamiento en mouse/escritorio, solo gestos tactiles. */
html, body, #app {
  touch-action: manipulation;
}

/* --------------------------------------------------------------------
   1500px  -> sobra poco aire: quitamos el ticker informativo (no es
   contenido esencial) para liberar ~376px para el resto de la cabecera.
   -------------------------------------------------------------------- */
@media (max-width: 1500px) {
  .topbar-ticker {
    display: none;
  }
}

/* --------------------------------------------------------------------
   1250px -> los botones "pill" (Global Files / Update List / Perfil /
   Logout) se muestran solo con icono, sin texto, para ahorrar espacio.
   -------------------------------------------------------------------- */
@media (max-width: 1250px) {
  .topbar-actions .pill-btn span,
  #btnLogout span {
    display: none;
  }

  .topbar-actions .pill-btn,
  #btnLogout {
    padding: 0 10px;
  }

  .topbar-actions {
    gap: 6px;
  }

  .topbar {
    gap: 10px;
  }
}

/* --------------------------------------------------------------------
   1080px -> ocultamos la fecha (mantenemos hora + estado) y reducimos
   paddings del bloque de carga de proyecto.
   -------------------------------------------------------------------- */
@media (max-width: 1080px) {
  #topbarDate {
    display: none;
  }

  .topbar-project #status {
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* --------------------------------------------------------------------
   900px -> ocultamos tambien la hora y el estado de texto largo,
   dejando solo el boton Refresh; el buscador puede seguir encogiendo.
   -------------------------------------------------------------------- */
@media (max-width: 900px) {
  .topbar-time,
  .topbar-project #status {
    display: none;
  }

  .topbar-search {
    flex: 1 1 100px;
    min-width: 90px;
  }

  .search-kbd {
    display: none;
  }
}

/* --------------------------------------------------------------------
   700px -> ultimo nivel de compactacion antes de depender del scroll
   interno del header como respaldo. Todo lo esencial (Refresh, buscar,
   accesos y logout) sigue siendo visible y pulsable.
   -------------------------------------------------------------------- */
@media (max-width: 700px) {
  .topbar {
    padding: 0 10px;
    gap: 8px;
  }

  .topbar-project {
    gap: 4px;
  }

  .topbar-search {
    max-width: 140px;
  }
}

/* ==========================================================================
   PIE: consola (.footer) + barra de cuenta (.account-bar)
   ========================================================================== */

/* 1550px -> el bloque de version/marca (Technovalab... / movilcenter-lab.com)
   no es informacion critica para operar el software; al tener
   margin-left:auto es el que mas espacio libre reserva, así que es el
   primero en ocultarse. */
@media (max-width: 1550px) {
  .account-version {
    display: none;
  }
}

/* 1200px -> ya no mostramos las etiquetas ("Anually", "Key", "Expires"...),
   solo el valor, para que cada bloque ocupe menos ancho. */
@media (max-width: 1200px) {
  .account-label {
    display: none;
  }

  .account-bar {
    gap: clamp(10px, 2.6vw, 40px);
  }
}

/* 1000px -> ocultamos el bloque "Config Panel" (menos prioritario) */
@media (max-width: 1000px) {
  .account-item:nth-of-type(5) {
    display: none;
  }

  .account-bar {
    gap: clamp(8px, 2.2vw, 28px);
  }
}

/* 800px -> priorizamos Usuario + Key; ocultamos "My IP" para que el resto
   quepa sin activar el scroll interno del pie. */
@media (max-width: 800px) {
  .account-item:nth-of-type(4) {
    display: none;
  }

  .account-bar {
    padding: 0 12px;
    gap: clamp(8px, 3vw, 20px);
  }
}

/* 560px -> ultimo respaldo: si aun asi no cupiera (pantallas muy angostas),
   tambien ocultamos "Expires", dejando solo Usuario + Key + version corta. */
@media (max-width: 560px) {
  .account-item:nth-of-type(3) {
    display: none;
  }
}

/* Consola (.footer): en ventanas muy angostas el texto interno ya trunca
   con ellipsis (ver .footer #consoleText), asi que solo evitamos que la
   caja completa se salga de la pantalla (ya resuelto arriba con
   width: min(500px, calc(100vw - 24px)) en la regla base de .footer). */

/* ==========================================================================
   LOGIN
   ========================================================================== */
.login-body {
  padding: 16px;
  box-sizing: border-box;
}

.login-card {
  width: min(360px, 100%);
  max-width: 92vw;
}

/* ==========================================================================
   MODAL: NUEVA CONTRIBUCIÓN (clic derecho sobre una región)
   Reutiliza la misma paleta que el resto del panel de contribuciones
   (verde #00c77b / #00e08a, fondo oscuro #1f1f1f).
   ========================================================================== */
.add-contribution-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10500;
}

.add-contribution-box {
  width: 460px;
  max-width: 92vw;
  max-height: 85vh;
  overflow-y: auto;
  background: #1f1f1f;
  border: 1px solid #00c77b;
  border-radius: 14px;
  box-shadow: 0 0 40px rgba(0, 199, 123, 0.25);
  padding: 18px;
  box-sizing: border-box;
}

.add-contribution-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  border-bottom: 1px solid #333;
  padding-bottom: 10px;
  margin-bottom: 14px;
}

.add-contribution-title {
  color: #fff;
  font-size: 17px;
  font-weight: bold;
}

.add-contribution-net {
  color: #00e08a;
  font-size: 12px;
  margin-top: 4px;
}

.add-contribution-close {
  width: 32px;
  height: 32px;
  flex: none;
  background: #111;
  color: #ccc;
  border: 1px solid #333;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
}

.add-contribution-close:hover {
  border-color: #00c77b;
  color: #fff;
}

.add-contribution-field {
  margin-bottom: 14px;
}

.add-contribution-field label {
  display: block;
  color: #bbb;
  font-size: 12px;
  margin-bottom: 6px;
}

.add-contribution-required {
  color: #ff6b6b;
}

.add-contribution-field input[type="text"],
.add-contribution-field textarea {
  width: 100%;
  box-sizing: border-box;
  background: #141414;
  border: 1px solid #333;
  border-radius: 8px;
  color: #eee;
  font-size: 13px;
  padding: 8px 10px;
  font-family: inherit;
  resize: vertical;
}

.add-contribution-field input[type="text"]:focus,
.add-contribution-field textarea:focus {
  outline: none;
  border-color: #00c77b;
}

.add-contribution-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  text-align: center;
  border: 1.5px dashed #444;
  border-radius: 10px;
  padding: 18px 12px;
  cursor: pointer;
  color: #999;
  font-size: 12px;
  transition: border-color .15s, background .15s;
}

.add-contribution-dropzone:hover,
.add-contribution-dropzone.dragover {
  border-color: #00c77b;
  background: rgba(0, 199, 123, 0.06);
  color: #ccc;
}

.add-contribution-dropzone-icon {
  font-size: 20px;
}

.add-contribution-filename {
  color: #00e08a;
  font-weight: bold;
  word-break: break-all;
}

.add-contribution-error {
  color: #ff6b6b;
  font-size: 12px;
  min-height: 16px;
  margin-bottom: 8px;
}

.add-contribution-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.add-contribution-btn-cancel,
.add-contribution-btn-submit {
  padding: 9px 18px;
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid #333;
}

.add-contribution-btn-cancel {
  background: #111;
  color: #ccc;
}

.add-contribution-btn-cancel:hover {
  border-color: #666;
}

.add-contribution-btn-submit {
  background: #00c77b;
  color: #06210f;
  font-weight: bold;
  border-color: #00c77b;
}

.add-contribution-btn-submit:hover {
  background: #00e08a;
}

.add-contribution-btn-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Botón de "like" de las tarjetas del Panel A: antes era solo texto, ahora
   es clickeable (para votar) sin abrir el detalle de la contribución. */
.contribution-like {
  cursor: pointer;
  user-select: none;
  border-radius: 4px;
  padding: 1px 6px;
  transition: background .12s, color .12s;
}

.contribution-like:hover {
  background: rgba(0, 199, 123, 0.15);
  color: #00e08a;
}

.contribution-like.voted {
  color: #00e08a;
  font-weight: bold;
}