/* Hoja de estilos compartida por toda la app (incluida la pantalla de
   login): antes esta paleta y estos componentes base estaban duplicados en
   <style> inline en templates/base.html y templates/registration/login.html,
   lo que además impedía que el navegador cacheara los estilos entre
   navegaciones. Cambios de paleta o de componentes base se hacen aquí, una
   sola vez. */

/* Inter servida desde la propia app (SIL OFL 1.1, ver fonts/LICENSE): antes
   se cargaba de Google Fonts, lo que enviaba la IP de cada visita a un
   tercero — algo que el RGPD no permite dar por supuesto. `font-display:
   swap` evita el texto invisible mientras la fuente se descarga. */
@font-face {
    font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
    src: url("../fonts/inter-latin-400-normal.da03732a27e1.woff2") format('woff2');
}
@font-face {
    font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
    src: url("../fonts/inter-latin-600-normal.2ede57db1a3a.woff2") format('woff2');
}
@font-face {
    font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
    src: url("../fonts/inter-latin-700-normal.8ca0a5155296.woff2") format('woff2');
}
@font-face {
    font-family: 'Inter'; font-style: normal; font-weight: 800; font-display: swap;
    src: url("../fonts/inter-latin-800-normal.900ae45e40b8.woff2") format('woff2');
}

:root {
    --fondo: #f3f4f6; --texto: #111827; --oscuro: #111827; --gris: #6b7280; --borde: #e5e7eb;
    --acento: #2563eb; --acento-oscuro: #1d4ed8; --acento-claro: #eff6ff;
}
* { box-sizing: border-box; }
body { margin: 0; font-family: 'Inter', Arial, sans-serif; background: var(--fondo); color: var(--texto); }

