/* Work Sans e IBM Plex Mono alojadas en el propio servidor (antes se
   cargaban desde fonts.googleapis.com en cada visita) -- más rápido y
   sin depender de que Google esté disponible. Mismos ficheros .woff2
   que serviría Google (descargados 2026-09-06), solo subconjuntos
   latin/latin-ext (suficiente para ES/CA, sin cirílico ni vietnamita).
   Work Sans es una fuente variable: un mismo fichero cubre los 4 pesos,
   por eso los 4 @font-face de cada subset apuntan al mismo src -- el
   navegador lo descarga una sola vez y lo reutiliza. */
@font-face{ font-family:'Work Sans'; font-style:normal; font-weight:400; font-display:swap; src:url('/fonts/work-sans-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Work Sans'; font-style:normal; font-weight:500; font-display:swap; src:url('/fonts/work-sans-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Work Sans'; font-style:normal; font-weight:600; font-display:swap; src:url('/fonts/work-sans-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Work Sans'; font-style:normal; font-weight:700; font-display:swap; src:url('/fonts/work-sans-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Work Sans'; font-style:normal; font-weight:400 700; font-display:swap; src:url('/fonts/work-sans-latin-ext.woff2') format('woff2'); unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face{ font-family:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap; src:url('/fonts/ibm-plex-mono-500-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap; src:url('/fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2'); unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face{ font-family:'IBM Plex Mono'; font-style:normal; font-weight:600; font-display:swap; src:url('/fonts/ibm-plex-mono-600-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'IBM Plex Mono'; font-style:normal; font-weight:600; font-display:swap; src:url('/fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2'); unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

:root{
  --bg: #F9FAFD;
  --panel: #FFFFFF;
  --panel2: #F3F5F6;
  --line: #E3E6EA;
  --text: #101010;
  --muted: #6C6C77;
  --volt: #00FFFF;
  --volt-text: #007373;
  --volt-dim: #D9FFFF;
  --amber: #C77800;
  --red: #D64545;
  --blue: #2E6DC4;
}
*{box-sizing:border-box; margin:0; padding:0;}
body{
  background: var(--bg);
  color: var(--text);
  font-family: 'Work Sans', sans-serif;
  min-height: 100vh;
}
.app-shell{
  display:flex;
  min-height: 100vh;
  position:relative;
  isolation:isolate;
}
/* Marca de agua fija en toda la pantalla de la app (pedido por Xavi
   2026-08-10, mismo mecanismo que en documentos impresos, ver
   .doc-preview::before): position:fixed para que quede siempre estatica,
   sin moverse al hacer scroll del contenido. */
.app-shell::before{
  content:"";
  position:fixed; inset:0;
  background-image:var(--watermark-logo);
  background-repeat:no-repeat; background-position:center; background-size:38vw auto;
  opacity:0.05; z-index:1; pointer-events:none;
}
::selection{ background: var(--volt-dim); color: var(--volt-text); }

/* ---------- Sidebar ---------- */
.sidebar{
  width: 240px;
  background: #FFFFFF;
  border-right: 1px solid #ECECEC;
  display:flex;
  flex-direction:column;
  padding: 22px 14px;
  position: sticky;
  top:0;
  height: 100vh;
  overflow-y: auto;
  flex-shrink:0;
}
.brand{
  font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif;
  font-weight:700;
  font-size: 19px;
  letter-spacing: 0.5px;
  padding: 0 8px 6px 8px;
  display:flex;
  align-items:center;
  gap:8px;
}
.brand .bolt{ color: var(--volt-text); font-size:22px; }
.brand-sub{
  font-size: 11px;
  color: #9A9A9A;
  padding: 0 8px 22px 8px;
  letter-spacing: 0.4px;
}
.nav-item{
  display:flex; align-items:center; gap:12px;
  padding: 15px 16px;
  border-radius: 10px;
  color: #3A3A3A;
  font-size: 15px;
  font-weight: 600;
  cursor:pointer;
  margin-bottom: 5px;
  transition: background .12s, color .12s;
  border-left: 3px solid transparent;
}
.nav-item:hover{ background: #F3F5F6; color: #101010; }
.nav-item.active{
  background: var(--volt);
  color: #04302F;
  border-left: 3px solid var(--volt-text);
}
.nav-icon{ width:20px; text-align:center; font-size:17px; }
.sidebar-foot{
  margin-top:auto;
  font-size: 11px;
  color: #9A9A9A;
  padding: 10px 8px 0 8px;
  border-top: 1px solid #ECECEC;
}

/* ---------- Main ---------- */
.main{ flex:1; padding: 28px 36px 60px 36px; max-width: 1180px; }
.topbar{
  display:flex; justify-content:space-between; align-items:flex-end;
  margin-bottom: 26px;
}
.page-title{
  font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing:0.01em;
}
.page-sub{ color: var(--muted); font-size: 13px; margin-top:4px; }
.btn{
  background: var(--volt);
  color: #04302F;
  border:none;
  font-family:'Work Sans';
  font-weight:700;
  font-size: 14px;
  padding: 12px 20px;
  border-radius: 10px;
  cursor:pointer;
  transition: filter .12s, transform .08s;
  box-shadow: 0 2px 6px rgba(0,180,180,0.28);
}
.btn:hover{ filter: brightness(1.08); transform: translateY(-1px); }
.btn:disabled{ opacity:0.4; cursor:not-allowed; box-shadow:none; }
.btn:disabled:hover{ filter:none; transform:none; }
.btn.ghost{
  background: var(--panel);
  border: 1.5px solid var(--line);
  color: var(--text);
  box-shadow: none;
}
.btn.ghost:hover{ background: var(--panel2); border-color: var(--volt); }
.btn.small{ padding: 8px 13px; font-size:12.5px; border-radius:8px; box-shadow:none; }

/* cards / grid */
.grid{ display:grid; gap:14px; }
.grid-5{ grid-template-columns: repeat(5, 1fr); }
.grid-4{ grid-template-columns: repeat(4, 1fr); }
.grid-3{ grid-template-columns: repeat(3, 1fr); }
.grid-2{ grid-template-columns: 1.3fr 1fr; }

.card{
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px;
  box-shadow: 0 1px 4px rgba(16,16,16,0.06);
}
.stat-card .stat-label{ font-size:12px; color:var(--muted); margin-bottom:8px; }
.stat-card .stat-value{ font-family:'IBM Plex Mono'; font-size: 28px; font-weight:600; }
.stat-card .stat-value.volt{ color: var(--volt-text); }
.stat-card .stat-value.amber{ color: var(--amber); }
.stat-card .stat-value.red{ color: var(--red); }
.stat-card-click{ cursor:pointer; transition:box-shadow .15s, transform .15s; }
.stat-card-click:hover{ box-shadow: 0 3px 10px rgba(16,16,16,0.12); transform: translateY(-1px); }

/* Ocultar información sensible (pedido por Xavi 2026-08-28): los
   importes se difuminan pero la tarjeta sigue ahí, para dejar claro
   que hay algo, solo que está oculto -- no se sustituye el texto por
   JS para no tener que tocar cada valor por separado. */
.info-oculta .stat-value{ filter: blur(7px); user-select:none; }
.section-title-click{ cursor:pointer; }
.section-title-click:hover{ color: var(--volt-text); }

.section-title{
  font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif;
  font-size: 15px;
  font-weight:700;
  letter-spacing:0.01em;
  margin: 30px 0 12px 0;
  display:flex; align-items:center; justify-content:space-between;
}

/* battery / charge bar — signature element used for all "status" */
.charge{
  width:100%; height:8px; border-radius:4px;
  background: var(--line);
  border: 1px solid var(--line);
  overflow:hidden;
  position:relative;
}
.charge > i{
  display:block; height:100%; border-radius:3px;
  background: linear-gradient(90deg, var(--volt-dim), var(--volt));
}
.charge.amber > i{ background: linear-gradient(90deg, #F6DFA8, var(--amber)); }
.charge.red > i{ background: linear-gradient(90deg, #F6C7C7, var(--red)); }

/* table */
table{ width:100%; border-collapse: collapse; font-size: 13px; }
th{
  text-align:left; color: var(--muted); font-weight:600; font-size:11.5px;
  text-transform: uppercase; letter-spacing:0.4px;
  padding: 8px 10px; border-bottom: 1px solid var(--line);
}
td{ padding: 11px 10px; border-bottom: 1px solid var(--line); vertical-align:middle; }
.th-sortable{ cursor:pointer; user-select:none; white-space:nowrap; }
.th-sortable:hover{ color: var(--text); }
tr:last-child td{ border-bottom:none; }
tr.row-click{ cursor:pointer; }
tr.row-click:hover td{ background: var(--panel2); }
.mono{ font-family:'IBM Plex Mono'; font-size:12.5px; color: var(--blue); }

.tag{
  display:inline-block; font-size: 11px; font-weight:700; padding: 4px 10px;
  border-radius: 20px; letter-spacing:0.2px;
}
.tag.recepcion{ background:#EFF1F2; color: var(--muted); }
.tag.diagnostico{ background:#FBEACB; color: var(--amber); }
.tag.reparacion{ background:var(--volt-dim); color: var(--volt-text); }
.tag.listo{ background:#DCF1DF; color: #227A3B; }
.tag.entregado{ background:#EFF1F2; color: var(--muted); }
.tag.pendiente{ background:#FBDCDC; color: #B23434; }

/* kanban */
.kanban{ display:grid; grid-template-columns: repeat(5,1fr); gap:12px; }
.kanban-col{ background: var(--panel); border:1px solid var(--line); border-radius:10px; padding:12px; min-height: 200px; }
.kanban-col h4{ font-size:12px; color:var(--muted); text-transform:uppercase; letter-spacing:0.4px; margin-bottom:10px; display:flex; justify-content:space-between; }
.kcard{
  background: var(--panel2); border:1px solid var(--line); border-radius:8px;
  padding: 10px; margin-bottom: 8px; font-size:12.5px; cursor:pointer;
}
.kcard:hover{ border-color: var(--volt-dim); }
.kcard .kc-moto{ font-weight:600; margin-bottom:4px; }
.kcard .kc-cliente{ color:var(--muted); font-size:11.5px; margin-bottom:6px; }

/* modal */
.overlay{
  position:fixed; inset:0; background: rgba(8,10,12,0.72);
  display:none; align-items:center; justify-content:center; z-index:50; padding:20px;
}
.overlay.open{ display:flex; }
.modal{
  background: var(--panel); border:1px solid var(--line); border-radius:12px;
  width: 560px; max-width:100%; max-height: 86vh; overflow-y:auto;
  padding: 24px;
}
.modal h3{ font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif; font-weight:700; font-size:17px; margin-bottom:16px; cursor:move; user-select:none; }
.modal h2, .modal [data-modal-drag]{ cursor:move; user-select:none; }
.field{ margin-bottom:12px; }
.field label{ display:block; font-size:11.5px; color:var(--muted); margin-bottom:5px; text-transform:uppercase; letter-spacing:0.3px; }
.field input, .field select, .field textarea{
  width:100%; background: var(--bg); border:1px solid var(--line); color:var(--text);
  padding: 9px 10px; border-radius:6px; font-family:'Work Sans'; font-size:13px;
}
.field textarea{ min-height: 70px; resize:vertical; }
.row2{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
/* Pedido por Xavi 2026-08-12: en modales largos (Seguimiento de venta,
   Configuración...) los botones Cerrar/Guardar quedaban al final, hay
   que scrollear para llegar a ellos. Sticky al fondo del modal, con
   fondo propio para no dejar ver el contenido que pasa por debajo. */
.modal-actions{
  display:flex; flex-wrap:wrap; justify-content:flex-end; gap:8px; margin-top:18px;
  position:sticky; bottom:-24px; z-index:2;
  margin-left:-24px; margin-right:-24px; margin-bottom:-24px;
  padding:14px 24px; background:var(--panel); border-top:1px solid var(--line);
  border-radius:0 0 12px 12px;
}

/* Botón de guardar flotante para vistas de página completa (no modal)
   que pueden crecer más altas que la pantalla -- pedido por Xavi
   2026-08-14, mismo motivo que .modal-actions pero fijo al viewport en
   vez de sticky dentro de un contenedor, porque aquí el que hace
   scroll es la página entera, no un modal con su propio overflow. */
.page-actions-flotante{
  position:fixed; bottom:0; left:240px; right:0; z-index:40;
  display:flex; align-items:center; gap:10px;
  padding:14px 36px; background:var(--panel); border-top:1px solid var(--line);
}
@media (max-width:900px){
  .page-actions-flotante{ left:0; }
}

.tabs{ display:flex; gap:6px; margin-bottom:18px; border-bottom:1px solid var(--line); }
.tab{ padding:9px 4px; margin-right:18px; color:var(--muted); font-size:13px; font-weight:500; cursor:pointer; border-bottom:2px solid transparent; }
.tab.active{ color:var(--text); border-bottom:2px solid var(--volt); }

/* Pestañas de Ajustes -- clase propia (no ".tab") para no engancharse a
   la delegación de eventos genérica de los tabs de Documentos. */
.ajustes-tabs{ display:flex; gap:6px; margin-bottom:18px; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.ajustes-tab{ padding:9px 4px; margin-right:18px; color:var(--muted); font-size:13px; font-weight:500; cursor:pointer; border-bottom:2px solid transparent; }
.ajustes-tab.active{ color:var(--text); border-bottom:2px solid var(--volt); }

/* Ficha de orden de taller -- pestañas propias (pedido por Xavi
   2026-09-25, reorganización de la ficha en Resumen/Artículos y
   presupuesto/Seguimiento/Datos de entrada/Entrega). Misma razón que
   .ajustes-tab: clase dedicada para no engancharse a la delegación de
   eventos de .tab/.ajustes-tab -- ver mostrarPestanaOrden() en
   index.html. Solo afecta a la ficha de orden, no a otras pantallas. */
.orden-tabs{ display:flex; gap:2px; margin-bottom:18px; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.orden-tab{
  display:flex; align-items:center; gap:6px;
  background:none; border:none; font-family:'Work Sans';
  padding:10px 4px; margin-right:22px; color:var(--muted); font-size:13px; font-weight:500;
  cursor:pointer; border-bottom:2px solid transparent;
}
.orden-tab.active{ color:var(--text); font-weight:700; border-bottom:2px solid var(--volt-text); }
.orden-tab-badge{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:18px; height:18px; padding:0 5px; border-radius:20px;
  font-size:10.5px; font-weight:700; background:var(--line); color:var(--muted);
}
.orden-tab.active .orden-tab-badge{ background:var(--volt-text); color:var(--panel); }
.orden-tab-panel .card{ padding:20px; border-radius:10px; }

/* Stepper del estado de la orden (pedido por Xavi 2026-09-25, sustituye
   visualmente al <select id="cambio-estado"> que sigue existiendo,
   oculto, como única fuente real del valor -- ver
   elegirEstadoOrdenStepper() en index.html). */
.orden-stepper{ display:flex; align-items:flex-start; margin-top:8px; }
.orden-stepper-paso{ flex:1; display:flex; flex-direction:column; align-items:center; position:relative; cursor:pointer; }
.orden-stepper-paso:not(:first-child)::before{
  content:''; position:absolute; top:7px; left:-50%; width:100%; height:2px; background:var(--line); z-index:0;
}
.orden-stepper-paso.pasado:not(:first-child)::before,
.orden-stepper-paso.actual:not(:first-child)::before{ background:var(--volt-dim); }
.orden-stepper-punto{ width:16px; height:16px; border-radius:50%; background:var(--panel); border:2px solid var(--line); position:relative; z-index:1; }
.orden-stepper-paso.pasado .orden-stepper-punto{ background:var(--volt-dim); border-color:var(--volt-dim); }
.orden-stepper-paso.actual .orden-stepper-punto{ background:var(--volt-text); border-color:var(--volt-text); box-shadow:0 0 0 5px var(--volt-dim); }
.orden-stepper-etiqueta{ font-size:11px; color:var(--muted); margin-top:7px; text-align:center; }
.orden-stepper-paso.actual .orden-stepper-etiqueta{ color:var(--volt-text); font-weight:700; }
.orden-stepper-paso.pasado .orden-stepper-etiqueta{ color:var(--text); }

.empty{ text-align:center; padding: 40px 20px; color: var(--muted); font-size:13px; }
.empty .big{ font-size:15px; color:var(--text); font-weight:600; margin-bottom:6px; font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif; }

/* ---------- Login ---------- */
.login-screen{ min-height:100vh; display:flex; }
.login-brand-panel{
  flex:1.1; position:relative; overflow:hidden;
  background: linear-gradient(160deg, #0A0A0A 0%, #1C1C1C 100%);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:40px;
}
.login-brand-panel::before{
  content:''; position:absolute; width:520px; height:520px; border-radius:50%;
  background: radial-gradient(circle, rgba(0,255,255,0.14), transparent 70%);
  top:-160px; right:-180px;
}
/* Instalación con logo propio configurado (pedido por Xavi 2026-09-09,
   caso real: Electromobilidad Letamendi): fondo claro en vez del
   degradado oscuro de fábrica -- un logo subido por el cliente no tiene
   por qué llevar una variante en blanco pensada para fondo oscuro. */
.login-brand-panel.logo-personalizado{ background:#F5F3EF; }
.login-brand-panel.logo-personalizado::before{ background: radial-gradient(circle, rgba(0,115,115,0.10), transparent 70%); }
.login-brand-panel.logo-personalizado .login-tagline{ color:#4A4A4A; }
.login-logo{ height: clamp(150px, 24vh, 230px); width:auto; margin-bottom:24px; position:relative; }
.login-tagline{
  font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif; color:#EDF7F7; font-size:17px; font-weight:600;
  text-align:center; line-height:1.55; max-width:320px; position:relative;
}
.login-charge{
  width:220px; height:70px; margin-top:30px;
  display:flex; align-items:center; justify-content:center;
}
.login-charge svg{ color:var(--volt); filter: drop-shadow(0 2px 8px rgba(0,0,0,0.3)); }
.login-charge rect[class^="login-batt-b"]{ animation: battRayita 2.4s ease-in-out infinite; }
.login-charge .login-batt-b1{ animation-delay: 0s; }
.login-charge .login-batt-b2{ animation-delay: .15s; }
.login-charge .login-batt-b3{ animation-delay: .3s; }
.login-charge .login-batt-b4{ animation-delay: .45s; }
.login-charge .login-batt-b5{ animation-delay: .6s; }
.login-charge .login-batt-b6{ animation-delay: .75s; }
.login-charge .login-batt-b7{ animation-delay: .9s; }
.login-charge .login-batt-b8{ animation-delay: 1.05s; }
@keyframes battRayita{ 0%,100%{opacity:.2;} 50%{opacity:1;} }
.login-brand-foot{
  position:absolute; bottom:26px; font-family:'IBM Plex Mono', monospace;
  font-size:11px; letter-spacing:3px; color:#8A8A8A;
}
.login-form-panel{ flex:1; display:flex; align-items:center; justify-content:center; background:var(--bg); padding:40px; }
.login-form-card{ width:100%; max-width:320px; }
.login-form-card h2{ font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif; font-weight:700; font-size:22px; margin-bottom:6px; }
.login-form-sub{ color:var(--muted); font-size:13px; margin-bottom:26px; }
.login-error{ color:var(--red); font-size:12.5px; margin:-10px 0 14px 0; }
@media (max-width: 760px){
  .login-brand-panel{ display:none; }
}

.hidden{ display:none !important; }
.doc-preview{ background:#fff; color:#111; border-radius:8px; padding:26px; font-size:12.5px; position:relative; padding-left:32px; isolation:isolate; }
.doc-preview h4{ font-family:'IBM Plex Mono'; font-size:11px; color:#888; letter-spacing:1px; text-transform:uppercase; }
.doc-preview .dp-total{ font-size:20px; font-weight:700; text-align:right; margin-top:10px; }
.doc-preview table td, .doc-preview table th{ border-color:#eee; color:#111; }
/* Vista previa en pantalla: se ajusta a lo que quepa cómodo (los botones
   de abajo -imprimir/cerrar- no deben quedar fuera de la vista), con
   scroll propio SOLO dentro del papel si el documento es largo -- ya no
   fuerza proporción A4 en pantalla, eso queda solo para la impresión
   real (ver @page más abajo). */
#doc-preview-content .doc-preview{ max-height:78vh; overflow-y:auto; box-shadow: inset 0 0 0 1px #eee; }
@page{ size: A4; margin: 15mm; }

/* Ficha de documento (presupuesto/albarán/factura): mismos datos que
   llevaba la factura de BitFac, con un diseño moderno de tarjetas en vez
   de la rejilla de cajas del programa antiguo. */
.dp-head{ display:flex; justify-content:space-between; align-items:flex-start; gap:18px; margin-bottom:20px; }
.dp-empresa{ display:flex; gap:12px; align-items:center; }
.dp-empresa img{ height:96px; width:auto; flex-shrink:0; }
.dp-empresa-datos{ font-size:11px; line-height:1.5; color:#666; }
.dp-empresa-datos b{ display:block; font-size:13.5px; color:#111; margin-bottom:2px; }
.dp-tipo{ text-align:right; flex-shrink:0; }
.dp-tipo-label{ font-size:19px; font-weight:800; color:var(--volt-text); letter-spacing:0.3px; }
.dp-tipo-num{ font-family:'IBM Plex Mono'; font-size:12px; color:#777; margin-top:3px; }
.dp-tipo-estado{ display:inline-block; margin-top:6px; font-size:10px; font-weight:600; padding:2px 8px; border-radius:20px; background:var(--volt-dim); color:var(--volt-text); }

.dp-cards{ display:grid; grid-template-columns: 1fr 1.3fr; gap:12px; margin-bottom:20px; }
.dp-card{ background:#D9FFFF; border-radius:10px; padding:12px 15px; }
.dp-card-label{ font-size:9px; text-transform:uppercase; letter-spacing:0.6px; color:#a39a89; margin-bottom:3px; }
.dp-card b{ font-size:13px; color:#111; }
.dp-card .dp-card-sub{ font-size:11.5px; color:#666; margin-top:1px; line-height:1.4; }
.dp-card-fila{ display:flex; justify-content:space-between; gap:10px; }
.dp-card-fila + .dp-card-fila{ margin-top:8px; }

.dp-tabla{ width:100%; border-collapse:collapse; margin-bottom:2px; }
.dp-tabla thead th{ text-align:left; font-size:9.5px; text-transform:uppercase; letter-spacing:0.5px; color:#a39a89; padding:0 8px 7px; border-bottom:2px solid #eee; font-weight:600; }
.dp-tabla thead th.num{ text-align:right; }
.dp-tabla tbody td{ padding:9px 8px; border-bottom:1px solid #f2f0eb; font-size:12.5px; color:#111; vertical-align:top; }
.dp-tabla tbody td.num{ text-align:right; font-family:'IBM Plex Mono'; white-space:nowrap; }
.dp-tabla tbody td.acciones{ white-space:nowrap; text-align:right; }
.dp-garantia-badge{ display:inline-block; font-size:9px; background:var(--volt-dim); color:var(--volt-text); border-radius:6px; padding:1px 6px; margin-left:6px; vertical-align:middle; }

.dp-totales{ display:flex; justify-content:flex-end; margin-top:12px; }
.dp-totales-box{ min-width:230px; }
.dp-totales-fila{ display:flex; justify-content:space-between; font-size:12px; padding:3px 0; color:#666; }
.dp-totales-fila.dp-total-final{ border-top:2px solid var(--volt); margin-top:6px; padding-top:8px; font-size:19px; font-weight:800; color:#111; }

.dp-nota-legal{ background:#FAF8F4; border-radius:10px; padding:10px 14px; font-size:10px; color:#8a8378; margin-top:20px; text-align:center; line-height:1.5; }
.dp-pie-contacto{ display:flex; justify-content:center; align-items:center; flex-wrap:wrap; gap:5px 20px; margin-top:14px; padding-top:11px; border-top:1px solid #eee; font-size:10.5px; color:#8a8378; text-align:center; letter-spacing:0.15px; }
.dp-pie-contacto span{ display:inline-flex; align-items:center; gap:5px; }

/* Impresión de la nota de entrega: se oculta todo excepto el documento */
#nota-entrega-imprimible{ display:none; }
.nota-print{ font-family: Arial, sans-serif; color:#111; font-size:13px; line-height:1.5; position:relative; padding-left:22px; isolation:isolate; }
/* Marca de agua (pedido por Xavi 2026-08-08): el logo de fondo, grande y
   casi imperceptible, en TODOS los documentos imprimibles. Un solo punto
   de verdad -- .doc-preview y .nota-print son los dos contenedores que
   usan absolutamente todas las funciones de impresion (documento,
   report de revision, notas de entrega/deposito/reparacion), asi que
   con esto solo ya cubre todo sin tocar cada funcion una a una. */
.doc-preview::before, .nota-print::before{
  content:"";
  position:absolute; top:0; left:0; right:0; bottom:0;
  background-image:var(--watermark-logo);
  background-repeat:no-repeat; background-position:center; background-size:75% auto;
  /* z-index POSITIVO (antes -1, detrás de todo): pedido por Xavi
     2026-08-16, seguía saliendo cortado por cualquier caja con fondo
     solido por encima (tarjeta de vehiculo/cliente, aviso de garantia...)
     -- un intento anterior de aclarar esos fondos a rgba no bastaba,
     porque al 10% de opacidad del logo, debajo de una caja casi opaca
     se queda en un 1-2% real, invisible. Unica forma de que NADA lo
     tape nunca, sea cual sea el contenido del documento, es pintarlo
     por delante de todo -- al 10% de opacidad se sigue leyendo el texto
     de debajo sin problema, igual que un membrete/marca de agua real. */
  opacity:0.06; z-index:5; pointer-events:none;
  /* Sin esto, Chrome no imprime fondos/imagenes de fondo salvo que el
     usuario marque a mano "Graficos de fondo" en el dialogo de impresion
     -- con esto se fuerza siempre, que es justo el pedido de Xavi ("que
     siempre este de fondo"). */
  print-color-adjust:exact; -webkit-print-color-adjust:exact;
}
/* padding-top: el logo ya no vive en el flujo del documento (ahora es
   .np-logo-print, position:fixed en impresión para repetirse en cada
   hoja -- ver @media print más abajo), así que este hueco reproduce el
   espacio que antes ocupaba el logo por encima de este bloque. */
.np-header{ text-align:right; margin-bottom:24px; padding-top:58px; }
.np-header b{ font-size:14px; }
.nota-print .np-linea{ margin:10px 0; }
.nota-print .np-linea .np-label{ display:inline-block; min-width:180px; font-weight:bold; }
.nota-print hr{ border:none; border-top:1px solid #999; margin:18px 0; }

/* Registro mercantil lateral: antes con position:absolute inline en el
   propio HTML, referido a la altura de TODO el documento (.nota-print/
   .doc-preview) -- si el documento pasaba de 1 pagina, el texto quedaba
   centrado respecto al total de paginas, no repetido en cada una
   (pedido por Xavi 2026-08-13: que salga en el costado de TODAS las
   hojas). Con clase propia para poder pasar a position:fixed SOLO en
   impresion (en pantalla, dentro de la vista previa con scroll propio,
   fixed se rompería contra el viewport en vez del panel). */
.rm-lateral{ position:absolute; top:0; bottom:0; left:0; width:14px; overflow:visible; }
.rm-lateral span{ position:absolute; top:50%; left:50%; transform: translate(-50%,-50%) rotate(-90deg); transform-origin:center center; white-space:nowrap; font-size:9px; color:#888; letter-spacing:0.5px; }

/* Logo repetido en cada hoja impresa (mismo motivo que el registro
   mercantil): en pantalla no se ve nunca (estos contenedores solo se
   muestran vía @media print), así que position:fixed aquí no rompe
   ninguna vista previa. */
.np-logo-print{ height:50px; width:auto; }
/* Sello de empresa en vez de firma del taller: mix-blend-mode quita el
   fondo blanco del jpg contra el papel (sin tener que retocar la imagen),
   la inclinación y el contraste imitan un sello de tampón real estampado
   a mano -- pidió explícitamente que NO quedara perfecto/vectorial. */
.sello-firma-taller{ display:flex; flex-direction:column; align-items:center; gap:2px; }
.sello-firma-taller img{
  width:225px; mix-blend-mode:multiply; opacity:0.85;
  transform:rotate(-6deg); filter:contrast(1.2) saturate(0.9);
}

/* Cabecera compacta de la nota de depósito/reparación (pedido por Xavi
   2026-08-13, retocada 2026-08-14 dos veces: primero porque el nombre/
   logo quedaban "minimizados" frente al título; luego porque el logo
   pequeño de la esquina sobraba (ya está la marca de agua central + el
   sello) y los datos de empresa iban todos en una sola línea corrida
   con separadores "·", que en una columna estrecha se cortaban de forma
   rara (el "·" antes del CIF quedaba huérfano al principio de línea,
   parecía un guión). Ahora sin logo pequeño, y cada dato de empresa en
   su propia línea (nombre / CIF / dirección / teléfono+email con
   iconos) en vez de un único párrafo corrido. */
.np-cabecera{ display:flex; justify-content:space-between; align-items:flex-start; gap:16px; border-bottom:2px solid #ddd; padding-bottom:10px; margin-bottom:12px; }
.np-cabecera-titulo{ text-align:right; flex-shrink:0; min-width:170px; }
.np-titulo-doc{ display:block; font-size:15.5px; font-weight:800; letter-spacing:0.3px; color:var(--volt-text); }
/* Lugar y fecha/hora en líneas propias (pedido por Xavi 2026-08-14):
   antes iban juntos en una sola línea ("Vilanova i la Geltrú · fecha —
   hora") y se partían de forma rara en la columna estrecha del título.
   Fecha y hora, además, centradas -- no alineadas a la derecha como el
   resto de la cabecera. */
.np-titulo-lugar{ display:block; font-size:10.5px; color:#777; margin-top:4px; white-space:nowrap; text-align:center; }
.np-titulo-fechahora{ display:block; font-size:10.5px; color:#777; margin-top:2px; text-align:center; }

/* Datos de cliente/moto en rejilla compacta, en vez de una línea suelta
   por dato con 10px de margen cada una (pedido por Xavi 2026-08-13:
   "mucho más juntos, optimizando espacio"). Solo para la nota de
   depósito -- .np-linea (líneas sueltas) se mantiene intacta para el
   resto de notas. */
.np-datos-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:3px 14px; font-size:11.5px; margin:6px 0; }
.np-datos-grid > div{ padding:1px 0; }
.np-datos-grid b, .np-linea-compacta b{ font-weight:bold; }
.np-linea-compacta{ font-size:11.5px; margin:3px 0; }
.nota-print-compacta hr{ margin:8px 0; }
/* Hueco reservado abajo en TODAS las páginas para que el contenido no
   se meta debajo del pie fijo (.np-pie-fijo, position:fixed en
   impresión -- se repite en cada hoja, incluida la de las fotos). */
.nota-print-compacta{ padding-bottom:32mm; }

/* Salto de página forzado antes de las fotos (pedido por Xavi
   2026-08-13: que las fotos queden en el reverso del documento -- todo
   el resto -datos, garantía, declaración, firma y sello- debe quedar
   en la primera página). */
.np-salto-pagina{ page-break-before:always; break-before:page; padding-top:20px; }

/* Declaración de depósito + garantía movidas al pie del documento
   (pedido por Xavi 2026-08-13: menos protagonismo, es texto legal de
   referencia, no lo principal de la página). Mismo estilo visual que
   .dp-nota-legal (factura/presupuesto/albarán) para quedar consistente.
   .np-pie-fijo va con position:fixed en impresión (ver @media print) --
   con margin-top:auto dentro del flex de .nota-print no bastaba: al
   convivir con el salto de página forzado antes de las fotos, quedaba
   sujeto al flujo normal en vez de anclado de verdad al pie de la
   página (pedido de Xavi 2026-08-13: "en el pie de página, no al final
   del texto"). Fixed lo resuelve igual que ya resuelve el logo/registro
   mercantil -- se repite abajo en cada hoja, algo razonable para un pie
   legal (mismo criterio que un pie de página real). */
.np-pie-fijo{ position:relative; }
.np-pie-legal{ background:#FAF8F4; border-radius:10px; padding:8px 12px; font-size:9.5px; color:#8a8378; margin-top:14px; text-align:center; line-height:1.5; }

/* Nota de depósito (pedido por Xavi 2026-08-15): el pie fijo (declaración
   + garantía + contacto) se repetía también en la página de las fotos
   por ser position:fixed -- ahí chocaba con la firma de esa página, que
   necesita ese mismo hueco de abajo. Aquí las "condiciones" van solo en
   la página 1, como contenido normal (no fijo, no se repite), dejando
   toda la página 2 libre para fotos + firma. */
.np-pie-normal{ position:relative; }
.nota-deposito-print{ padding-bottom:0; }
/* El fondo sólido de .np-pie-legal tapaba la marca de agua al quedar
   en mitad de la página 1 (ya no está fijo al pie, ver arriba) --
   pedido por Xavi 2026-08-15: sin fondo aquí, para que la marca de
   agua se siga viendo por debajo del texto. */
.nota-deposito-print .np-pie-legal{ background:transparent; }
/* Pedido por Xavi 2026-08-15 (segunda vuelta): las condiciones tienen
   que quedar ancladas al pie de la PÁGINA 1 en concreto, no fijas en
   todas las páginas (chocaría otra vez con la firma de la página 2,
   que se queda tal cual está). .np-pagina1 envuelve solo el contenido
   de la primera página (todo lo de antes de .np-salto-pagina, que es
   un hermano aparte) -- al ser un contenedor flex con la altura de una
   página, margin-top:auto en el pie sí funciona esta vez (a diferencia
   del intento de 2026-08-13 con .nota-print entero, que abarcaba las
   dos páginas de golpe y por eso no anclaba bien). */
.np-pagina1{ display:flex; flex-direction:column; min-height:250mm; }
.np-pagina1 .np-pie-normal{ margin-top:auto; }

/* Fecha/hora estampada sobre cada foto (pedido por Xavi 2026-08-13:
   para que no se pueda alegar que se sustituyeron las fotos después).
   Barra semitransparente sobre el borde inferior de la imagen. */
.np-foto-wrap{ position:relative; }
.np-foto-marca{
  position:absolute; left:0; right:0; bottom:0;
  background:rgba(0,0,0,0.55); color:#fff; font-size:9.5px;
  padding:2px 0; text-align:center; letter-spacing:0.2px;
  print-color-adjust:exact; -webkit-print-color-adjust:exact;
}

@media print{
  /* FALLO GRAVE de verdad, encontrado 2026-08-15 tras varios intentos
     fallidos (Xavi: presupuestos/albaranes/facturas de un puñado de
     líneas imprimiendo 36, 15, 12 páginas -- número INESTABLE entre
     intentos idénticos, sin cambiar nada de código de por medio, lo
     cual ya apuntaba a que el contenido del documento no era la causa).
     Causa real: "visibility:hidden" en body * OCULTA visualmente el
     resto de la aplicación (barra lateral, la vista que estuviera
     abierta detrás -Documentos, Taller...-, cualquier modal) pero NO
     le quita el espacio en el documento -- sigue maquetado a tamaño
     real, solo invisible. Chrome calcula cuántas páginas hacen falta
     según la altura TOTAL del documento, así que la vista real que
     tuvieras abierta detrás (con sus filas/tarjetas de verdad, tantas
     como datos reales haya) inflaba el número de páginas -- y como esa
     vista cambia según qué estés mirando en cada momento, el número de
     páginas variaba de un intento a otro con el mismo documento a
     imprimir. #nota-entrega-imprimible ya tenía position:absolute,
     por eso el contenido bueno salía siempre en la primera página --
     el resto eran solo hueco vacío con la marca de agua repetida
     (position:fixed) encima.
     Arreglo real: ocultar del todo (display:none, sin espacio) el
     contenedor raíz de toda la aplicación en vez de solo su
     visibilidad -- #nota-entrega-imprimible vive FUERA de
     #app-shell-wrap en el HTML, así que no le afecta. */
  #app-shell-wrap{ display:none !important; }
  /* Los modales (.overlay) viven FUERA de #app-shell-wrap en el HTML
     -- normalmente se imprime con uno abierto (el propio modal desde
     el que se pulsa "Imprimir"), y al ser position:fixed no engordan
     el número de páginas, pero sin ocultarlo aparecería por encima del
     documento en la propia hoja impresa. */
  .overlay{ display:none !important; }
  #nota-entrega-imprimible{ display:block !important; position:absolute !important; top:0; left:0; width:100%; padding:30px; }
  /* Pie (totales + condiciones + contacto) anclado al fondo de la página
     en presupuesto/albarán/factura -- pedido por Xavi 2026-08-16: tras
     quitar el flex/min-height en a14753b (14-08) el pie quedaba pegado
     justo debajo de la tabla en vez de al fondo de la hoja. Aquella
     regla se quitó por prudencia mientras se buscaba la causa de las
     páginas de más, pero la causa real (encontrada al día siguiente,
     ver comentario arriba) era el visibility:hidden del app-shell, no
     esto -- ya corregida, así que se puede recuperar el anclaje sin
     reintroducir el bug. Mismo patrón que .np-pagina1 (nota de
     depósito): min-height de una página + margin-top:auto en el pie.
     En documentos largos que ya superan una página, el flex no tiene
     hueco extra que repartir y el pie simplemente sigue al contenido,
     igual que hasta ahora -- solo cambia el caso de documento corto. */
  /* La altura debe incluir el padding del papel. Sin border-box, los 52px
     de padding se sumaban a la altura mínima y el pie de contacto saltaba
     a una segunda hoja al añadir los textos legales. */
  .doc-preview{ display:flex; flex-direction:column; box-sizing:border-box; min-height:267mm; }
  /* Coordenada fija de página: el contacto no depende de cuánto contenido
     tenga el documento ni vuelve a saltar por los textos legales. */
  .dp-pie-contacto{ position:fixed; left:32px; right:26px; bottom:8mm; break-inside:avoid; page-break-inside:avoid; }
  .dp-pie-documento{ padding-top:20px; margin-top:auto; }

  /* Registro mercantil, logo y marca de agua repetidos en CADA hoja
     impresa (pedido por Xavi 2026-08-13) -- position:fixed en impresión
     se repite en todas las páginas del trabajo de impresión (a
     diferencia de position:absolute, que solo se coloca una vez
     respecto a la altura total del documento). Solo dentro de
     @media print: en pantalla estos contenedores nunca se muestran
     (ver #nota-entrega-imprimible{display:none} arriba), así que no
     hay vista previa que se pueda romper. */
  .rm-lateral{ position:fixed; top:0; bottom:0; left:0; }
  .np-logo-print{ position:fixed; top:10mm; right:10mm; }
  .doc-preview::before, .nota-print::before{ position:fixed; }
  .np-pie-fijo{ position:fixed; left:22px; right:0; bottom:6mm; }
}

@media (max-width: 900px){
  .grid-5{ grid-template-columns: repeat(2,1fr); }
  .grid-4{ grid-template-columns: repeat(2,1fr); }
  .grid-3{ grid-template-columns: repeat(2,1fr); }
  .grid-2{ grid-template-columns: 1fr; }
  .kanban{ grid-template-columns: 1fr; }
  .sidebar{ display:none; }
  .main{ padding: 14px; }
  .mobile-nav{ display:block !important; }
  /* Listados en móvil (pedido por Xavi 2026-08-18): las tablas tienen
     demasiadas columnas para caber en pantalla, y sin esto arrastraban
     TODA la página en horizontal (nav, botones...) para poder verlas
     enteras. Con esto solo desliza la tabla en sí, el resto de la
     pantalla se queda fija -- truco CSS estándar: display:block en la
     <table> la convierte en su propio contenedor con scroll, sin tocar
     el layout interno de filas/columnas (que sigue siendo el de una
     tabla real, no se toca el HTML). */
  table{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  table thead, table tbody{ min-width:100%; }
}
.mobile-nav{
  display:none;
  position: sticky; top:44px; z-index: 40;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  padding: 10px 14px;
  margin: -14px -14px 18px -14px;
}
.mobile-nav select{
  width:100%; background: var(--panel2); color: var(--text);
  border:1px solid var(--line); border-radius:8px;
  padding: 11px 12px; font-size:14px; font-weight:600;
  font-family:'Copperplate','Copperplate Gothic Light',Georgia,serif;
}