/* Cabecera + menú: un único bloque sticky en escritorio. */
.barra-superior { position: sticky; top: 0; z-index: 5; }
header { background: var(--oscuro); color: #fff; padding: 18px 16px; }
header .marca { display: flex; align-items: center; justify-content: space-between; gap: 10px; max-width: 1000px; margin: 0 auto; }
header h1 { margin: 0; font-size: 21px; }
header small { opacity: .75; }
.boton-salir { font-size: 13px; padding: 7px 12px; display: inline-flex; align-items: center; gap: 6px; }
.boton-salir .icono { display: none; }

.icono { width: 24px; height: 24px; flex-shrink: 0; vertical-align: middle; }
.texto-corto { display: none; }

nav.nav-principal { overflow: auto; padding: 8px; background: #fff; border-bottom: 1px solid #ddd; }
/* Envoltorio con `margin: 0 auto` para que los enlaces queden centrados cuando
   caben en el ancho disponible; si no caben, el margen automático se anula
   solo y `nav` permite hacer scroll horizontal. */
nav .nav-enlaces { display: flex; gap: 6px; width: max-content; margin: 0 auto; }
nav a { border: 0; background: #e5e7eb; padding: 10px 13px; border-radius: 10px; white-space: nowrap;
        font-weight: 600; font-size: 14px; color: var(--texto); text-decoration: none; }
nav a .icono { display: none; }
nav a.activa { background: var(--acento); color: #fff; }

/* Pestañas «Facturas | Presupuestos» sobre los dos listados. */
.pestanas { display: flex; gap: 6px; margin: 0 0 16px; }
.pestanas a { flex: 1; text-align: center; padding: 10px; border-radius: 10px; background: #e5e7eb;
              color: var(--texto); font-weight: 700; text-decoration: none; }
.pestanas a.activa { background: var(--acento); color: #fff; }

main { max-width: 1000px; margin: auto; padding: 16px; }

h1 { font-size: 22px; margin: 4px 0 16px; }
h2 { margin: 0 0 12px; font-size: 18px; }
h3 { margin: 0 0 8px; font-size: 15px; }
p.subtitulo { color: var(--gris); font-size: 14px; margin-top: -10px; }

.card { background: #fff; border-radius: 14px; padding: 18px; margin-bottom: 16px; box-shadow: 0 1px 4px rgba(0,0,0,.06); }

.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 640px) { .grid { grid-template-columns: 1fr; } }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

label { font-size: 13px; font-weight: 700; display: block; margin: 10px 0 4px; }
/* 16px como mínimo: iOS hace zoom automático al enfocar campos más pequeños. */
input, select, textarea {
    width: 100%; padding: 11px; border: 1px solid #d1d5db; border-radius: 9px;
    font-size: 16px; background: #fff; font-family: inherit;
}
input[type="checkbox"] { width: auto; }
.formulario p { margin: 0.4rem 0; }

button, .boton {
    border: 0; border-radius: 9px; padding: 10px 16px; font-weight: 700; font-size: 14px;
    cursor: pointer; font-family: inherit; text-decoration: none; display: inline-block;
    transition: background-color .15s ease, opacity .15s ease;
}
button, .boton, .boton-primario { background: var(--acento); color: #fff; }
button:hover, .boton:hover, .boton-primario:hover { background: var(--acento-oscuro); }
.boton-secundario { background: #e5e7eb; color: var(--texto); }
.boton-secundario:hover { background: #d1d5db; }
.boton-peligro { background: #fee2e2; color: #991b1b; }
.boton-peligro:hover { background: #fecaca; }
button:disabled, .boton[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* Estado de carga: se aplica con JS a botones que lanzan una petición async. */
button.cargando, .boton.cargando { opacity: .75; cursor: wait; position: relative; color: transparent !important; }
button.cargando::after, .boton.cargando::after {
    content: ""; position: absolute; top: 50%; left: 50%; width: 15px; height: 15px;
    margin: -8px 0 0 -8px; border-radius: 50%; border: 2px solid rgba(255,255,255,.5);
    border-top-color: #fff; animation: girar .6s linear infinite;
}
.boton-secundario.cargando::after { border-color: rgba(17,24,39,.25); border-top-color: var(--texto); }
@keyframes girar { to { transform: rotate(360deg); } }

table { width: 100%; border-collapse: collapse; }
th, td { padding: 9px 10px; border-bottom: 1px solid var(--borde); text-align: left; font-size: 14px; }
th { color: var(--gris); font-weight: 700; text-transform: uppercase; font-size: 11px; letter-spacing: .03em; }
tbody tr:nth-child(even) { background: #f9fafb; }
tbody tr:hover { background: var(--acento-claro); }
.tabla-wrap { overflow: auto; }
.right { text-align: right; }

.price-btn { width: 100%; border: 1px solid #d1d5db; background: #fff; border-radius: 8px; padding: 8px;
             font-weight: 700; cursor: pointer; color: var(--texto); }
.price-btn:hover { background: #f3f4f6; }
.price-btn.selected { background: var(--acento); color: #fff; border-color: var(--acento); }
.price-table-wrap { overflow: auto; }
.price-table-wrap table { min-width: 560px; }
.price-table-wrap tbody tr:hover { background: transparent; }

/* Chips de selección para las calculadoras (paso a paso, sin mostrar toda la tabla de precios). */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 4px; }
.chip {
    border: 1.5px solid #d1d5db; background: #fff; border-radius: 999px; padding: 9px 16px;
    font-weight: 700; font-size: 14px; cursor: pointer; color: var(--texto); font-family: inherit;
}
.chip:hover { border-color: var(--acento); }
.chip.selected { background: var(--acento); border-color: var(--acento); color: #fff; }
.chip:disabled { opacity: .35; cursor: not-allowed; }
.chip:disabled:hover { border-color: #d1d5db; }
/* Sin precio de tabla pero seleccionable (hace falta precio manual):
   distinto de :disabled a propósito, para que siga siendo pulsable. */
.chip-sin-precio { border-style: dashed; color: var(--gris); }
.paso { margin-bottom: 16px; }
.paso-titulo { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 14px; margin-bottom: 2px; }
.paso-numero {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 20px; height: 20px;
    border-radius: 50%; background: var(--acento); color: #fff; font-size: 12px;
}
.precio-preview {
    display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 14px;
    padding: 12px 14px; background: var(--acento-claro); border: 1px solid #bfdbfe; border-radius: 10px;
}
.precio-preview .total { font-size: 22px; }
details.tabla-avanzada { margin-top: 14px; }
details.tabla-avanzada > summary {
    cursor: pointer; font-weight: 700; font-size: 13px; color: var(--gris); list-style: none;
}
details.tabla-avanzada > summary::-webkit-details-marker { display: none; }
details.tabla-avanzada > summary::before { content: "▸ "; }
details.tabla-avanzada[open] > summary::before { content: "▾ "; }
details.tabla-avanzada > .price-table-wrap { margin-top: 10px; }

/* Diagrama interactivo del coche (calculadora PDR). Las zonas se dibujan con
   JS en porcentajes sobre la imagen, así que el `style` en línea de cada
   hotspot solo lleva su posición: el resto del aspecto vive aquí. */
.diagrama { max-width: 420px; margin: 0 auto; }
.diagrama-lienzo { position: relative; }
.diagrama-lienzo img { width: 100%; display: block; border-radius: 10px; }
.diagrama-hotspots { position: absolute; inset: 0; }
.diagrama-pie { text-align: center; }
.hotspot {
    position: absolute; border: 2px solid var(--oscuro); border-radius: 8px;
    cursor: pointer; font-weight: bold; background: rgba(255,255,255,.35);
}
.hotspot.activa { background: rgba(17,24,39,.55); color: #fff; }

/* Casillas y selectores en línea de las calculadoras (urgencia,
   desplazamiento, IVA): etiqueta y control en la misma fila. */
.opcion-en-linea { margin: 0; display: flex; align-items: center; gap: 6px; font-weight: 600; }
.opcion-en-linea input[type="checkbox"], .opcion-en-linea select, select.ancho-auto { width: auto; }
.fila-opciones { margin-top: 14px; }

/* Precio manual de una combinación sin precio de tabla. */
.precio-manual { margin-bottom: 0; }
.precio-manual label { margin-top: 0; }
.precio-manual input { max-width: 160px; }
.linea-acciones { margin: 10px 0 0; }
/* Varias líneas (impactos + diámetro) dentro de una misma zona: la primera
   pegada al título y las siguientes separadas entre sí. */
#zona-lineas .selection-box { margin-top: 0; }
#zona-lineas .selection-box + .selection-box { margin-top: 14px; }
.fila-entre { justify-content: space-between; }

/* Selector de cliente con su filtro y el botón «+ Nuevo». */
.filtro-clientes { margin-bottom: 6px; }
.selector-cliente { flex-wrap: nowrap; }
.selector-cliente button { white-space: nowrap; }

/* Fotos de la factura (miniatura + botón de borrar). El botón mantiene los
   44px de alto mínimo recomendados para pulsar con el dedo. */
.foto-item { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.foto-item img { max-width: 130px; border-radius: 8px; }
.foto-item .btn-borrar-foto { font-size: 13px; padding: 4px 12px; min-height: 44px; }

/* Subida de fotos: los `input[type=file]` van ocultos a la vista (pero no para
   el teclado ni el lector de pantalla) y quien hace de botón es su `label`. */
.subida-fotos { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.subida-fotos label { display: inline-flex; align-items: center; gap: 7px; margin: 0; min-height: 44px; }
.subida-fotos .icono { width: 18px; height: 18px; }
.input-fichero {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.input-fichero:focus-visible + label { outline: 2px solid var(--acento); outline-offset: 2px; }
.input-fichero:disabled + label { opacity: .5; cursor: not-allowed; pointer-events: none; }
.estado-subida { color: var(--gris); font-size: 13px; }
/* Hacer la foto en el momento solo tiene sentido con cámara a mano, así que el
   botón aparece únicamente en pantallas táctiles (móvil y tablet). */
.opcion-camara { display: none; }
@media (pointer: coarse) { .opcion-camara { display: inline-flex; } }

/* Desglose de base, IVA y total en el detalle del documento. */
.tabla-totales { margin-top: 12px; }

/* Anchos de los filtros de los listados y del formulario de exportación. */
.filtro-estrecho { max-width: 260px; }
.filtro-muy-estrecho { max-width: 110px; }
.filtro-ancho { flex: 1; min-width: 200px; }
.etiqueta-en-linea { margin: 0; }
.sin-margen { margin: 0; }
.margen-arriba { margin-top: 10px; }
.margen-arriba-grande { margin-top: 14px; }
.oculto { display: none; }

.list { display: grid; gap: 8px; }
.item { border: 1px solid var(--borde); border-radius: 10px; padding: 11px; }
.item strong { display: block; margin-bottom: 3px; }
.item-precio { display: grid; grid-template-columns: 1fr 90px auto; align-items: center; gap: 10px; }
.item-precio .precio { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Zonas de la calculadora: los botones no se parten en dos filas. */
.item-zona .acciones-zona { flex-wrap: nowrap; }
.item-zona .acciones-zona button { white-space: nowrap; }
/* En móvil no caben nombre, importe y botones en la misma línea: el importe se
   queda a la derecha junto al nombre (así todos los importes quedan alineados
   contra el mismo borde) y los botones bajan a su propia fila, también a la
   derecha. */
@media (max-width: 640px) {
    .item-zona { grid-template-columns: 1fr auto; row-gap: 10px; }
    .item-zona strong { margin-bottom: 0; }
    .item-zona .acciones-zona { grid-column: 1 / -1; justify-content: flex-end; }
}

.desglose-iva { width: 100%; }
.desglose-iva td { padding: 2px 0; border: 0; }
.desglose-iva .total td { font-size: 24px; }
.selection-box { margin-top: 12px; padding: 14px; border: 1px solid var(--borde); border-radius: 10px; background: #f9fafb; }
.stat { font-size: 25px; font-weight: 800; }

.badge { display: inline-block; border-radius: 999px; padding: 4px 10px; font-size: 12px; font-weight: 700; }
.badge-pagada, .badge-aceptado { background: #dcfce7; color: #166534; }
.badge-pendiente { background: #fef3c7; color: #92400e; }
.badge-rechazado { background: #fee2e2; color: #991b1b; }
.badge-convertido { background: #dbeafe; color: #1e40af; }

.total { font-size: 28px; font-weight: 800; }
.muted { color: var(--gris); font-size: 13px; }
.acciones { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.acciones a, .acciones button { margin: 0; display: inline-flex; align-items: center; gap: 7px; }
/* Dentro de un botón el icono acompaña al texto, así que va más pequeño que
   los 24px del menú. */
.acciones .icono { width: 18px; height: 18px; }
/* Enlace que hace de botón pero no lleva a ninguna parte (p. ej. WhatsApp sin
   teléfono): se ve apagado y no se puede pulsar ni tabular hasta él. */
.enlace-desactivado { pointer-events: none; opacity: .5; }

.errorlist { color: #b00020; list-style: none; padding: 0; margin: 4px 0 0; font-size: 13px; }

/* Etiqueta accesible para lectores de pantalla sin ocupar espacio visual
   (buscadores con placeholder en vez de <label> visible). */
.visualmente-oculto {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.paginacion { display: flex; gap: 12px; align-items: center; justify-content: center; margin-top: 12px; }

#toasts {
    position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 50;
    display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none;
}
/* `pointer-events: none` (como el contenedor): un aviso no se pulsa, y si
   capturase el toque, arrastrar el dedo sobre él no desplazaría la página (los
   elementos fijos cuelgan del viewport, no del `.lienzo` que hace scroll en
   móvil, ver «Cáscara de app»). */
.toast {
    pointer-events: none; max-width: 420px; width: 100%; background: var(--oscuro); color: #fff;
    padding: 12px 16px; border-radius: 10px; font-size: 14px; font-weight: 600;
    box-shadow: 0 4px 14px rgba(0,0,0,.2); animation: toast-entrada .2s ease;
}
.toast-exito { background: #166534; }
.toast-error { background: #991b1b; }
@keyframes toast-entrada { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Pantalla de login: única página sin header/nav, con la tarjeta centrada. */
body.pagina-login {
    min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 16px;
}
body.pagina-login .card { width: 100%; max-width: 360px; padding: 28px; }
body.pagina-login h1 { margin: 0 0 4px; }
body.pagina-login p.subtitulo { margin: 0 0 20px; }
body.pagina-login button { width: 100%; margin-top: 20px; padding: 11px 16px; font-size: 15px; }
.no-field-errors { margin: 0 0 12px; }

/* Diálogos modales (<dialog>): p. ej. pedir el cliente al convertir un presupuesto. */
dialog.dialogo {
    width: min(480px, calc(100vw - 32px)); border: 0; border-radius: 14px;
    padding: 20px; box-shadow: 0 20px 50px rgba(0, 0, 0, .25);
}
dialog.dialogo::backdrop { background: rgba(17, 24, 39, .5); }
dialog.dialogo h2 { margin-top: 0; }

a.item { color: inherit; text-decoration: none; }
a.item:hover { border-color: var(--acento); }
.error-campo { display: block; color: #b91c1c; font-size: 13px; margin-top: 4px; }
.error-campo:empty { display: none; }

/* Listados: tarjetas en móvil, tabla en escritorio. */
.lista-tarjetas { display: none; list-style: none; margin: 0; padding: 0; }
.lista-tarjetas > li { margin-bottom: 8px; }
.tarjeta { display: block; border: 1px solid var(--borde); border-radius: 10px; padding: 12px;
           color: inherit; text-decoration: none; }
a.tarjeta:hover { border-color: var(--acento); }
.tarjeta-fila { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin: 2px 0; }
@media (max-width: 640px) {
    .lista-tarjetas { display: block; }
    .solo-tabla { display: none; }
}

/* Barra de la calculadora: solo en móvil (ver capas en el bloque móvil). */
.barra-calculadora { display: none; }
@media (max-width: 640px) {
    .barra-calculadora:not([hidden]) {
        display: flex; align-items: center; justify-content: space-between; gap: 12px;
        position: fixed; left: 0; right: 0; z-index: 21;
        bottom: var(--alto-nav-movil);
        height: var(--alto-barra-calculadora); padding: 0 16px;
        background: #fff; border-top: 1px solid var(--borde); box-shadow: 0 -2px 10px rgba(0,0,0,.06);
    }
    .barra-calculadora strong { display: block; font-size: 20px; }
}

/* La barra inferior mide exactamente `--alto-nav-movil`: no se le suma
   `env(safe-area-inset-bottom)` porque eso dejaba una franja blanca vacía
   bajo los iconos (en un móvil con navegación por gestos el sistema ya dibuja
   encima su propia barrita, no hace falta reservarle sitio). */
/* Al final a propósito: debe ganar en la cascada a `main` y `#toasts`. */
/* Móvil: cabecera compacta no fija y menú como barra inferior fija.
   Capas de los elementos fijos: navegación 20, barra de la calculadora 21
   (justo encima de la navegación), toasts 50 (encima de ambas). */
:root { --alto-nav-movil: 60px; --alto-barra-calculadora: 64px; }
@media (max-width: 640px) {
    /* Cáscara de app: el documento en sí no se desplaza; quien hace scroll es
       `.lienzo` (cabecera + contenido). Con el scroll en un contenedor
       interno el navegador móvil deja de esconder y volver a enseñar su barra
       de direcciones, que era lo que movía arriba y abajo la barra inferior
       fija al hacer scroll; y como no hay scroll (ni rebote) de documento,
       arrastrar sobre la barra tampoco la desplaza ya hacia los lados.
       `100vh` primero como reserva para navegadores sin `dvh`. */
    body:not(.pagina-login) {
        height: 100vh; height: 100dvh;
        display: flex; flex-direction: column; overflow: hidden;
        overscroll-behavior: none;
    }
    .lienzo {
        flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
        overscroll-behavior-y: contain; -webkit-overflow-scrolling: touch;
    }
    /* Un arrastre que empiece sobre la barra inferior no debe mover nada. */
    nav.nav-principal { touch-action: none; }

    .barra-superior { position: static; }
    header { padding: 10px 16px; }
    header h1 { font-size: 18px; }
    header small { display: none; }
    .boton-salir { padding: 8px; background: transparent; color: #fff; }
    .boton-salir:hover { background: rgba(255,255,255,.12); }
    .boton-salir .icono { display: block; }
    .boton-salir .texto-largo { display: none; }

    nav.nav-principal {
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
        height: var(--alto-nav-movil);
        padding: 0; border-top: 1px solid #ddd; border-bottom: 0;
        overflow: visible; box-shadow: 0 -2px 10px rgba(0,0,0,.06);
    }
    nav .nav-enlaces { width: 100%; height: var(--alto-nav-movil); gap: 0; }
    /* `flex: 1 1 auto` y no `flex: 1`: con seis pestañas, repartir el ancho a
       partes iguales deja ~58px por pestaña en una pantalla de 360px y
       «Documentos» necesita 66px, así que se partía en dos líneas y rompía el
       alto fijo de la barra. Así cada pestaña parte de su texto y solo se
       reparte el sobrante: las etiquetas suman ~260px y caben hasta en 320px. */
    nav a {
        flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
        gap: 2px; padding: 4px 2px; border-radius: 0; background: transparent; font-size: 11px; color: var(--gris);
        white-space: nowrap;
    }
    nav a .icono { display: block; }
    nav a.activa, nav a.activa-movil { background: transparent; color: var(--acento); }
    nav a .texto-largo, nav a.solo-escritorio { display: none; }
    nav a .texto-corto { display: inline; }

    main { padding-bottom: calc(var(--alto-nav-movil) + 16px); }
    body.con-barra-calculadora main {
        padding-bottom: calc(var(--alto-nav-movil) + var(--alto-barra-calculadora) + 16px);
    }
    #toasts { bottom: calc(var(--alto-nav-movil) + 12px); }
    body.con-barra-calculadora #toasts {
        bottom: calc(var(--alto-nav-movil) + var(--alto-barra-calculadora) + 12px);
    }
}
