/* ==========================================================================
   GestioERP Ventas — hoja de estilo de la app externa.

   Es una app fuera del ERP, con su propio diseño: por eso no carga Bootstrap.
   Los colores salen de las variables del tema (--ge-1/2/3) cuando la
   instalación las define, y si no de los valores por defecto de GestioERP.

   Móvil primero. A partir de 768 px el menú inferior se cambia por el
   superior y el contenido se centra en una columna de 1180 px.
   ========================================================================== */

:root {
    --g: var(--ge-1, #0D9E80);
    --g-d: var(--ge-2, #0B6B58);
    --g-dd: color-mix(in srgb, var(--g-d) 78%, #000);
    --g-l: var(--ge-3, #6FD9BE);
    --wash: color-mix(in srgb, var(--g) 12%, #fff);

    /* El color de los botones se elige aparte en «Mi cuenta»: si no se
       toca, es el mismo verde oscuro de la barra. */
    --btn: var(--ge-btn, var(--g-d));
    --btn-d: color-mix(in srgb, var(--btn) 78%, #000);

    /* ── El redondeo ───────────────────────────────────────────────────────
       Todos los radios de la hoja van multiplicados por este factor, así que
       el diseño entero se estira o se aprieta desde aquí. En «Clásico» vale 1
       y la app queda exactamente como estaba.

       Se lee de --ge-rr igual que los colores se leen de --ge-1/2/3: la
       plantilla define esa variable en un <style> que va ANTES de esta hoja,
       así que si aquí se pusiera «--rr: 1» a secas, esta línea ganaría por ser
       la última y no habría manera de cambiar el diseño. */
    --rr: var(--ge-rr, 1);

    --ink: #0E1A17;
    --ink-2: #3C4F49;
    --mut: #7A8D86;
    --line: #E2EBE7;
    --surf: #fff;
    --canvas: #F4F7F5;

    /* Semánticos: separados de la marca para que el estado se lea de un vistazo. */
    --amber: #C77700;
    --amber-w: #FDF4E4;
    --red: #B3402F;
    --red-w: #FBEDEA;
    --slate: #5A7180;
    --slate-w: #EEF2F4;
    --brass: #8A5E10;
    --brass-w: #FBF1DE;
}

* { box-sizing: border-box; }

body.av {
    margin: 0;
    background: var(--canvas);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 14px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
    padding-bottom: 86px;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; }
.num, .amt, .money { font-variant-numeric: tabular-nums; }
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 12px; letter-spacing: -.02em; }
.ocultar-movil { display: none; }
.solo-movil { display: block; }
.wsalir, .wayuda { display: none; }
:focus-visible { outline: 3px solid color-mix(in srgb, var(--g) 45%, transparent); outline-offset: 2px; }

/* ── Logo ─────────────────────────────────────────────────────────────── */
.logo { display: flex; align-items: center; gap: 9px; justify-content: center; }
.logomark {
    width: 44px; height: 44px; border-radius: calc(14px * var(--rr)); display: grid; place-items: center; flex: none;
    /* Del acento al mismo acento apagado, no al color de la barra: con una
        paleta de mucho contraste —barra negra, acento naranja— mezclar los dos
        daba un marrón que no era de nadie. */
    background: linear-gradient(155deg, var(--g), color-mix(in srgb, var(--g) 65%, #000));
}
.logomark.sm { width: 30px; height: 30px; border-radius: calc(9px * var(--rr)); background: rgba(255, 255, 255, .16); }
.logotxt { font-weight: 800; letter-spacing: -.03em; font-size: 20px; line-height: 1; color: #fff; }
.logotxt span {
    display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
    color: var(--g-l); text-transform: uppercase; margin-top: 3px;
}

/* ── Acceso ───────────────────────────────────────────────────────────── */
.av-login {
    min-height: 100vh; background: linear-gradient(168deg, var(--g-d), var(--g-dd));
    display: flex; align-items: center; justify-content: center; padding: 24px 20px;
}
/* El ancho máximo tiene que contar el padding del contenedor: con grid y
   max-width fijo, en un móvil de 390 px la tarjeta se salía por la derecha. */
.av-login-box { width: 100%; max-width: 360px; margin: 0 auto; }
.av-login-box .logo { margin-bottom: 6px; }
/* Logo oficial de GestioERP: grande y centrado sobre el verde. */
.av-login-logo { display: block; width: 100%; max-width: 264px; height: auto; margin: 0 auto 10px; }
.av-login-sub { text-align: center; color: var(--g-l); font-size: 13px; margin: 8px 0 22px; }
.av-login-pie { text-align: center; color: color-mix(in srgb, var(--g-l) 80%, #fff); font-size: 12px; margin-top: 18px; }
.av-login .card { border: none; border-radius: calc(20px * var(--rr)); }

/* ── Cabecera de sección (verde en móvil, limpia en web) ───────────────── */
.top { background: linear-gradient(168deg, var(--g-d), var(--g-dd)); color: #fff; padding: 14px 16px 16px; }
.top .line1 { display: flex; align-items: center; gap: 12px; min-height: 38px; }
.top h1 { font-size: 20px; font-weight: 700; letter-spacing: -.02em; margin: 0; flex: 1; line-height: 1.2; }
/* El nombre del cliente y la fecha, debajo del número del documento. A 12,5 px
   sobre el fondo oscuro casi no se leía, y es de lo primero que se mira. */
.top .sub { font-size: 14px; color: color-mix(in srgb, var(--g-l) 92%, #fff); margin-top: 3px; }
.top .grande { font-size: 30px; font-weight: 800; letter-spacing: -.035em; line-height: 1.1; }
.top .etiqueta { font-size: 11px; letter-spacing: .12em; font-weight: 700; color: var(--g-l); }

.icobtn {
    /* 40 px: a 34 no se veian y en el movil no se acertaba con el dedo. */
    width: 40px; height: 40px; border-radius: calc(12px * var(--rr)); background: rgba(255, 255, 255, .16);
    display: grid; place-items: center; color: #fff; flex: none; border: none; cursor: pointer;
    position: relative;
}
.icobtn:hover { background: rgba(255, 255, 255, .28); }
.icobtn svg { width: 20px; height: 20px; }
.icobtn.plain { background: none; width: 32px; }
.icobtn.plain:hover { background: rgba(255, 255, 255, .14); }

/* ── Lo que hace el botón, al pasar por encima ─────────────────────────────
   Un icono solo no dice nada, y el aviso del navegador tarda un segundo largo
   en salir. Este sale al momento y con la letra de la app. Se pinta con el
   propio `title`, así que no hay que escribir el texto dos veces.
   ------------------------------------------------------------------------ */
@media (hover: hover) {
    .icobtn[title]:hover::after {
        content: attr(title);
        position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
        z-index: 80; padding: 5px 9px; border-radius: calc(8px * var(--rr));
        background: var(--ink); color: #fff; font-size: 11.5px; font-weight: 600;
        white-space: nowrap; pointer-events: none;
        box-shadow: 0 8px 20px -8px rgba(9, 46, 38, .5);
    }
    /* Pegado al borde derecho, el aviso se saldría de la pantalla. */
    .top .line1 > .icobtn:last-child[title]:hover::after { left: auto; right: 0; transform: none; }
}
.avat {
    width: 34px; height: 34px; border-radius: 50%; background: var(--g-l); color: var(--g-dd);
    display: grid; place-items: center; font-weight: 700; font-size: 13px; flex: none;
}

.searchbar {
    margin-top: 12px; height: 40px; background: rgba(255, 255, 255, .16); border-radius: calc(12px * var(--rr));
    display: flex; align-items: center; gap: 9px; padding: 0 12px;
}
.searchbar input {
    flex: 1; background: none; border: none; color: #fff; font-size: 14px; min-width: 0;
}
.searchbar input::placeholder { color: color-mix(in srgb, var(--g-l) 90%, #fff); }
.searchbar svg { color: color-mix(in srgb, var(--g-l) 90%, #fff); flex: none; }

/* ── Contenido ────────────────────────────────────────────────────────── */
.contenido {
    padding: 14px; display: flex; flex-direction: column; gap: 12px;
    max-width: 1180px; margin: 0 auto;
}
.sec-t {
    font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--mut);
    font-weight: 700; margin: 2px 0 -4px;
}
.av-avisos { max-width: 1180px; margin: 0 auto; padding: 12px 14px 0; }
.aviso { border-radius: calc(12px * var(--rr)); padding: 11px 14px; font-size: 13.5px; font-weight: 600; }
/* Un aviso dentro de la botonera ocupa la fila entera. Como una celda más se
   quedaba en una columna de 118 px, con «Lo hizo el cliente desde el portal»
   partido en tres renglones al lado de los botones. */
.grid3 > .aviso, .grid4 > .aviso { grid-column: 1 / -1; }

/* Una tabla de verdad, para lo que de verdad es una tabla: las primeras filas
   de un fichero que se va a importar, con las columnas que traiga. Va dentro de
   un contenedor con scroll propio, que la página no se mueve de lado. */
.tabla-min { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tabla-min th, .tabla-min td {
    padding: 7px 10px; text-align: left; white-space: nowrap;
    border-bottom: 1px solid var(--line);
}
.tabla-min th { font-weight: 700; color: var(--ink-2); background: var(--wash); }
.tabla-min td { color: var(--ink); font-variant-numeric: tabular-nums; }
.tabla-min tr:last-child td { border-bottom: none; }
.aviso.bueno { background: var(--wash); color: var(--g-d); }
.aviso.malo { background: var(--red-w); color: var(--red); }
/* «Estoy en ello». Se queda puesto hasta que hay respuesta, y con los puntos
   moviendose, que un texto quieto tampoco dice que siga trabajando. */
.aviso.trabajando { background: var(--wash); color: var(--ink-2); }
.aviso.trabajando::after {
    content: ''; display: inline-block; width: 12px; height: 12px;
    margin-left: 8px; vertical-align: -1px;
    border: 2px solid var(--line); border-top-color: var(--g-d);
    border-radius: 50%; animation: av-gira-der 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .aviso.trabajando::after { animation: none; }
}

.card { background: var(--surf); border: 1px solid var(--line); border-radius: calc(16px * var(--rr)); box-shadow: 0 1px 2px rgba(14, 26, 23, .04); }
/* Sirve suelta y sobre .card: los formularios de dentro de un desplegable la
   llevan sin ser tarjeta, y sin esto salían pegados a los bordes en el móvil. */
.pad { padding: 14px; }
.vacio { padding: 28px 14px; text-align: center; color: var(--mut); font-size: 13.5px; }

/* ── Indicadores ──────────────────────────────────────────────────────── */
.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Una columna de bloques, separados igual que lo están en el contenido: un
   div suelto no hereda el hueco de su abuelo, así que sin esto las tarjetas de
   dentro se pegan unas a otras. */
.pila { display: flex; flex-direction: column; gap: 12px; }

.kpi { background: var(--surf); border: 1px solid var(--line); border-radius: calc(16px * var(--rr)); padding: 13px 14px; }
.kpi .lab { font-size: 11.5px; color: var(--mut); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.kpi .val { font-size: 22px; font-weight: 750; letter-spacing: -.03em; margin-top: 5px; font-variant-numeric: tabular-nums; }
.kpi .foot { font-size: 11.5px; margin-top: 3px; font-weight: 600; color: var(--mut); }
.kpi.hi {
    background: linear-gradient(160deg, var(--g), color-mix(in srgb, var(--g) 65%, #000));
    border-color: transparent; color: #fff;
}
.kpi.hi .lab, .kpi.hi .foot { color: color-mix(in srgb, var(--g-l) 85%, #fff); }
/* La flecha del recuadro que lleva a alguna parte: pequeña, al lado del
   rótulo, para que se vea que se puede pulsar sin gritarlo. */
.kpi .lab { display: flex; align-items: center; gap: 5px; }
.kpi-chev { display: inline-flex; opacity: .75; }
a.kpi.hi:hover { filter: brightness(1.06); }

.kpi .val.amber { color: var(--amber); }
.kpi .val.red { color: var(--red); }
.kpi .foot.red { color: var(--red); }

/* ── Filas de lista ───────────────────────────────────────────────────── */
.rows { display: flex; flex-direction: column; }
.row {
    display: flex; align-items: center; gap: 12px; padding: 12px 14px;
    border-bottom: 1px solid var(--line); color: inherit;
}
.row:last-child { border-bottom: none; }
.row:hover { background: color-mix(in srgb, var(--wash) 45%, #fff); }
.row .grow { flex: 1; min-width: 0; overflow: hidden; }
.row .t { display: block; font-weight: 650; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .s { display: block; font-size: 12.5px; color: var(--mut); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .amt { text-align: right; font-weight: 700; letter-spacing: -.02em; flex: none; white-space: nowrap; }
.row .amt .u { font-size: 11.5px; color: var(--mut); font-weight: 600; display: block; margin-top: 2px; }
.row .amt.amber { color: var(--amber); }
.row .amt.red { color: var(--red); }
.chev { color: #B9C7C1; flex: none; }

.sq {
    width: 42px; height: 42px; border-radius: calc(13px * var(--rr)); background: var(--wash); color: var(--g-d);
    display: grid; place-items: center; font-weight: 700; font-size: 13px; flex: none;
}
.sq.doc { background: var(--slate-w); color: var(--slate); }
.sq.amber { background: var(--amber-w); color: var(--amber); }
.sq.red { background: var(--red-w); color: var(--red); }

/* ── Estados ──────────────────────────────────────────────────────────── */
.pill {
    display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700;
    padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.pill.ok { background: var(--wash); color: var(--g-d); }
.pill.warn { background: var(--amber-w); color: var(--amber); }
.pill.bad { background: var(--red-w); color: var(--red); }
.pill.draft { background: var(--slate-w); color: var(--slate); }
.pill.brass { background: var(--brass-w); color: var(--brass); }

/* ── Chips y segmentos ────────────────────────────────────────────────── */
.chiprow { display: flex; gap: 7px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.chiprow::-webkit-scrollbar { display: none; }
.chip {
    border: 1px solid var(--line); background: var(--surf); color: var(--ink-2); border-radius: 999px;
    padding: 7px 13px; font-size: 12.5px; font-weight: 650; white-space: nowrap; cursor: pointer;
}
.chip.on { background: var(--g-d); border-color: var(--g-d); color: #fff; }

.seg { display: flex; background: rgba(255, 255, 255, .16); border-radius: calc(12px * var(--rr)); padding: 3px; gap: 2px; margin-top: 12px; }
.seg a { flex: 1; text-align: center; font-size: 12.5px; font-weight: 650; padding: 7px 4px; border-radius: calc(9px * var(--rr)); color: #fff; }
.seg a.on { background: #fff; color: var(--g-d); }

/* ── Pestañas de la ficha ─────────────────────────────────────────────── */
.tabs {
    display: flex; gap: 18px; overflow-x: auto; border-bottom: 1px solid var(--line);
    padding: 0 14px; background: none; scrollbar-width: none;
    /* Un poco de aire arriba: pegada a los botones parecía parte de ellos. */
    margin-top: 4px;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
    padding: 11px 0; font-size: 13px; font-weight: 650; color: var(--mut); white-space: nowrap;
    border-bottom: 2.5px solid transparent;
}
.tabs a.on { color: var(--g-d); border-bottom-color: var(--g); }

/* Pestañas dentro de la cabecera oscura: el color de la activa es var(--g-d),
   que ES el fondo de la cabecera, así que el rótulo desaparecía. Sobre oscuro
   van en blanco; en el escritorio la cabecera es clara y mandan las de arriba. */
.top .tabs { border-bottom-color: rgba(255, 255, 255, .22); }
.top .tabs a { color: color-mix(in srgb, var(--g-l) 88%, #fff); }
.top .tabs a.on { color: #fff; }

/* ── Botones ──────────────────────────────────────────────────────────── */
.btn {
    display: flex; align-items: center; justify-content: center; gap: 8px; height: 48px; width: 100%;
    border-radius: calc(14px * var(--rr)); font-weight: 700; font-size: 15px; letter-spacing: -.01em;
    border: none; cursor: pointer; text-align: center;
}
.btn.pri { background: var(--btn); color: #fff; box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--btn) 70%, transparent); }
.btn.pri:hover { background: var(--btn-d); }
.btn.sec { background: var(--surf); color: var(--btn); border: 1.5px solid var(--g); }
.btn.brassy { background: var(--brass-w); color: var(--brass); border: 1.5px solid #E9CE96; }
.btn.peligro { background: var(--red-w); color: var(--red); }

/* Los botones de apoyo con color propio (Compras del cliente, Productos
   vivos, Mover lineas...) NO se pintan aqui: cada negocio elige su tono en
   Ajustes > Configuracion y el CSS lo escribe Lib/AvColoresBotones, que es
   quien sabe cual esta puesto. Aqui solo se les deja sitio. */
.btn.sm { height: 38px; font-size: 13.5px; border-radius: calc(11px * var(--rr)); padding: 0 14px; width: auto; }
.btn-fila { display: grid; grid-template-columns: 1fr 1.3fr; gap: 9px; }

/* ── Presentar a la Agencia ────────────────────────────────────────────────
   Los dos pasos de una declaración, debajo de su fila. Van en columna y no en
   la rejilla de botones de siempre porque el de presentar lleva encima su
   casilla de conformidad, y una casilla al lado de un botón se marca sin
   leerla.
   ------------------------------------------------------------------------ */
.aeat-pasos { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.aeat-pasos form { display: flex; flex-direction: column; gap: 7px; }
.aeat-pasos .btn { width: auto; }
.conforme {
    display: flex; align-items: flex-start; gap: 7px; cursor: pointer;
    font-size: 12.5px; color: var(--ink-2); max-width: 320px; line-height: 1.35;
}
.conforme input { margin: 2px 0 0; flex: none; }

/* ── Rejilla de acciones ──────────────────────────────────────────────── */
/* Cuatro por fila cuando caben, y se reparten solos si hay uno más (el de
   WhatsApp sale únicamente si el cliente tiene teléfono). */
.grid4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 9px; }

/* En el móvil, los cuatro accesos en UNA fila: con el mínimo de 84 px se caían
   a la línea de abajo y quedaba una tarjeta suelta. Aquí mandan las columnas,
   no el ancho de la tarjeta. */
@media (max-width: 639px) {
    .grid4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 7px; }
    .grid4 .act { padding: 10px 3px; font-size: 10.5px; border-radius: calc(13px * var(--rr)); }
    .grid4 .act .ic { width: 30px; height: 30px; border-radius: calc(10px * var(--rr)); margin-bottom: 5px; }
    .grid4 .act .ic svg { width: 16px; height: 16px; }
}

/* ── Lista + ficha, el patrón de toda la app ───────────────────────────────
   Una columna en el móvil, dos en cuanto hay sitio: la lista manda y la ficha
   de lo señalado se abre al lado, sin entrar y salir de pantallas.
   ------------------------------------------------------------------------ */
.av-2col { display: block; }
.col-ficha { display: none; }

@media (min-width: 1100px) {
    .av-2col { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 16px; align-items: start; }
    .col-ficha { display: block; position: sticky; top: 74px; }
    .col-ficha-caja { display: flex; flex-direction: column; gap: 10px; }
    .col-ficha .totes { border: 1px solid var(--line); border-radius: calc(16px * var(--rr)); }
    .col-ficha-botones { display: flex; flex-wrap: wrap; gap: 6px; }
    .col-ficha-botones .btn { width: auto; flex: 1 1 auto; min-width: 88px; }

    /* La foto del artículo, debajo de los botones y con todo el ancho de la
       columna. Fondo blanco y «contain»: las fotos de catálogo vienen con el
       producto recortado sobre blanco y encajarlas a la fuerza las deforma. */
    .art-foto {
        display: block; background: #fff; border: 1px solid var(--line);
        border-radius: calc(16px * var(--rr)); padding: 10px;
    }
    .art-foto img {
        display: block; width: 100%; aspect-ratio: 1; object-fit: contain; max-width: 100%;
    }
    .art-foto:hover { border-color: var(--g); }
    .av-2col .rows .row:hover { background: none; }
    .av-2col .rows .row.senalada { background: var(--wash); box-shadow: inset 3px 0 0 var(--g-d); }
}

/* Tres columnas cuando la pantalla da de sí: la ficha se parte en datos y
   líneas, y se ve el documento entero sin abrirlo. */
@media (min-width: 1600px) {
    .av-2col { grid-template-columns: minmax(0, 1fr) 360px; }
    .contenido.ancho .av-2col { grid-template-columns: minmax(0, 1fr) 380px; }
}

/* Subtítulo dentro de un apartado: más discreto que el título de sección,
   para separar bloques sin partir el apartado en dos. */
.sub-t {
    font-size: 12.5px; font-weight: 700; color: var(--ink-2);
    letter-spacing: -.01em; margin: 14px 2px 6px;
}

/* ── Lo que se marca ───────────────────────────────────────────────────────
   El color de selección se elige en Ajustes. El navegador pinta de azul por
   su cuenta el texto seleccionado y la opción elegida de un desplegable, y en
   una app verde canta; aquí se le dice con qué color.
   ------------------------------------------------------------------------ */
::selection { background: color-mix(in srgb, var(--ge-sel, var(--g)) 30%, #fff); color: var(--ink); }

option:checked,
option:hover,
select option:checked {
    background: var(--ge-sel, var(--g));
    color: #fff;
}

/* El recuadro del campo en el que estás, del mismo color. */
.input:focus-visible,
.searchbar input:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--ge-sel, var(--g)) 60%, transparent);
    outline-offset: 1px;
}

/* Esconder de verdad lo que lleva [hidden]: los botones de la app son flex y
   se comían el atributo. */
[hidden] { display: none !important; }

/* ── Guardado automático ───────────────────────────────────────────────────
   El cartelito que dice si lo escrito ya está a salvo. Discreto: solo se mira
   cuando uno duda de si se ha guardado.
   ------------------------------------------------------------------------ */
.av-guardado {
    font-size: 12px; font-weight: 650; color: var(--mut);
    min-height: 18px; margin-top: 10px; display: flex; align-items: center; gap: 6px;
}
.av-guardado::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: transparent; }
.av-guardado.guardando::before { background: var(--amber, #C98A1B); }
.av-guardado.guardado { color: var(--g-d); }
.av-guardado.guardado::before { background: var(--g); }
.av-guardado.error { color: var(--red); font-weight: 700; }
.av-guardado.error::before { background: var(--red); }

/* ── Embudo del CRM ────────────────────────────────────────────────────────
   Una columna por fase cuando hay sitio; apiladas en el móvil. Es el kanban de
   GestioERP con el diseño de la app.
   ------------------------------------------------------------------------ */
.embudo { display: grid; gap: 12px; }
.fase-cab { display: flex; align-items: baseline; gap: 8px; padding: 0 2px 6px; }
.fase-cab .t { font-weight: 700; letter-spacing: -.01em; }
.fase-cab .s { font-size: 11.5px; color: var(--mut); }
.fase-cab .amt { margin-left: auto; font-weight: 700; letter-spacing: -.02em; }

@media (min-width: 900px) {
    .embudo { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); align-items: start; }
}

/* ── Gráfico de ventas contra gastos ───────────────────────────────────────
   Doce meses, dos barras por mes y el resultado debajo en su color. Dibujado
   con cajas: sin biblioteca, que la app tiene que ir sin internet.
   ------------------------------------------------------------------------ */
.grafico { display: flex; align-items: flex-end; gap: 4px; }
.grafico .mes { flex: 1; min-width: 0; text-align: center; }
.grafico .barras {
    height: 120px; display: flex; align-items: flex-end; justify-content: center;
    gap: 2px; position: relative;
}
.grafico .barras span { width: 44%; border-radius: calc(4px * var(--rr)) calc(4px * var(--rr)) calc(2px * var(--rr)) calc(2px * var(--rr)); min-height: 2px; }
.grafico .ventas { background: linear-gradient(180deg, var(--g-l), var(--g)); }
.grafico .gastos { background: linear-gradient(180deg, #E7C795, var(--amber)); }
/* El año pasado va detrás, en gris, para comparar sin estorbar. */
.grafico .antes {
    position: absolute; left: 50%; transform: translateX(-100%);
    width: 44%; background: color-mix(in srgb, var(--slate) 22%, #fff); border-radius: calc(4px * var(--rr)) calc(4px * var(--rr)) calc(2px * var(--rr)) calc(2px * var(--rr));
}
.grafico .mes.ahora .barras { background: var(--wash); border-radius: calc(8px * var(--rr)); }
.grafico .res { font-size: 10.5px; font-weight: 700; margin-top: 4px; min-height: 14px; }
.grafico .lab { font-size: 10px; color: var(--mut); font-weight: 650; }

.leyenda { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; font-size: 11.5px; color: var(--mut); }
.leyenda span { display: inline-flex; align-items: center; gap: 5px; }
.leyenda i { width: 10px; height: 10px; border-radius: calc(3px * var(--rr)); display: inline-block; }
.leyenda .c-ventas { background: var(--g); }
.leyenda .c-gastos { background: var(--amber); }
.leyenda .c-antes { background: color-mix(in srgb, var(--slate) 22%, #fff); }
.leyenda .c-verde { background: var(--g-d); }
.leyenda .c-rojo { background: var(--red); }

/* Ganamos o perdemos: el color lo dice antes que el número. */
.verde { color: var(--g-d); }
.rojo { color: var(--red); }
.grande.verde { color: var(--g-d); }
.grande.rojo { color: var(--red); }

/* La barrita de peso de cada subcuenta en el desglose. */
.peso { display: block; height: 4px; border-radius: calc(3px * var(--rr)); background: var(--wash); margin-top: 6px; }
.peso i { display: block; height: 100%; border-radius: calc(3px * var(--rr)); background: var(--g); }
/* Lo que resta, en rojo: en el desglose del resultado se distingue de un vistazo. */
.peso.peso-rojo i { background: var(--red); }

.tabla a { color: inherit; text-decoration: underline; text-decoration-color: var(--line); }
.tabla a:hover { text-decoration-color: var(--g); }
.tabla .mes-on { color: var(--g-d); font-weight: 800; }
.tabla .anterior td { color: var(--mut); font-size: 11.5px; }
.tabla .anterior td:first-child { font-weight: 600; color: var(--mut); }
.tabla .diferencia td { font-weight: 700; border-top: 1px solid var(--line); }
/* La celda cuyo detalle se está viendo, marcada. */
.tabla .celda-on { background: var(--g-d); }
.tabla .celda-on a { color: #fff; font-weight: 700; text-decoration: none; }
.tabla td a { display: block; }
.tabla .verde { color: var(--g-d); }

/* ── Tabla de meses (balance de P y G) ─────────────────────────────────────
   Doce meses no caben en un móvil: la tabla se desliza de lado, con el
   concepto siempre a la vista.
   ------------------------------------------------------------------------ */
.tabla-desliza { overflow-x: auto; }
.tabla { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tabla th, .tabla td { padding: 8px 10px; white-space: nowrap; text-align: left; }
.tabla thead th {
    font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
    color: var(--mut); font-weight: 700; border-bottom: 1px solid var(--line);
}
.tabla tbody tr + tr td { border-top: 1px solid var(--line); }
.tabla .num { text-align: right; font-variant-numeric: tabular-nums; }
.tabla .ahora { background: var(--wash); }
.tabla .total { font-weight: 700; background: var(--wash); }
.tabla .rojo { color: var(--red); }
.tabla .resultado td { font-weight: 700; }
.tabla th:first-child, .tabla td:first-child {
    position: sticky; left: 0; background: var(--surf); font-weight: 650;
}
.tabla .resultado td:first-child { background: var(--surf); }

/* Un mes en negativo se ve de otro color en las barras del inicio. */
.bars div.malo { background: linear-gradient(180deg, #E9A8A8, var(--red)); }

/* ── Ayuda dentro de la app ────────────────────────────────────────────────
   Bloques que se abren y se cierran: se lee solo lo que hace falta.
   ------------------------------------------------------------------------ */
.ayuda-t {
    display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer;
    list-style: none; font-weight: 650; letter-spacing: -.01em;
}
.ayuda-t::-webkit-details-marker { display: none; }
.ayuda-t::after { content: '+'; margin-left: auto; color: var(--mut); font-size: 17px; line-height: 1; }
details[open] > .ayuda-t::after { content: '−'; }
.ayuda-c { padding: 0 14px 14px; font-size: 13.5px; color: var(--ink-2); line-height: 1.55; }
.ayuda-c p { margin: 0 0 9px; }
.ayuda-c ul { margin: 0; padding-left: 18px; }
.ayuda-c li { margin-bottom: 6px; }

/* ── El manual: un artículo ───────────────────────────────────────────────
   Un artículo se lee de arriba abajo: el dibujo, de qué va, y el texto. Con
   línea larga —unos setenta caracteres— porque esto se lee, no se ojea.
   ------------------------------------------------------------------------ */
.ayuda-art { font-size: 14px; color: var(--ink-2); line-height: 1.6; }
/* 62ch se quedaba corto: con la columna de al lado ya no sobra media
   pantalla, y 76 caracteres se siguen leyendo de un tiron. */
.ayuda-art p { margin: 0 0 11px; max-width: 76ch; }
.ayuda-art p:last-child { margin-bottom: 0; }
.ayuda-dice {
    font-size: 15px; font-weight: 650; color: var(--ink); letter-spacing: -.01em;
    margin-bottom: 14px !important;
}
.ayuda-nota {
    display: flex; gap: 9px; align-items: flex-start;
    background: var(--amber-w); color: var(--amber-d, var(--ink)); border-radius: calc(12px * var(--rr));
    padding: 11px 13px; font-size: 13.5px;
}
.ayuda-nota svg { flex: none; margin-top: 2px; }
.ayuda-teclas { margin: 0 0 11px; padding-left: 18px; max-width: 76ch; }
.ayuda-teclas li { margin-bottom: 7px; }
.ayuda-teclas b { color: var(--ink); }

/* Lo anterior y lo siguiente, uno a cada lado. */
/* Configuracion a dos columnas cuando hay sitio. Son ocho tarjetas seguidas:
   en un monitor se quedaba media pantalla en blanco y los colores caian tan
   abajo que habia que buscarlos. A la izquierda lo que se monta una vez, a la
   derecha como se ve. */
.cfg-2col { display: block; }
.cfg-2col > div > .sec-t:first-child { margin-top: 0; }

@media (min-width: 1100px) {
    .cfg-2col {
        display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 18px; align-items: start;
    }
}

/* Los cuadros comparados de la ayuda -los tres proveedores de correo, uno al
   lado de otro-. En fila india eran tres pantallas de movil de bajar y en el
   ordenador dejaban media pantalla en blanco; asi se comparan de un vistazo,
   que es justo para lo que se miran. */
.ayuda-cuadros {
    display: grid; gap: 10px; margin: 0 0 13px;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.ayuda-cuadro {
    border: 1px solid var(--line); border-radius: 10px; padding: 11px 12px;
    background: var(--wash);
}
.ayuda-cuadro > .t {
    font-weight: 700; color: var(--ink); font-size: 13.5px; margin-bottom: 7px;
}
.ayuda-cuadro > .s {
    display: block; margin-top: 8px; font-size: 12px; line-height: 1.45;
    color: var(--mut);
}
.ay-cam {
    display: flex; gap: 8px; align-items: baseline; padding: 3px 0;
    border-top: 1px solid var(--line);
}
.ay-cam:first-of-type { border-top: 0; }
.ay-cam .k { flex: none; width: 92px; font-size: 11.5px; color: var(--mut); }
.ay-cam .v {
    flex: 1; min-width: 0; font-size: 12.5px; font-weight: 650; color: var(--ink);
    word-break: break-word;
}

/* Lo unico de la ayuda que sale de la app: las paginas de Google y la de
   probar el spam. Son suyas, cambian, y sin ellas no se acaba de configurar
   el correo; van marcadas como lo que son y se abren aparte. */
.ayuda-enlaces { display: grid; gap: 8px; margin: 0 0 13px; }
.ayuda-enlace {
    display: flex; align-items: center; gap: 10px; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 10px; background: var(--surf);
    color: inherit; text-decoration: none;
}
.ayuda-enlace:hover { border-color: var(--g); background: var(--wash); }
.ayuda-enlace .t { display: block; font-weight: 650; color: var(--g-d); }
.ayuda-enlace .s {
    display: block; font-size: 12px; color: var(--mut); margin-top: 2px;
    line-height: 1.45;
}
.ayuda-enlace svg { flex: none; color: var(--mut); }

.ayuda-pasos { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.ayuda-paso { flex: 1; min-width: 180px; display: block; color: inherit; }
.ayuda-paso .s { font-size: 11.5px; color: var(--mut); display: flex; align-items: center; gap: 5px; }
.ayuda-paso .t { display: block; font-weight: 650; margin-top: 3px; }
.ayuda-paso.der { text-align: right; }
.ayuda-paso.der .s { justify-content: flex-end; }

/* ── Los dibujos del manual ───────────────────────────────────────────────
   Cuatro rectángulos y cuatro palabras, con los colores del tema: pesan unos
   cientos de bytes y no envejecen como una captura.
   ------------------------------------------------------------------------ */
.dib-caja-marco { background: var(--wash); display: flex; justify-content: center; }
.dib { width: 100%; max-width: 420px; height: auto; }
.dib-hoja { fill: var(--surf); stroke: var(--line); stroke-width: 1.5; }
.dib-menu { fill: var(--g-dd); }
.dib-barra { fill: var(--g-dd); }
.dib-marca { fill: var(--g); opacity: .85; }
.dib-item { fill: currentColor; opacity: .22; }
.dib-item.dib-on { fill: var(--g); opacity: .9; }
.dib-caja { fill: var(--wash); stroke: var(--line); stroke-width: 1.2; }
.dib-caja.dib-on { fill: var(--g-w, var(--wash)); stroke: var(--g); }
.dib-caja.dib-lado { fill: var(--surf); }
.dib-buscar { fill: var(--surf); opacity: .35; }
.dib-verde { fill: var(--g); }
.dib-rojo { fill: var(--red); }
.dib-flecha { stroke: var(--mut); stroke-width: 1.6; fill: none; stroke-linecap: round; }
.dib-txt {
    fill: var(--ink-2); font-size: 9px; font-weight: 650; text-anchor: middle;
    font-family: inherit;
}
.dib-txt.dib-claro { fill: #fff; }
.dib-txt.dib-mut { fill: var(--mut); font-weight: 600; }

/* Cartera a dos columnas: con sitio, el detalle del cliente se lee en la
   columna de al lado y la lista queda limpia (la flecha ya no hace falta). */
@media (min-width: 1100px) {
    .cart-2col .rows .cart-detalle { display: none; }
    .cart-2col .rows summary .chev { opacity: .35; }
    .cart-2col .rows details.row.senalada > summary { background: var(--wash); }
    /* La columna de la cartera pide algo más de ancho: caben la factura, el
       vencimiento y el importe sin partirse en tres renglones. */
    .cart-2col { grid-template-columns: minmax(0, 1fr) 380px; }

    #avFichaCartera .cart-detalle { padding: 0 !important; }
    #avFichaCartera .cart-detalle > div:first-child { padding-top: 0 !important; }

    /* El detalle viaja clonado fuera de .rows, así que se le repiten aquí los
       cuatro estilos de fila que necesita. */
    #avFichaCartera .cart-detalle .t { display: block; font-weight: 650; letter-spacing: -.01em; }
    #avFichaCartera .cart-detalle .s { display: block; font-size: 12.5px; color: var(--mut); margin-top: 2px; }
    #avFichaCartera .cart-detalle .amt { text-align: right; font-weight: 700; flex: none; white-space: nowrap; }
    #avFichaCartera .cart-detalle .icobtn { background: var(--wash); color: var(--g-d); }
    #avFichaCartera .cart-detalle .icobtn:hover { background: var(--g-d); color: #fff; }
}

/* ── Clientes a dos columnas ───────────────────────────────────────────────
   En el móvil, la lista de siempre a pantalla completa. A partir de 1100 px
   entra al lado la ficha del cliente que se señala, para repasar la cartera
   sin entrar y salir de fichas.
   ------------------------------------------------------------------------ */
.cli-2col { display: block; }
.cli-ficha { display: none; }

@media (min-width: 1100px) {
    .cli-2col { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 16px; align-items: start; }
    .cli-ficha { display: block; position: sticky; top: 74px; }
    .cli-ficha-caja { display: flex; flex-direction: column; gap: 10px; }
    .cli-ficha-top { display: flex; align-items: center; gap: 11px; padding: 2px 2px 4px; }
    .cli-ficha-top .t { font-weight: 700; display: block; letter-spacing: -.01em; }
    .cli-ficha-top .s { font-size: 12.5px; color: var(--mut); }
    .cli-ficha .kpi { padding: 10px 12px; }
    .cli-ficha .kpi .val { font-size: 18px; }
    .cli-ficha .row { padding: 9px 12px; }
    /* Una sola marca: la fila cuyo cliente se está viendo a la derecha, venga
       del ratón o del teclado. El subrayado del ratón se quita para que no
       queden dos filas marcadas a la vez y no se sepa cuál se está mirando. */
    .cli-2col .rows .row:hover { background: none; }
    .cli-2col .rows .row.senalada {
        background: var(--wash);
        box-shadow: inset 3px 0 0 var(--g-d);
    }
}

/* Elegir un color de la app: la muestra grande, porque en el móvil hay que
   poder acertarle con el dedo. */
.col-sw { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.col-sw input[type="color"] {
    width: 54px; height: 40px; padding: 0; border: 1px solid var(--line);
    border-radius: calc(10px * var(--rr)); background: none; cursor: pointer; flex: none;
}
.col-sw b { display: block; font-size: 13.5px; }
.col-sw .mono { color: var(--mut); }

/* Campo con botones al lado: el teléfono se marca, la dirección abre el mapa
   y el correo abre la ventana de escribir, sin copiar nada a mano. */
.con-acciones { display: flex; align-items: center; gap: 6px; }
.con-acciones .input { flex: 1; min-width: 0; }
.con-acciones .icobtn { background: var(--wash); color: var(--g-d); flex: none; }
.con-acciones .icobtn:hover { background: var(--g-d); color: #fff; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }

/* Con pantalla de sobra, la botonera del documento cabe en una sola fila:
   botones más bajos, el icono al lado del texto y todo a la vista sin bajar. */
@media (min-width: 1100px) {
    .grid3 { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; }
    .grid3 .act {
        display: flex; align-items: center; gap: 8px; text-align: left;
        padding: 8px 10px; border-radius: calc(12px * var(--rr)); font-size: 12px; min-height: 0;
    }
    .grid3 .act .ic { width: 26px; height: 26px; border-radius: calc(9px * var(--rr)); margin: 0; flex: none; }
    .grid3 .act .ic svg { width: 15px; height: 15px; }
    /* El rótulo parte en dos líneas antes que cortarse: «Estado de cuenta»
       tiene que leerse entero.

       Y parte DENTRO de su hueco, al lado del icono. Sin el `flex: 1 1 0` el
       rótulo pedía todo el ancho de su texto, no cabía, y como la fila lleva
       `wrap` se bajaba entero al renglón de abajo: por eso «Enviar» salía al
       lado del icono y «Pasar a albarán» debajo, en la misma botonera. Los
       rótulos cortos y los largos tienen que colocarse igual. */
    /* Y la chapa del importe queda FUERA: «span:not(.ic)» lleva un selector de
       tipo y por eso gana a «.act-aviso» aunque esta escrito despues -0,3,1
       contra 0,3,0-. Con «flex: 1 1 0» la chapa se quedaba con ancho cero, y
       como el importe no parte (nowrap) se salia del boton por la derecha,
       cruzando el borde redondeado. */
    .grid3 .act > span:not(.ic):not(.act-aviso) { flex: 1 1 0; min-width: 0; line-height: 1.15; }

    /* En una fila el importe NO puede ir flotando en la esquina: caía justo
       encima del rótulo y se leía «Imp847,00 €ada». Y al lado tampoco cabe —el
       botón mide 118 px y entre icono, rótulo e importe no queda sitio—, así
       que baja a su propio renglón, alineado con el texto de arriba. */
    .grid3 .act { flex-wrap: wrap; }
    .grid3 .act .act-aviso {
        /* Base 100 % para que se lleve su propio renglón; el ancho de verdad
           lo pone el max-width, que es lo que ocupa el importe. */
        flex: 0 0 100%; margin: 3px 0 0 34px;
        /* Y que no se pase del boton ni con un importe de siete cifras: el
           ancho util es el del boton MENOS la sangria del icono. Si no cabe
           en una linea, que parta; un importe partido en dos se lee, uno que
           cruza el borde redondeado parece un fallo. */
        max-width: calc(100% - 34px); white-space: normal;
    }
}
.act {
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(15px * var(--rr)); padding: 12px 5px;
    text-align: center; font-size: 11.5px; font-weight: 650; color: var(--ink-2); line-height: 1.25;
    display: block; cursor: pointer;
}
.act .ic {
    width: 36px; height: 36px; border-radius: calc(12px * var(--rr)); background: var(--wash); color: var(--g-d);
    display: grid; place-items: center; margin: 0 auto 7px;
}
.act.on { border-color: var(--g); background: var(--wash); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 15%, transparent); }
.act.on .ic { background: var(--g-d); color: #fff; }
.act.on span { color: var(--g-d); font-weight: 750; }
.act.brass .ic { background: var(--brass-w); color: var(--brass); }
.act.red .ic { background: var(--red-w); color: var(--red); }
/* Una acción que ahora no se puede hacer: se ve, pero apagada y sin invitar. */
.act.apagado { color: var(--mut); background: var(--wash); border-style: dashed; cursor: default; }
.act.apagado .ic { background: var(--surf); color: var(--mut); }

/* ── Formularios ──────────────────────────────────────────────────────── */
/* La frase corta que explica un campo. Se usa desde los recargos del TPV, y
   sin regla propia salia con el tamano del texto normal: se leia como si
   fuese otro dato mas del formulario. */
.field .s { display: block; font-size: 12px; color: var(--mut); margin-top: 4px; }

.field { margin-bottom: 11px; }
.field:last-child { margin-bottom: 0; }
.field label { display: block; font-size: 11.5px; font-weight: 700; color: var(--ink-2); margin-bottom: 5px; }
.input {
    width: 100%; height: 46px; border: 1px solid var(--line); background: var(--surf); border-radius: calc(12px * var(--rr));
    padding: 0 13px; font-size: 14.5px; color: var(--ink); font-family: inherit;
}
.input:focus { border-color: var(--g); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 14%, transparent); outline: none; }
textarea.input { height: auto; padding: 12px 13px; line-height: 1.55; resize: vertical; }
select.input { appearance: none; background-image: none; }
/* El desplegable, en el verde de GestioERP: por defecto el navegador pinta la
   opción marcada con su azul de sistema y desentona con toda la app. */
select.input, input.input { accent-color: var(--g); }
select.input option:checked, select.input option:hover {
    background: var(--wash); color: var(--g-d);
}
/* minmax(0,…) y no 1fr a secas: con 1fr una opción larga del desplegable
   ensancha la columna y se sale de la tarjeta. */
.two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.tres { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }

/* Una línea de un encargo: qué es, cuántos y a qué precio. Las tres cosas van
   SIEMPRE en la misma fila, también en el móvil: apiladas, la segunda línea y
   la tercera se quedan sin rótulo y no se sabe qué se está escribiendo. */
.lin-encargo { display: grid; grid-template-columns: minmax(0, 1fr) 62px 86px; gap: 7px; align-items: end; }
.lin-encargo + .lin-encargo { margin-top: 8px; }
.lin-encargo > .field { margin-bottom: 0; }

/* En el móvil, un campo por línea: dos o tres columnas de 375 px dejan los
   desplegables cortados y no se lee lo que pone dentro. Salvo los pares que
   piden ir juntos a propósito (familia y fabricante), marcados aparte. */
@media (max-width: 599px) {
    .two:not(.dos-siempre), .tres { grid-template-columns: 1fr; gap: 0; }
    .two:not(.dos-siempre) > .field, .tres > .field { margin-bottom: 11px; }
    .two.dos-siempre { gap: 8px; }
    .two.dos-siempre .input, .two.dos-siempre .av-sel-boton {
        height: 40px; padding-top: 0; padding-bottom: 0; font-size: 13.5px;
    }
    .two.dos-siempre label { font-size: 11px; }

    .lin-encargo .input {
        height: 42px; padding-top: 0; padding-bottom: 0; font-size: 13.5px;
    }
    .lin-encargo label { font-size: 11px; }
}

/* En el móvil, la botonera a cinco por fila y con el icono pequeño.
   Un documento puede tener hasta diez acciones. A tres columnas eran tres o
   cuatro filas de tarjetas grandes que se comían media pantalla antes de
   llegar a las líneas; a cinco, cabe todo en dos filas —casi siempre en una o
   dos— y el documento empieza a verse enseguida. El dibujo aquí solo sirve
   para reconocer el botón de un vistazo, así que se queda en lo justo y el
   sitio se lo lleva el rótulo. */
@media (max-width: 639px) {
    /* Hasta cinco por fila; cuando el grupo tiene tres o cuatro, se
       reparten el ancho entero en vez de dejar un hueco a la derecha. */
    .grid3 { grid-template-columns: repeat(auto-fit, minmax(62px, 1fr)); gap: 5px; }
    .grid3 .act {
        padding: 7px 2px; border-radius: calc(11px * var(--rr)); font-size: 9px;
        letter-spacing: -.02em; display: flex; flex-direction: column;
        align-items: center; justify-content: flex-start; height: 100%;
    }
    .grid3 .act .ic { width: 22px; height: 22px; border-radius: calc(8px * var(--rr)); margin: 0 0 4px; }
    .grid3 .act .ic svg { width: 13px; height: 13px; }
    .grid3 .act > span:last-child { line-height: 1.1; overflow-wrap: anywhere; }
    /* El botón de convertir va dentro de un formulario, así que la celda de la
       rejilla es el formulario y no el botón: sin esto se quedaba con su
       propio alto y rompía la fila. */
    .grid3 form { display: flex; }
    .grid3 form .act { flex: 1; width: 100%; }
}

/* Teléfonos estrechos: las mismas cinco columnas, todo un punto más apretado. */
@media (max-width: 360px) {
    .grid3 { grid-template-columns: repeat(auto-fit, minmax(56px, 1fr)); gap: 4px; }
    .grid3 .act { padding: 6px 1px; font-size: 8.4px; }
    .grid3 .act .ic { width: 20px; height: 20px; margin-bottom: 3px; }
    .grid3 .act .ic svg { width: 12px; height: 12px; }
}

/* ── Entradas rápidas ─────────────────────────────────────────────────────
   Las bases con su IVA: en el móvil cada una es un bloque con sus etiquetas;
   en el ordenador, una fila como la de una hoja de cálculo.
   ------------------------------------------------------------------------ */
.base-fila {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px;
    padding: 11px 12px; border-bottom: 1px solid var(--line);
}
.base-fila .field { margin: 0; }
.base-fila.extra { display: none; }
.base-fila.extra.vista { display: grid; }
.base-cab { display: none; }
.solo-movil { display: block; }

@media (min-width: 860px) {
    .base-fila { grid-template-columns: 1.2fr 1fr 1fr 1fr; align-items: center; }
    .base-cab {
        display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr; gap: 9px;
        padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line);
    }
    /* Con cabecera no hacen falta las etiquetas de cada campo. Va con la
       misma fuerza que «.field label» o no le gana. */
    .base-fila .solo-movil { display: none; }
}

/* Con pantalla ancha, el asiento se dibuja en su columna y se queda a la
   vista mientras se rellena el formulario de la izquierda. */
.rap-2col { display: block; }
.rap-asiento { display: block; }

@media (min-width: 1200px) {
    .rap-2col {
        display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
        gap: 16px; align-items: start;
    }
    .rap-asiento { position: sticky; top: 14px; }
    .rap-asiento .sec-t { margin-top: 0; }
}

/* ── Mayor de una cuenta ──────────────────────────────────────────────────
   En el móvil cada apunte es un bloque; en el ordenador, una fila con el
   saldo a la derecha, que es como se lee un mayor.
   ------------------------------------------------------------------------ */
.mayor-fila { display: grid; grid-template-columns: auto auto 1fr; gap: 4px 10px; align-items: start; }
.mayor-fila .c { grid-column: 1 / -1; min-width: 0; display: block; }
.mayor-fila .f { font-size: 12px; color: var(--mut); font-weight: 650; }
.mayor-fila .n { text-align: right; font-weight: 650; font-variant-numeric: tabular-nums; }
.mayor-fila .saldo { font-weight: 750; }
.mayor-cab { display: none; }

/* Cuatro indicadores no caben en una fila de móvil con importes de seis
   cifras: van de dos en dos y se estiran cuando hay sitio. */
.kpis-dos { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }

@media (min-width: 760px) {
    .kpis-dos { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ── El punteo ─────────────────────────────────────────────────────────────
   Marcar lo que ya ha salido en el extracto del banco. La casilla es grande
   porque se puntea con el dedo, apunte a apunte, extracto en mano. */
.mayor-fila .p {
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; flex: none; cursor: pointer; border-radius: calc(9px * var(--rr));
}
.mayor-fila .p input { width: 19px; height: 19px; accent-color: var(--g); cursor: pointer; }
.mayor-fila .p:hover { background: var(--slate-w); }

/* Lo punteado se aparta de la vista sin desaparecer: lo que queda en negro
   es lo que falta por casar. */
.mayor-fila.punteada .f,
.mayor-fila.punteada .c,
.mayor-fila.punteada .n { opacity: .5; }
.mayor-fila.punteada .c .t { text-decoration: line-through; }

@media (min-width: 860px) {
    .mayor-fila {
        grid-template-columns: 38px 92px minmax(0, 1fr) 110px 110px 120px;
        align-items: center; gap: 10px;
    }
    .mayor-fila .c { grid-column: auto; }
    /* Con «.lin-cab» delante porque la cabecera del editor de líneas se
       define más abajo y, a igual fuerza, mandaba la última. */
    .lin-cab.mayor-cab {
        display: grid; grid-template-columns: 38px 92px minmax(0, 1fr) 110px 110px 120px; gap: 10px;
    }
    .lin-cab.mayor-cab span:nth-child(3) { text-align: left; }
    .lin-cab.mayor-cab span:nth-child(n+4) { text-align: right; }
}

/* ── Revisar una factura escaneada ────────────────────────────────────────
   Los datos a la izquierda y el papel a la derecha, que es como se coteja.
   En el móvil el papel va primero, para verlo antes de corregir nada.
   ------------------------------------------------------------------------ */
.esc-2col { display: flex; flex-direction: column-reverse; gap: 14px; }
.esc-visor { overflow: hidden; padding: 0; }
.esc-visor img { width: 100%; display: block; }
.esc-visor iframe { width: 100%; height: 60vh; border: 0; display: block; }

@media (min-width: 1100px) {
    /* El papel, más ancho que los datos: es lo que hay que leer, y con el
       reparto a medias no se distinguían ni las referencias. */
    .esc-2col {
        display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
        gap: 16px; align-items: start;
    }
    .esc-papel { position: sticky; top: 14px; }
    .esc-visor { max-height: calc(100vh - 120px); overflow-y: auto; }
    .esc-visor iframe { height: calc(100vh - 150px); }
}

/* Con pantalla grande de verdad, el papel se lleva más sitio todavía. */
@media (min-width: 1500px) {
    .esc-2col { grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr); }
}

/* «Más grande»: el documento a pantalla completa, encima de todo. */
.esc-2col.papel-grande { display: block; }
.esc-2col.papel-grande .esc-datos { display: none; }
.esc-2col.papel-grande .esc-papel { position: static; }
.esc-2col.papel-grande .esc-visor { max-height: none; }
.esc-2col.papel-grande .esc-visor iframe { height: calc(100vh - 130px); }

/* ── Cartera de pagos ─────────────────────────────────────────────────────
   Cada recibo con su factura, su vencimiento y su forma de pago. En el
   ordenador es una tabla como la del ERP; en el móvil, un bloque por recibo.
   ------------------------------------------------------------------------ */
.pago-cab {
    display: flex; align-items: center; gap: 12px; padding: 12px 14px;
    border-bottom: 1px solid var(--line); background: var(--wash);
    border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
}
.pago-cab .t { display: block; font-weight: 750; color: var(--ink); }
.pago-cab .t:hover { color: var(--g-d); }
.pago-cab .s { display: block; font-size: 12px; color: var(--mut); margin-top: 2px; }
.pago-cab .grow { flex: 1; min-width: 0; }

.pago-titulos { display: none; }
.pago-fila {
    display: grid; grid-template-columns: auto 1fr; gap: 4px 10px;
    padding: 11px 14px; border-bottom: 1px solid var(--line); align-items: center;
}
.pago-fila.vencida { background: color-mix(in srgb, var(--red-w) 45%, #fff); }
.pago-fila .rec { font-size: 12px; color: var(--mut); font-weight: 700; }
.pago-fila .fac { font-weight: 650; }
.pago-fila .fac a { color: var(--g-d); }
.pago-fila .emi, .pago-fila .ven, .pago-fila .fpa { font-size: 12.5px; color: var(--ink-2); }
.pago-fila .imp { grid-column: 2; text-align: right; }
.pago-fila .acc { grid-column: 1 / -1; }
.pago-fila .acc .btn { width: 100%; }
.pago-form { padding: 0 14px 12px; border-bottom: 1px solid var(--line); }

@media (min-width: 1000px) {
    .pago-titulos {
        display: grid; gap: 10px; padding: 8px 14px;
        grid-template-columns: 70px minmax(0, 1.2fr) 92px 130px minmax(0, 1fr) 120px 118px;
        font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
        color: var(--mut); font-weight: 700; border-bottom: 1px solid var(--line);
    }
    .pago-titulos span:nth-child(6) { text-align: right; }
    .pago-fila {
        grid-template-columns: 70px minmax(0, 1.2fr) 92px 130px minmax(0, 1fr) 120px 118px;
        gap: 10px;
    }
    .pago-fila .imp, .pago-fila .acc { grid-column: auto; }
    .pago-fila .solo-movil { display: none; }
}

/* El recuadro donde se sueltan las fotos. En el móvil es el botón que abre
   la galería; en el ordenador, además, recibe lo que se arrastra. */
.soltar {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    margin-top: 10px; padding: 14px 12px; cursor: pointer; text-align: center;
    border: 1.5px dashed var(--line); border-radius: calc(14px * var(--rr));
    color: var(--mut); font-size: 12.5px; font-weight: 650; background: var(--wash);
}
.soltar:hover { border-color: var(--g); color: var(--g-d); }
.soltar.encima { border-color: var(--g); background: var(--g-l); color: var(--g-dd); }
.soltar.con-fichero { border-style: solid; border-color: var(--g); color: var(--g-d); }

/* Los datos de una referencia: cuatro campos que en el móvil van de dos en
   dos y en el ordenador en una sola fila. */
.var-edit { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.var-edit .field { margin: 0; }
.var-edit .input { height: 42px; font-size: 14px; }
@media (min-width: 760px) {
    .var-edit { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); }
}

/* La búsqueda con su interruptor al lado, en vez de dos renglones. Si no
   caben los dos —en el móvil, con la casilla del IVA puesta— pasan a dos:
   antes el interruptor no encogía y se comía el precio de al lado. */
.busca-linea { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.busca-linea .input { flex: 1; min-width: 0; }
.chip-check {
    flex: none; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    height: 46px; padding: 0 12px; border-radius: calc(12px * var(--rr)); white-space: nowrap;
    border: 1.5px solid var(--line); background: var(--surf);
    font-size: 13px; font-weight: 650; color: var(--ink-2);
}
.chip-check input { width: 17px; height: 17px; accent-color: var(--ge-sel, var(--g)); }
.chip-check.on { border-color: var(--g); background: var(--wash); color: var(--g-d); }

@media (max-width: 599px) {
    .busca-linea .input, .chip-check { height: 42px; font-size: 13.5px; }
    .chip-check { padding: 0 10px; font-size: 12.5px; }
}
.check { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.check input { width: 20px; height: 20px; accent-color: var(--g); }
.check label { font-size: 13.5px; font-weight: 600; color: var(--ink-2); }
.ayuda { font-size: 12.5px; color: var(--mut); line-height: 1.5; margin-top: 8px; }

/* ── Totales ──────────────────────────────────────────────────────────── */
.totes {
    background: var(--surf); border-top: 1px solid var(--line); padding: 12px 14px 16px;
    display: flex; flex-direction: column; gap: 8px;
    position: sticky; bottom: 0; z-index: 5;
}
.tline { display: flex; justify-content: space-between; font-size: 13px; color: var(--mut); font-variant-numeric: tabular-nums; }
.tline.big {
    font-size: 19px; color: var(--ink); font-weight: 750; letter-spacing: -.02em;
    padding-top: 8px; border-top: 1px dashed var(--line);
}

/* ── Firma ────────────────────────────────────────────────────────────── */
.signpad {
    background: #fff; border: 1.5px dashed #C4D3CD; border-radius: calc(16px * var(--rr)); height: 240px;
    position: relative; overflow: hidden; touch-action: none;
}
.signpad canvas { width: 100%; height: 100%; display: block; touch-action: none; }
.signhint {
    position: absolute; bottom: 14px; left: 0; right: 0; text-align: center; font-size: 11.5px;
    color: #A9B8B2; font-weight: 600; pointer-events: none;
}
.signpad.firmado .signhint { display: none; }
.nota { border-radius: calc(15px * var(--rr)); padding: 13px 14px; display: flex; gap: 13px; align-items: center; }
.nota.brass { background: #FDF7EA; border: 1px solid #F0DFBC; }
.nota .h { font-weight: 700; font-size: 13.5px; color: #6E4A08; }
.nota .p { font-size: 12.5px; color: #8A6A2C; margin-top: 3px; line-height: 1.45; }
.qrbox { width: 112px; height: 112px; border-radius: calc(12px * var(--rr)); background: #fff; padding: 7px; border: 1px solid var(--line); flex: none; }
.qrbox img { width: 100%; height: 100%; display: block; image-rendering: pixelated; }
.firma-img { max-width: 220px; max-height: 90px; }

/* ── Gráfico de barras (web) ──────────────────────────────────────────── */
.bars { display: flex; align-items: flex-end; gap: 9px; height: 118px; padding: 0 4px; }
.bars div { flex: 1; background: linear-gradient(180deg, var(--g-l), var(--g)); border-radius: calc(5px * var(--rr)) calc(5px * var(--rr)) calc(2px * var(--rr)) calc(2px * var(--rr)); min-height: 3px; }
.bars div.now { background: linear-gradient(180deg, var(--g), var(--g-d)); }
.barlabs { display: flex; gap: 9px; padding: 6px 4px 0; }
.barlabs span { flex: 1; text-align: center; font-size: 10.5px; color: var(--mut); font-weight: 600; }

/* ── Menú inferior (móvil) ────────────────────────────────────────────── */
.nav {
    background: var(--surf); border-top: 1px solid var(--line); display: grid;
    /* Las columnas salen de los elementos que haya, no fijas a 5: al técnico de
       obra le salen menos y con repeat(5,1fr) se le amontonaban a la izquierda
       dejando el botón grande descentrado y medio fuera. */
    grid-auto-flow: column; grid-auto-columns: 1fr; padding: 7px 0 10px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
.nav a { text-align: center; font-size: 10px; font-weight: 650; color: #93A69F; }
.nav a i { display: block; margin: 0 auto 3px; width: 22px; height: 22px; }
.nav a i svg { width: 22px; height: 22px; }
.nav a.on { color: var(--g-d); }
/* El botón del menú del pie se ve igual que los demás: es uno más. */
.nav .nav-menu {
    /* Ocupa toda su casilla: en el móvil se toca con el pulgar, no se apunta. */
    text-align: center; font-size: 10px; font-weight: 650; color: #93A69F;
    background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
    width: 100%; height: 100%; display: block;
}
.nav .nav-menu i { display: block; margin: 0 auto 3px; width: 22px; height: 22px; }
.nav .nav-menu i svg { width: 22px; height: 22px; }
.fabwrap { position: relative; }
.fab {
    position: absolute; top: -24px; left: 50%; transform: translateX(-50%); width: 54px; height: 54px;
    border-radius: calc(19px * var(--rr)); background: linear-gradient(160deg, var(--g), var(--g-d)); color: #fff;
    display: grid; place-items: center; box-shadow: 0 10px 20px -8px color-mix(in srgb, var(--g-d) 85%, transparent);
}

/* ── Menú superior (web) ──────────────────────────────────────────────── */
.wnav { display: none; }

/* ── Diálogo propio ───────────────────────────────────────────────────── */
.av-modal {
    position: fixed; inset: 0; background: rgba(14, 26, 23, .45); display: grid; place-items: center;
    z-index: 60; padding: 20px;
}
.av-modal[hidden] { display: none; }
.av-modal-box { background: #fff; border-radius: calc(18px * var(--rr)); padding: 22px; max-width: 360px; width: 100%; }
.av-modal-box p { margin: 0 0 18px; font-size: 15px; line-height: 1.5; }
.av-modal-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ── Buscador de artículos ────────────────────────────────────────────── */
.sugerencias { border: 1px solid var(--line); border-radius: calc(12px * var(--rr)); background: #fff; overflow: hidden; }
.sugerencias:empty { display: none; }
.sugerencias button {
    display: flex; width: 100%; gap: 10px; align-items: center; padding: 11px 13px; background: none;
    border: none; border-bottom: 1px solid var(--line); text-align: left; cursor: pointer;
}
.sugerencias button:last-child { border-bottom: none; }
.sugerencias button:hover { background: var(--wash); }

/* ==========================================================================
   Web: a partir de 768 px
   ========================================================================== */
@media (min-width: 768px) {
    body.av { padding-bottom: 0; }
    .nav { display: none; }
    .ocultar-movil { display: inline; }

    .wnav {
        display: flex; align-items: center; gap: 14px; padding: 0 22px; height: 58px;
        background: linear-gradient(100deg, var(--g-d), var(--g-dd)); color: #fff;
        position: sticky; top: 0; z-index: 30;
    }
    .wnav .brand { display: flex; align-items: center; gap: 9px; font-weight: 800; letter-spacing: -.02em; font-size: 15px; }
    .wnav .wctx {
        display: flex; align-items: center; gap: 6px; color: #fff; font-weight: 700; font-size: 12.5px;
        padding: 5px 11px; border-radius: 999px; background: rgba(255,255,255,.14); white-space: nowrap;
    }
    .wnav .wctx svg { opacity: .85; flex: none; }
    /* Los desplegables de empresa y ejercicio se funden con la píldora: se ven
       como el texto que había antes, pero se pueden cambiar. */
    .wnav .wctx select {
        background: none; border: none; color: #fff; font: inherit; font-weight: 700;
        padding: 2px 2px 2px 4px; border-radius: calc(8px * var(--rr)); cursor: pointer; max-width: 170px;
    }
    .wnav .wctx select:hover, .wnav .wctx select:focus-visible { background: rgba(255, 255, 255, .16); }
    .wnav .wctx select option { color: var(--ink); background: var(--surf); font-weight: 600; }
    /* Con ocho apartados el menú no cabe: se deja encoger y desplazar en vez
       de empujar la página y provocar scroll horizontal. */
    .wnav nav { display: flex; gap: 2px; flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
    .wnav nav::-webkit-scrollbar { display: none; }
    .wnav nav a { white-space: nowrap; padding: 19px 10px; }
    .wnav nav a {
        color: color-mix(in srgb, var(--g-l) 85%, #fff); font-size: 13.5px; font-weight: 650;
        padding: 19px 13px; border-bottom: 3px solid transparent;
    }
    .wnav nav a.on { color: #fff; border-bottom-color: #fff; }
    .wnav .wsearch {
        width: 260px; height: 34px; background: rgba(255, 255, 255, .15); border-radius: calc(10px * var(--rr));
        display: flex; align-items: center; gap: 8px; padding: 0 11px; color: var(--g-l); flex: none;
    }
    .wnav .wsearch input { background: none; border: none; color: #fff; font-size: 13px; width: 100%; }
    .wnav .wsearch input::placeholder { color: color-mix(in srgb, var(--g-l) 90%, #fff); }
    .wnav .who { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--g-l); flex: none; }
    .wnav .wsalir, .wnav .wayuda { display: block; flex: none; }

    /* ── Todo lo de la derecha, junto y pegado a la derecha ──────────────
       El hueco se abre ANTES del grupo, no en medio. Antes el margen estaba en
       la version -que va la penultima-, asi que el hueco partia el grupo en
       dos y el usuario con sus iconos se quedaban sueltos en mitad de la barra
       verde:

           [usuario ✉ 💬 📦 ?]          [v25.5 ⏻]

       Con el grupo envuelto, el margen va delante de todo y se van juntos. */
    .wnav .wder {
        margin-left: auto; flex: none;
        display: flex; align-items: center; gap: 10px;
    }
    .wnav .wver {
        flex: none; font-size: 11px; font-weight: 700;
        letter-spacing: .02em; white-space: nowrap;
        color: color-mix(in srgb, var(--g-l) 80%, #fff);
    }
    .wnav .icobtn { font-weight: 800; font-size: 15px; }
    .solo-movil { display: none; }

    /* Por debajo de 1100 px el buscador estorba: la lupa está en Clientes. */
    @media (max-width: 1100px) {
        .wnav .wsearch { display: none; }
    }

    /* La cabecera de sección deja de ser verde: ya lo es el menú superior. */
    .top { background: none; color: var(--ink); padding: 20px 22px 6px; max-width: 1180px; margin: 0 auto; }

    /* La flecha de volver, en su propia línea: dentro de la del título lo
       empujaba 38 px a la derecha y el nombre no cuadraba con las pestañas ni
       con las tarjetas de abajo. En el móvil se queda al lado, que es donde se
       espera y donde no sobra espacio. */
    .top .line1 { flex-wrap: wrap; row-gap: 2px; }
    .top .line1 > .icobtn.plain { flex: 0 0 100%; justify-content: flex-start; width: auto; }
    .top h1 { font-size: 25px; }

    /* El titulo y lo que va debajo, en la MISMA linea: «Factura F0526A26» y
       el nombre del cliente son dos datos cortos que ocupaban dos renglones
       enteros de la pantalla. Si no cabe, el subtitulo baja solo. */
    .top .line1 > div:has(> h1 + .sub) {
        display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 11px; row-gap: 0;
    }
    .top .line1 > div:has(> h1 + .sub) > h1 { flex: 0 1 auto; }
    .top .line1 > div:has(> h1 + .sub) > .sub { margin-top: 0; }

    .top .sub, .top .etiqueta { color: var(--mut); }
    .top .grande { color: var(--ink); }
    .top .icobtn { background: var(--wash); color: var(--g-d); }
    .top .avat { background: var(--g-d); color: #fff; }
    .searchbar { background: var(--surf); border: 1px solid var(--line); max-width: 420px; }
    .searchbar input { color: var(--ink); }
    .searchbar input::placeholder, .searchbar svg { color: var(--mut); }
    .seg { background: var(--slate-w); max-width: 460px; }
    .seg a { color: var(--ink-2); }
    .seg a.on { box-shadow: 0 1px 3px rgba(14, 26, 23, .12); }

    .contenido { padding: 14px 22px 40px; gap: 16px; }
    /* Mismo carril que el contenido: las pestañas empiezan donde empiezan las
       tarjetas, y la raya de abajo llega hasta donde llegan. */
    .tabs { padding: 0 22px; max-width: 1180px; margin: 6px auto 0; border-radius: 0; }
    /* Aqui la cabecera ya no es oscura: las pestañas vuelven a su color. */
    .top .tabs { border-bottom-color: var(--line); }
    .top .tabs a { color: var(--mut); }
    .top .tabs a.on { color: var(--g-d); }
    .contenido.ancho + .tabs, .tabs.ancho { max-width: 1560px; }
    .kpis { grid-template-columns: repeat(4, 1fr); }
    .dos-col { display: grid; grid-template-columns: 1.7fr 1fr; gap: 16px; align-items: start; }
    .dos-col-igual { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
    /* Una columna de rejilla no se encoge por debajo de lo que mida su
       contenido si no se le dice: sin esto, en tableta las dos columnas
       sumaban más que la pantalla y la página salía con barra horizontal. */
    .dos-col > *, .dos-col-igual > * { min-width: 0; }
    .pila { gap: 16px; }

    .totes { border: 1px solid var(--line); border-radius: calc(16px * var(--rr)); position: static; }
    .btn { width: auto; padding: 0 22px; }
    .btn.ancho { width: 100%; }
    .btn-fila { grid-template-columns: max-content max-content; justify-content: end; }
    .av-avisos { padding: 14px 22px 0; }
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}

/* ── Editor de documento: en el ordenador, líneas a la izquierda y pie a la
   derecha, para verlo todo sin bajar. En el móvil sigue en una columna. ── */
.editor { display: flex; flex-direction: column; gap: 12px; }
.editor > div, .editor > aside { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* Los totales, abajo y pegados: las líneas se llevan todo el ancho, que es
   donde se trabaja, y el total con sus botones va siempre a la vista en el
   pie sin tener que bajar hasta el final. Antes ocupaban una columna de 330
   px a la derecha que se estaba quieta mientras se escribían las líneas. */
@media (min-width: 768px) {
    .editor { display: flex; flex-direction: column; gap: 12px; }
    .editor > aside { position: sticky; bottom: 0; z-index: 20; margin-top: 4px; }
    .editor .totes {
        border: 1px solid var(--line); border-radius: calc(16px * var(--rr));
        display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 22px;
        align-items: center; box-shadow: 0 -6px 22px rgba(9, 46, 38, .1);

        /* Semitransparente y con el fondo desenfocado: la barra del total va
           pegada abajo TAPANDO las ultimas lineas del documento, y en blanco
           macizo parece que ahi se acaba la lista. Translucida se ve que
           debajo sigue habiendo lineas, y el total sigue leyendose. */
        background: color-mix(in srgb, var(--surf) 80%, transparent);
        backdrop-filter: blur(11px) saturate(1.3);
        -webkit-backdrop-filter: blur(11px) saturate(1.3);
    }

    /* Sin desenfoque (navegadores viejos, o el usuario lo tiene apagado) casi
       opaca: translucida y sin desenfoque, el texto de debajo se cuela entre
       las cifras y no se lee ninguna de las dos. */
    @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
        .editor .totes { background: color-mix(in srgb, var(--surf) 96%, transparent); }
    }
    /* Las sumas en fila, que a lo ancho caben de sobra. */
    .editor .totes .tline { grid-column: 1; display: flex; gap: 16px; }
    .editor .totes .tline span:first-child { flex: none; }
    .editor .totes .tot { grid-column: 1; }
    .editor .totes .botones,
    .editor .totes .btn-fila { grid-column: 2; grid-row: 1 / -1; display: flex; gap: 8px; }
    .editor .totes .btn { width: auto; }
}

/* Miniatura del artículo en el buscador de líneas. */
.sugerencias img { width: 42px; height: 42px; border-radius: calc(10px * var(--rr)); object-fit: cover; background: var(--wash); flex: none; }

/* Buscador con lupa dentro del campo. */
.conlupa { position: relative; display: flex; align-items: center; }
.conlupa .lupabtn { position: absolute; left: 4px; width: 30px; height: 30px; display: flex;
    align-items: center; justify-content: center; border: 0; background: none; color: var(--g-d);
    cursor: pointer; border-radius: calc(8px * var(--rr)); padding: 0; }
.conlupa .lupabtn:hover { background: var(--surf); }
.conlupa .lupabtn:disabled { opacity: .5; }
.conlupa .input { padding-left: 35px; }

/* Alta rapida de articulo, plegada hasta que hace falta. */
/* ── La fila de meter articulos ────────────────────────────────────────────
   Lector, buscador y alta rapida: tres cosas del mismo gesto que estaban en
   tres alturas distintas y se comian el primer pantallazo del editor. En el
   ordenador van una al lado de la otra; en el movil siguen apiladas, que ahi
   el ancho no da para tres. */
.buscar-fila { display: grid; gap: 11px; }

@media (min-width: 900px) {
    .buscar-fila { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; align-items: end; }
    .buscar-fila > .field { margin-bottom: 0; }
    /* Al abrirla, el formulario del articulo nuevo se estira de lado a lado:
       es cuando de verdad necesita el ancho. */
    .buscar-fila > .altaart.en-fila[open] { grid-column: 1 / -1; }
    .buscar-fila > .sugerencias, .buscar-fila > .ayuda { grid-column: 1 / -1; }
}

/* El alta rapida metida en la fila: cerrada mide lo que un campo (46 px) y
   solo dice su nombre; abierta vuelve a ser la tarjeta de siempre. */
.altaart.en-fila {
    margin: 0; align-self: end; background: var(--surf);
    border: 1px solid var(--line); border-radius: calc(14px * var(--rr));
}
.altaart.en-fila > summary { padding: 0 13px; min-height: 46px; gap: 9px; }
.altaart.en-fila .aa-que { flex: 1; min-width: 0; }
.altaart.en-fila .aa-t { display: block; font-weight: 650; white-space: nowrap; }
.altaart.en-fila .aa-s { display: block; font-size: 12.5px; color: var(--mut); }
.altaart.en-fila:not([open]) .aa-s { display: none; }
.altaart.en-fila:not([open]) .sq { width: 30px; height: 30px; }
.altaart.en-fila[open] > summary { padding: 13px 14px; }

.altaart { margin-top: 12px; }
.altaart > summary { display: flex; align-items: center; gap: 12px; padding: 13px 14px;
    cursor: pointer; list-style: none; }
.altaart > summary::-webkit-details-marker { display: none; }
.altaart[open] > summary { border-bottom: 1px solid var(--line); }
.altaart > form { padding: 13px 14px 14px; }

/* Miniatura del articulo en las lineas del documento. */
.minia { width: 42px; height: 42px; border-radius: calc(10px * var(--rr)); overflow: hidden; flex: 0 0 auto;
    background: var(--surf); border: 1px solid var(--line); display: flex; align-items: center;
    justify-content: center; color: var(--slate); }
.minia img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Sin foto queda el dibujo de la caja: el hueco no se ve vacio. */
.minia:not(:has(img)) { background: var(--slate-w); }

/* Capa de "procesando", para las esperas largas (la IA tarda 8-15 s). */
.procesando { position: fixed; inset: 0; z-index: 90; display: none; align-items: center;
    justify-content: center; padding: 24px; background: rgba(9, 46, 38, .55);
    backdrop-filter: blur(3px); }
.procesando.on { display: flex; }
.procesando .caja { background: #fff; border-radius: calc(18px * var(--rr)); padding: 22px 20px; width: 100%;
    max-width: 330px; text-align: center; box-shadow: 0 18px 44px rgba(0,0,0,.25); }
.procesando .tit { font-weight: 700; font-size: 16px; color: var(--ink); }
.procesando .det { font-size: 13px; color: var(--mut); margin-top: 6px; line-height: 1.45; }
.procesando .seg { font-size: 12.5px; color: var(--g-d); font-weight: 700; margin-top: 10px;
    font-variant-numeric: tabular-nums; }
.procesando .barra { height: 6px; border-radius: 99px; background: var(--surf); overflow: hidden;
    margin-top: 14px; }
.procesando .barra i { display: block; height: 100%; width: 40%; border-radius: 99px;
    background: linear-gradient(90deg, var(--g), var(--g-d));
    animation: avCorre 1.15s ease-in-out infinite; }
@keyframes avCorre {
    0%   { transform: translateX(-105%); }
    100% { transform: translateX(255%); }
}
@media (prefers-reduced-motion: reduce) {
    .procesando .barra i { animation: none; width: 100%; opacity: .6; }
}

/* Boton pequeno, para acciones dentro de una fila. */
.btn.chico { padding: 6px 11px; font-size: 12.5px; border-radius: calc(10px * var(--rr)); width: auto;
    display: inline-flex; gap: 5px; }

/* Referencia del articulo, en su propia linea y sin recortar. */
.ref { display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px; font-weight: 700; letter-spacing: .3px; color: var(--g-d);
    background: var(--wash); border-radius: calc(6px * var(--rr)); padding: 2px 7px; margin-bottom: 4px; }

/* Avisos de la IA, plegados: se lee el primero y el resto se despliega. */
.aviso.avisos { padding: 0; }
.aviso.avisos > summary { display: flex; align-items: center; gap: 8px; cursor: pointer;
    list-style: none; padding: 11px 13px; }
.aviso.avisos > summary::-webkit-details-marker { display: none; }
.aviso.avisos > summary::after { content: '⌄'; margin-left: auto; font-size: 16px; opacity: .7; }
.aviso.avisos[open] > summary::after { content: '⌃'; }
.aviso.avisos > summary .linea { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    min-width: 0; }
.aviso.avisos[open] > summary .linea { white-space: normal; }
.aviso.avisos > summary .cuantos { flex: 0 0 auto; font-weight: 700; font-size: 12px;
    border-radius: 99px; padding: 1px 7px; background: rgba(0, 0, 0, .07); }
.aviso.avisos .mas { padding: 0 13px 11px; }
.aviso.avisos .mas + .mas { padding-top: 0; }
/* El boton de ir al programa desde el acceso de la app. Es un boton y no un
   enlace subrayado: lleva a OTRA casa, y eso se dice con su marca delante, no
   con un subrayado que parece una nota al pie. */
.av-login-erp {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 9px 14px 9px 10px; border-radius: 99px;
    background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .28);
    color: #fff; font-weight: 650; font-size: 13.5px; text-decoration: none;
}
.av-login-erp:hover { background: rgba(255, 255, 255, .24); text-decoration: none; }
.av-login-erp svg:last-child { opacity: .8; }
.av-login-erp .av-marca .marca-fondo { fill: #fff; opacity: .92; }
.av-login-erp .av-marca .marca-flecha { stroke: var(--g-d); }

/* En la tarjeta clara —el diseno de una sola columna— el boton va sobre
   blanco, asi que el blanco translucido no se veria. */
.av-login .card ~ .av-login-erp,
.av-login:not(.doble) .av-login-erp {
    background: var(--wash); border-color: var(--line); color: var(--g-d);
}
.av-login:not(.doble) .av-login-erp:hover { background: var(--g-d); color: #fff; }
.av-login:not(.doble) .av-login-erp:hover .av-marca .marca-flecha { stroke: var(--g-d); }

/* ==========================================================================
   Editor de líneas del documento.

   En el móvil cada línea es un bloque: foto y descripción arriba, los tres
   números debajo. En el ordenador la misma línea se estira de lado a lado y
   ocupa UNA fila —como una hoja de cálculo—, que es lo que permite ver el
   documento entero sin bajar.
   ========================================================================== */
.lineas { display: flex; flex-direction: column; }

.linea {
    display: grid; gap: 8px 10px; padding: 11px 13px;
    grid-template-columns: var(--c-minia, 38px) minmax(0, 1fr) auto;
    grid-template-areas: "minia desc desc" "nums nums nums" "acts acts imp";
    align-items: center; border-bottom: 1px solid var(--line);
}
.linea:last-child { border-bottom: none; }
.linea:hover { background: color-mix(in srgb, var(--wash) 45%, #fff); }

.linea .minia { grid-area: minia; width: 38px; height: 38px; color: var(--slate); }
.linea .minia:not(:has(img)) {
    display: flex; align-items: center; justify-content: center;
    background: var(--slate-w); border-radius: calc(10px * var(--rr));
}
.linea .lin-desc { grid-area: desc; min-width: 0; position: relative; }

/* Los artículos que cuadran con lo que se está escribiendo en la línea.
   Va pegado al campo y por encima de todo: se elige y la línea se rellena. */
.lin-sug {
    position: absolute; z-index: 30; left: 0; top: 100%; margin-top: 4px;
    /* Ancho de sobra para que el nombre del artículo quepa: cortado a la
       primera sílaba no sirve para elegir, que es para lo que se abre. */
    min-width: min(380px, 92vw); width: max-content; max-width: min(520px, 94vw);
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(12px * var(--rr));
    box-shadow: 0 14px 34px rgba(9, 46, 38, .16); overflow: hidden auto; max-height: 268px;
}
.lin-sug button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: none; border: 0; border-bottom: 1px solid var(--line);
    padding: 8px 11px; cursor: pointer; font: inherit; color: var(--ink-2);
}
.lin-sug button:last-child { border-bottom: 0; }
.lin-sug button:hover, .lin-sug button:focus-visible { background: var(--wash); }

/* La foto del artículo, pequeña: se reconoce antes por el dibujo que leyendo.
   Sin foto, el mismo cuadro con el icono, para que las filas no bailen. */
.minia-sug {
    width: 30px; height: 30px; flex: none; border-radius: calc(8px * var(--rr)); object-fit: cover;
    background: var(--wash); border: 1px solid var(--line);
}
.minia-sug.vacia { display: grid; place-items: center; color: var(--mut); }

/* El nombre entero, hasta dos líneas: cortado a la primera palabra no sirve
   de nada, que es justo lo que hay que leer para elegir. */
.lin-sug .que { flex: 1 1 auto; min-width: 140px; }
.lin-sug .t { display: block; font-size: 12.5px; font-weight: 650; color: var(--ink);
    line-height: 1.25; overflow: hidden; display: -webkit-box;
    -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.lin-sug .s { display: block; font-size: 11px; color: var(--mut); margin-top: 2px; }

/* A la derecha, el precio y debajo el stock. */
.lin-sug .p { flex: 0 0 auto; text-align: right; font-weight: 700; font-size: 12.5px;
    color: var(--ink); white-space: nowrap; }
.lin-sug .stk { display: block; font-size: 11px; font-weight: 650; color: var(--g-d); margin-top: 2px; }
.lin-sug .stk.cero { color: var(--mut); }
.linea .lin-desc .s { display: block; font-size: 11.5px; color: var(--mut); margin-top: 3px; }
.linea .lin-desc .input.desc {
    font-weight: 650; height: auto; min-height: 44px; padding-top: 11px; padding-bottom: 11px;
    line-height: 1.35; resize: vertical; overflow: hidden;
}
.linea .lin-nums { grid-area: nums; display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.linea .imp { grid-area: imp; text-align: right; font-weight: 700; white-space: nowrap; }
.linea .lin-acts { grid-area: acts; display: flex; gap: 4px; }

/* Los botones de la fila: discretos, para que no compitan con los números. */
.linea .lin-acts .icobtn {
    width: 30px; height: 30px; background: none; color: var(--mut); border-radius: calc(9px * var(--rr));
}
.linea .lin-acts .icobtn:hover { background: var(--wash); color: var(--g-d); }
.linea .lin-acts .icobtn.rojo:hover { background: var(--red-w); color: var(--red); }

/* Cabecera de columnas: solo tiene sentido con la fila estirada. */
.lin-cab { display: none; }
.lin-pie { display: flex; gap: 7px; flex-wrap: wrap; border-top: 1px solid var(--line); }
.btn.auto { width: auto; padding: 0 16px; height: 42px; }

/* Los botones del pie de las líneas, pequeños: son cinco y así caben en una
   sola fila; lo que importa ahí son las líneas, no los botones. */
.lin-pie .btn.auto {
    height: 34px; padding: 0 11px; font-size: 12.5px; border-radius: calc(10px * var(--rr)); gap: 6px;
}
.lin-pie .btn.auto svg { width: 15px; height: 15px; }

/* La fila estirada solo cuando de verdad cabe: con el pie de totales al lado,
   por debajo de 1200 px la descripción se quedaba en un hilo y la cabecera se
   solapaba. Entre el móvil y ese ancho, la línea sigue en bloque. */
@media (min-width: 1200px) {
    .linea {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 92px var(--c-dto, 66px) 92px auto;
        grid-template-areas: "minia desc cant precio dto imp acts";
        gap: 8px; padding: 8px 12px;
    }
    /* La descripción es lo que más se lee: los botones se aprietan para
       dejarle sitio, que es lo que se echaba de menos en el ERP.

       Y el sitio de los botones es fijo —el de OCHO, que es el máximo desde
       que el historial salió del menú «…»— aunque la fila tenga seis: si no,
       una línea con artículo y otra sin él empujaban distinto y los números no
       caían bajo su título. Ocho botones de 27 px con 2 de separación son
       230; si algún día se añade otro, esta cuenta hay que rehacerla. */
    .linea .lin-acts { gap: 2px; width: 230px; justify-content: flex-end; }
    .linea .lin-acts .icobtn { width: 27px; height: 27px; }
    .linea .lin-nums { display: contents; }
    /* Con la cabecera puesta, la etiqueta de cada casilla sobra en cada fila. */
    .linea .lin-nums .field { margin-bottom: 0; }
    .linea .lin-nums .field label { display: none; }
    /* Por su nombre y no por su posición: con las columnas opcionales
       delante, la cantidad deja de ser la primera. */
    .linea .lin-nums .field[data-col="cantidad"] { grid-area: cant; }
    .linea .lin-nums .field[data-col="pvpunitario"] { grid-area: precio; }
    .linea .lin-nums .field[data-col="dtopor"] { grid-area: dto; }
    .linea .lin-nums .field[data-col="unidades"] { grid-area: uds; }

    /* ── El embalaje y las medidas, en la MISMA fila ──
       Son campos de unos artículos sí y de otros no, así que no había
       columna reservada para ellos: la rejilla los auto-colocaba y
       auto-colocar donde hay áreas nombradas significa fila nueva. La línea
       se partía en dos justo en la pantalla donde más sitio hay.

       Ahora, si el documento lleva alguno, la columna existe para TODAS sus
       líneas -que es lo que hace que la cabecera cuadre- y las que no lo
       usan dejan el hueco vacío. Es el mismo trato que ya tenían unidades y
       bultos. */
    .linea .lin-nums .field[data-col="pisos"] { grid-area: pis; }
    .linea .lin-nums .field[data-col="cajas"] { grid-area: caj; }
    .linea .lin-nums .field[data-col="uds"] { grid-area: udc; }
    .linea .lin-nums .field[data-col="pomos"] { grid-area: pom; }
    .linea .lin-nums .field[data-col="largo"] { grid-area: lar; }
    .linea .lin-nums .field[data-col="ancho"] { grid-area: anc; }
    .linea .lin-nums .field[data-col="alto"] { grid-area: alt; }

    .lineas.con-pisos .linea, .lin-cab.con-pisos {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 64px 64px 68px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-pisos .linea {
        grid-template-areas: "minia desc cant pis caj udc precio dto imp acts";
    }

    .lineas.con-pomos .linea, .lin-cab.con-pomos {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 68px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-pomos .linea {
        grid-template-areas: "minia desc cant pom precio dto imp acts";
    }

    .lineas.con-medidas .linea, .lin-cab.con-medidas {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 64px 64px 64px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-medidas .linea {
        grid-template-areas: "minia desc cant lar anc alt precio dto imp acts";
    }
    .linea .lin-nums .field[data-col="bultos"] { grid-area: bul; }
    .linea .lin-nums .input { text-align: right; }
    .linea .lin-desc .input.desc { border-color: transparent; background: transparent; padding-left: 0; }
    .linea .lin-desc .input.desc:focus { border-color: var(--g); background: var(--surf); padding-left: 12px; }

    .lin-cab {
        display: grid; gap: 8px; padding: 9px 12px;
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 92px var(--c-dto, 66px) 92px auto;
        border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
        font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
        font-weight: 700; color: var(--mut);
    }
    /* Los títulos de las casillas, con el mismo hueco a la derecha que tiene
       el texto dentro del recuadro: así «CANTIDAD» cae justo encima de su
       número y no trece píxeles a la derecha. */
    .lin-cab span:nth-child(n+3) { text-align: right; }
    .lin-cab span:nth-child(3),
    .lin-cab span:nth-child(4),
    .lin-cab span:nth-child(5) { padding-right: 13px; }
    /* Tanto como ocupan los botones de la fila. */
    .lin-cab .hueco { width: 230px; }

    /* Con las columnas de unidades o de bultos encendidas, la rejilla crece.
       La cabecera y las filas comparten la misma plantilla, que es lo que las
       mantiene alineadas.

       **Unidades va detrás de la cantidad**, no delante. La cantidad es lo que
       se teclea siempre y lo que manda en el precio; las unidades son las de
       verdad —kilos, metros— y salen de ella. Con las unidades delante, el
       primer hueco de la fila era el que casi nunca se rellena, y el dedo
       tenía que saltárselo en cada línea. */
    .lineas.con-uds .linea,
    .lin-cab.con-uds:not(.con-bultos) {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 86px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-uds .linea { grid-template-areas: "minia desc cant uds precio dto imp acts"; }

    .lineas.con-bultos .linea,
    .lin-cab.con-bultos:not(.con-uds) {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 86px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-bultos .linea { grid-template-areas: "minia desc cant bul precio dto imp acts"; }

    .lineas.con-uds.con-bultos .linea,
    .lin-cab.con-uds.con-bultos {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 86px 86px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-uds.con-bultos .linea {
        grid-template-areas: "minia desc cant uds bul precio dto imp acts";
    }

    /* El coste, cuando se puede escribir a mano. Se cuela justo antes del
       precio, que es su sitio natural: se mira el coste y se pone el precio.

       Con las rejillas de arriba ya declaradas por nombre de área, aquí basta
       con estirar la plantilla y decir dónde cae. */
    .lineas.con-coste .linea,
    .lin-cab.con-coste:not(.con-uds):not(.con-bultos) {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 84px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-coste .linea { grid-template-areas: "minia desc cant cos precio dto imp acts"; }

    .lineas.con-uds.con-coste .linea,
    .lin-cab.con-uds.con-coste:not(.con-bultos) {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 86px 84px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-uds.con-coste .linea {
        grid-template-areas: "minia desc cant uds cos precio dto imp acts";
    }

    .lineas.con-uds.con-bultos.con-coste .linea,
    .lin-cab.con-uds.con-bultos.con-coste {
        grid-template-columns: var(--c-minia, 34px) minmax(0, 1fr) 76px 86px 86px 84px 92px var(--c-dto, 66px) 92px 230px;
    }
    .lineas.con-uds.con-bultos.con-coste .linea {
        grid-template-areas: "minia desc cant uds bul cos precio dto imp acts";
    }

    .linea .lin-nums .field[data-col="coste"] { grid-area: cos; }
    /* El coste no es el precio: en gris, para no confundirlos de un vistazo. */
    .linea .lin-nums .field[data-col="coste"] .input { color: var(--ink-2); }

    /* Unidades y bultos son texto: se leen mejor pegados a la izquierda. */
    .linea .lin-nums .field[data-col="unidades"] .input,
    .linea .lin-nums .field[data-col="bultos"] .input { text-align: left; }
}

/* El editor es la pantalla que más ancho pide: se le deja toda la mesa. */
@media (min-width: 1280px) {
    .contenido.ancho { max-width: 1560px; }
    /* A partir de aquí las líneas ya tienen toda la mesa; los totales siguen
       abajo, que es donde no estorban. */
    .editor { display: flex; }
}

/* ── Panel del historial del artículo ──────────────────────────────────────
   En el móvil sube desde abajo (se llega con el pulgar); en el ordenador es
   una ventana centrada. Misma marca, mismas tarjetas.
   ------------------------------------------------------------------------ */
.av-panel {
    position: fixed; inset: 0; z-index: 60; background: rgba(14, 26, 23, .45);
    display: flex; align-items: flex-end; justify-content: center;
}
/* Sin esto el panel nace abierto: el display:flex de arriba le gana al
   [hidden] del navegador, que es solo display:none del estilo por defecto. */
.av-panel[hidden] { display: none; }
.av-panel-caja {
    background: var(--canvas); width: 100%; max-height: 86vh; display: flex; flex-direction: column;
    border-radius: calc(18px * var(--rr)) calc(18px * var(--rr)) 0 0; box-shadow: 0 -10px 40px rgba(14, 26, 23, .25);
}
.av-panel-top {
    display: flex; align-items: center; gap: 10px; padding: 14px 16px;
    background: linear-gradient(168deg, var(--g-d), var(--g-dd)); color: #fff;
    border-radius: calc(18px * var(--rr)) calc(18px * var(--rr)) 0 0;
}
.av-panel-top > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.av-panel-top .icobtn { background: rgba(255, 255, 255, .16); color: #fff; }
.av-panel-filtro { padding: 12px 16px 0; }
.av-panel-cuerpo { padding: 14px 16px 22px; overflow-y: auto; }
.av-panel-cuerpo .rows { background: var(--surf); border: 1px solid var(--line); border-radius: calc(14px * var(--rr)); }

/* Lo que se gana: los tres números que se miran antes de dar un precio. */
.hist-margen {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; margin-bottom: 14px;
}
.hist-margen > div {
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(14px * var(--rr)); padding: 10px 12px;
}
.hist-margen .etiqueta {
    display: block; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--mut); font-weight: 700;
}
.hist-margen .v { display: block; font-weight: 750; font-size: 15px; letter-spacing: -.02em; margin-top: 3px; }

.hist-tit {
    display: flex; align-items: center; gap: 10px; margin: 16px 0 8px;
    font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--mut); font-weight: 700;
}
.hist-tit .btn { margin-left: auto; text-transform: none; letter-spacing: 0; }
.av-panel-cuerpo .row .amt { margin-right: 6px; }

/* Los botones de cada fila del panel (meter como línea, poner en
   observaciones, añadir al documento). Sin esto heredaban el estilo de los
   botones de la barra oscura: blancos sobre fondo claro, invisibles. */
.av-panel-cuerpo .row .icobtn {
    width: 32px; height: 32px; background: var(--wash); color: var(--g-d);
    border: 1px solid var(--line);
}
.av-panel-cuerpo .row .icobtn:hover { background: var(--g-d); color: #fff; border-color: var(--g-d); }

@media (min-width: 768px) {
    .av-panel { align-items: center; padding: 20px; }
    .av-panel-caja { max-width: 760px; border-radius: calc(18px * var(--rr)); max-height: 84vh; }
    .av-panel-top { border-radius: calc(18px * var(--rr)) calc(18px * var(--rr)) 0 0; }
}

/* El importe que avisa dentro de una tarjeta de acción: una chapa en la
   esquina, no una línea más. Así el rótulo no se parte en tres. */
.act { position: relative; }
/* Debajo del rótulo, no encima: flotando en la esquina caía sobre el icono en
   el móvil y sobre el texto en el ordenador —se leía «Imp847,00 €ada»—. */
.act .act-aviso {
    display: block; width: fit-content; margin: 5px auto 0;
    /* Y nunca mas ancha que su boton: en el movil el boton mide 65 px y un
       importe de siete cifras se salia por los dos lados, cruzando el borde
       redondeado. Que parta antes que salirse. */
    max-width: 100%;
    padding: 1px 5px; border-radius: calc(7px * var(--rr));
    font-size: 10px; font-weight: 800; line-height: 1.5;
    background: var(--wash); color: var(--ink-2);
}
.act .act-aviso.rojo { background: var(--red-w); color: var(--red); }
.act.red { border-color: color-mix(in srgb, var(--red) 45%, #fff); }
.act.red .ic { background: var(--red-w); color: var(--red); }
/* El rótulo, no la chapa del importe: con chapa, «:last-child» era ella. */
.act.red > span:not(.ic):not(.act-aviso) { color: var(--red); font-weight: 750; }

/* Con algo vencido el botón se enciende del todo: no es un aviso más, es lo
   que hay que mirar antes de servirle otra vez. */
.act.red.urge { background: var(--red-w); border-color: var(--red); }
.act.red.urge .ic { background: var(--red); color: #fff; }

/* El riesgo: cuánto de lo que se le deja fiar lleva gastado. */
.riesgo-barra { display: block; height: 9px; border-radius: calc(5px * var(--rr)); background: var(--wash);
    margin-top: 12px; overflow: hidden; }
.riesgo-barra span { display: block; height: 100%; border-radius: calc(5px * var(--rr));
    background: linear-gradient(90deg, var(--g-l), var(--g)); }
.riesgo-barra span.malo { background: var(--red); }
.kpi.hi-malo { background: var(--red-w); border-color: color-mix(in srgb, var(--red) 35%, #fff); }

/* La barra del lector de códigos: la primera de las líneas, con el cursor
   dentro al entrar. */
.lector-fila label .s { display: block; font-weight: 600; color: var(--mut); font-size: 11.5px; }
.lector-fila .icobtn { background: var(--wash); color: var(--g-d); pointer-events: none; }
.lector-fila #avLector { letter-spacing: .04em; }
.lector-fila .verde { color: var(--g-d); font-weight: 650; }
.lector-fila .rojo { color: var(--red); font-weight: 650; }

/* El repaso de la contabilidad: cada hallazgo en su tarjeta, con una franja de
   color a la izquierda segun lo que corra. El rojo no es decoracion: es lo que
   bloquea a lo demas. */
.rev { border-left: 4px solid var(--bor); }
.rev-para { border-left-color: var(--red); }
.rev-mira { border-left-color: var(--amber, #e0a800); }
.rev-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
.rev-cab strong { flex: 1; }
.rev-ej { margin-top: 10px; background: var(--wash); border-radius: calc(8px * var(--rr)); }
.rev-ej .row { padding: 7px 10px; }
.rev-limpias summary { cursor: pointer; }
.rev-limpias .rows { margin-top: 10px; }

/* La caja de la IA del Panel de gerencia: el desplegable y la pregunta a lo
   ancho, con su boton al lado, y la respuesta en un recuadro que se distingue
   de los numeros —es una lectura, no un dato—. */
.ia-fila { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.ia-fila .btn { white-space: nowrap; }
.ia-respuesta { margin-top: 12px; padding: 12px 14px; background: var(--wash);
    border-left: 3px solid var(--g); border-radius: calc(8px * var(--rr)); }
.ia-respuesta p { margin: 0 0 8px; line-height: 1.6; }
.ia-respuesta p:last-child { margin-bottom: 0; }

/* Las casillas del embalaje del vivero: pisos, cajas y unidades. Van mas
   estrechas que la cantidad —son numeros de dos cifras— y con la etiqueta en
   verde, para que se vea de un golpe que esas tres mandan sobre la cantidad. */
.linea .field.emb { max-width: 74px; }
.linea .field.emb label { color: var(--g-d); font-weight: 650; }
.linea .field.emb .input { text-align: right; }

/* La chuleta de las formulas del vivero: plegada, que no estorbe a quien ya
   se las sabe, y a un toque para el que no. */
.lector-formulas { margin-top: 6px; color: var(--mut); }
.lector-formulas summary { cursor: pointer; font-weight: 650; color: var(--g-d); }
.lector-formulas ul { margin: 6px 0 0; padding-left: 16px; line-height: 1.7; }
.lector-formulas .mono { background: var(--wash); border-radius: calc(4px * var(--rr));
    padding: 1px 5px; font-weight: 650; color: var(--ink); }
.lector-formulas p { margin: 6px 0 0; }

/* La linea que acaba de cambiar por un comando: si no parpadea, se teclea
   «+6» y parece que no ha pasado nada. */
.linea.recien { animation: av-recien .9s ease-out; }
@keyframes av-recien {
    0% { background: var(--g-l); }
    100% { background: transparent; }
}

/* ── Estado de cuenta ─────────────────────────────────────────────────────
   Una fila por recibo: en el móvil se apila y en el ordenador es una tabla
   con su casilla para marcar y el importe que se va a cobrar.
   ------------------------------------------------------------------------ */
.cuenta-cab { display: none; }
.cuenta-fila {
    display: grid; grid-template-columns: 28px 1fr; gap: 4px 10px;
    padding: 11px 14px; border-bottom: 1px solid var(--line); align-items: center;
}
.cuenta-fila.vencida { background: color-mix(in srgb, var(--red-w) 45%, #fff); }
.cuenta-fila .fac { font-weight: 650; }
.cuenta-fila .fac a { color: var(--g-d); }
.cuenta-fila .fac .s { display: block; font-size: 11.5px; color: var(--mut); font-weight: 600; }
.cuenta-fila .fec, .cuenta-fila .ven { font-size: 12.5px; color: var(--ink-2); grid-column: 2; }
.cuenta-fila .imp { grid-column: 2; text-align: left; }
.cuenta-fila .cob { grid-column: 2; }
.cuenta-fila .rec { grid-column: 2; display: flex; gap: 4px; }
/* El sobre y el compartir de cada recibo. Van con «icobtn plain», que es
   blanco porque nacio para la cabecera oscura: dentro de la tarjeta, blanco
   sobre blanco no se ve. */
.cuenta-fila .rec .icobtn { color: var(--mut); }
.cuenta-fila .rec .icobtn:hover { color: var(--g-d); }
.cuenta-fila .cob .input { height: 38px; max-width: 140px; }
.cuenta-marca input { width: 20px; height: 20px; accent-color: var(--ge-sel, var(--g)); }

/* Lo vencido se marca con una chapa roja al lado del título, no pintando la
   cabecera entera: con el menú arriba la cabecera no tiene fondo y el rojo
   dejaba la flecha de volver y el subtítulo ilegibles. */
.top .pill.bad { vertical-align: middle; }

@media (min-width: 1000px) {
    .cuenta-cab {
        display: grid; gap: 10px; padding: 8px 14px;
        grid-template-columns: 28px minmax(0, 1.2fr) 100px 150px 120px 140px 78px;
        font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
        color: var(--mut); font-weight: 700; border-bottom: 1px solid var(--line);
    }
    .cuenta-fila {
        grid-template-columns: 28px minmax(0, 1.2fr) 100px 150px 120px 140px 78px; gap: 10px;
    }
    .cuenta-fila .fec, .cuenta-fila .ven, .cuenta-fila .imp, .cuenta-fila .cob,
    .cuenta-fila .rec { grid-column: auto; }
    .cuenta-fila .imp { text-align: right; }
    .cuenta-fila .solo-movil { display: none; }
}

/* El dibujo de un texto: el icono o la foto que lo acompaña. */
.texto-dibujo {
    width: 30px; height: 30px; flex: none; object-fit: contain; padding: 4px;
    border-radius: calc(9px * var(--rr)); background: var(--wash);
}
.dibujo-fila { display: flex; align-items: center; gap: 8px; }
.dibujo-fila .input { flex: 1; min-width: 0; }
.dibujo-actual {
    width: 44px; height: 44px; flex: none; display: grid; place-items: center;
    border-radius: calc(12px * var(--rr)); background: var(--wash); color: var(--g-d);
}
.dibujo-actual img { width: 24px; height: 24px; object-fit: contain; }
.iconos-rejilla {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 6px;
    margin-top: 10px; max-height: 250px; overflow-y: auto; padding: 6px;
    border: 1px solid var(--line); border-radius: calc(12px * var(--rr)); background: var(--wash);
}
.iconos-rejilla button {
    height: 44px; border: 1px solid transparent; border-radius: calc(10px * var(--rr)); cursor: pointer;
    background: var(--surf); display: grid; place-items: center;
}
.iconos-rejilla button:hover { border-color: var(--g); }
.iconos-rejilla img { width: 22px; height: 22px; object-fit: contain; }

/* El contador de los paneles: − cantidad +, para llevarse varias de una vez. */
.hist-cant { display: flex; align-items: center; gap: 2px; flex: none; }
.hist-cant .icobtn {
    width: 28px; height: 28px; font-size: 16px; font-weight: 700; line-height: 1;
    background: var(--wash); color: var(--g-d); border-radius: calc(8px * var(--rr));
}
.hist-cant .icobtn:hover { background: var(--g-d); color: #fff; }
.hist-cant .input {
    width: 46px; height: 28px; padding: 0 4px; text-align: center;
    font-size: 13px; font-weight: 650; border-radius: calc(8px * var(--rr));
}

/* La miniatura del artículo en «Compras del cliente» y en «Productos vivos».
   Cuando el artículo no tiene foto va el mismo hueco con un icono dentro: así
   todas las filas empiezan a la misma altura y la lista se lee en columna. */
.minia-hist {
    width: 38px; height: 38px; flex: none; border-radius: calc(10px * var(--rr)); object-fit: cover;
    background: var(--wash); border: 1px solid var(--line);
}
.minia-hist.vacia { display: grid; place-items: center; color: var(--mut); }

/* La foto y la referencia de una línea llevan a la ficha del artículo: se nota
   que se pueden tocar, sin cambiar el aspecto de la línea. */
a.minia, button.minia { cursor: pointer; transition: box-shadow .12s ease; padding: 0; }
a.minia:hover, a.minia:focus-visible,
button.minia:hover, button.minia:focus-visible {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--g) 55%, transparent);
    border-color: var(--g);
}

/* ── El panel de gerencia ──────────────────────────────────────────────────
   Las barras se dibujan con CSS: ni una biblioteca que cargar, y en el móvil
   se ven igual de bien. */
.barras { display: flex; align-items: flex-end; gap: 4px; height: 150px; }
.barras .barra { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100%; }
.barras .tallo { flex: 1; display: flex; align-items: flex-end; }
.barras .tallo span {
    display: block; width: 100%; border-radius: calc(5px * var(--rr)) calc(5px * var(--rr)) 0 0;
    background: linear-gradient(180deg, var(--g), color-mix(in srgb, var(--g) 55%, #fff));
    min-height: 2px;
}
.barras .pie {
    font-size: 9.5px; color: var(--mut); text-align: center; margin-top: 5px;
    white-space: nowrap; overflow: hidden; font-variant-numeric: tabular-nums;
}

/* ── La cuenta hecha de los recargos ───────────────────────────────────────
   Salones en filas y horas en columnas. Con cuatro salones y cuatro franjas ya
   no cabe en un móvil, así que la tabla se desliza sola dentro de su tarjeta:
   la página no se mueve. */
.tabla-ancha { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rec-tabla { width: 100%; border-collapse: collapse; font-size: 13px; }
.rec-tabla th, .rec-tabla td {
    padding: 9px 12px; white-space: nowrap; border-bottom: 1px solid var(--line);
    font-variant-numeric: tabular-nums;
}
.rec-tabla th {
    font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--mut); font-weight: 700; text-align: left;
}
.rec-tabla td { color: var(--ink-2); }
.rec-tabla tr:last-child td { border-bottom: none; }
.rec-tabla .der { text-align: right; }
.rec-mas { color: var(--ink); font-weight: 650; }
.rec-menos { color: var(--g); font-weight: 650; }

/* El atajo al monedero desde la ficha del cliente: una tarjeta que se pulsa,
   con la misma forma que una fila de lista. */
.mon-atajo { display: flex; align-items: center; gap: 11px; }

/* ── Un pedido que ha entrado solo ─────────────────────────────────────────
   Lo que ha pedido, en una sola línea de etiquetas: es lo que hay que
   preparar, y abrir pedido por pedido para verlo no vale cuando hay cinco
   esperando. */
.ped-lineas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ped-linea {
    display: inline-flex; align-items: baseline; gap: 4px;
    background: var(--wash); border-radius: calc(9px * var(--rr));
    padding: 4px 9px; font-size: 12.5px; color: var(--ink-2); line-height: 1.35;
}
.ped-linea b { font-variant-numeric: tabular-nums; color: var(--ink); }

/* Aceptar es decir en cuántos minutos estará: el desplegable y el botón van
   juntos, que es un solo gesto. */
.ped-acepta { display: grid; grid-template-columns: 110px 1fr; gap: 8px; margin-top: 12px; }
.ped-acepta .btn { margin-top: 0; }

/* Un pedido que lleva demasiado esperando se ve desde lejos. */
.card.malo { border-color: var(--red); background: var(--red-w); }

/* La explicacion de un modulo, plegada bajo su nombre. Son setenta y cinco:
   desplegadas no se encontraria ninguna, y sin ellas nadie sabe que enciende. */
.mod-mas { margin-top: 6px; }
.mod-mas > summary {
    display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
    font-size: 12px; font-weight: 650; color: var(--g-d); list-style: none;
}
.mod-mas > summary::-webkit-details-marker { display: none; }
/* La flecha es el icono de la app, girado: un carácter suelto se dibuja
   distinto en cada teléfono y en alguno salía una cosa rara. */
.mod-mas > summary svg { transform: rotate(90deg); transition: transform .15s ease; }
.mod-mas[open] > summary svg { transform: rotate(-90deg); }
.mod-texto {
    display: block; margin-top: 7px; font-size: 13px; line-height: 1.5;
    color: var(--ink-2); white-space: normal;
}
.mod-donde {
    display: block; margin-top: 6px; font-size: 12px; line-height: 1.45;
    color: var(--mut); white-space: normal;
}
.mod-donde svg { vertical-align: -2px; }
/* Lo que conviene saber antes de tocarlo: se distingue, pero no alarma. */
.mod-ojo { color: var(--amber); }
.mod-texto a, .mod-donde a { color: var(--g-d); text-decoration: underline; }

/* Lo que trae un plugin: sus pantallas, una debajo de otra. Alguno trae
   ciento veintiséis, así que en pantalla grande se reparten en columnas;
   en una sola fila india no se acaba nunca de bajar. */
.plug-pant {
    display: block; padding: 2px 0; break-inside: avoid;
}
.plug-pant .pill { margin-left: 5px; }
.plug-pant .s { margin-left: 5px; color: var(--mut); }
@media (min-width: 900px) {
    .plug-trae[open] .mod-texto { columns: 2; column-gap: 26px; }
}
@media (min-width: 1400px) {
    .plug-trae[open] .mod-texto { columns: 3; }
}

/* El peso de un cliente sobre el total, bajo su nombre. */
.mini-barra {
    display: block; height: 5px; border-radius: 99px; background: var(--slate-w);
    margin-top: 5px; overflow: hidden; max-width: 260px;
}
.mini-barra span { display: block; height: 100%; background: var(--g); border-radius: 99px; }

/* Un indicador que pide atención sin llegar a ser un error. */
.kpi.aviso-kpi { border-color: var(--amber); }
.kpi.aviso-kpi .val { color: var(--amber); }
a.kpi { display: block; transition: box-shadow .12s ease; }
a.kpi:hover { box-shadow: 0 0 0 2px color-mix(in srgb, var(--g) 45%, transparent); }

/* El pendiente repartido por vencimiento: de un vistazo se ve cuánto de lo
   que falta por cobrar ya se pasó de fecha. */
.tramo-barra {
    display: flex; height: 13px; border-radius: 99px; overflow: hidden;
    background: var(--slate-w); margin-bottom: 11px;
}
.tramo-barra span { display: block; height: 100%; }
.t-venc { background: var(--red); }
.t-30 { background: var(--amber); }
.t-60 { background: var(--g); }
.t-90 { background: color-mix(in srgb, var(--g) 60%, #fff); }
.t-mas { background: var(--slate); }

.tramos { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 14px; font-size: 12.5px; }
.tramos .tramo { display: flex; align-items: center; gap: 7px; }
.tramos .tramo b { margin-left: auto; font-variant-numeric: tabular-nums; }
.tramos .p { width: 11px; height: 11px; border-radius: calc(4px * var(--rr)); flex: none; }

@media (min-width: 760px) {
    .tramos { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .tramos .tramo { flex-wrap: wrap; }
    .tramos .tramo b { margin-left: 0; width: 100%; }
}

/* Tablas de cuatro columnas (familias, RFM, trimestres): en el móvil cada
   fila se apila con su etiqueta delante. */
.fam-cab { display: none; }
.fam-fila { display: grid; grid-template-columns: 1fr; gap: 3px; align-items: start; }
.fam-fila .n1 { font-weight: 700; }
.fam-fila .amt { text-align: left; font-weight: 650; }

@media (min-width: 760px) {
    .fam-fila { grid-template-columns: minmax(0, 1.6fr) 1fr 1fr 1fr; gap: 10px; align-items: center; }
    .fam-fila .amt { text-align: right; }
    .fam-cab {
        display: grid; grid-template-columns: minmax(0, 1.6fr) 1fr 1fr 1fr; gap: 10px;
        padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
    }
    .fam-cab span:nth-child(n+2) { text-align: right; }
    .fam-fila .solo-movil { display: none; }
}

/* Las seis pestañas del panel no caben en un móvil: se deslizan. */
.tabs.desliza { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
.tabs.desliza::-webkit-scrollbar { display: none; }
.tabs.desliza a { white-space: nowrap; flex: none; }

/* ── Remesas ───────────────────────────────────────────────────────────────
   Los pasos por los que va la remesa, y los recibos que lleva dentro. */
.pasos { display: grid; grid-template-columns: 1fr; gap: 8px; }
.pasos .paso { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--mut); }
.pasos .bola {
    width: 26px; height: 26px; flex: none; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--slate-w); color: var(--slate); font-weight: 750; font-size: 12px;
}
.pasos .paso.hecho { color: var(--ink); }
.pasos .paso.hecho .bola { background: var(--g); color: #fff; }
.pasos .paso.ahora { color: var(--ink); font-weight: 700; }
.pasos .paso.ahora .bola { background: var(--amber); color: #fff; }

@media (min-width: 760px) {
    .pasos { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .pasos .paso { flex-direction: column; text-align: center; gap: 6px; }
}

.rem-cab { display: none; }
.rem-fila { display: grid; grid-template-columns: 1fr; gap: 3px; align-items: start; }
.rem-fila .q { min-width: 0; }
/* Casilla de alta: meter recibos en una remesa. */
.marca-alta {
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; flex: none; cursor: pointer; border-radius: calc(9px * var(--rr));
}
.marca-alta input { width: 19px; height: 19px; accent-color: var(--g); cursor: pointer; }
.marca-alta:hover { background: var(--slate-w); }

.rem-fila .marca {
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; flex: none; cursor: pointer; border-radius: calc(9px * var(--rr));
}
.rem-fila .marca input { width: 19px; height: 19px; accent-color: var(--red); cursor: pointer; }
.rem-fila .amt { text-align: left; }

@media (min-width: 900px) {
    .rem-fila { grid-template-columns: minmax(0, 1.6fr) 140px 110px 150px; gap: 10px; align-items: center; }
    .rem-fila:has(.marca) { grid-template-columns: 38px minmax(0, 1.6fr) 140px 110px 150px; }
    .rem-fila .amt { text-align: right; }
    .rem-fila .solo-movil { display: none; }
    .rem-cab {
        display: grid; grid-template-columns: minmax(0, 1.6fr) 140px 110px 150px; gap: 10px;
        padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
    }
    .rem-cab:has(span:nth-child(5)) {
        grid-template-columns: 38px minmax(0, 1.6fr) 140px 110px 150px;
    }
    .rem-cab span:last-child { text-align: right; }
}

/* ── El 347: seis columnas ─────────────────────────────────────────────────
   Los cuatro trimestres y el total no caben en un móvil: se apilan con su
   etiqueta y en la mesa vuelven a ser una tabla. */
.op-cab { display: none; }
.op-fila { display: grid; grid-template-columns: 1fr; gap: 3px; align-items: start; }
.op-fila .n1 { font-weight: 700; }
.op-fila .amt { text-align: left; font-weight: 650; }

@media (min-width: 900px) {
    .op-fila {
        grid-template-columns: minmax(0, 2fr) repeat(5, minmax(0, 1fr));
        gap: 8px; align-items: center;
    }
    .op-fila .amt { text-align: right; }
    .op-fila .solo-movil { display: none; }
    .op-cab {
        display: grid; grid-template-columns: minmax(0, 2fr) repeat(5, minmax(0, 1fr));
        gap: 8px; padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
    }
    .op-cab span:nth-child(n+2) { text-align: right; }
}

/* ── El tablero del CRM ────────────────────────────────────────────────────
   Como el de las citas, pero cada columna dice lo que suma y lo que cabe
   esperar de ella: es el número con el que se decide si el mes sale. */
.kanban-crm .tab-suma {
    display: flex; align-items: baseline; gap: 6px; padding: 0 10px 8px;
    font-size: 11.5px; color: var(--mut); border-bottom: 1px solid var(--line);
    margin-bottom: 6px; font-variant-numeric: tabular-nums;
}
.kanban-crm .tab-suma .p { opacity: .8; }
.kanban-crm .tab-suma b { margin-left: auto; color: var(--g-d); font-size: 12.5px; }

.kanban-crm .tab-ficha .t { display: block; font-weight: 700; line-height: 1.3; }
.kanban-crm .tab-ficha .imp {
    display: flex; align-items: baseline; gap: 6px; margin-top: 4px;
    font-weight: 750; font-variant-numeric: tabular-nums;
}
.kanban-crm .tab-ficha .imp .u { margin-left: auto; font-weight: 600; font-size: 11px; color: var(--mut); }

/* La fase que gana y la que pierde, marcadas por arriba. */
.kanban-crm .tab-col.gana .tab-cab { border-top: 2px solid var(--g); }
.kanban-crm .tab-col.pierde .tab-cab { border-top: 2px solid var(--red); }
.kanban-crm .tab-col.pierde .tab-ficha { opacity: .6; }

/* ── El recuento del almacén ───────────────────────────────────────────────
   Cuatro columnas en la mesa y una ficha apilada en el móvil, con la etiqueta
   delante de cada dato para no perderse contando. */
.stock-cab { display: none; }
.stock-fila { display: grid; grid-template-columns: 1fr; gap: 6px; align-items: start; }
/* El articulo de la fila: la foto a la izquierda y el texto al lado, para
   reconocerlo sin leer la referencia. En rejilla y no en flex porque el texto
   tiene que poder encogerse hasta cero sin empujar a la foto. */
.stock-fila .art { display: grid; grid-template-columns: auto 1fr; align-items: center;
    gap: 10px; min-width: 0; }
.stock-foto { width: 38px; height: 38px; border-radius: calc(11px * var(--rr));
    object-fit: cover; background: var(--wash); display: block; grid-row: span 2; }
.stock-foto-no { width: 38px; height: 38px; border-radius: calc(11px * var(--rr));
    grid-row: span 2; }
.stock-fila .c { display: flex; align-items: center; gap: 8px; }
.stock-fila .c .input { max-width: 120px; }
.stock-fila .c .solo-movil { font-size: 11px; color: var(--mut); min-width: 58px; }

/* Lo que hay que reponer se ve sin leer los números. */
.stock-fila.falta { background: color-mix(in srgb, var(--amber-w) 65%, transparent); }
.stock-fila.guardando { opacity: .55; }
.stock-fila.guardado { background: color-mix(in srgb, var(--g-l) 45%, transparent); }

@media (min-width: 900px) {
    .stock-fila {
        grid-template-columns: minmax(0, 1.7fr) 150px 170px minmax(0, 1fr);
        gap: 10px; align-items: center;
    }
    .stock-fila .c .solo-movil { display: none; }
    .stock-cab {
        display: grid; grid-template-columns: minmax(0, 1.7fr) 150px 170px minmax(0, 1fr);
        gap: 10px; padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
    }
}

/* ── Facturación periódica ─────────────────────────────────────────────────
   Los doce meses en una rejilla que cabe en el móvil de tres en tres, y la
   fila de cuota con su casilla para llevarla al documento. */
.meses-rejilla {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px;
}

@media (min-width: 560px) {
    .meses-rejilla { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
    .meses-rejilla { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.meses-rejilla .chip-check { margin: 0; justify-content: flex-start; }

.cuota-fila { align-items: flex-start; }
.cuota-fila .marca {
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; flex: none; cursor: pointer; border-radius: calc(9px * var(--rr));
}
.cuota-fila .marca input { width: 19px; height: 19px; accent-color: var(--g); cursor: pointer; }
.cuota-fila .marca:hover { background: var(--slate-w); }
.cuota-fila .grow { min-width: 0; display: block; }
/* La que ya toca cobrar se nota sin leer las fechas. */
.cuota-fila.toca { background: color-mix(in srgb, var(--amber-w) 70%, transparent); }

/* ── Los datos del artículo, al pulsar su foto ──────────────────────────────
   Un vistazo a precio, coste, stock y código de barras sin salir del
   documento: mientras se atiende a alguien no se puede perder la pantalla. */
.art-ojo { display: flex; gap: 12px; align-items: flex-start; }
.art-ojo .foto {
    width: 76px; height: 76px; flex: 0 0 auto; border-radius: calc(12px * var(--rr)); overflow: hidden;
    border: 1px solid var(--line); background: var(--slate-w);
    display: flex; align-items: center; justify-content: center; color: var(--slate);
}
.art-ojo .foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.art-ojo .des { font-weight: 700; line-height: 1.3; }
.art-ojo .ref { font-size: 12.5px; }
.art-datos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.art-datos .dato {
    border: 1px solid var(--line); border-radius: calc(12px * var(--rr)); padding: 8px 10px; background: var(--surf);
}
.art-datos .dato .lab {
    font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--slate);
}
.art-datos .dato .val { font-weight: 700; font-size: 15px; }
.art-datos .dato .val.red { color: var(--red); }
.art-datos .ancho2 { grid-column: 1 / -1; }
a.ref:hover { background: color-mix(in srgb, var(--g) 22%, #fff); }

/* ==========================================================================
   El armazón: menú lateral y columna de contenido.

   Móvil: no hay lateral, manda la barra de abajo.
   Tableta (768-1199): el lateral se queda en iconos; al tocar uno se abre
   por encima del contenido, sin empujarlo.
   Ordenador (≥1200): lateral abierto con sus grupos y subopciones.
   ========================================================================== */
.av-shell { display: block; }
.lateral {
    display: none; flex-direction: column;
    background: var(--g-d); color: #fff; transition: width .14s ease;
}

/* El interior del menú es el mismo colgado al lado o abierto en el cajón
   del móvil: por eso vive fuera de las medidas de pantalla. */
.lat-marca { display: flex; align-items: center; gap: 8px; padding: 12px 10px; min-height: 58px; }
.lat-marca .brand { display: flex; align-items: center; gap: 9px; font-weight: 800; font-size: 15px; letter-spacing: -.02em; }

/* El nombre y su versión, uno encima de otro. La segunda línea cabe dentro de
   los 58 px que ya ocupaba la marca —de ahí el interlineado corto—, así que la
   versión no empuja el menú ni un píxel hacia abajo. */
.lat-marca .marca-txt { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.12; }
.lat-marca .lat-ver { font-size: 10.5px; font-weight: 700; opacity: .72; letter-spacing: .01em; }
/* Con el menú plegado solo se ve el logotipo: el número sobraría y además no
   cabe. */
.lateral.plegada .marca-txt { display: none; }
.lat-plegar { background: rgba(255, 255, 255, .14); margin-left: auto; }

.lateral nav { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 4px 6px 10px; scrollbar-width: thin; }

.lat-item, .lat-cab {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 8px 9px; border-radius: calc(10px * var(--rr)); border: none; background: none;
    color: color-mix(in srgb, var(--g-l) 88%, #fff);
    font-size: 13.5px; font-weight: 650; text-align: left; cursor: pointer;
}
.lat-item i, .lat-cab i { display: flex; flex: none; }

/* La puerta del salto rapido dentro del propio menu: se lee como un apartado
   mas, porque para quien lo usa lo es. */
.lat-salto {
    display: flex; align-items: center; gap: 10px; width: 100%;
    margin: 0 0 6px; padding: 8px 9px;
    border-radius: calc(10px * var(--rr));
    border: 1px solid rgba(255, 255, 255, .2); background: rgba(255, 255, 255, .07);
    color: color-mix(in srgb, var(--g-l) 88%, #fff);
    font: inherit; font-size: 13.5px; font-weight: 650; text-align: left; cursor: pointer;
}
.lat-salto:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.lat-salto i { display: flex; flex: none; }
.lat-salto span { flex: 1; white-space: nowrap; overflow: hidden; }
.lat-salto kbd {
    font: inherit; font-size: 10px; font-weight: 700; letter-spacing: .02em;
    padding: 2px 5px; border-radius: calc(5px * var(--rr));
    background: rgba(255, 255, 255, .16); flex: none;
}
/* Plegado a iconos no cabe el rotulo, solo la lupa. */
.lateral.plegada .lat-salto span, .lateral.plegada .lat-salto kbd { display: none; }

/* En el movil no hay tecla Ctrl: enseñar «Ctrl K» ahi es decir una cosa que no
   se puede hacer. El boton se queda; el atajo, no. Se mira si el aparato se
   maneja con el dedo y no solo el ancho, que una tableta con teclado si lo
   tiene. */
@media (hover: none) and (pointer: coarse) {
    .lat-salto kbd, .wsalto kbd { display: none; }
}
@media (max-width: 900px) {
    .lat-salto kbd { display: none; }
}
.lat-item span, .lat-cab span { flex: 1; white-space: nowrap; overflow: hidden; }
.lat-item:hover, .lat-cab:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.lat-item.on, .lat-cab.on { background: rgba(255, 255, 255, .18); color: #fff; }
.lat-cab svg:last-child { transition: transform .14s ease; opacity: .8; }
.lat-grupo.abierto .lat-cab svg:last-child { transform: rotate(90deg); }

/* La flecha de un grupo es un boton: pliega y despliega, y se queda como la
   dejes. Tiene su propia zona para poder darle con el dedo. */
.lat-chev {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; margin: -6px -6px -6px 0; flex: none;
    border-radius: 8px; cursor: pointer;
}
.lat-chev:hover { background: rgba(255, 255, 255, .22); }
/* La flecha es un <span>, asi que le entra `.lat-cab span { flex: 1 }` —una
   clase mas un elemento pesa mas que la clase sola de arriba— y se repartia el
   ancho a medias con el rotulo: reservaba 74 px para dibujar 26, y por eso
   «Comptabilitat» salia «Comptabili». Con la clase del padre delante gana el
   `flex: none` y el rotulo recupera su sitio. */
.lat-item .lat-chev, .lat-cab .lat-chev { flex: none; }
.lat-grupo.abierto .lat-cab .lat-chev svg { transform: rotate(90deg); }
.lat-grupo.abierto .lat-cab { color: #fff; }

.lat-sub { display: none; padding: 2px 0 6px; }
.lat-grupo.abierto > .lat-sub { display: block; }
.lat-sub a {
    display: block; padding: 6px 9px 6px 37px; border-radius: calc(9px * var(--rr));
    font-size: 13px; color: color-mix(in srgb, var(--g-l) 80%, #fff);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lat-sub a:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.lat-sub a.on { color: #fff; font-weight: 700; background: rgba(255, 255, 255, .14); }

/* Un montoncito dentro del submenú. No es un enlace ni se pulsa: solo dice de
   qué van los tres o cuatro que vienen debajo, para no tener que leerlos
   todos buscando uno. */
.lat-sub-t {
    display: block; padding: 9px 9px 3px 37px; font-size: 9.5px; font-weight: 750;
    text-transform: uppercase; letter-spacing: .07em;
    color: color-mix(in srgb, var(--g-l) 55%, transparent);
}
.lat-sub-t:first-child { padding-top: 3px; }

/* ── Tercer nivel del menú ─────────────────────────────────────────────────
   Un grupo dentro de un grupo, para lo que se toca de higos a brevas: se ve
   que cuelga de lo de arriba por la sangría y por la línea de la izquierda. */
.lat-grupo.hondo { margin: 2px 0 2px 24px; border-left: 1px solid rgba(255, 255, 255, .14); }
.lat-grupo.hondo > .lat-cab {
    padding: 6px 9px 6px 13px; font-size: 13px; font-weight: 600;
    color: color-mix(in srgb, var(--g-l) 80%, #fff);
}
.lat-grupo.hondo > .lat-cab span { flex: 1; }
.lat-grupo.hondo > .lat-sub { padding: 0 0 4px; }
.lat-grupo.hondo > .lat-sub a { padding-left: 26px; font-size: 12.5px; }

.lat-pie { padding: 8px 6px 12px; border-top: 1px solid rgba(255, 255, 255, .12); }
.lat-salir {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 8px 9px; border-radius: calc(10px * var(--rr)); border: none; background: none; cursor: pointer;
    color: color-mix(in srgb, var(--g-l) 85%, #fff); font-size: 13px; font-weight: 650;
}
.lat-salir:hover { background: rgba(255, 255, 255, .12); color: #fff; }


@media (min-width: 768px) {
    .av-shell { display: flex; align-items: stretch; min-height: 100vh; }
    .av-main { flex: 1; min-width: 0; }

    .lateral {
        display: flex; flex: none; width: 54px;
        position: sticky; top: 0; align-self: flex-start; height: 100vh;
    }


    /* Plegado: el icono con su nombre debajo, para que siga leyéndose como un
       menú y no como una franja de colores. */
    .lateral.plegada { width: 66px; }
    .lateral.plegada .lat-marca { justify-content: center; padding: 12px 4px; }
    .lateral.plegada .lat-marca .brand span,
    .lateral.plegada .lat-cab svg:last-child,
    .lateral.plegada .lat-sub { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .lateral.plegada .lat-item,
    .lateral.plegada .lat-cab,
    .lateral.plegada .lat-salir {
        flex-direction: column; gap: 3px; justify-content: center; padding: 8px 2px;
    }
    .lateral.plegada .lat-item span,
    .lateral.plegada .lat-cab span,
    .lateral.plegada .lat-salir span {
        flex: none; font-size: 9.5px; font-weight: 650; letter-spacing: -.01em;
        text-align: center; width: 100%; text-overflow: ellipsis;
    }

    /* La barra de arriba ya no lleva el menú: se queda con lo de la derecha. */
    .wnav { padding: 0 18px; }
    .wnav .brand { display: none; }
    .wnav nav { display: none; }
}

/* En tableta (768-1039 px) el menú se queda como una franja de iconos.
   Estaba a 54 px de ancho pero con los rótulos puestos AL LADO del icono, que
   es como se ven cuando el menú está abierto: se cortaban a media palabra
   («Pi», «Fa», «A»), se salían de la franja y empujaban la página, que acababa
   con barra horizontal. Aquí se le da el mismo aspecto que al plegado —el
   icono y su nombre debajo— lleve o no la clase.

   Solo cuando el cajón NO está abierto: abierto manda el cajón, que ahí sí hay
   sitio para el menú entero. */
@media (min-width: 768px) and (max-width: 1039px) {
    .av-shell:not(.menu-abierto) .lateral { width: 68px; }
    .av-shell:not(.menu-abierto) .lateral .lat-marca { justify-content: center; padding: 12px 4px; }
    .av-shell:not(.menu-abierto) .lateral .lat-marca .brand span,
    .av-shell:not(.menu-abierto) .lateral .lat-cab svg:last-child,
    .av-shell:not(.menu-abierto) .lateral .lat-sub {
        position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
    }
    .av-shell:not(.menu-abierto) .lateral .lat-item,
    .av-shell:not(.menu-abierto) .lateral .lat-cab,
    .av-shell:not(.menu-abierto) .lateral .lat-salir {
        flex-direction: column; gap: 3px; justify-content: center; padding: 8px 2px;
    }
    .av-shell:not(.menu-abierto) .lateral .lat-item span,
    .av-shell:not(.menu-abierto) .lateral .lat-cab span,
    .av-shell:not(.menu-abierto) .lateral .lat-salir span {
        flex: none; font-size: 9.5px; font-weight: 650; letter-spacing: -.02em;
        text-align: center; width: 100%; white-space: nowrap;
        overflow: hidden; text-overflow: ellipsis;
    }
    /* Plegar una franja que ya es una franja no significa nada. */
    .av-shell:not(.menu-abierto) .lat-plegar { display: none; }
}

@media (min-width: 1040px) {
    .lateral { width: 208px; }
}

/* ── Menú de hamburguesa (móvil y tableta) ─────────────────────────────────
   Por debajo de 1040 px el menú lateral no cabe abierto, así que se saca en
   un cajón por encima del contenido. Es el MISMO <aside>: no se duplica nada.
   ------------------------------------------------------------------------ */
.whamb { display: grid; margin-right: 2px; }
.lat-cortina { display: none; }

@media (max-width: 1039px) {
    .av-shell.menu-abierto .lat-cortina {
        display: block; position: fixed; inset: 0; z-index: 60;
        background: rgba(9, 46, 38, .45);
    }
    .av-shell.menu-abierto .lateral {
        display: flex; position: fixed; top: 0; left: 0; bottom: 0; height: 100dvh;
        width: 246px; z-index: 61; box-shadow: 0 18px 46px rgba(9, 46, 38, .32);
    }
    /* Dentro del cajón hay sitio de sobra: nunca se enseña plegado. */
    .av-shell.menu-abierto .lateral.plegada { width: 246px; }
    .av-shell.menu-abierto .lateral.plegada .lat-item span,
    .av-shell.menu-abierto .lateral.plegada .lat-cab span,
    .av-shell.menu-abierto .lateral.plegada .lat-sub { display: block; }
    .av-shell.menu-abierto .lat-plegar { display: none; }
}

/* Con el menú siempre a la vista, el botón sobra. */
@media (min-width: 1040px) {
    .whamb { display: none; }
}

/* ── Menú arriba en vez de al lado ─────────────────────────────────────────
   Se elige en Configuración. Es el MISMO menú: se tumba, los grupos pasan a
   ser desplegables y el contenido gana altura. No se duplica nada.

   Solo en pantalla grande (≥1200 px): tumbado ocupa mucho a lo ancho y con
   todos los módulos encendidos no cabe. Por debajo de eso —y también si aun
   así se sale, que lo mira el navegador— manda el menú de al lado.
   ------------------------------------------------------------------------ */
@media (min-width: 1200px) {
    .av-shell.arriba { display: block; }
    .av-shell.arriba .lateral {
        width: auto; height: auto; min-height: 0; position: sticky; top: 0; z-index: 40;
        flex-direction: row; align-items: center; gap: 6px; padding: 0 14px;
    }
    .av-shell.arriba .lat-marca { padding: 0 8px 0 0; min-height: 52px; }
    .av-shell.arriba .lat-plegar { display: none; }
    .av-shell.arriba .lateral nav {
        display: flex; align-items: center; gap: 2px; flex: 1;
        overflow: visible; padding: 0; min-width: 0;
    }
    .av-shell.arriba .lat-item,
    .av-shell.arriba .lat-cab { width: auto; padding: 7px 11px; white-space: nowrap; }
    .av-shell.arriba .lat-grupo { position: relative; }

    /* El submenú cae por debajo, como en GestioERP. */
    .av-shell.arriba .lat-sub {
        position: absolute; top: calc(100% + 4px); left: 0; z-index: 50;
        min-width: 208px; padding: 6px; border-radius: calc(14px * var(--rr));
        background: var(--g-dd); box-shadow: 0 14px 34px -12px rgba(14, 26, 23, .55);
    }
    /* Arriba el submenú es un desplegable: se enseña al pasar por encima y se
       esconde al salir, aunque el grupo esté marcado como abierto (que es lo
       que vale con el menú al lado, donde se queda desplegado). */
    .av-shell.arriba .lat-grupo .lat-sub { display: none; }
    .av-shell.arriba .lat-grupo:hover .lat-sub,
    .av-shell.arriba .lat-grupo:focus-within .lat-sub { display: block; }
    .av-shell.arriba .lat-sub a { padding: 7px 11px; }
    .av-shell.arriba .lat-cab svg:last-child { transform: rotate(90deg); }

    .av-shell.arriba .lat-pie { border: none; padding: 0; }
    .av-shell.arriba .lat-salir span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .av-shell.arriba .lat-salir { padding: 8px; }

    /* Con el menú arriba, la barra de la derecha se funde con él. */
    .av-shell.arriba .wnav { background: var(--g-dd); }

    /* Lo que no cabe en la barra se guarda aquí. Dentro, los grupos se ven ya
       desplegados: un desplegable dentro de otro no hay quien lo use. */
    .av-shell.arriba .lat-mas { margin-left: auto; }
    .av-shell.arriba .lat-mas > .lat-sub {
        left: auto; right: 0; max-height: 72vh; overflow-y: auto;
    }
    .av-shell.arriba .lat-mas .lat-grupo .lat-sub {
        display: block; position: static; min-width: 0; padding: 0 0 4px 12px;
        background: none; box-shadow: none;
    }
    .av-shell.arriba .lat-mas .lat-cab svg:last-child { display: none; }
}

/* El menú «…» de cada línea del documento. */
.lin-mas { position: relative; display: inline-flex; }
.lin-menu {
    position: absolute; top: calc(100% + 4px); right: 0; z-index: 60; min-width: 210px;
    padding: 6px; border-radius: calc(13px * var(--rr)); background: var(--surf); border: 1px solid var(--line);
    box-shadow: 0 16px 34px -14px rgba(9, 46, 38, .4);
}
.lin-menu button, .lin-menu a {
    display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
    background: none; border: none; padding: 8px 10px; border-radius: calc(9px * var(--rr));
    font: inherit; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.lin-menu button:hover, .lin-menu a:hover { background: var(--wash); }
.lin-menu .rojo { color: var(--red); }
/* Quitar, suelto, solo cuando hay sitio de sobra. */
.solo-ancho { display: none; }
@media (min-width: 1200px) { .solo-ancho { display: grid; } }

/* La barra de estado del documento: etiqueta, desplegable y la explicación. */
.estado-doc { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.estado-doc label { font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--mut); font-weight: 700; }
.estado-doc select { max-width: 260px; }
.estado-doc .ayuda { flex: 1; min-width: 180px; }

/* ── Desplegables propios ──────────────────────────────────────────────────
   Los del sistema pintan de azul la fila marcada y no hay CSS que lo cambie.
   Estos son nuestros, así que usan el color de «Selección» de Ajustes.
   ------------------------------------------------------------------------ */
.av-sel { position: relative; display: inline-flex; }
/* Sustituyendo a un campo de formulario, se ve y ocupa como el campo. */
.av-sel-campo { display: flex; width: 100%; }
.av-sel-campo .av-sel-boton {
    width: 100%; text-align: left; max-width: none;
    border: 1.5px solid var(--line); background: var(--surf); color: var(--ink);
    border-radius: calc(13px * var(--rr)); padding: 12px 30px 12px 13px; font-size: 15px; font-weight: 600;
}
.av-sel-campo .av-sel-boton:hover { background: var(--wash); }
.av-sel-campo .av-sel-boton[aria-expanded="true"] { border-color: var(--g); background: var(--surf); }
.av-sel-campo .av-sel-menu { width: 100%; min-width: 0; }
.av-sel-oculto { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.av-sel-boton {
    background: none; border: none; color: inherit; font: inherit; font-weight: 700;
    padding: 3px 20px 3px 6px; border-radius: calc(8px * var(--rr)); cursor: pointer; max-width: 180px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
        linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 10px) 52%, calc(100% - 6px) 52%;
    background-size: 4px 4px, 4px 4px;
    background-repeat: no-repeat;
}
.wnav .av-sel-boton:hover, .wnav .av-sel-boton[aria-expanded="true"] { background-color: rgba(255, 255, 255, .16); }

.av-sel-menu {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 70; min-width: 190px;
    max-height: 320px; overflow-y: auto; padding: 6px; border-radius: calc(14px * var(--rr));
    background: var(--surf); border: 1px solid var(--line);
    box-shadow: 0 16px 38px -14px rgba(9, 46, 38, .4);
}
/* Mientras hay una lista abierta, el padre que recorta deja ver: si no, la
   fila le corta las opciones de abajo (lo pone el JS y lo quita al cerrar). */
.av-sel-deja-ver { overflow: visible !important; }

.av-sel-item {
    display: block; width: 100%; text-align: left; background: none; border: none;
    padding: 8px 10px; border-radius: calc(9px * var(--rr)); font: inherit; font-size: 13.5px; font-weight: 600;
    color: var(--ink); cursor: pointer; white-space: nowrap;
}
.av-sel-item:hover, .av-sel-item:focus-visible {
    background: color-mix(in srgb, var(--ge-sel, var(--g)) 14%, #fff); outline: none;
}
/* La opción puesta, del color de selección elegido en Ajustes. */
.av-sel-item.on { background: var(--ge-sel, var(--g)); color: #fff; font-weight: 700; }

/* El buscador de los desplegables largos: se queda arriba mientras la lista
   corre por debajo, para no perderlo al bajar entre trescientas opciones. */
.av-sel-buscar {
    position: sticky; top: -6px; z-index: 1; display: block; width: 100%;
    margin: -6px -6px 6px; padding: 9px 10px; box-sizing: content-box;
    border: none; border-bottom: 1px solid var(--line); border-radius: 0;
    background: var(--surf); font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.av-sel-buscar:focus { outline: none; background: var(--wash); }
.av-sel-buscar::placeholder { font-weight: 500; color: var(--ink3, #7d8f89); }

/* La miniatura de la familia dentro de la lista. */
.av-sel-item { display: flex; align-items: center; gap: 9px; }
.av-sel-img {
    width: 24px; height: 24px; flex: none; border-radius: calc(6px * var(--rr));
    object-fit: contain; background: var(--wash); padding: 1px;
}

/* En el móvil la lista se abre abajo, a lo ancho de la pantalla y con filas
   que se pulsan con el dedo. Así el color de selección de Ajustes manda
   también aquí: el desplegable del sistema pinta en azul y no se deja. */
@media (max-width: 767px) {
    .av-sel-menu {
        position: fixed; top: auto; bottom: 0; left: 0; right: 0; width: auto;
        max-height: 62vh; padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
        border-radius: calc(18px * var(--rr)) calc(18px * var(--rr)) 0 0; border-bottom: none; min-width: 0;
        box-shadow: 0 -18px 50px -14px rgba(9, 46, 38, .45);
    }
    .av-sel-item { padding: 13px 12px; font-size: 15px; white-space: normal; }
    /* Un velo detrás para que se entienda que hay que elegir. */
    body.av-sel-abierto::after {
        content: ''; position: fixed; inset: 0; z-index: 69;
        background: rgba(9, 46, 38, .35);
    }
}

/* ── Medidas de las dos filas de la ficha ──────────────────────────────────
   La botonera de arriba (Llamar, WhatsApp…) ocupaba demasiado alto para lo que
   dice; las pestañas, al revés: se leían pequeñas.
   ------------------------------------------------------------------------ */
@media (min-width: 768px) {
    .top .grid4 .act {
        display: flex; align-items: center; justify-content: center; gap: 8px;
        padding: 7px 10px; border-radius: calc(12px * var(--rr)); font-size: 12px;
    }
    .top .grid4 .act .ic { width: 24px; height: 24px; border-radius: calc(8px * var(--rr)); margin: 0; }
    .top .grid4 .act .ic svg { width: 14px; height: 14px; }

    .tabs { gap: 20px; }
    .tabs a { font-size: 14px; padding: 13px 0; }
}

/* ── Datos que hacen algo ──────────────────────────────────────────────────
   Las líneas de dirección, teléfono y correo de una ficha no son texto: se
   pulsan y abren el mapa, la llamada o la ventana de escribir.
   ------------------------------------------------------------------------ */
.dato {
    display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: calc(12px * var(--rr));
    margin: 0 -10px 3px; color: inherit;
}
.dato .ic { color: var(--g-d); flex: none; display: flex; }
.dato .t { font-weight: 650; display: block; letter-spacing: -.01em; }
.dato .s { font-size: 12.5px; color: var(--mut); display: block; margin-top: 1px; }
.dato .chev { margin-left: auto; color: var(--mut); display: flex; }
.dato:hover { background: var(--wash); }
.dato.apagado { color: var(--mut); }
.dato.apagado:hover { background: none; }
.dato-fila { display: flex; align-items: center; gap: 6px; }
.dato-fila .dato { flex: 1; }
.dato-fila .icobtn { background: var(--wash); color: var(--g-d); flex: none; }
.dato-fila .icobtn:hover { background: var(--g-d); color: #fff; }

/* ── Agenda de la semana ───────────────────────────────────────────────────
   Una columna por día y las horas a la izquierda. Las citas se colocan por su
   hora y duran lo que miden: se ve de un vistazo dónde queda hueco.

   En el móvil la rejilla es la misma: las columnas tienen ancho mínimo y el
   cuadro se desliza de lado, con la columna de horas clavada a la izquierda.
   Las citas se mueven y se alargan con el dedo igual que con el ratón.
   ------------------------------------------------------------------------ */
/* ── La jornada del equipo ─────────────────────────────────────────────────
   Una fila por persona y el día en columnas: quién está dentro, quién ya ha
   salido y quién no viene hoy, de un vistazo. Es la misma idea que la rejilla
   de la agenda, pero al revés: allí el eje son los días, aquí son las horas y
   cada fila es una persona.

   En el móvil la caja se desliza de lado y la columna de los nombres se queda
   clavada, que si no se pierde de quién es la barra que se está mirando.
   ------------------------------------------------------------------------ */
.jor-cab {
    display: flex; align-items: center; gap: 8px; padding: 0 2px 10px;
}
.jor-cab .grow { flex: 1; min-width: 0; }
.jor-cab b { display: block; font-size: 14.5px; letter-spacing: -.01em; text-transform: capitalize; }
.jor-cab .s { display: block; font-size: 12.5px; color: var(--mut); }

.jor-caja { overflow-x: auto; -webkit-overflow-scrolling: touch; padding: 4px 0; }
.jornada { min-width: min-content; }

.jor-regla, .jor-fila { display: flex; align-items: stretch; }
.jor-fila { border-top: 1px solid var(--line); }

/* El nombre no se va con el deslizamiento. */
.jor-quien {
    width: 132px; flex: none; padding: 8px 10px; position: sticky; left: 0; z-index: 3;
    background: var(--surf); box-shadow: 1px 0 0 var(--line);
}
.jor-quien .t { display: block; font-weight: 650; font-size: 13px; letter-spacing: -.01em; }
.jor-quien .s { display: block; font-size: 11.5px; color: var(--mut); margin-top: 1px; }

.jor-pista {
    position: relative; flex: 1; display: grid;
    grid-template-columns: repeat(var(--h, 12), minmax(34px, 1fr));
}
.jor-celda { border-left: 1px solid var(--line); }
.jor-celda:first-child { border-left: none; }

.jor-regla { position: sticky; top: 0; z-index: 4; background: var(--surf); }
.jor-regla .jor-pista { min-height: 26px; }
.jor-hora {
    font-size: 10px; font-weight: 700; color: var(--mut);
    display: flex; align-items: center; justify-content: center;
    border-left: 1px solid var(--line);
}
.jor-hora:first-child { border-left: none; }

/* La barra de un tramo trabajado. Gris el cerrado, verde el que sigue
   abierto: es lo único que hay que ver desde lejos. */
.jor-barra {
    position: absolute; top: 9px; bottom: 9px; min-width: 3px;
    border-radius: calc(5px * var(--rr)); background: var(--slate-w);
    border: 1px solid color-mix(in srgb, var(--slate) 30%, #fff);
}
.jor-barra.abierta {
    background: var(--g-l); border-color: var(--g-d);
    box-shadow: 0 1px 4px -2px color-mix(in srgb, var(--g-d) 60%, transparent);
}
.jor-fila.dentro .jor-quien .t { color: var(--g-d); }

/* Quien no viene hoy: rayado, para que no se confunda con «no ha fichado». */
.jor-pista.ausente {
    background: repeating-linear-gradient(135deg,
        transparent 0 7px, color-mix(in srgb, var(--mut) 12%, transparent) 7px 14px);
}

/* ── La agenda en pantalla ancha ───────────────────────────────────────────
   Con sitio, la semana se mira mejor con el mes al lado: se salta de fecha sin
   ir y volver, y las capas dejan de ser pastillas para ser una lista que se
   lee. Por debajo de 1100 px la columna no está y manda la fila de pastillas,
   que es lo que funciona con el dedo.
   ------------------------------------------------------------------------ */
.agenda-2col { display: block; }
.agenda-lado { display: none; }

@media (min-width: 1100px) {
    .agenda-2col { display: grid; grid-template-columns: 212px minmax(0, 1fr); gap: 12px; align-items: start; }
    .agenda-lado { display: flex; flex-direction: column; gap: 10px; }
    /* La misma decisión no se pone dos veces en la misma pantalla. */
    .agenda-chips .chip.capa { display: none; }
}

.minimes .mm-cab {
    display: flex; align-items: center; justify-content: space-between; gap: 4px; margin-bottom: 8px;
}
.minimes .mm-cab b { font-size: 12.5px; font-weight: 750; letter-spacing: -.01em; text-transform: capitalize; }
.mm-rejilla { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mm-dow {
    font-size: 9.5px; font-weight: 750; color: var(--mut); text-align: center;
    text-transform: uppercase; letter-spacing: .04em; padding-bottom: 3px;
}
.mm-dia {
    position: relative; display: grid; place-items: center; height: 24px;
    font-size: 11.5px; font-weight: 600; color: var(--ink-2);
    border-radius: calc(7px * var(--rr));
}
.mm-dia:hover { background: var(--wash); }
/* Los días de la semana que se está mirando, marcados: dice dónde estás. */
.mm-dia.dentro { background: var(--wash); color: var(--g-d); font-weight: 750; }
.mm-dia.hoy { background: var(--g-d); color: #fff; font-weight: 800; }
/* Un punto debajo del día que tiene algo: en un mes entero no cabe más. */
.mm-dia.con::after {
    content: ''; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
    width: 3px; height: 3px; border-radius: 50%; background: var(--g);
}
.mm-dia.hoy.con::after { background: #fff; }

.mm-t {
    font-size: 10.5px; font-weight: 750; color: var(--mut); text-transform: uppercase;
    letter-spacing: .06em; margin-bottom: 7px;
}
.capa-fila {
    display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-radius: calc(9px * var(--rr));
    font-size: 12.5px; font-weight: 600; color: var(--ink-2);
}
.capa-fila:hover { background: var(--wash); }
.capa-fila.on { color: var(--ink); }
.capa-caja {
    width: 16px; height: 16px; flex: none; border: 1.5px solid var(--line); border-radius: calc(5px * var(--rr));
    display: grid; place-items: center; color: #fff;
}
.capa-fila.on .capa-caja { background: var(--g-d); border-color: var(--g-d); }
.capa-fila i { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* ── La tira de todo el día ────────────────────────────────────────────────
   Lo que no lleva hora —un recibo que vence, un aviso— no se puede dibujar en
   una rejilla de horas sin inventarle una. Va aquí arriba, igual que en
   cualquier calendario.
   ------------------------------------------------------------------------ */
.sem-todo-lab {
    min-height: 26px; display: flex; align-items: center; justify-content: flex-end;
    padding: 0 6px 0 4px; font-size: 9px; font-weight: 700; color: var(--mut);
    text-transform: uppercase; letter-spacing: .03em; line-height: 1.1; text-align: right;
    border-bottom: 1px solid var(--line);
}
.sem-todo {
    min-height: 26px; padding: 3px; display: flex; flex-direction: column; gap: 2px;
    border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--canvas) 60%, var(--surf));
}
.todo-cinta {
    display: block; font-size: 10.5px; font-weight: 650; line-height: 1.25;
    padding: 2px 6px; border-radius: calc(6px * var(--rr));
    background: var(--g-l); color: var(--g-dd);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.todo-cinta.tipo-cobrar { background: var(--amber-w); color: #7A4C09; }
.todo-cinta.tipo-pagar { background: var(--red-w); color: #7A2A1E; }
.todo-cinta.tipo-trabajo { background: #E4EEF8; color: #18496F; }
.todo-cinta.tipo-crm { background: #EFE8F7; color: #4A2E72; }
.todo-cinta.urgente { box-shadow: 0 0 0 1.5px var(--red) inset; }

.semana-caja {
    display: block; padding: 10px 0 10px 0;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.agenda-lista { display: none; }
.agenda-lista.siempre { display: block; }

.semana {
    --alto-hora: 46px;
    display: grid; grid-template-columns: 46px repeat(var(--dias, 7), minmax(96px, 1fr)); gap: 1px;
    background: var(--line); border-radius: calc(14px * var(--rr)); overflow: hidden;
    min-width: min-content;
}
.sem-horas, .sem-dia { background: var(--surf); }

/* La columna de las horas no se va con el deslizamiento: sin ella no se sabe
   a qué hora cae lo que se está mirando. */
.sem-horas { position: sticky; left: 0; z-index: 6; box-shadow: 1px 0 0 var(--line); }

/* La cabecera va lisa y el color se guarda para el día de hoy: si se tiñen
   las siete, hoy deja de verse, que era justo lo que el color tenía que
   decir. */
.sem-cab {
    height: 42px; display: flex; align-items: center; justify-content: center; gap: 6px;
    background: var(--surf); font-size: 12px; font-weight: 700; color: var(--ink-2);
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 4;
}
/* Hoy se marca tiñendo la columna entera y poniendo el número en negrita,
   no rellenando la cabecera de color: así el día de hoy se sigue leyendo
   igual que los demás y la marca no tapa lo que hay dentro. */
.sem-dia.hoy { background: color-mix(in srgb, var(--wash) 55%, var(--surf)); }
.sem-dia.hoy .sem-cab { background: var(--wash); color: var(--g-d); }
.sem-dia.hoy .sem-cab .n { font-weight: 850; }
.sem-cab .n { font-size: 15px; letter-spacing: -.02em; }
/* El nombre largo solo aparece cuando la columna da de sí. */
.sem-cab .d.largo { display: none; }
@media (min-width: 1100px) {
    .sem-cab .d.corto { display: none; }
    .sem-cab .d.largo { display: inline; text-transform: capitalize; }
}
.sem-hora {
    height: var(--alto-hora); font-size: 10.5px; color: var(--mut); font-weight: 650;
    display: flex; justify-content: flex-end; padding: 2px 6px 0 0;
}
.sem-pista { position: relative; }
.sem-celda { height: var(--alto-hora); border-top: 1px solid var(--line); }
.sem-celda:hover { background: var(--wash); }

/* ── La hora de ahora ──────────────────────────────────────────────────────
   Una raya en la columna de hoy: se ve de un vistazo qué queda por delante y
   qué ya ha pasado, que es lo primero que se mira al abrir la agenda.
   ------------------------------------------------------------------------ */
.sem-ahora {
    position: absolute; left: 0; right: 0; height: 2px; z-index: 8; pointer-events: none;
    background: var(--red);
}
.sem-ahora::before {
    content: ''; position: absolute; left: -1px; top: -3px;
    width: 8px; height: 8px; border-radius: 50%; background: var(--red);
}

/* Una cita: color por usuario, y el borde de abajo para alargarla.
   touch-action en «none» porque si no el móvil se queda el gesto para
   desplazar la pantalla y la cita no llega a moverse. */
.cita {
    position: absolute; left: 3px; right: 3px; overflow: hidden; cursor: grab;
    border-radius: calc(9px * var(--rr)); padding: 4px 6px; font-size: 11px; line-height: 1.2;
    background: var(--g-l); color: var(--g-dd);
    border-left: 3px solid var(--g-d);
    box-shadow: 0 2px 6px -3px rgba(9, 46, 38, .35);
    touch-action: none; user-select: none; -webkit-user-select: none;
}
.cita:hover { filter: brightness(.98); }
.cita.arrastrando { cursor: grabbing; opacity: .85; z-index: 20; }
.cita .h { font-weight: 800; margin-right: 4px; }
.cita .t { font-weight: 650; }
.cita .q, .cita .i { display: block; opacity: .85; }
.cita .u {
    position: absolute; top: 3px; right: 4px; font-size: 8.5px; font-weight: 800;
    background: rgba(255, 255, 255, .75); border-radius: calc(5px * var(--rr)); padding: 1px 3px;
}
/* La marca de «ya avisada»: pequeña y en una esquina, que la cita ya lleva
   bastante información encima. */
.cita .avisada {
    position: absolute; bottom: 3px; right: 4px; line-height: 0;
    color: var(--g-d); opacity: .8;
}

.cita .tirador {
    position: absolute; left: 0; right: 0; bottom: 0; height: 7px; cursor: ns-resize;
    touch-action: none;
}
.cita .tirador::after {
    content: ''; position: absolute; left: 50%; bottom: 2px; width: 18px; height: 2px;
    transform: translateX(-50%); border-radius: calc(2px * var(--rr)); background: currentColor; opacity: .35;
}

/* Con el dedo, el tirador de abajo ha de ser agarrable: siete píxeles no se
   cogen. Se le da altura y una barrita bien visible. */
@media (pointer: coarse) {
    .semana { --alto-hora: 54px; }
    .cita { padding-bottom: 12px; }
    .cita .tirador { height: 16px; }
    .cita .tirador::after { width: 26px; height: 3px; bottom: 4px; opacity: .55; }
}

/* Cada tipo, de su color: igual que los chips de las capas. */
.cita.tipo-trabajo { background: #E4EEF8; color: #18496F; border-left-color: #2E6CA4; }
.cita.tipo-crm { background: #EFE8F7; color: #4A2E72; border-left-color: #7A57B0; }
.cita.tipo-cobrar { background: var(--amber-w); color: #7A4C09; border-left-color: var(--amber); }
.cita.tipo-pagar { background: var(--red-w); color: #7A2A1E; border-left-color: var(--red); }
.cita.urgente { box-shadow: 0 0 0 2px var(--red) inset; }
/* Lo mío, más marcado: en una agenda compartida es lo que se busca. */
.cita.mia { border-left-width: 5px; }

/* Ocho colores para ocho manos distintas. */
.cita.tipo-cita.color-1 { background: #DFF1E9; border-left-color: #0B6B58; }
.cita.tipo-cita.color-2 { background: #E7EEF9; border-left-color: #2E6CA4; }
.cita.tipo-cita.color-3 { background: #F7EFE2; border-left-color: #B2801E; }
.cita.tipo-cita.color-4 { background: #F3E8EE; border-left-color: #99356E; }
.cita.tipo-cita.color-5 { background: #E8F3F6; border-left-color: #1B7A8C; }
.cita.tipo-cita.color-6 { background: #EFEFE4; border-left-color: #6E7A1B; }
.cita.tipo-cita.color-7 { background: #F1E9E9; border-left-color: #8C4B3A; }

/* En la pantalla grande caben los siete días sin deslizar. */
@media (min-width: 900px) {
    .semana-caja { padding: 10px; overflow-x: visible; }
    .semana { grid-template-columns: 54px repeat(var(--dias, 7), minmax(0, 1fr)); min-width: 0; }
}

/* El segmentado nació para la cabecera (fondo oscuro). Dentro de una tarjeta
   hay que darle la vuelta a los colores o no se lee. */
.contenido .seg { background: var(--wash); border: 1px solid var(--line); }
.contenido .seg a, .contenido .seg label { color: var(--ink-2); }
.contenido .seg a.on, .contenido .seg label.on {
    background: var(--surf); color: var(--g-d); font-weight: 750;
    box-shadow: 0 1px 3px -1px rgba(9, 46, 38, .25);
}

/* Un segmentado hecho de radios: se pulsa la etiqueta entera. */
.seg label {
    flex: 1; text-align: center; font-size: 12.5px; font-weight: 650;
    padding: 7px 4px; border-radius: calc(9px * var(--rr)); cursor: pointer;
}

/* El menú de compartir, cuando el sistema no trae el suyo. */
.av-compartir {
    position: absolute; z-index: 90; min-width: 210px; padding: 6px;
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(14px * var(--rr));
    box-shadow: 0 16px 38px -14px rgba(9, 46, 38, .4);
}
.av-compartir a, .av-compartir button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: none; border: none; padding: 9px 10px; border-radius: calc(10px * var(--rr));
    font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.av-compartir a:hover, .av-compartir button:hover { background: var(--wash); }
.av-compartir svg { color: var(--g-d); flex: none; }

/* Las fichas de asiento predefinido llevan nombres largos («Pago modelo 115
   - arrendamientos»): que se lean enteras, aunque ocupen dos renglones. */
.grid3 .act > span:not(.ic):not(.act-aviso) { white-space: normal; overflow: visible; }
@media (min-width: 1100px) {
    .grid3 .act { align-items: flex-start; }
    .grid3 .act .ic { margin-top: 1px; }
}

/* ── Entrada de asientos ───────────────────────────────────────────────────
   Una fila por partida: subcuenta, concepto, debe y haber. En el móvil se
   apila, que con cuatro columnas no hay quien escriba.
   ------------------------------------------------------------------------ */
.partida {
    display: grid; grid-template-columns: 1fr; gap: 8px;
    padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.partida .num { text-align: right; font-variant-numeric: tabular-nums; }
.p-sub { position: relative; }
.p-sub .s { font-size: 11.5px; color: var(--mut); display: block; margin-top: 3px; }
.p-sub .sugerencias {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
    max-height: 240px; overflow-y: auto;
}
.asiento-cab { display: none; }

@media (min-width: 900px) {
    .partida { grid-template-columns: 2fr 2.2fr 1fr 1fr 40px; align-items: start; }
    .asiento-cab {
        display: grid; grid-template-columns: 2fr 2.2fr 1fr 1fr 40px; gap: 8px;
        padding: 9px 12px; font-size: 10.5px; text-transform: uppercase;
        letter-spacing: .08em; color: var(--mut); font-weight: 700;
        border-bottom: 1px solid var(--line);
    }
    .asiento-cab span:nth-child(3), .asiento-cab span:nth-child(4) { text-align: right; }
    /* El hueco de la cabecera de líneas mide 201 px, que es lo que ocupan los
       botones de una línea de venta. Aquí la última columna son 40 px, y con
       los 201 puestos el asiento se salía de la pantalla por la derecha. */
    .lin-cab.asiento-cab .hueco { width: auto; }
}

/* El cuadre: en rojo mientras no cuadre, que es lo que no deja guardar. */
.cuadre { display: flex; gap: 22px; flex-wrap: wrap; }
.cuadre .lab {
    display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .1em;
    color: var(--mut); font-weight: 700;
}
.cuadre .val { font-weight: 750; font-size: 17px; letter-spacing: -.02em; }
.cuadre.malo { border-color: var(--red); background: var(--red-w); }
.cuadre.malo .val { color: var(--red); }

/* ── Tablero de documentos ─────────────────────────────────────────────────
   Una columna por estado y una ficha por documento. Se arrastra de columna a
   columna para cambiar el estado, que es como se lleva un presupuesto de
   «boceto» a «aprobado» sin abrirlo.
   ------------------------------------------------------------------------ */
.tablero {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(230px, 1fr);
    gap: 12px; overflow-x: auto; padding-bottom: 6px; align-items: start;
}
.tab-col { background: var(--wash); border-radius: calc(16px * var(--rr)); padding: 10px; min-height: 120px; }
.tab-col.encima { background: color-mix(in srgb, var(--g) 12%, #fff); outline: 2px dashed var(--g); }
.tab-cab { display: flex; align-items: center; gap: 6px; padding: 2px 4px 10px; }
.tab-cab .t { font-weight: 750; letter-spacing: -.01em; font-size: 13px; }
.tab-cab .n {
    font-size: 11px; font-weight: 700; color: var(--g-dd);
    background: var(--g-l); border-radius: 999px; padding: 1px 7px;
}
.tab-cab .amt { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--mut); }
.tab-fichas { display: flex; flex-direction: column; gap: 8px; max-height: 62vh; overflow-y: auto; }
.tab-ficha {
    display: block; background: var(--surf); border: 1px solid var(--line); border-radius: calc(13px * var(--rr));
    padding: 9px 11px; color: inherit; cursor: grab;
    box-shadow: 0 1px 3px -2px rgba(9, 46, 38, .3);
    touch-action: none; user-select: none; -webkit-user-select: none;
}
.tab-ficha:hover { border-color: var(--g); }
.tab-ficha.arrastrando { opacity: .55; }
.tab-ficha .c { font-size: 11.5px; color: var(--mut); font-weight: 700; display: block; }
.tab-ficha .q { font-weight: 650; display: block; margin: 2px 0; letter-spacing: -.01em; }
.tab-ficha .f { font-size: 11.5px; color: var(--mut); display: block; }
.tab-ficha .i { font-weight: 750; display: block; margin-top: 4px; letter-spacing: -.02em; }

/* ── Mes y año ─────────────────────────────────────────────────────────────
   El mes es el cuadro de toda la vida; el año, doce cuadritos para ver de un
   vistazo dónde se acumula el trabajo.
   ------------------------------------------------------------------------ */
.mes-rejilla { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.mes-cab {
    font-size: 10.5px; font-weight: 700; color: var(--mut); text-align: center;
    text-transform: uppercase; letter-spacing: .08em; padding-bottom: 2px;
}
.mes-dia {
    min-height: 92px; border: 1px solid var(--line); border-radius: calc(11px * var(--rr)); padding: 5px 6px;
    display: flex; flex-direction: column; gap: 2px; color: inherit; background: var(--surf);
}
.mes-dia:hover { background: var(--wash); }
.mes-dia.fuera { opacity: .45; }
.mes-dia.hoy { border-color: var(--g); box-shadow: 0 0 0 2px color-mix(in srgb, var(--g) 22%, transparent); }
.mes-dia .n { font-weight: 750; font-size: 12.5px; }
.mes-dia .mini {
    font-size: 10px; line-height: 1.25; border-radius: calc(5px * var(--rr)); padding: 1px 4px;
    background: var(--g-l); color: var(--g-dd);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mes-dia .mini.tipo-trabajo { background: #E4EEF8; color: #18496F; }
.mes-dia .mini.tipo-crm { background: #EFE8F7; color: #4A2E72; }
.mes-dia .mini.tipo-cobrar { background: var(--amber-w); color: #7A4C09; }
.mes-dia .mini.tipo-pagar { background: var(--red-w); color: #7A2A1E; }
.mes-dia .mas { font-size: 10px; color: var(--mut); font-weight: 650; }

.anio-rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.anio-dias { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.anio-dia {
    position: relative; aspect-ratio: 1; display: grid; place-items: center;
    font-size: 10.5px; color: var(--ink-2); border-radius: calc(7px * var(--rr)); background: var(--wash);
}
.anio-dia:hover { background: var(--g-l); }
.anio-dia.con { font-weight: 750; color: var(--g-dd); }
.anio-dia.con i {
    position: absolute; bottom: 2px; width: 4px; height: 4px; border-radius: 50%;
    background: var(--g); display: block;
}
.anio-dia.hoy { background: var(--g-d); color: #fff; }

/* La lista, cuando se pide a propósito, se ve también en pantalla grande. */
@media (min-width: 900px) {
    .agenda-lista.siempre { display: block; }
}

/* Los chips de las capas llevan su color delante. */
.chip i { width: 9px; height: 9px; border-radius: calc(3px * var(--rr)); display: inline-block; margin-right: 6px; }
.capa-citas i { background: var(--g); }
.capa-trabajos i { background: #2E6CA4; }
.capa-crm i { background: #7A57B0; }
.capa-cobros i { background: var(--amber); }
.capa-pagos i { background: var(--red); }

.cita-caja { height: min(640px, 100%); width: min(520px, 100%); }

/* ── Visor de PDF ──────────────────────────────────────────────────────────
   El documento se ve dentro de la app, con sus botones de guardar e imprimir
   arriba. Así no se depende de cómo imprima el programa desde el que se abra.
   ------------------------------------------------------------------------ */
.av-visor {
    position: fixed; inset: 0; z-index: 80; background: rgba(9, 46, 38, .55);
    display: flex; align-items: center; justify-content: center; padding: 18px;
}
.av-visor-caja {
    background: var(--surf); border-radius: calc(18px * var(--rr)); overflow: hidden;
    width: min(1100px, 100%); height: min(900px, 100%); display: flex; flex-direction: column;
    box-shadow: 0 24px 60px -18px rgba(9, 46, 38, .5);
}
.av-visor-top {
    display: flex; align-items: center; gap: 8px; padding: 10px 12px;
    background: var(--g-d); color: #fff;
}
.av-visor-top .btn { flex: none; }
.av-visor-cuerpo { flex: 1; background: var(--wash); }
.av-visor-cuerpo iframe { width: 100%; height: 100%; border: none; display: block; }

/* ── Agencias de transporte ────────────────────────────────────────────────
   El distintivo de la compania: sus iniciales con un color propio y estable.
   Seis colores de los acentos que ya usa la app; el septimo vuelve al primero,
   porque mas de seis colores dejan de distinguir y empiezan a marear.
   ------------------------------------------------------------------------ */
.ag-ini {
    width: 38px; height: 38px; border-radius: calc(12px * var(--rr)); flex: none;
    display: grid; place-items: center; font-size: 13px; font-weight: 800;
    letter-spacing: .02em;
}
.ag-ini.grande { width: 46px; height: 46px; font-size: 15.5px; border-radius: calc(14px * var(--rr)); }
.ag-ini.c1 { background: var(--wash); color: var(--g-d); }
.ag-ini.c2 { background: var(--slate-w); color: var(--slate); }
.ag-ini.c3 { background: var(--brass-w); color: var(--brass); }
.ag-ini.c4 { background: var(--amber-w); color: var(--amber); }
.ag-ini.c5 { background: color-mix(in srgb, var(--g-d) 12%, #fff); color: var(--g-d); }
.ag-ini.c6 { background: var(--red-w); color: var(--red); }

.ag-fila { gap: 11px; align-items: center; }
.ag-fila.on { background: var(--wash); }

/* ── Mover lineas arrastrando ──────────────────────────────────────────────
   Mientras dura el modo, la linea entera es el asa: se coge por donde sea. Los
   campos se apagan —no se borra nada, solo dejan de recibir el dedo— para que
   arrastrar no acabe seleccionando el texto de una descripcion.
   ------------------------------------------------------------------------ */
.lineas.moviendo .linea {
    cursor: grab; user-select: none; touch-action: none;
    border-left: 3px solid var(--g-l);
}
.lineas.moviendo .linea .input,
.lineas.moviendo .linea textarea,
.lineas.moviendo .linea .icobtn,
.lineas.moviendo .linea button,
.lineas.moviendo .linea a { pointer-events: none; }
.lineas.moviendo .linea.cogida {
    cursor: grabbing; background: var(--wash); border-left-color: var(--g);
    box-shadow: 0 6px 18px -8px rgba(9, 46, 38, .45); position: relative; z-index: 2;
}

/* ── Un dato de contacto que se puede pulsar ───────────────────────────────
   Telefono, correo y direccion. No se pintan de azul de enlace —en una ficha
   llena de datos, cinco palabras azules cansan—: se quedan del color del texto
   y se subrayan por debajo, y al pasar por encima se marcan.
   ------------------------------------------------------------------------ */
.av-dato {
    color: inherit; text-decoration: underline; text-decoration-color: var(--line);
    text-underline-offset: 3px; cursor: pointer;
}
.av-dato:hover { text-decoration-color: var(--g); color: var(--g-d); }

/* ── La vista previa de una etiqueta ───────────────────────────────────────
   La etiqueta sobre un fondo gris, para que se vea donde acaba el papel
   blanco. El dibujo lleva los milimetros del formato dentro, asi que basta
   con darle un alto maximo y que se ajuste solo.
   ------------------------------------------------------------------------ */
.etq-vista {
    background: var(--canvas); border: 1px solid var(--line);
    border-radius: calc(12px * var(--rr)); padding: 14px;
    display: flex; align-items: center; justify-content: center;
}
.etq-vista .etq-svg { max-width: 100%; max-height: 260px; height: auto;
    filter: drop-shadow(0 1px 3px rgba(9, 46, 38, .12)); }

/* ── La foto a tamano grande ───────────────────────────────────────────────
   Se toca una imagen y se ve entera. Sin caja ni marco: la foto sobre el fondo
   oscuro y nada mas, que lo que se quiere mirar es la foto.
   ------------------------------------------------------------------------ */
.av-foto {
    position: fixed; inset: 0; z-index: 90; background: rgba(9, 46, 38, .82);
    display: flex; align-items: center; justify-content: center; padding: 24px;
    cursor: zoom-out;
}
.av-foto img {
    max-width: 100%; max-height: 100%; border-radius: calc(14px * var(--rr));
    background: #fff; display: block; object-fit: contain;
}
#avFotoCerrar {
    position: absolute; top: 14px; right: 14px; background: rgba(255, 255, 255, .92);
    color: var(--ink);
}
.ampliable { cursor: zoom-in; }

/* ── El chat con el asistente ──────────────────────────────────────────────
   Una conversación, no una pantalla: caja estrecha, el hilo que crece hacia
   abajo y la línea de escribir siempre abajo del todo. En el móvil ocupa la
   pantalla entera, que es como se usa.
   ------------------------------------------------------------------------ */
.chat-caja { width: min(560px, 100%); height: min(680px, 100%); }
.chat-top {
    display: flex; align-items: center; gap: 8px; padding: 12px 14px;
    background: var(--g-d); color: #fff;
}
.chat-top b { display: block; font-size: 15px; letter-spacing: -.01em; }
.chat-top .s { display: block; font-size: 11.5px; color: var(--g-l); }
.chat-top .icobtn { color: #fff; }

.chat-hilo {
    flex: 1; overflow-y: auto; padding: 14px; background: var(--canvas);
    display: flex; flex-direction: column; gap: 10px;
}
.chat-msg {
    max-width: 88%; padding: 9px 12px; border-radius: calc(14px * var(--rr));
    font-size: 13.5px; line-height: 1.45;
}
.chat-msg p { margin: 0 0 8px; }
.chat-msg p:last-child { margin-bottom: 0; }
/* Lo mío a la derecha y en el verde de la marca; lo suyo a la izquierda y en
   blanco, que es como se lee una conversación sin tener que pensar. */
.chat-msg.de-mi { align-self: flex-end; background: var(--g-d); color: #fff; }
.chat-msg.de-el { align-self: flex-start; background: var(--surf); border: 1px solid var(--line); }
.chat-msg.esperando { color: var(--mut); font-style: italic; }

.chat-ir { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.chat-ir .btn { width: auto; }
.chat-fuentes { margin-top: 8px; font-size: 11.5px; color: var(--mut); }
.chat-voto { display: flex; gap: 8px; margin-top: 9px; font-size: 11.5px; color: var(--mut); }
/* Un enlace dentro de la respuesta: lleva a la pantalla de la que habla. */
.chat-ira { color: var(--g-d); font-weight: 700; text-decoration: underline; }
.chat-msg.de-mi .chat-ira { color: #fff; }

.chat-fuentes a { color: var(--g-d); text-decoration: underline; }
.chat-aprendida {
    margin-top: 8px; font-size: 11.5px; color: var(--g-d);
    background: var(--wash); border-radius: calc(7px * var(--rr));
    padding: 3px 8px; display: inline-block;
}

/* Las preguntas de seguimiento, fuera del globo y como pastillas: son un «y
   ahora qué», no parte de la respuesta. */
.chat-sug { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.chat-sug-t { width: 100%; font-size: 11.5px; color: var(--mut); }
.chat-sug .chip {
    background: var(--surf); border: 1px solid var(--line); color: var(--ink-2);
    font: inherit; font-size: 12px; cursor: pointer; text-align: left;
}
.chat-sug .chip:hover { border-color: var(--g); color: var(--g-d); }

.chat-voto button {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--g-d); font: inherit; text-decoration: underline;
}

.chat-pie {
    display: flex; gap: 8px; padding: 10px 12px; background: var(--surf);
    border-top: 1px solid var(--line);
}
.chat-pie input {
    flex: 1; min-width: 0; height: 42px; padding: 0 14px; font: inherit;
    border: 1px solid var(--line); border-radius: 99px; background: var(--canvas);
    color: var(--ink);
}
.chat-pie input:focus { outline: none; border-color: var(--g); background: var(--surf); }
.chat-pie .btn { flex: none; width: auto; padding: 0 16px; }

/* Con el chat abierto, la página de detrás no se mueve: en el móvil, al
   desplazar el hilo se arrastraba también lo de debajo. */
body.sin-scroll { overflow: hidden; }

@media (max-width: 640px) {
    .chat-caja { width: 100%; height: 100%; border-radius: 0; }
    .av-visor:has(.chat-caja) { padding: 0; }
}

/* En el móvil, a pantalla completa: el PDF necesita todo el sitio que haya. */
@media (max-width: 767px) {
    .av-visor { padding: 0; }
    .av-visor-caja { border-radius: 0; height: 100%; }
    .av-visor-top .btn span { display: none; }
}

/* ── Impresión ─────────────────────────────────────────────────────────────
   En papel sobra todo lo que sirve para navegar: menús, buscadores y botones.
   Queda la pantalla en sí, a ancho completo y en blanco y negro donde toca.
   ------------------------------------------------------------------------ */
@media print {
    .lateral, .wnav, .nav, .lat-cortina, .av-panel, .procesando, .av-visor,
    .sin-imprimir, .searchbar, .chiprow, .icobtn, .fabwrap { display: none !important; }

    body.av { background: #fff; }
    .av-shell { display: block; }
    .contenido, .contenido.ancho { max-width: none; padding: 0; gap: 10px; }
    .top { background: #fff; color: #000; padding: 0 0 8px; }
    .top h1, .top .sub, .top .etiqueta, .top .grande { color: #000; }

    .card { box-shadow: none; border: 1px solid #999; break-inside: avoid; }
    .kpis { grid-template-columns: repeat(3, 1fr); }
    .kpi { border: 1px solid #999; }
    .kpi.hi { background: #fff; color: #000; }
    .kpi.hi .lab, .kpi.hi .val, .kpi.hi .foot { color: #000; }

    /* La tabla de meses entra entera en un A4 apaisado. */
    .tabla-desliza { overflow: visible; }
    .tabla { font-size: 8.5pt; }
    .tabla th, .tabla td { padding: 3px 5px; }
    .desglose-lista { max-height: none; overflow: visible; }
    .pyg-2col.con-detalle { display: block; }

    /* El color sí se imprime: ganar o perder se tiene que ver también en papel. */
    .verde, .tabla .verde { color: #0B6B58 !important; }
    .rojo, .tabla .rojo { color: #B3402F !important; }

    a[href]::after { content: none !important; }
}


/* ── Qué hace cada módulo ─────────────────────────────────────────────
   Una lista larga que se lee de arriba abajo: el nombre, para qué sirve y
   la palanca. La explicacion tiene que caber entera —por eso aqui la fila
   deja de recortar el texto en una linea— y la palanca se toca con el
   dedo, asi que no baja de 44 px de alto en su zona pulsable. */
.sec-t.mod-sec {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-top: 16px;
}
.mod-cuenta { font-weight: 800; color: var(--g); letter-spacing: 0; }
.mod-todo { margin-left: auto; }
.mod-todo .btn { text-transform: none; letter-spacing: 0; }

.mod-fila { align-items: flex-start; gap: 14px; padding-top: 12px; padding-bottom: 12px; }

/* Los módulos, en columnas cuando hay sitio ─────────────────────────────────
   Son casi cien: en una sola columna la pantalla mide tres metros y para ver
   los de abajo hay que bajar a ciegas. En un portátil caben dos al lado y en
   un monitor grande, tres. El mínimo de 340 px no es capricho: por debajo de
   eso el nombre del módulo y su explicación ya no caben en dos renglones.
   La raya de abajo la pone la propia fila; la de en medio, la rejilla.
   ------------------------------------------------------------------------ */
@media (min-width: 1080px) {
    .mod-rejilla { display: grid; grid-template-columns: repeat(2, minmax(340px, 1fr)); }
    .mod-rejilla > .row:nth-child(2n) { border-left: 1px solid var(--line); }
    /* En columnas, «la última» ya no es la última de la pantalla: la raya solo
       sobra en las filas de abajo del todo. */
    .mod-rejilla > .row:last-child { border-bottom: 1px solid var(--line); }
    .mod-rejilla > .row:nth-last-child(-n+2):nth-child(2n+1),
    .mod-rejilla > .row:nth-last-child(-n+1) { border-bottom: none; }
}

@media (min-width: 1560px) {
    .mod-rejilla { grid-template-columns: repeat(3, minmax(340px, 1fr)); }
    .mod-rejilla > .row:nth-child(2n) { border-left: none; }
    .mod-rejilla > .row:not(:nth-child(3n+1)) { border-left: 1px solid var(--line); }
    .mod-rejilla > .row:nth-last-child(-n+3):nth-child(3n+1),
    .mod-rejilla > .row:nth-last-child(-n+2):nth-child(3n+2),
    .mod-rejilla > .row:nth-last-child(-n+1) { border-bottom: none; }
}
.mod-fila .t { white-space: normal; }
.mod-fila .s {
    white-space: normal; overflow: visible; text-overflow: clip;
    line-height: 1.45; margin-top: 3px;
}
/* ── Encendido o apagado, de un vistazo ────────────────────────────────────
   Antes solo cambiaba el color del nombre, y en una rejilla de setenta y
   cinco módulos a tres columnas eso no se ve: había que ir leyendo el «sí» o
   el «no» de cada uno para saber qué faltaba por encender.

   Ahora el ENCENDIDO va con el fondo del tema —verde en la paleta verde, azul
   en la azul: el color se coge de las variables, no se escribe a mano, o al
   cambiar de paleta la pantalla quedaría de dos colores— y el APAGADO se
   queda gris y apagado de verdad: fondo neutro, nombre en gris y el icono y
   la explicación atenuados. Escaneando la rejilla, los huecos cantan.

   El texto NO se atenúa tanto como para no poder leerse: un módulo apagado se
   lee igual, que para eso está la lista —para decidir si se enciende—.
   ------------------------------------------------------------------------ */
/* El hueco que deja la última fila cuando no llena las columnas.
   Antes daba igual porque todas las tarjetas eran blancas; ahora que cada
   módulo lleva su color, ese hueco se quedaba blanco y parecía un recuadro
   vacío pegado al final del bloque. Se pinta del gris de los apagados, que
   es lo que hay alrededor, y así el bloque acaba en una línea recta. */
.mod-rejilla { background: color-mix(in srgb, var(--ink-2) 8%, #fff); }

.mod-fila.mod-on {
    background: var(--wash);
    box-shadow: inset 3px 0 0 var(--g);
}
.mod-fila.mod-on .t { color: var(--g-d); }

.mod-fila:not(.mod-on) {
    background: color-mix(in srgb, var(--ink-2) 8%, #fff);
    box-shadow: inset 3px 0 0 color-mix(in srgb, var(--ink-2) 28%, #fff);
}
.mod-fila:not(.mod-on) .t { color: var(--ink-2); }
.mod-fila:not(.mod-on) .s,
.mod-fila:not(.mod-on) .sq { opacity: .72; }

/* La pastilla del «no» tiene que leerse como un aviso suave, no como un
   error: un módulo apagado no está roto. */
.mod-fila:not(.mod-on) > .pill {
    background: color-mix(in srgb, var(--ink-2) 12%, #fff);
    color: var(--ink-2);
}

.mod-sw { flex: none; display: flex; align-items: center; min-height: 44px; }

/* La palanca: apagada gris, encendida del color del negocio. */
.palanca {
    width: 48px; height: 28px; border-radius: 99px; border: none; padding: 3px;
    background: var(--slate-w); cursor: pointer; display: block;
    transition: background .15s ease;
}
.palanca .bolita {
    display: block; width: 22px; height: 22px; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
    transition: transform .15s ease;
}
.palanca.on { background: var(--g); }
.palanca.on .bolita { transform: translateX(20px); }
.palanca:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
/* La misma palanca, pero mandada por una casilla de verdad.

   En Apartados cada interruptor es su propio formulario y se guarda al tocarlo.
   En los ajustes de un módulo son varios que se guardan juntos, así que hace
   falta una casilla real dentro del formulario: se esconde y la palanca de al
   lado se pinta según esté marcada. Escondida con opacity y no con display, que
   con display:none el teclado no llega a ella. */
.palanca-chk { position: absolute; opacity: 0; width: 0; height: 0; }
.palanca-chk:checked + .palanca { background: var(--g); }
.palanca-chk:checked + .palanca .bolita { transform: translateX(20px); }
.palanca-chk:focus-visible + .palanca { outline: 2px solid var(--g); outline-offset: 2px; }
/* La fila entera se pulsa, que en un móvil acertarle a la palanca es pedir mucho. */
.row.sw { cursor: pointer; }

/* La palanca de lo que no se puede encender: se ve, pero no se toca. */
.palanca.muerta { opacity: .45; }
.ap-fila.apagado { opacity: .7; }

/* Una fila que canta: el arqueo que no cuadra, el saldo en rojo. */
.rows .row.malo { background: var(--red-w); }

/* Una tarjeta que es un enlace: se usa en Configuración. */
.fila-enlace {
    display: flex; align-items: center; gap: 12px; text-decoration: none;
    color: inherit;
}
.fila-enlace .grow { flex: 1; min-width: 0; }
.fila-enlace .s { display: block; font-size: 12.5px; color: var(--mut); margin-top: 3px; line-height: 1.45; }
.fila-enlace svg { flex: none; color: var(--mut); }
.fila-enlace:hover { background: color-mix(in srgb, var(--wash) 45%, #fff); }

@media (max-width: 560px) {
    /* En el movil el boton de encender el bloque entero se pone debajo del
       titulo, para no aplastarlo. */
    .mod-todo { margin-left: 0; width: 100%; }
    .mod-todo .btn { width: 100%; }
}


/* ── Lo del TPV en la ficha del artículo ──────────────────────────────
   Los alérgenos son catorce y hay que poder marcarlos con el dedo, así que
   van como etiquetas que se encienden, no como una lista de casillas. */
.alerg { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 4px; }
.alerg-uno {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    padding: 8px 12px; border-radius: 99px; font-size: 13px; font-weight: 600;
    background: var(--slate-w); color: var(--mut);
    border: 1.5px solid transparent; transition: all .12s ease;
    min-height: 38px;
}
.alerg-uno input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Con :has() se enciende al marcarla, sin esperar a guardar; la clase .on
   queda de respaldo para el navegador que no lo entienda. */
.alerg-uno.on,
.alerg-uno:has(input:checked) { background: var(--amber-w); color: #7A4C09; border-color: #E9CE96; }
.alerg-uno:has(input:not(:checked)) { background: var(--slate-w); color: var(--mut); border-color: transparent; }
.alerg-uno:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 2px; }

/* Un apartado que se pliega dentro de una tarjeta. */
.plegable { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
.plegable > summary {
    display: flex; align-items: center; gap: 8px; cursor: pointer;
    font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
    color: var(--mut); font-weight: 700; list-style: none; padding: 4px 0;
}
.plegable > summary::-webkit-details-marker { display: none; }
.plegable > summary::after { content: '⌄'; margin-left: auto; font-size: 16px; opacity: .7; }
.plegable[open] > summary::after { content: '⌃'; }
.plegable[open] > summary { margin-bottom: 8px; }


/* ── Balances ─────────────────────────────────────────────────────────
   Un balance es una lista sangrada: cuatro niveles, del epígrafe grande al
   detalle. La sangría y el peso de la letra son lo que lo hace legible, así
   que van por nivel y no a ojo. En el móvil la sangría se reduce, que si no
   el texto se queda sin sitio. */
.filtros-bal { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start; }
.filtros-bal .field { flex: 1 1 200px; margin: 0; }
.filtros-bal .check { flex: 1 1 240px; }

.bal-fila { align-items: baseline; gap: 10px; padding-top: 9px; padding-bottom: 9px; }
.bal-fila .q { flex: 1; min-width: 0; }
.bal-fila .t { white-space: normal; font-weight: 500; }
.bal-fila .amt { flex: none; min-width: 108px; text-align: right; font-variant-numeric: tabular-nums; }
.bal-fila .amt.ant { color: var(--mut); font-weight: 600; }
.bal-fila .amt.neg { color: var(--red); }

/* Nivel 1: el epígrafe grande —«A) ACTIVO NO CORRIENTE»—, con su raya. */
.bal-fila.n1 { background: var(--wash); border-top: 1px solid var(--line); }
.bal-fila.n1 .t { font-weight: 800; text-transform: none; letter-spacing: -.01em; }
.bal-fila.n1 .amt { font-weight: 800; }
.bal-fila.n2 { padding-left: 26px; }
.bal-fila.n2 .t { font-weight: 700; }
.bal-fila.n3 { padding-left: 42px; }
.bal-fila.n3 .t { font-weight: 600; }
.bal-fila.n4 { padding-left: 58px; }
.bal-fila.n4 .t { color: var(--mut); font-size: 13px; }
.bal-fila.n4 .amt { color: var(--mut); font-weight: 600; }

.bal-fila.total {
    border-top: 2px solid var(--g); background: var(--wash);
    font-weight: 800; padding-top: 12px; padding-bottom: 12px;
}
.bal-fila.total .t, .bal-fila.total .amt { font-weight: 800; }

/* Sumas y saldos: cuatro columnas de números. */
.bal-fila.sumas .amt { min-width: 118px; }
/* La cabecera de columnas del balance es de flex, no de la rejilla de las
   líneas de documento: tiene que caer justo encima de los importes, con el
   mismo hueco y el mismo margen que la fila.

   Solo en pantalla ancha: en el móvil las filas se apilan y cada importe
   lleva su propio rótulo, así que una fila de títulos sobra y descuadra. */
@media (min-width: 701px) {
    .lin-cab.bal-cab {
        display: flex; grid-template-columns: none;
        gap: 10px; padding: 9px 14px;
    }
    .lin-cab.bal-cab span:not(:first-child) { text-align: right; min-width: 108px; flex: none; }
    .lin-cab.bal-cab span:first-child { flex: 1; min-width: 0; }
    .lin-cab.bal-cab.sumas span:not(:first-child) { min-width: 118px; }
}

@media (max-width: 700px) {
    /* En el móvil no caben columnas: cada importe se pone debajo con su
       rótulo, y la sangría se recorta para que quepa el concepto. */
    .bal-fila.n2 { padding-left: 14px; }
    .bal-fila.n3 { padding-left: 24px; }
    .bal-fila.n4 { padding-left: 34px; }
    .bal-fila.sumas { flex-wrap: wrap; }
    .bal-fila.sumas .q { flex: 1 1 100%; }
    .bal-fila.sumas .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
    .bal-fila .amt { min-width: 92px; }
}


/* ── Tesorería ────────────────────────────────────────────────────────
   Cifras grandes arriba y dos columnas iguales debajo: lo que te deben y
   lo que debes, una al lado de la otra, que es como se comparan. */
.av-mitades { display: grid; grid-template-columns: 1fr; gap: 0 16px; align-items: start; }
.cifras-3 { display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 4px; }

@media (min-width: 760px) {
    .av-mitades { grid-template-columns: 1fr 1fr; }
    .cifras-3 { grid-template-columns: repeat(3, 1fr); }
}

/* Los rótulos y las cifras también fuera de la cabecera. */
.contenido .etiqueta {
    font-size: 11px; letter-spacing: .12em; font-weight: 700; color: var(--mut);
    text-transform: uppercase;
}
.rojo, .top .grande.malo { color: var(--red); }

.row.tramo { padding-top: 9px; padding-bottom: 9px; }
.row.tramo .s { flex: none; color: var(--mut); font-size: 12.5px; min-width: 24px; text-align: right; }

/* La proyección: el mes en que hay que tirar de la póliza se marca en ámbar,
   y el que ni con la póliza llega, en rojo. Es el aviso que se viene a ver. */
.tes-fila.est-credito { background: var(--amber-w); }
.tes-fila.est-peligro { background: var(--red-w); }
.tes-fila.est-peligro .t { font-weight: 700; color: var(--red); }
@media (min-width: 701px) { .lin-cab.tes-cab span:not(:first-child) { min-width: 112px; } }
.tes-fila .amt { min-width: 112px; }

@media (max-width: 700px) {
    .tes-fila { flex-wrap: wrap; }
    .tes-fila .q { flex: 1 1 100%; }
    .tes-fila .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
}


/* ── Analitica ────────────────────────────────────────────────────────
   Cada centro con su color, para reconocerlo de un vistazo en la tabla y
   en la lista de apuntes. El selector de la derecha es lo que coloca un
   apunte a mano, asi que tiene que caber en el movil sin pelear. */
.punto {
    display: inline-block; width: 9px; height: 9px; border-radius: 50%;
    margin-right: 7px; vertical-align: middle; flex: none;
}
.ana-fila .amt { min-width: 104px; }
.ana-fila .amt.s { color: var(--mut); font-weight: 600; }
.ana-fila.sin .t { color: var(--mut); }
@media (min-width: 761px) { .lin-cab.bal-cab.ana-cab span:not(:first-child) { min-width: 104px; } }

.ana-mov { align-items: center; }
.ana-mov.sin { background: color-mix(in srgb, var(--amber-w) 35%, #fff); }
.ana-sel { flex: none; display: flex; align-items: center; gap: 6px; }
.ana-sel .input.chico {
    height: 36px; font-size: 13px; padding: 0 10px; width: auto;
    min-width: 150px; max-width: 200px;
}

@media (max-width: 760px) {
    .ana-fila { flex-wrap: wrap; }
    .ana-fila .q { flex: 1 1 100%; }
    .ana-fila .amt { min-width: 0; flex: 1 1 28%; font-size: 12.5px; }
    .ana-mov { flex-wrap: wrap; }
    .ana-mov .grow { flex: 1 1 65%; }
    .ana-sel { flex: 1 1 100%; margin-top: 8px; }
    .ana-sel .input.chico { flex: 1; max-width: none; }
}


/* Conciliar el banco: cada movimiento con lo que se le propone debajo, para
   poder decidir de un vistazo sin abrir nada. */
.barra-avance {
    height: 8px; border-radius: 99px; overflow: hidden;
    background: rgba(255, 255, 255, .25);
}
.barra-avance span { display: block; height: 100%; background: #fff; border-radius: 99px; }

/* La misma barra, dentro de una fila blanca: el blanco sobre blanco no se ve,
   asi que aqui va el color del negocio sobre su propio tono claro. Es una
   variante y no una barra nueva a proposito: dos barras acaban con dos
   alturas y dos redondeos. */
.barra-avance.en-fila { background: var(--wash); margin-top: 5px; height: 6px; }
.barra-avance.en-fila span { background: var(--g-l); }
/* Lo que sale en negativo -mas devoluciones que ventas- en rojo: si no, una
   fila de -340 euros se lee como una venta floja. */
.barra-avance.en-rojo span { background: var(--red); }

/* El hilo de un ticket: los de gerencia a un lado y los del trabajador al
   otro. En un hilo de quince mensajes, saber de quien es cada uno sin leer el
   nombre es la diferencia entre seguirlo y no. */
.msg { max-width: 82%; margin-bottom: 10px; }
.msg-t {
    padding: 9px 12px; border-radius: calc(12px * var(--rr));
    line-height: 1.45; overflow-wrap: anywhere;
}
.msg-s { font-size: 12px; color: var(--mut); margin-top: 3px; }
.msg-mio { margin-right: auto; }
.msg-mio .msg-t { background: var(--wash); border-bottom-left-radius: calc(3px * var(--rr)); }
.msg-ellos { margin-left: auto; }
.msg-ellos .msg-t {
    background: var(--g); color: #fff;
    border-bottom-right-radius: calc(3px * var(--rr));
}
.msg-ellos .msg-s { text-align: right; }

.conc-fila { align-items: flex-start; }
.conc-fila.hecho { background: color-mix(in srgb, var(--wash) 50%, #fff); }
.conc-fila.fuera .t { color: var(--mut); text-decoration: line-through; }
.conc-fila .t { white-space: normal; }

.propuesta {
    display: flex; align-items: flex-start; gap: 6px; margin-top: 6px;
    font-size: 12.5px; line-height: 1.4;
}
.propuesta svg { flex: none; margin-top: 2px; }
.propuesta.segura { color: var(--g-d); }
.propuesta.dudosa { color: #7A4C09; }
.propuesta.nada, .propuesta.hecha { color: var(--mut); font-style: italic; }

.conc-acts { flex: none; display: flex; gap: 6px; align-items: center; }
.conc-acts .btn.chico { white-space: nowrap; }

@media (max-width: 700px) {
    .conc-fila { flex-wrap: wrap; }
    .conc-fila .grow { flex: 1 1 60%; }
    .conc-acts { flex: 1 1 100%; margin-top: 8px; }
    .conc-acts form { flex: 1; }
    .conc-acts .btn.chico { width: 100%; }
}


/* Un rotulo de seccion dentro de una tarjeta de campos: sin aire se pega a
   la etiqueta del campo de debajo y parecen la misma cosa. */
.card.pad > .sec-t { margin: 16px 0 8px; }
.card.pad > .sec-t:first-child { margin-top: 0; }

/* Amortizaciones: una barra fina en cada elemento dice cuánto lleva
   amortizado, que es lo que se quiere saber sin abrir la ficha. */
.amo-barra {
    display: block; height: 5px; border-radius: 99px; margin-top: 8px;
    background: var(--slate-w); overflow: hidden; max-width: 320px;
}
.amo-barra span { display: block; height: 100%; background: var(--g); border-radius: 99px; }
.amo-fila .amt .u { display: block; margin-top: 4px; }
.amo-linea .amt { min-width: 110px; }
.amo-linea .amt.est { min-width: 130px; }
.amo-linea.hecha { background: color-mix(in srgb, var(--wash) 50%, #fff); }
.amo-linea .pill.ok { text-decoration: none; }
.lin-cab.bal-cab.amo-cab span:nth-child(2) { min-width: 110px; }
.lin-cab.bal-cab.amo-cab span:nth-child(3) { min-width: 130px; }

@media (max-width: 700px) {
    .amo-linea { flex-wrap: wrap; }
    .amo-linea .q { flex: 1 1 100%; }
    .amo-linea .amt { min-width: 0; flex: 1 1 45%; }
    .amo-linea .amt.est { min-width: 0; text-align: right; }
}


/* La letra de una plantilla: un cuadradito delante de la pregunta, para
   poder relacionarla con la que sale en la tabla de abajo. */
.letra {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: calc(6px * var(--rr)); margin-right: 6px;
    background: var(--g); color: #fff; font-weight: 800; font-size: 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.pre-linea .amt { min-width: 96px; }
@media (min-width: 701px) { .lin-cab.bal-cab.pre-cab span:not(:first-child) { min-width: 96px; } }
@media (max-width: 700px) {
    .pre-linea { flex-wrap: wrap; }
    .pre-linea .q { flex: 1 1 100%; }
    .pre-linea .amt { min-width: 0; flex: 1 1 45%; }
}


/* Previsión: mes a mes con el saldo arrastrado, y el mes en que se queda en
   negativo en rojo, que es lo que se viene a mirar. */
.prv-fila .amt { min-width: 112px; }
.prv-fila.malo { background: var(--red-w); }
.prv-fila.malo .t { font-weight: 700; color: var(--red); }
.prv-apunte.pasado .t { color: var(--mut); }
@media (min-width: 701px) { .lin-cab.bal-cab.prv-cab span:not(:first-child) { min-width: 112px; } }
@media (max-width: 700px) {
    .prv-fila { flex-wrap: wrap; }
    .prv-fila .q { flex: 1 1 100%; }
    .prv-fila .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
}

/* Elegir entre dos: entra o sale. Con el dedo, dos botones grandes en vez de
   dos redondeles diminutos. */
.elige { display: flex; gap: 8px; }
.elige-uno {
    flex: 1; display: flex; align-items: center; justify-content: center;
    min-height: 44px; border-radius: calc(12px * var(--rr)); cursor: pointer; font-weight: 650;
    background: var(--slate-w); color: var(--mut);
    border: 1.5px solid transparent; transition: all .12s ease;
}
.elige-uno input { position: absolute; opacity: 0; width: 0; height: 0; }
.elige-uno.on,
.elige-uno:has(input:checked) { background: var(--wash); color: var(--g-d); border-color: var(--g); }
.elige-uno:has(input:not(:checked)) { background: var(--slate-w); color: var(--mut); border-color: transparent; }
.elige-uno:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 2px; }


/* Arreglar dentro del propio aviso lo que impide seguir. */
.pega-arreglo {
    display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap;
}
.pega-arreglo .input { width: auto; max-width: 110px; height: 38px; }
.pega-arreglo .btn { width: auto; height: 38px; padding: 0 16px; }

/* El ejercicio en curso, marcado en la lista: es el que se está usando. */
.eje-fila.ahora { background: var(--wash); box-shadow: inset 3px 0 0 var(--g-d); }


/* ── Informes ─────────────────────────────────────────────────────────
   Tarjetas con lo que contesta cada uno: en una lista de nombres sueltos
   no se distingue «Resultados» de «Balance mensual». Hasta tres por fila
   en pantalla grande, dos en tableta, una en el movil. */
.inf-rejilla { display: grid; grid-template-columns: 1fr; gap: 10px; }
.inf-card { text-decoration: none; color: inherit; display: block; }
.inf-card:hover { background: color-mix(in srgb, var(--wash) 45%, #fff); }
.inf-card.pendiente { opacity: .55; pointer-events: none; }
.inf-cab { display: flex; align-items: center; gap: 9px; margin-bottom: 5px; }
.inf-cab b { font-weight: 750; }
.inf-ico { color: var(--g-d); display: inline-flex; flex: none; }
.inf-card .s { display: block; font-size: 12.5px; color: var(--mut); line-height: 1.45; }

@media (min-width: 760px) { .inf-rejilla { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .contenido.ancho .inf-rejilla { grid-template-columns: repeat(3, 1fr); } }

/* ── IVA ──────────────────────────────────────────────────────────────
   Cada trimestre con sus dos mitades —lo repercutido y lo soportado— y el
   resultado al pie, que es la cifra que se lleva uno apuntada. */
.iva-lado + .iva-lado { border-top: 1px solid var(--line); }
.iva-rot {
    font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--mut); font-weight: 700; padding: 12px 14px 2px;
}
.iva-fila .amt { min-width: 128px; }
.iva-fila.total { border-top: 1px solid var(--line); font-weight: 750; }
@media (min-width: 701px) { .lin-cab.bal-cab.iva-cab span:not(:first-child) { min-width: 128px; } }

.iva-resultado {
    display: flex; align-items: center; justify-content: space-between;
    padding: 13px 14px; border-top: 2px solid var(--g);
    font-weight: 750; background: var(--wash);
}
.iva-resultado.devolver { background: var(--amber-w); border-top-color: #E9CE96; }
.iva-resultado b { font-size: 17px; }

@media (max-width: 700px) {
    .iva-fila { flex-wrap: wrap; }
    .iva-fila .q { flex: 1 1 100%; }
    .iva-fila .amt { min-width: 0; flex: 1 1 45%; }
}


/* Los libros: cuatro columnas de numeros en pantalla ancha, apiladas en el
   movil con su rotulo delante. */
.lib-fila .amt { min-width: 112px; }
.lib-fila.total { border-top: 2px solid var(--g); background: var(--wash); font-weight: 750; }
@media (min-width: 701px) { .lin-cab.bal-cab.lib-cab span:not(:first-child) { min-width: 112px; } }
@media (max-width: 700px) {
    .lib-fila { flex-wrap: wrap; }
    .lib-fila .q { flex: 1 1 100%; }
    .lib-fila .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
}


/* ── Verifactu ────────────────────────────────────────────────────────
   El estado de la factura arriba del todo y, si algo falló, el rastro de
   lo que pasó desplegado: es lo unico que dice por que. */
.vf-estado { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.vf-paso {
    padding: 9px 0; border-bottom: 1px solid var(--line); font-size: 13px;
    line-height: 1.45;
}
.vf-paso:last-child { border-bottom: none; }
.vf-paso .s { display: block; color: var(--mut); font-size: 12.5px; margin-top: 2px; }
.vf-paso.bien b { color: var(--g-d); }
.vf-paso.mal b { color: var(--red); }

/* Un dato que solo se lee, con el mismo alto que un campo. */
.valor-fijo {
    min-height: 44px; display: flex; align-items: center; padding: 0 12px;
    border-radius: calc(12px * var(--rr)); background: var(--slate-w); color: var(--txt);
    border: 1.5px solid transparent;
}
.valor-fijo.rojo { background: var(--red-w); color: var(--red); }


/* ── Desgloses ────────────────────────────────────────────────────────
   Los cortes como fichas: son ocho y hay que poder cambiar de uno a otro
   sin buscar en un desplegable. */
.cortes { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.corte {
    padding: 9px 14px; border-radius: 99px; font-size: 13px; font-weight: 650;
    background: var(--surf); color: var(--mut); text-decoration: none;
    border: 1.5px solid var(--line); min-height: 38px; display: inline-flex;
    align-items: center; transition: all .12s ease;
}
.corte:hover { border-color: var(--g); color: var(--g-d); }
.corte.on { background: var(--g); color: #fff; border-color: var(--g); }

.dg-barra {
    display: block; height: 4px; border-radius: 99px; margin-top: 7px;
    background: var(--slate-w); overflow: hidden; max-width: 300px;
}
.dg-barra span { display: block; height: 100%; background: var(--g); border-radius: 99px; }
.dg-fila .amt { min-width: 116px; }
.dg-fila .amt.s { min-width: 70px; color: var(--mut); font-weight: 600; }
.dg-fila.resto { background: var(--wash); }
.dg-fila.resto .t { color: var(--mut); }
.dg-fila.total { border-top: 2px solid var(--g); background: var(--wash); font-weight: 750; }

/* ── Resultados ───────────────────────────────────────────────────────
   El mes que pierde dinero, en rojo: es lo que se busca al abrirlo. */
.res-fila .amt { min-width: 116px; }
.res-fila .amt .u { display: block; font-weight: 600; margin-top: 2px; }
.res-fila.malo { background: var(--red-w); }
.res-fila.total { border-top: 2px solid var(--g); background: var(--wash); font-weight: 750; }

/* ── Cobrar desde el documento ──────────────────────────────
   Los atajos de porcentaje, para el que paga a plazos: se calculan sobre lo
   que queda, no sobre el total. */
.av-modal-box.ancho { max-width: 420px; text-align: left; }
.cobro-tit { display: flex; align-items: center; gap: 9px; font-size: 15.5px;
    font-weight: 800; color: var(--ink); margin-bottom: 14px; }
.cobro-tit svg { color: var(--g-d); flex: none; }

.cobro-partes { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0;
    border: 1px solid var(--line); border-radius: calc(11px * var(--rr)); overflow: hidden; margin-top: 10px; }
.cobro-partes .parte {
    background: var(--surf); border: 0; border-right: 1px solid var(--line);
    padding: 9px 4px; font: inherit; font-size: 12px; font-weight: 700;
    color: var(--ink-2); cursor: pointer;
}
.cobro-partes .parte:last-child { border-right: 0; }
.cobro-partes .parte:hover { background: var(--wash); }
.cobro-partes .parte.on { background: var(--wash); color: var(--g-d); }
.cobro-partes .parte.todo { color: var(--g-d); }

/* ── El rótulo de los iconos ────────────────────────────────
   Lo que sale al pasar por encima de un icono. Oscuro y pequeño, por encima
   de todo y sin estorbar al ratón. */
.av-rotulo {
    position: fixed; z-index: 120; pointer-events: none;
    background: var(--ink); color: #fff; border-radius: calc(8px * var(--rr));
    padding: 5px 9px; font-size: 11.5px; font-weight: 650; line-height: 1.25;
    max-width: 240px; box-shadow: 0 8px 22px rgba(9, 46, 38, .3);
    opacity: 0; transform: translateY(-2px); transition: opacity .1s ease, transform .1s ease;
}
.av-rotulo.on { opacity: 1; transform: none; }

@media print { .av-rotulo { display: none !important; } }

.log-malo { background: var(--red-w); }
.log-malo .t { color: var(--red); }

/* ── Fichar ────────────────────────────────────────────
   El botón grande y el punto que dice si estás dentro: se ficha con el móvil en
   la mano, muchas veces con guantes, y esto tiene que acertarse sin mirar. */
.fichar { border-left: 4px solid var(--line); }
.fichar.dentro { border-left-color: var(--g); background: var(--wash); }
.fichar-estado { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.fichar-estado .punto { width: 14px; height: 14px; border-radius: 50%; flex: none;
    background: var(--mut); }
.fichar-estado .punto.on { background: var(--g); box-shadow: 0 0 0 5px color-mix(in srgb, var(--g) 22%, transparent); }
.btn.grande { height: 56px; font-size: 16px; }

/* ── Tablero de tareas ──────────────────────────────────
   Las fases en columnas que se deslizan; en el móvil, una detrás de otra. */
.tablero { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.tab-col { flex: 1 0 236px; min-width: 236px; background: var(--wash);
    border: 1px solid var(--line); border-radius: calc(14px * var(--rr)); overflow: hidden; }
.tab-cab { padding: 9px 12px; font-size: 11.5px; font-weight: 800; color: var(--ink-2);
    text-transform: uppercase; letter-spacing: .06em; border-bottom: 1px solid var(--line);
    display: flex; align-items: center; gap: 7px; }
.tab-cuerpo { padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.tab-vacio { color: var(--mut); font-size: 12px; text-align: center; padding: 14px 0; }

/* En el móvil, el tablero de las citas de la agenda se aprieta para que entren
   tres estados a la vez: con columnas de 236 px cabía una y media, y para saber
   cuántas citas hay en cada estado —que es para lo que se mira— había que
   deslizar el dedo tres veces. Las fichas de dentro se encogen con él. */
@media (max-width: 700px) {
    #avTableroCitas { gap: 5px; }
    /* Los cuatro estados a la vez: en un tablero, lo que se mira es cuántas
       hay en cada montón, y para eso hay que verlos todos sin deslizar. */
    #avTableroCitas .tab-col { flex: 0 0 23.6%; min-width: 0; }
    /* El nombre arriba y el contador debajo: en 82 px no caben al lado, y
       poniéndolos en la misma línea el nombre se partía por la mitad
       («PENDIENT / E»), que es peor que ocupar dos renglones. */
    #avTableroCitas .tab-cab {
        padding: 6px; font-size: 9px; letter-spacing: 0; gap: 2px;
        flex-direction: column; align-items: flex-start; line-height: 1.15;
    }
    #avTableroCitas .tab-cab .t { font-size: 9.5px; min-width: 0; }
    #avTableroCitas .tab-cab .n { padding: 0 5px; font-size: 10px; }
    #avTableroCitas .tab-fichas { padding: 5px; gap: 5px; }
    #avTableroCitas .tab-ficha { padding: 6px 7px; font-size: 11px; }

    /* En 82 px de ancho, el asunto entero sale a una palabra por renglón y la
       ficha se estira media pantalla. Se corta a dos líneas —con puntos
       suspensivos, que el asunto entero está en el título del elemento y en la
       ficha de la cita— y del pie se queda solo la hora, que es lo que se mira
       en un tablero. El cliente ya está en la columna de al lado. */
    #avTableroCitas .tab-ficha .t {
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
        overflow: hidden; line-height: 1.25; font-size: 11px;
    }
    #avTableroCitas .tab-ficha .s {
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 9.5px;
    }
    #avTableroCitas .tab-ficha .s ~ .s { display: none; }
}

.tarea { background: var(--surf); border: 1px solid var(--line); border-radius: calc(11px * var(--rr)); padding: 9px 10px; }
.tarea.tarde { border-color: color-mix(in srgb, var(--red) 45%, #fff); background: var(--red-w); }
.tarea-t { font-size: 12.5px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.tarea .s { font-size: 11px; color: var(--mut); margin-top: 3px; line-height: 1.3; }
/* El pie de la tarea: el desplegable de la fase y los dos botones.
   En una columna de 236 px, con el lapiz y la equis al lado, al desplegable
   le quedaban setenta y pico pixeles: se leia «Pen...» y la lista que abre
   el navegador -que sale del ancho del propio desplegable- salia igual de
   estrecha, con los nombres cortados. Ahora, cuando no caben los tres en
   una linea, el desplegable se queda una para el solo y los botones bajan
   a la siguiente, pegados a la derecha. En una columna ancha siguen los
   tres en la misma linea, como estaban. */
.tarea-pie {
    display: flex; align-items: center; gap: 6px; margin-top: 8px;
    flex-wrap: wrap; justify-content: flex-end;
}
.tarea-pie form { flex: 1 1 128px; min-width: 0; }
.tarea-pie form:last-child { flex: 0 0 auto; }
.tarea-pie .input.chico { height: 30px; font-size: 11.5px; padding: 0 8px; width: 100%; }

/* La foto del articulo en el presupuesto: cuadrada y pequeña, del tamaño del
   cuadro que lleva la fila cuando no hay foto, para que las lineas con foto y
   sin ella no bailen. */
.presu-foto {
    width: 38px; height: 38px; flex: none; object-fit: cover; background: #fff;
    border: 1px solid var(--line); border-radius: calc(9px * var(--rr));
}

/* ── Como ha ido subiendo el gasto ─────────────────────────────────────────
   Barras del gasto acumulado mes a mes con la raya del presupuesto cruzada.
   Sin biblioteca: son diez barras y una linea, y una libreria de graficas
   para esto son doscientos kilobytes que hay que descargar sin cobertura. */
.py-curva {
    position: relative; display: flex; align-items: flex-end; gap: 6px;
    height: 170px; padding-bottom: 18px;
}
.py-curva-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.py-curva-barra {
    background: linear-gradient(180deg, var(--g-l), var(--g)); border-radius: 5px 5px 0 0;
    min-height: 2px; transition: height .2s;
}
.py-curva-barra.pasado { background: linear-gradient(180deg, color-mix(in srgb, var(--red) 70%, #fff), var(--red)); }
.py-curva-mes { font-size: 10px; color: var(--mut); text-align: center; margin-top: 4px; }
.py-curva-raya {
    position: absolute; left: 0; right: 0; border-top: 2px dashed var(--ink-2);
    pointer-events: none;
}
.py-curva-raya span {
    position: absolute; right: 0; top: -17px; font-size: 10.5px; font-weight: 700;
    color: var(--ink-2); background: var(--surf); padding: 0 4px;
}

.tarea-nueva { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.tarea-nueva .field { flex: 1 1 200px; margin: 0; }
.tarea-nueva .btn { flex: none; }

.py-fila .amt { min-width: 116px; }
.py-fila.malo { background: var(--red-w); }

@media (max-width: 700px) {
    .py-fila { flex-wrap: wrap; }
    .py-fila .q { flex: 1 1 100%; }
    .py-fila .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
    .tab-col { flex: 1 0 84%; min-width: 84%; }
}

/* ── Modelos de PDF ─────────────────────────────────────
   Cada modelo con su hojita dibujada, con los colores que se han elegido: se
   ve en qué se parecen antes de sacar un PDF de prueba. */
.modelos { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
.modelo {
    display: flex; gap: 11px; align-items: center; cursor: pointer;
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(14px * var(--rr)); padding: 11px;
}
.modelo:hover { border-color: var(--g); }
.modelo.on { border-color: var(--g); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 15%, transparent); }
.modelo input { position: absolute; opacity: 0; pointer-events: none; }

.modelo-hoja {
    width: 42px; height: 56px; flex: none; background: #fff; border: 1px solid var(--line);
    border-radius: calc(4px * var(--rr)); padding: 4px; display: flex; flex-direction: column; gap: 3px;
}
.mh-cab { height: 10px; border-radius: calc(2px * var(--rr)); }
.mh-linea { height: 3px; border-radius: calc(2px * var(--rr)); background: var(--line); }
.mh-linea.larga { width: 80%; }
.mh-total { height: 7px; border-radius: calc(2px * var(--rr)); margin-top: auto; }

.modelo-que { min-width: 0; font-size: 12.5px; color: var(--ink-2); }
.modelo-que b { display: block; color: var(--ink); }
.modelo-que .s { display: block; font-size: 11px; color: var(--mut); line-height: 1.25; margin-top: 2px; }

/* ── Países ────────────────────────────────────────────
   Se arregla el nombre en la propia lista: son dos campos y abrir una ficha
   para eso sobra. */
.pais-fila { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pais-cod { flex: none; width: 34px; font-weight: 800; color: var(--g-d); }
.pais-fila .input { flex: 1; min-width: 160px; height: 38px; }
.pais-fila .input.chico { flex: none; width: 86px; text-align: center; }
.pais-uso { flex: none; }
.pais-fila .icobtn { flex: none; }

@media (max-width: 560px) {
    .pais-fila .input { min-width: 0; flex: 1 1 100%; }
    .pais-fila .input.chico { flex: none; }
}

/* ── Usuarios ──────────────────────────────────────────
   Las iniciales delante: en una lista de nombres cortos, reconocer al de uno
   por la letra es más rápido que leer. El apagado, en gris. */
.us-fila { gap: 11px; align-items: center; }
.us-ini {
    width: 34px; height: 34px; border-radius: calc(11px * var(--rr)); flex: none;
    background: var(--wash); color: var(--g-d);
    display: grid; place-items: center; font-size: 12.5px; font-weight: 800;
}
.us-fila.apagado .us-ini { background: var(--surf); color: var(--mut); border: 1px dashed var(--line); }
.us-fila.apagado .t { color: var(--mut); }
.us-fila .amt { flex: none; text-align: right; min-width: 78px; line-height: 1.25; }

/* Los roles, como casillas grandes: se marcan con el dedo. */
.roles { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 8px; }
.rol {
    display: flex; align-items: center; gap: 9px; cursor: pointer;
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(12px * var(--rr));
    padding: 9px 11px; font-size: 12.5px; font-weight: 650; color: var(--ink-2);
}
.rol input { width: 18px; height: 18px; accent-color: var(--g); flex: none; }
.rol.on { border-color: var(--g); background: var(--wash); color: var(--g-d); }
.rol:hover { border-color: var(--g); }

@media (max-width: 700px) {
    .roles { grid-template-columns: 1fr 1fr; gap: 6px; }
    .rol { padding: 8px 9px; font-size: 11.5px; }
}

/* ── Gráficas ────────────────────────────────────────────
   SVG hecho a mano, sin biblioteca. El año pasado va detrás y más claro; el
   de ahora, delante y en el verde de la casa. Los meses que todavía no han
   terminado salen rayados, que si no parece que se ha vendido menos. */
.gr-alto { width: 100%; height: 210px; }
.gr-alto svg { width: 100%; height: 100%; display: block; }

.gr-guia { stroke: var(--line); stroke-width: 1; }
.gr-cero { stroke: var(--mut); stroke-width: 1.5; stroke-dasharray: 3 3; }

/* Cada cosa, su color.

   Todo verde cansaba la vista y, peor, no decia nada: dos barras del mismo
   color obligan a leer la leyenda para saber cual es cual. Ahora cada serie
   tiene el suyo y se distingue de un vistazo, sin leer.

   Los colores no son inventados: son los acentos que ya usa la app en los
   avisos y las pastillas —pizarra, laton, ambar, rojo—, asi que la pantalla
   sigue siendo la misma casa. Y el verde, que es el color del tema y lo puede
   cambiar cada negocio, se guarda para lo de este ano, que es lo que se mira. */
.gr-barra { transition: opacity .12s ease; }
.gr-barra.ahora { fill: var(--g); }
.gr-barra.antes { fill: var(--slate-w); stroke: var(--slate); stroke-width: 1; stroke-opacity: .45; }
.gr-barra.malo { fill: var(--red); }
.gr-barra.encurso { fill: var(--g-l); }

/* El margen no es una venta: es lo que queda. Con su propio color —laton, que
   es el del dinero guardado— deja de confundirse con la grafica de arriba. */
.gr-barra.margen { fill: var(--brass); }
.gr-etiq { fill: var(--mut); font-size: 12px; font-weight: 650; text-anchor: middle; }

.gr-punto { display: inline-block; width: 9px; height: 9px; border-radius: calc(2px * var(--rr)); margin-right: 5px; vertical-align: -1px; }
.gr-punto.ahora { background: var(--g); }
.gr-punto.antes { background: var(--slate-w); border: 1px solid var(--slate); }
.gr-punto.margen { background: var(--brass); }
.gr-punto.malo { background: var(--red); }

.gr-pie { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
    margin-top: 8px; font-size: 11.5px; color: var(--mut); font-weight: 600; }

.gr-fila { align-items: center; gap: 12px; }
.gr-fila .amt { min-width: 120px; text-align: right; flex: none; }
.gr-fila .amt .u { display: block; margin-top: 2px; }
.gr-fila.resto .t { color: var(--mut); }
.gr-cinta { display: block; height: 9px; border-radius: calc(5px * var(--rr)); background: var(--wash); margin-top: 6px; overflow: hidden; }
.gr-cinta span { display: block; height: 100%; border-radius: calc(5px * var(--rr));
    background: linear-gradient(90deg, var(--g-l), var(--g)); }

/* El reparto: un color por puesto.

   Nueve barras verdes de distinta longitud se leen como una sola cosa larga.
   Dando a cada puesto su color, la vista separa las filas sola y el ojo salta
   a la que busca. Se repiten a partir de la sexta a proposito: mas de cinco
   colores dejan de ser informacion y pasan a ser ruido. */
.gr-fila:nth-child(6n+2) .gr-cinta span { background: linear-gradient(90deg,
    color-mix(in srgb, var(--slate) 45%, #fff), var(--slate)); }
.gr-fila:nth-child(6n+3) .gr-cinta span { background: linear-gradient(90deg,
    color-mix(in srgb, var(--brass) 45%, #fff), var(--brass)); }
.gr-fila:nth-child(6n+4) .gr-cinta span { background: linear-gradient(90deg,
    color-mix(in srgb, var(--amber) 45%, #fff), var(--amber)); }
.gr-fila:nth-child(6n+5) .gr-cinta span { background: linear-gradient(90deg,
    color-mix(in srgb, var(--g-d) 40%, #fff), var(--g-d)); }
.gr-fila:nth-child(6n+6) .gr-cinta span { background: linear-gradient(90deg,
    color-mix(in srgb, var(--red) 40%, #fff), var(--red)); }

@media (max-width: 700px) {
    .gr-alto { height: 168px; }
    .gr-etiq { font-size: 15px; }
    .gr-fila .amt { min-width: 96px; font-size: 12.5px; }
}

/* ── Registro Mercantil ──────────────────────────────────
   El balance tal como se deposita: los epígrafes de suma, marcados, que son
   los que se miran. */
.rm-papel { align-items: center; gap: 12px; }
.rm-botones { display: flex; gap: 6px; flex: none; }
.rm-fila .amt { min-width: 128px; }
.rm-fila.suma { background: var(--wash); font-weight: 750; }
.rm-fila.suma .t { text-transform: none; }

@media (max-width: 700px) {
    .rm-papel { flex-wrap: wrap; }
    .rm-botones { width: 100%; }
    .rm-botones .btn { flex: 1; }
    .rm-fila .amt { min-width: 96px; font-size: 12.5px; }
}

/* ── Paletas de color ─────────────────────────────────────
   Cada juego se ve antes de elegirlo: tres tiras con sus colores de verdad.
   Se pulsa y se aplica, sin más pasos. */
/* ── El elegidor de forma ──────────────────────────────────────────────────
   Dos botones con una miniatura de la app dibujada con los radios de cada
   diseño: se ve la diferencia antes de aplicarla, que es de lo que se trata.
   Reaprovecha la caja de las paletas —mismo borde, mismo marcado— porque son
   la misma decisión tomada dos veces.
   ------------------------------------------------------------------------ */
.disenos { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 9px; }
.diseno {
    position: relative; display: block; text-align: left; cursor: pointer;
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(13px * var(--rr));
    padding: 10px 11px 11px; font: inherit; color: var(--ink-2);
}
.diseno:hover { border-color: var(--g); }
.diseno.on { border-color: var(--g); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 15%, transparent); }
.diseno-nombre { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink); }
.diseno-dice { display: block; font-size: 11.5px; color: var(--mut); margin-top: 1px; }

/* La miniatura lleva su propio --rr, así que cada botón se dibuja con el
   redondeo del diseño que ofrece. */
.diseno-muestra {
    display: block; background: var(--canvas); border: 1px solid var(--line);
    border-radius: calc(10px * var(--rr)); padding: 6px; margin-bottom: 8px;
}
.dm-barra { display: block; height: 13px; background: var(--g-d); border-radius: calc(7px * var(--rr)); }
.dm-card {
    display: block; height: 20px; background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(9px * var(--rr)); margin-top: 5px;
}
.dm-fila { display: flex; gap: 5px; margin-top: 5px; }
.dm-fila i { flex: 1; height: 11px; background: var(--g-l); border-radius: calc(6px * var(--rr)); }
.dm-fila i:last-child { flex: .5; background: var(--line); }

.paletas { display: grid; grid-template-columns: repeat(auto-fill, minmax(126px, 1fr)); gap: 9px; }
.paleta {
    position: relative; display: block; text-align: left; cursor: pointer;
    background: var(--surf); border: 1px solid var(--line); border-radius: calc(13px * var(--rr));
    padding: 9px 10px 10px; font: inherit; color: var(--ink-2);
}
.paleta:hover { border-color: var(--g); }
.paleta.on { border-color: var(--g); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 15%, transparent); }
.paleta-tiras { display: flex; gap: 3px; margin-bottom: 8px; }
.paleta-tiras span { height: 22px; flex: 1; border-radius: calc(6px * var(--rr)); }
.paleta-tiras span:first-child { flex: 1.6; }
.paleta-nombre { font-size: 12.5px; font-weight: 700; color: var(--ink); }
.paleta-marca {
    position: absolute; top: 7px; right: 8px; width: 19px; height: 19px;
    border-radius: 50%; background: var(--g-d); color: #fff;
    display: grid; place-items: center;
}

@media (max-width: 639px) {
    .paletas { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 7px; }
    .paleta { padding: 7px 8px 8px; border-radius: calc(11px * var(--rr)); }
    .paleta-tiras span { height: 18px; }
    .paleta-nombre { font-size: 11.5px; }
}

/* ── Deudas ────────────────────────────────────────────
   La barra de cada tramo dice de un vistazo si lo que hay es retraso normal o
   dinero que lleva medio año parado. */
.de-tramo .amt { text-align: right; min-width: 120px; flex: none; }
.de-tramo .amt .u { display: block; color: var(--mut); }
.de-tramo.malo .t { color: var(--red); font-weight: 750; }
.de-barra { display: block; height: 6px; border-radius: calc(3px * var(--rr)); background: var(--wash); margin-top: 6px; overflow: hidden; }
.de-barra span { display: block; height: 100%; background: var(--g); border-radius: calc(3px * var(--rr)); }
.de-barra span.malo { background: var(--red); }
.de-barra span.bueno { background: var(--g-l); }
.de-fila .amt { min-width: 116px; }
.de-fila.malo { background: var(--red-w); }
.de-fila.total { border-top: 2px solid var(--g); background: var(--wash); font-weight: 750; }

@media (min-width: 701px) {
    .lin-cab.bal-cab.de-cab span:not(:first-child) { min-width: 116px; }
}
@media (max-width: 700px) {
    .de-fila { flex-wrap: wrap; }
    .de-fila .q { flex: 1 1 100%; }
    .de-fila .amt { min-width: 0; flex: 1 1 40%; font-size: 12.5px; }
}

.envio-doc { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-top: 12px; }
.envio-doc .field { flex: 1 1 200px; margin: 0; }
.envio-doc .btn { flex: none; }

/* ── Transporte ───────────────────────────────────────── */
.tp-fila .amt { min-width: 110px; }

@media (min-width: 701px) {
    .lin-cab.bal-cab.tp-cab span:not(:first-child) { min-width: 110px; }
}
@media (max-width: 700px) {
    .tp-fila { flex-wrap: wrap; }
    .tp-fila .q { flex: 1 1 100%; }
    .tp-fila .amt { min-width: 0; flex: 1 1 40%; font-size: 12.5px; }
}

/* ── Trazabilidad ───────────────────────────────────────
   La vida de una unidad, con un punto de color: verde entra, rojo sale, gris
   lo de antes de la migración. De un vistazo se ve si todavía está en casa. */
.tz-mov { align-items: flex-start; gap: 10px; }
.tz-mov .punto { width: 9px; height: 9px; border-radius: 50%; flex: none; margin-top: 6px; }
.tz-mov .punto.entra { background: var(--g); }
.tz-mov .punto.sale { background: var(--red); }
.tz-mov .punto.viejo { background: var(--mut); }
.tz-fila .amt { text-align: right; flex: none; }
.tz-fila .amt .u { display: block; margin-top: 3px; }

/* ── Valoración del almacén ─────────────────────────────
   Lo que lleva género parado de los años que no se importaron, marcado: es
   justo lo que se viene a buscar. */
.vl-fila .amt { min-width: 112px; }
/* La miniatura del articulo. Del mismo tamano que el cuadrito del icono que
   sale cuando no hay foto, para que la lista no baile de renglon a renglon
   segun cual tenga imagen. */
.vl-foto { width: 42px; height: 42px; border-radius: calc(13px * var(--rr));
    flex: none; object-fit: cover; background: var(--wash); }
.vl-fila.parado { background: var(--red-w); }
.vl-fila.resto .t { color: var(--mut); }
.vl-fila.total { border-top: 2px solid var(--g); background: var(--wash); font-weight: 750; }

@media (min-width: 701px) {
    .lin-cab.bal-cab.vl-cab span:not(:first-child) { min-width: 112px; }
}
@media (max-width: 700px) {
    .vl-fila { flex-wrap: wrap; }
    .vl-fila .q { flex: 1 1 100%; }
    .vl-fila .amt { min-width: 0; flex: 1 1 40%; font-size: 12.5px; }
}

@media (min-width: 701px) {
    .lin-cab.bal-cab.dg-cab span:nth-child(2) { min-width: 116px; }
    .lin-cab.bal-cab.dg-cab span:nth-child(3) { min-width: 70px; }
    .lin-cab.bal-cab.res-cab span:not(:first-child) { min-width: 116px; }
}
@media (max-width: 700px) {
    .dg-fila, .res-fila { flex-wrap: wrap; }
    .dg-fila .q, .res-fila .q { flex: 1 1 100%; }
    .dg-fila .amt, .res-fila .amt { min-width: 0; flex: 1 1 30%; font-size: 12.5px; }
}


/* La barra de sacar el informe: Excel, PDF e imprimir. Va discreta, arriba
   a la derecha, porque se usa al final y no es lo que se viene a mirar. */
.exportar { display: flex; gap: 7px; justify-content: flex-end; margin-bottom: 10px; flex-wrap: wrap; }
.exportar .btn { white-space: nowrap; }
@media (max-width: 520px) {
    .exportar { justify-content: stretch; }
    .exportar .btn { flex: 1; }
}


/* ── Departamentos y tipos de trabajo ───────────────────
   Una pantalla de mantener tablas: cada departamento es una caja con su
   nombre arriba y sus tipos de trabajo dentro, y cada línea se guarda sola
   sin salir de aquí. Con el dedo, todo lo que se toca pasa de 40 px. */
.dep-caja.huerfana { border-color: color-mix(in srgb, var(--amber) 55%, #fff); background: var(--amber-w); }
.dep-cab { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.dep-cab .field { flex: 1 1 200px; margin: 0; }
.dep-acts { display: flex; gap: 6px; padding-bottom: 2px; }
.dep-nota { color: var(--mut); margin: 8px 0 2px; }

.rows.tipos { margin-top: 10px; border-top: 1px solid var(--line); }
.rows.tipos .row { gap: 8px; align-items: center; }
.rows.tipos .row .tipo-f { flex: 1 1 300px; min-width: 0; overflow: visible; }
.tipo-f { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.tipo-f .input { flex: 1 1 130px; min-width: 0; }
.tipo-f .input.chico { flex: 0 1 150px; font-size: 12px; }
/* El desplegable de la app se dibuja dentro de una caja propia: es a ella a
   la que hay que darle el ancho, si no se come la fila entera. */
.tipo-f .av-sel { flex: 0 1 170px; min-width: 0; }
.tipo-f .av-sel-boton { font-size: 12px; }

.tipo-nuevo { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.tipo-nuevo .input { flex: 1 1 220px; min-width: 0; }

/* El botón de guardar de cada línea. El de la cabecera nace blanco porque
   vive sobre la barra oscura; aquí, sobre papel, tiene que verse. */
.dep-cab .icobtn, .tipo-f .icobtn { background: var(--g-l); color: var(--g-dd); }
.dep-cab .icobtn:hover, .tipo-f .icobtn:hover { background: var(--g); color: #fff; }

.tipo-acts { display: flex; align-items: center; gap: 8px; justify-content: flex-end; }
.tipo-acts .s { color: var(--mut); white-space: nowrap; }

@media (max-width: 700px) {
    /* En el móvil no caben en una línea: el nombre arriba, y debajo el
       departamento con el guardar; las acciones, a la derecha del todo. */
    .rows.tipos .row { flex-wrap: wrap; row-gap: 6px; }
    .rows.tipos .row .tipo-f { flex: 1 1 100%; }
    .tipo-f .input { flex: 1 1 100%; }
    .tipo-f .av-sel { flex: 1 1 0; }
    .tipo-acts { flex: 1 1 100%; }
}


/* ── Contratos de mantenimiento ─────────────────────────
   Lo que se viene a ver es el saldo, así que la barra va debajo del nombre
   del cliente, del ancho de la fila: se lee de un vistazo quién va justo. */
.ct-fila.malo { background: var(--red-w); }
.ct-fila.ojo { background: var(--amber-w); }
.ct-fila .amt { min-width: 104px; }

.ct-barra {
    display: block; height: 5px; border-radius: 99px; background: var(--line);
    overflow: hidden; margin-top: 7px; max-width: 320px;
}
.ct-barra-in { display: block; height: 100%; border-radius: 99px; background: var(--g); }
.ct-barra-in.ojo { background: var(--amber); }
.ct-barra-in.mal { background: var(--red); }

.ct-apunte { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.ct-apunte .field { flex: 1 1 160px; margin: 0; }
.ct-apunte .field:nth-child(3) { flex: 2 1 240px; }
.ct-apunte .btn { flex: none; }

@media (max-width: 700px) {
    .ct-fila { flex-wrap: wrap; }
    .ct-fila .q { flex: 1 1 100%; }
    .ct-fila .amt { min-width: 0; flex: 1 1 40%; font-size: 12.5px; }
    .ct-apunte .field, .ct-apunte .btn { flex: 1 1 100%; }
}


/* ── Mensajes al cliente ────────────────────────────────
   Lista a la izquierda y la que se toca a la derecha, el mismo patrón que
   los clientes. Los huecos son botones: se tocan y caen donde está el cursor,
   que es más rápido y más seguro que escribir «{codigo}» a mano. */
.ms-fila.on { background: var(--wash); box-shadow: inset 3px 0 0 var(--g); }

.huecos { display: flex; flex-wrap: wrap; gap: 6px; }
.hueco {
    border: 1px solid var(--line); background: var(--surf); color: var(--ink-2);
    border-radius: 999px; padding: 4px 11px; font-size: 12px; font-weight: 650;
    cursor: pointer; font-family: inherit;
}
.hueco:hover { border-color: var(--g); color: var(--g-d); background: var(--wash); }

.ms-cuerpo { min-height: 150px; height: auto; padding: 10px 12px; line-height: 1.45; }
.ms-cuerpo.codigo { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11.5px; }

/* Cómo se lee el mensaje: en papel, con sus saltos de línea respetados. */
.ms-lectura {
    background: var(--wash); border-radius: calc(12px * var(--rr)); padding: 12px 14px;
    font-size: 13px; line-height: 1.5; color: var(--ink);
    white-space: pre-wrap; word-break: break-word; max-height: 320px; overflow: auto;
}


/* ── Reservas ───────────────────────────────────────────
   La pantalla que se mira con la sala llena y el móvil en una mano: la hora
   grande a la izquierda, el nombre en medio y los botones de sala a la
   derecha, todos de más de 30 px para que se acierte con el pulgar. */
.rv-dias { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.rv-dias .input { height: 34px; font-size: 13px; }
/* La misma flecha, del revés: una sola forma para ir y volver. */
.rv-siguiente svg { transform: rotate(180deg); }

.rv-servicios { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.rv-servicio {
    background: rgba(255, 255, 255, .14); border-radius: calc(12px * var(--rr)); padding: 7px 12px;
    min-width: 128px; color: #fff;
}
.rv-servicio.lleno { background: rgba(255, 255, 255, .26); }
.rv-servicio .t { display: block; font-size: 11.5px; font-weight: 700; opacity: .85; }
.rv-servicio .n { font-size: 16px; font-weight: 800; letter-spacing: -.02em; }
.rv-servicio .ct-barra { margin-top: 5px; background: rgba(255, 255, 255, .28); max-width: none; }
.rv-servicio .ct-barra-in { background: #fff; }

.rv-fila { gap: 10px; align-items: center; }
.rv-fila.ojo { background: var(--amber-w); }
.rv-fila.apagado { opacity: .55; }
.rv-hora { flex: none; width: 58px; text-align: center; line-height: 1.15; }
.rv-hora b { font-size: 15px; font-weight: 800; letter-spacing: -.02em; }
.rv-hora .s { display: block; color: var(--mut); font-size: 11px; }
.rv-acts { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.rv-acts .icobtn { background: var(--wash); color: var(--g-dd); width: 32px; height: 32px; }
.rv-acts .icobtn:hover { background: var(--g); color: #fff; }
.rv-acts .icobtn.rojo { color: var(--red); }
.rv-acts .icobtn.rojo:hover { background: var(--red); color: #fff; }

.rv-cliente { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }

@media (max-width: 700px) {
    .rv-fila { flex-wrap: wrap; }
    .rv-fila .grow { flex: 1 1 60%; }
    .rv-acts { flex: 1 1 100%; justify-content: flex-start; }
    .rv-servicio { flex: 1 1 42%; min-width: 0; }
}


/* El hueco de la plantilla que no se ha dibujado: se ve que hay algo, se lee
   su nombre debajo y no parece una tarjeta rota. */
.plant-sin {
    display: grid; place-items: center; width: 100%; height: 100%;
    color: var(--mut); background: var(--wash);
}

@page { size: A4 landscape; margin: 12mm; }

/* ══════════════════════════════════════════════════════════════════════════
   ACABADO PLANO
   ══════════════════════════════════════════════════════════════════════════
   El segundo eje del diseño, junto a la forma: el mismo color pero sin
   efectos. Quita los diecinueve degradados de adorno, los brillos de color
   debajo de los botones y la sombra de las tarjetas -que ya tienen borde, y
   dos maneras de decir «esto es una caja» se estorban-.

   Va todo aquí, al final y en un bloque, y no repartido por la hoja: así se ve
   de un vistazo qué cambia y se puede quitar entero si no convence.

   Lo que NO se toca, porque no es adorno sino información: el rayado de «hoy
   no viene» en la jornada del equipo y las flechas de los desplegables, que
   están dibujadas con degradados para no meter una imagen.
   ────────────────────────────────────────────────────────────────────────── */

/* La cabecera de cada pantalla y la de entrada.

   Ojo con `.top`: en el móvil es una banda de color con texto blanco, pero a
   partir de 768 px la hoja la deja sin fondo y con texto oscuro, sobre el
   blanco de la página. Pintarla aquí sin más le ponía fondo negro y dejaba el
   texto oscuro encima: «Hola, admin» ilegible. Así que se le devuelve lo suyo
   en pantalla grande. */
body.plano .top,
body.plano .av-login,
body.plano .av-panel-top,
body.plano .esc-top { background: var(--g-d); }

@media (min-width: 768px) {
    body.plano .top { background: none; color: var(--ink); }
}

/* El logo y el recuadro destacado. */
body.plano .logomark,
body.plano .kpi.hi,
body.plano .totes-tot { background: var(--g); }

/* Las barras de las gráficas: lo que dice algo es la altura, no el degradado. */
body.plano .bars div,
body.plano .grafico .ventas { background: var(--g); }
body.plano .bars div.now { background: var(--g-d); }
body.plano .grafico .gastos { background: var(--amber); }
body.plano .bars div.malo { background: var(--red); }

/* Las barras de progreso. */
body.plano .mini-barra span,
body.plano .procesando .barra i,
body.plano .gr-cinta i { background: var(--g); }

/* Los brillos de color: el botón ya se distingue por su relleno. */
body.plano .btn.pri { box-shadow: none; }

/* Borde o sombra, no las dos. */
body.plano .card,
body.plano .kpi { box-shadow: none; }

/* Los rótulos de sección, con la mitad de separación entre letras: tan
   abierta es marca de cuadro de mando genérico. */
body.plano .sec-t,
body.plano .etiqueta,
body.plano .kpi .lab { letter-spacing: .05em; }

/* Las miniaturas del elegidor de acabado: la de «con relieve» lleva el
   degradado y la de «plano» no, que es justo lo que se está eligiendo. */
.dm-barra { background: linear-gradient(160deg, var(--g-d), var(--g-dd)); }
.dm-barra.plana { background: var(--g-d); }
.dm-card.plana { box-shadow: none; }


/* ── Inicio: sin repetir lo que ya está arriba ─────────────────────────────
   En el ordenador la barra de arriba ya lleva el buscador de clientes y el
   avatar, y la cabecera de Inicio los repetía justo debajo: dos cajas iguales
   de «Buscar cliente» a la vez y el mismo «AD» dos veces, perdiendo una fila
   entera de pantalla para no decir nada nuevo.

   En el móvil no se tocan: allí la barra de arriba va recogida y estos son los
   únicos que hay.
   ------------------------------------------------------------------------ */
@media (min-width: 768px) {
    body[data-s="inicio"] .top .searchbar,
    body[data-s="inicio"] .top .avat { display: none; }
    body[data-s="inicio"] .top { padding-bottom: 0; }
}


/* ── La bandeja de entrada ─────────────────────────────────────────────────
   El sobre de la barra de arriba y la pantalla que abre.

   La lista se pinta de una consulta a la caché del módulo de correo, así que
   entra como cualquier otra pantalla; lo único que espera de verdad es el
   botón de actualizar, y por eso es un botón y no algo automático.
   ------------------------------------------------------------------------ */

/* El sobre, con el número de lo que queda por leer encima. La chapa va
   pegada a la esquina y no empuja nada: la barra de arriba ya va justa y un
   número que mueva los iconos de sitio se nota más que el propio número. */
/* La chapa de «N sin leer» de la cabecera no se deja recortar: en el movil
   la fila va justa y el numero es justo lo que se mira. */
.top .line1 .pill { flex: none; white-space: nowrap; }

.wsobre { position: relative; }
.wsobre.on { color: var(--g-d); }
.wsobre .chapa {
    position: absolute; top: -3px; right: -4px;
    min-width: 16px; height: 16px; padding: 0 4px;
    border-radius: 999px; background: var(--red); color: #fff;
    font-size: 10.5px; font-weight: 700; line-height: 16px; text-align: center;
    box-sizing: border-box; pointer-events: none;
}

/* En el móvil, la lista a pantalla completa y el mensaje encima al abrirlo.
   A partir de 1100 px caben las dos cosas, que es como se lee el correo:
   la lista a la izquierda sin perderla de vista. */
/* Tres columnas: carpetas, lista y mensaje. En el movil van una detras de
   otra, con las carpetas convertidas en una tira que se desliza de lado. */
.ban-3col { display: block; }

/* ── Los tiradores entre columnas ────────────────────────────────────────
   En una pantalla ancha cada uno quiere el reparto a su manera: quien repasa
   mucho correo quiere la lista ancha, y quien lee correos largos quiere el
   mensaje. Se arrastra la raya de en medio y se queda como se deje, guardado
   en el propio navegador: es una preferencia de esta pantalla y de esta
   maquina, no un ajuste del negocio.

   En el movil no salen: no hay dos columnas que repartir. */
.ban-tirador { display: none; }

/* ── La columna de carpetas ──────────────────────────────────────────────
   Salen de la cache del modulo con sus contadores ya hechos, asi que pintarlas
   no cuesta ni una consulta al servidor de correo. */
/* En el movil las carpetas no caben, asi que van en un cajon que entra por la
   izquierda, como en cualquier programa de correo: se abre con el boton de las
   rayas y se cierra tocando fuera, con Esc o al elegir una. */
.ban-carpetas {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 72;
    width: 268px; max-width: 84vw; padding: 14px 10px;
    display: flex; flex-direction: column; gap: 2px;
    background: var(--surf); border-right: 1px solid var(--line);
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    transform: translateX(-102%); transition: transform .18s ease;
}
.ban-carpetas.abierto { transform: none; box-shadow: 0 0 40px rgba(0, 0, 0, .25); }
/* Escribir, lo primero de la columna. Con el color de la casa porque es la
   unica accion de la bandeja que crea algo; todo lo demas es ordenar lo que ya
   ha llegado. */
.ban-redactar {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: auto; height: 42px; margin: 0 0 10px; flex: none;
    border-radius: calc(14px * var(--rr));
}

/* El buscador de «Para»: las opciones salen debajo del campo, encima de todo. */
.ban-campo { display: flex; flex-direction: column; gap: 5px; padding: 10px 14px; position: relative; }
.ban-campo > span { font-size: 11.5px; font-weight: 600; color: var(--mut); }
.ban-campo input, .ban-campo textarea {
    padding: 9px 11px; border: 1px solid var(--line); border-radius: calc(10px * var(--rr));
    background: var(--surf); color: var(--ink); font: inherit; font-size: 14px;
    width: 100%; resize: vertical;
}
.ban-sugiere {
    position: absolute; left: 14px; right: 14px; top: 100%; z-index: 60;
    max-height: 280px; overflow-y: auto; padding: 5px;
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(12px * var(--rr));
    box-shadow: 0 1px 2px rgba(14, 26, 23, .16), 0 16px 40px rgba(14, 26, 23, .22);
}
.ban-sugiere[hidden] { display: none; }
.ban-sugiere button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    padding: 8px 10px; border: 0; background: none; cursor: pointer;
    font: inherit; border-radius: calc(8px * var(--rr)); color: var(--ink);
}
.ban-sugiere button:hover, .ban-sugiere button.puesta { background: var(--wash); }
.ban-sugiere .quien { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.ban-sugiere .quien b { font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-sugiere .quien small { font-size: 11.5px; color: var(--mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-nuevo-pie { display: flex; gap: 8px; justify-content: flex-end; padding: 6px 14px 14px; }

/* ── El editor del correo ────────────────────────────────────────────────
   Los botones de siempre y ninguno mas: negrita, cursiva, subrayado, listas,
   enlace y quitar formato. Un correo de trabajo no necesita una imprenta. */
.ban-herramientas {
    display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
    padding: 4px; border: 1px solid var(--line); border-bottom: 0;
    border-radius: calc(10px * var(--rr)) calc(10px * var(--rr)) 0 0;
    background: var(--wash);
}
.ban-herramientas button {
    min-width: 30px; height: 28px; padding: 0 7px; cursor: pointer;
    border: 0; background: none; color: var(--ink);
    font: inherit; font-size: 13.5px; border-radius: calc(7px * var(--rr));
    display: inline-flex; align-items: center; justify-content: center;
}
.ban-herramientas button:hover { background: var(--line); }
.ban-herramientas .sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }

.ban-editor {
    min-height: 220px; max-height: 46vh; overflow-y: auto;
    padding: 12px; border: 1px solid var(--line);
    border-radius: 0 0 calc(10px * var(--rr)) calc(10px * var(--rr));
    background: var(--surf); color: var(--ink);
    font-size: 14px; line-height: 1.5; outline: none;
}
.ban-editor:focus { border-color: var(--g-d); }
.ban-editor img { max-width: 100%; height: auto; }

/* Adjuntos: del ordenador o de la biblioteca del negocio. */
.ban-adjuntar { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 14px 10px; position: relative; }
.ban-adjuntar label.btn { cursor: pointer; }
.ban-adjuntos-puestos { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.ban-puesto {
    display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
    padding: 4px 6px 4px 10px; border-radius: 999px;
    background: var(--wash); border: 1px solid var(--line); font-size: 12px;
}
.ban-puesto span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-puesto button {
    border: 0; background: none; cursor: pointer; color: var(--mut);
    font-size: 15px; line-height: 1; padding: 0 2px;
}
/* La biblioteca, como una galeria: con la foto se reconoce el fichero de un
   vistazo, y con el nombre solo hay que leerse veinte lineas iguales. */
/* Debajo de los botones, no encima.
   Con «top: auto» el panel caia justo sobre la fila de botones y se comia el
   clic: con la biblioteca abierta, pulsar «Un documento» no hacia nada porque
   el clic lo recibia el buscador del panel. Medido con elementFromPoint sobre
   el centro del boton. */
.ban-biblio { left: 14px; right: 14px; top: 100%; max-height: 340px; }
.ban-biblio-ficha { align-items: center; }
.ban-biblio-ficha .tapa {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 42px; height: 42px; overflow: hidden;
    border-radius: calc(8px * var(--rr)); background: var(--wash);
    border: 1px solid var(--line);
    font-size: 10px; font-weight: 700; color: var(--mut); letter-spacing: .03em;
}
.ban-biblio-ficha .tapa img { width: 100%; height: 100%; object-fit: cover; }
.ban-biblio-ficha .tapa.pdf { background: var(--red-w); color: var(--red); border-color: var(--red-w); }
.ban-biblio-ficha .tapa.quien { background: var(--g-l); color: var(--g-d); border-color: var(--g-l); }

/* El buscador del panel de adjuntar: se queda arriba mientras la lista
   se desliza debajo, que es lo que se espera al escribir y mirar. */
.ban-biblio-busca {
    position: sticky; top: 0; z-index: 1;
    padding: 8px; background: var(--surf); border-bottom: 1px solid var(--line);
}
.ban-biblio-campo {
    width: 100%; padding: 7px 10px; font-size: 13.5px;
    border: 1px solid var(--line); border-radius: calc(9px * var(--rr));
    background: var(--wash); color: var(--ink);
}
.ban-biblio-campo:focus { outline: 2px solid var(--g-l); border-color: var(--g); }
.ban-biblio-lista { display: flex; flex-direction: column; }
.ban-biblio-tit {
    padding: 8px 11px 4px; font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .05em; color: var(--mut);
}
.ban-biblio-vacio { padding: 14px 12px; font-size: 13px; color: var(--mut); text-align: center; }
.ban-biblio-mas {
    margin: 6px 8px 10px; padding: 8px; font-size: 13px; font-weight: 600;
    border: 1px dashed var(--line); border-radius: calc(9px * var(--rr));
    background: var(--wash); color: var(--ink); cursor: pointer;
}
.ban-biblio-mas:hover { background: var(--surf); border-color: var(--g); }

/* ── La ventana para ver un adjunto ──────────────────────────────────────
   Encima del correo, no en su lugar: se cierra y sigues donde estabas. */
.av-visor-adjunto {
    position: fixed; inset: 0; z-index: 90; display: flex;
    align-items: center; justify-content: center; padding: 20px;
    background: rgba(14, 26, 23, .58);
}
.av-visor-adjunto-caja {
    display: flex; flex-direction: column; width: min(1000px, 100%); height: min(88vh, 100%);
    background: var(--surf); border-radius: calc(14px * var(--rr)); overflow: hidden;
    box-shadow: 0 24px 60px rgba(14, 26, 23, .34);
}
.av-visor-adjunto-cab {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--wash);
}
.av-visor-adjunto-cab b { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.av-visor-adjunto-cab span { display: flex; gap: 8px; flex: none; }
.av-visor-adjunto-cuerpo { flex: 1; width: 100%; border: 0; background: var(--canvas); }
img.av-visor-adjunto-cuerpo { object-fit: contain; padding: 12px; }
/* El adjunto, como tarjeta: se ve lo que es antes de abrirlo. */
button.ban-adjunto {
    display: flex; align-items: center; gap: 10px; cursor: pointer; font: inherit;
    padding: 7px 12px 7px 7px; text-align: left; color: var(--ink);
    border: 1px solid var(--line); border-radius: calc(10px * var(--rr));
    background: var(--surf);
}
button.ban-adjunto:hover { background: var(--wash); border-color: var(--g); }
button.ban-adjunto .tapa {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 44px; height: 44px; overflow: hidden;
    border-radius: calc(8px * var(--rr)); background: var(--wash);
    border: 1px solid var(--line);
    font-size: 10px; font-weight: 700; color: var(--mut); letter-spacing: .03em;
}
button.ban-adjunto .tapa img { width: 100%; height: 100%; object-fit: cover; }
button.ban-adjunto .tapa.pdf { background: var(--red-w); color: var(--red); border-color: var(--red-w); }
button.ban-adjunto .quien { display: flex; flex-direction: column; min-width: 0; }
button.ban-adjunto .quien b { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button.ban-adjunto .quien small { font-size: 11.5px; color: var(--mut); }

/* ── El detalle de la línea ──────────────────────────────────────────────
   Plegado bajo su fila: lo que en GestioERP está detrás del «…». */
.lin-detalle {
    grid-column: 1 / -1; margin: 2px 0 8px; padding: 12px;
    background: var(--wash); border: 1px solid var(--line);
    border-radius: calc(10px * var(--rr));
    display: flex; flex-direction: column; gap: 10px;
}
.lin-detalle[hidden] { display: none; }
.lin-detalle-campos { display: flex; flex-wrap: wrap; gap: 10px; }
.lin-detalle-campos label { display: flex; flex-direction: column; gap: 3px; flex: 1 1 130px; }
.lin-detalle-campos label > span { font-size: 11.5px; font-weight: 600; color: var(--mut); }
.lin-detalle-sis { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.lin-detalle-ben { width: 100%; }

/* Por dónde ha pasado el documento: enviado, leído, impreso.
   En verde y pequeños, dentro de la línea del cliente: son una confirmación,
   no un dato que haya que leer. */
.marca-doc { display: inline-flex; vertical-align: -2px; margin-left: 5px; color: var(--g); }

/* El aviso de los borradores olvidados: plegado, que no estorbe la lista. */
.aviso-olvidados { border-left: 4px solid var(--amber); background: var(--amber-w); }
.aviso-olvidados summary { cursor: pointer; display: flex; flex-direction: column; gap: 2px; }
.aviso-olvidados summary b { font-size: 14px; }
.aviso-olvidados summary span { font-size: 12.5px; color: var(--mut); }
.aviso-olvidados .rows { margin-top: 10px; }

/* ── El aviso de «está en borrador» ──────────────────────────────────────
   En ámbar, no en rojo: no es un error, es un estado. Pero se ve, porque
   dejar una factura en boceto para siempre es justo lo que ha estado
   pasando. */
.aviso-borrador {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    border-left: 4px solid var(--amber); background: var(--amber-w);
}
.aviso-borrador-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.aviso-borrador-txt b { font-size: 14px; }
.aviso-borrador-txt span { font-size: 12.5px; color: var(--mut); }
.aviso-borrador-btn { flex: none; margin: 0; }

/* Y el de «está emitida»: en verde, que aquí no hay nada que corregir,
   solo se dice dónde está y qué se puede hacer. */
.aviso-emitida {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    border-left: 4px solid var(--g); background: var(--g-l);
}

/* La puerta al programa entero, junto a la marca. */
.wsalir-erp { margin-left: 2px; opacity: .8; }
.wsalir-erp:hover { opacity: 1; }
/* La marca de GestioERP dentro de la barra: solo el trazo, como los demas
   iconos. Con su cuadro de color parecia una insignia pegada y no un boton. */
.wsalir-erp .av-marca .marca-fondo { fill: none; }
.wsalir-erp .av-marca .marca-flecha { stroke: currentColor; }

/* ── La conversación ─────────────────────────────────────────────────────
   Lo tuyo con una marca a la izquierda: en un hilo, saber de un vistazo cuál
   es tuyo es la mitad de entenderlo. */
.ban-hilo { border-top: 1px solid var(--line); padding: 10px 14px; }
.ban-hilo-tit {
    display: flex; align-items: center; gap: 6px; padding-bottom: 6px;
    font-size: 11.5px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .04em; color: var(--mut);
}
.ban-hilo-fila {
    display: flex; align-items: baseline; gap: 10px; padding: 7px 9px;
    text-decoration: none; color: var(--ink); font-size: 13px;
    border-radius: calc(8px * var(--rr)); border-left: 3px solid transparent;
}
.ban-hilo-fila:hover { background: var(--wash); }
.ban-hilo-fila.mio { border-left-color: var(--g); background: var(--g-l); }
.ban-hilo-quien { font-weight: 700; flex: none; max-width: 30%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-hilo-asunto { flex: 1; min-width: 0; color: var(--mut); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-hilo-cuando { flex: none; font-size: 11.5px; color: var(--mut); }

/* Contestar, al pie del mensaje. */
.ban-responder { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px; border-top: 1px solid var(--line); }

@media (max-width: 700px) {
    .av-visor-adjunto { padding: 0; }
    .av-visor-adjunto-caja { width: 100%; height: 100%; border-radius: 0; }
}

/* La miniatura del articulo en el panel del TPV. */
.panel-foto {
    flex: none; width: 40px; height: 40px; margin-right: 10px;
    object-fit: cover; border-radius: calc(8px * var(--rr));
    border: 1px solid var(--line); background: var(--wash);
}

/* Ajustes del correo: la muestra de la firma y las dos fechas. */
.ban-muestra-firma {
    padding: 12px; border: 1px dashed var(--line); border-radius: calc(10px * var(--rr));
    background: var(--wash); max-height: 260px; overflow: auto;
}
.ban-muestra-firma img { max-width: 100%; height: auto; }
.ban-dos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ban-dos label { display: flex; flex-direction: column; gap: 4px; }
.ban-dos label > span { font-size: 11.5px; font-weight: 600; color: var(--mut); }
.ban-raya { border: 0; border-top: 1px solid var(--line); margin: 6px 14px; }

/* La raya que separa las carpetas de lo que no es una carpeta. */
.ban-carpetas-raya { border: 0; border-top: 1px solid var(--line); margin: 10px 8px; width: auto; }

.ban-carpetas-tit {
    font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
    color: var(--mut); padding: 2px 11px 8px;
}
.ban-velo {
    position: fixed; inset: 0; z-index: 71; background: rgba(14, 26, 23, .38);
}
.ban-velo[hidden] { display: none; }
.ban-carpeta {
    display: flex; align-items: center; gap: 7px; flex: none;
    padding: 8px 12px; text-decoration: none; white-space: nowrap;
    border: 1px solid var(--line); border-radius: calc(11px * var(--rr));
    background: var(--surf); color: var(--ink); font-size: 13.5px;
}
.ban-carpeta i { display: inline-flex; color: var(--mut); }
.ban-carpeta.on { background: var(--wash); border-color: var(--g-d); color: var(--g-d); font-weight: 700; }
.ban-carpeta.on i { color: var(--g-d); }
/* El color de una carpeta: una barrita a su izquierda. No se pinta el fondo
   entero porque entonces la carpeta puesta y la coloreada compiten, y la que
   hay que ver de un vistazo es en cual estas. */
.ban-carpeta[data-color] { box-shadow: inset 3px 0 0 var(--car-color); }
.ban-carpeta[data-color] i { color: var(--car-color); }

.ban-carpeta .cuantos {
    font-size: 11px; font-weight: 700; padding: 1px 6px;
    border-radius: 999px; background: var(--g-d); color: #fff;
}
/* Los destacados no son correo nuevo: el numero se dice, no se grita. */
.ban-carpeta .cuantos.suave { background: var(--wash); color: var(--mut); }

/* ── El menu del boton derecho ───────────────────────────────────────────
   Uno para toda la lista. Sale donde este el dedo o el raton, se cierra
   tocando fuera o con Esc, y cada opcion es un boton que manda el formulario:
   sin ajax, para que si algo falla se vea el aviso de siempre. */
.ban-menu {
    /* Por encima de la columna de carpetas, que en el movil es un cajon con
       z-index propio: sin esto el menu salia POR DEBAJO de las carpetas y se
       veian los nombres y los contadores atravesandolo. */
    /* Solo se desliza a lo alto: a lo ancho ya cabe, y el «nowrap» de las
       opciones sacaba una barra horizontal fea dentro del menu. */
    position: fixed; z-index: 80; min-width: 236px; max-height: 80vh;
    overflow-y: auto; overflow-x: hidden;
    padding: 6px; margin: 0;
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(12px * var(--rr));
    /* Dos sombras: una pegada, que lo despega del fondo, y otra larga que lo
       levanta. Con una sola, sobre una lista blanca no se sabe donde acaba. */
    box-shadow: 0 1px 2px rgba(14, 26, 23, .16), 0 16px 40px rgba(14, 26, 23, .22);
}
.ban-menu button {
    display: flex; align-items: center; gap: 9px; width: 100%;
    padding: 10px 12px; border: 0; background: none; cursor: pointer;
    font: inherit; font-size: 14px; color: var(--ink); text-align: left;
    white-space: nowrap; border-radius: calc(8px * var(--rr));
}
.ban-menu button:hover { background: var(--wash); }
/* Los iconos del menu van en gris, pero las estrellas no: su color es lo que
   las distingue, y esta regla se las comia a las tres. */
.ban-menu button:not(.ban-estrella-boton) svg { color: var(--mut); flex: none; }
.ban-menu .ban-estrella-boton svg { flex: none; }
.ban-menu button[hidden] { display: none; }
.ban-menu hr { border: 0; border-top: 1px solid var(--line); margin: 6px 0; }
.ban-menu-tit {
    display: block; padding: 7px 12px 5px; font-size: 10.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em; color: var(--mut);
}
/* Un nombre de carpeta largo no puede estirar el menu a lo ancho. */
#avBanCarNombre { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Vaciar es lo unico sin vuelta atras: se dice con el color, no con otro aviso. */
.ban-menu button[value="vaciar"], .ban-menu button[value="vaciar"] svg { color: var(--red); }

/* ── Arrastrar un correo a una carpeta ───────────────────────────────────
   Mientras se arrastra, el correo se queda medio borrado en su sitio -para
   saber cual se esta moviendo- y la carpeta de debajo se enciende. Sin eso no
   se sabe si se va a soltar donde uno cree. */
/* ── El cuadro de preguntar ──────────────────────────────────────────────
   Propio y no el del navegador: los navegadores que van dentro de una
   aplicacion desactivan `prompt` y `confirm`, y cuando lo hacen no dan error,
   devuelven vacio. El boton parecia roto y no habia manera de saber por que. */
.av-pregunta-velo {
    position: fixed; inset: 0; z-index: 90; display: flex;
    align-items: center; justify-content: center; padding: 20px;
    background: rgba(14, 26, 23, .4);
}
.av-pregunta {
    width: 100%; max-width: 380px; padding: 18px;
    background: var(--surf); border-radius: calc(16px * var(--rr));
    box-shadow: 0 20px 50px rgba(14, 26, 23, .3);
}
.av-pregunta p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.45; }
.av-pregunta input {
    width: 100%; height: 40px; padding: 0 12px; margin-bottom: 14px;
    border: 1px solid var(--line); border-radius: calc(10px * var(--rr));
    background: var(--surf); color: var(--ink); font: inherit; font-size: 14px;
}
.av-pregunta input:focus { border-color: var(--g-d); outline: none; }
.av-pregunta .pie { display: flex; gap: 8px; justify-content: flex-end; }
.av-pregunta-colores { display: flex; gap: 10px; align-items: center; margin-bottom: 14px; }
.av-pregunta-colores .ban-color {
    display: block; width: 22px; height: 22px; min-width: 0; flex: none;
    padding: 0; margin: 0; cursor: pointer; border: 0; border-radius: 999px;
    background: var(--car-color);
}
.av-pregunta-colores .ban-color.sin { background: none; border: 2px solid var(--line); }
.av-pregunta-colores .ban-color.puesta { outline: 2px solid var(--ink); outline-offset: 2px; }

.ban-fila-caja.arrastrando { opacity: .4; }
/* La etiqueta que se lleva el cursor al arrastrar. Arrastrando cinco correos,
   la imagen que pone el navegador es la de UNO, y uno suelta sin saber si van
   los cinco o solo ese. Vive fuera de la pantalla salvo el instante en que el
   navegador le hace la foto. */
.ban-fantasma {
    position: fixed; top: -1000px; left: -1000px; z-index: -1; display: none;
    padding: 9px 14px; border-radius: 999px;
    background: var(--g-d); color: #fff; font-size: 13.5px; font-weight: 600;
    white-space: nowrap; pointer-events: none;
}
/* Mientras el servidor de correo contesta, la fila se apaga en su sitio. Es
   lo que antes era una pantalla en blanco de dos segundos. */
.ban-fila-caja.yendose { opacity: .45; pointer-events: none; }
.ban-carpeta.encima {
    background: var(--wash); outline: 2px dashed var(--g-d); outline-offset: -2px;
    color: var(--g-d);
}
/* Arrastrando una carpeta: encima de otra la mete dentro, y entre dos la
   cambia de sitio. Se distingue por donde cae el cursor, asi que la marca
   tiene que decir cual de las dos cosas va a pasar. */
.ban-carpeta.arrastrando { opacity: .45; }
.ban-carpeta.antes { box-shadow: inset 0 3px 0 var(--g-d); }
.ban-carpeta.despues { box-shadow: inset 0 -3px 0 var(--g-d); }
.ban-carpeta[data-propia] { cursor: grab; }

/* Las tres estrellas. IMAP solo sabe de una marca, asi que el color es de
   aqui: verde lo revisado, ambar lo que importa y rojo lo que hay que hacer.
   Sin color -una estrella puesta desde otro programa- sale ambar. */
.ban-estrella { color: var(--amber); display: inline-flex; }
.ban-estrella svg { fill: currentColor; }
/* Los tres colores son fijos a proposito, no de la paleta del negocio: son
   tres significados que hay que poder distinguir de un vistazo, y con una
   paleta oscura «verde» salia casi negro. */
.ban-estrella.verde { color: #1E8E5A; }
.ban-estrella.naranja { color: #E8720C; }
.ban-estrella.rojo { color: #C0392B; }

/* Las muestras de color de una carpeta: circulos, como en cualquier sitio
   donde se elige un color, y del tamaño que se acierta con el dedo. */
.ban-colores { display: flex; align-items: center; gap: 8px; padding: 4px 12px 8px; }
/* Con el nombre del menu delante: si no, la regla general de sus botones
   -ancho completo y relleno- gana por especificidad y las muestras salen
   estiradas y sin color, que es lo que pasaba. */
.ban-menu .ban-color {
    display: block; width: 20px; height: 20px; min-width: 0; flex: none;
    padding: 0; margin: 0; cursor: pointer;
    border: 0; border-radius: 999px; background: var(--car-color);
}
.ban-menu .ban-color:hover { outline: 2px solid var(--car-color); outline-offset: 2px; }
.ban-menu .ban-color.sin { background: none; border: 2px solid var(--line); }
.ban-menu .ban-color.sin:hover { outline: 2px solid var(--line); outline-offset: 2px; }

.ban-estrellas { display: flex; align-items: center; gap: 2px; padding: 2px 8px 6px; }
.ban-estrellas form { margin: 0; }
.ban-estrella-boton,
.ban-menu .ban-estrella-boton {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; min-width: 0; flex: none;
    padding: 0; margin: 0; cursor: pointer;
    border: 0; background: none; border-radius: calc(8px * var(--rr));
}
.ban-estrella-boton svg { fill: currentColor; }
.ban-estrella-boton:hover { background: var(--wash); }
.ban-estrella-boton.verde { color: #1E8E5A; }
.ban-estrella-boton.naranja { color: #E8720C; }
.ban-estrella-boton.rojo { color: #C0392B; }
/* La de quitar es la misma estrella sin rellenar: se entiende sin leerla. */
.ban-estrella-boton.vacia { color: var(--mut); }
.ban-estrella-boton.vacia svg { fill: none; }
.ban-estrella-boton.puesta { background: var(--wash); outline: 1px solid currentColor; }

.ban-barra { display: flex; align-items: center; gap: 8px; padding: 10px 12px 0; }
.ban-buscar {
    flex: 1; display: flex; align-items: center; gap: 8px;
    padding: 0 12px; height: 38px; min-width: 0;
    border: 1px solid var(--line); border-radius: calc(11px * var(--rr));
    background: var(--wash); color: var(--mut);
}
.ban-buscar input {
    flex: 1; min-width: 0; border: 0; background: none; outline: none;
    font: inherit; font-size: 14px; color: var(--ink);
}
.ban-bajar, .ban-orden { flex: none; margin: 0; }
.ban-orden select {
    height: 38px; max-width: 160px; padding: 0 8px; cursor: pointer;
    border: 1px solid var(--line); border-radius: calc(11px * var(--rr));
    background: var(--wash); color: var(--ink); font: inherit; font-size: 12.5px;
}
/* Boton propio y no `.icobtn`: ese esta hecho para la barra oscura de arriba
   —texto blanco sobre un velo claro— y aqui, sobre la tarjeta blanca, se
   volvia invisible. Mismo tamaño que el campo de al lado. */
.ban-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; padding: 0; cursor: pointer;
    border: 1px solid var(--line); border-radius: calc(11px * var(--rr));
    background: var(--wash); color: var(--ink);
}
.ban-btn:hover { background: var(--line); }
/* El unico boton de la bandeja que sale a internet a traer correo. Suelto y sin
   nombre, al lado de la lupa, no se veia: en pantalla ancha lleva su palabra y
   el color de la casa, y en el movil se queda en el icono, que alli no cabe. */
.ban-refrescar {
    gap: 7px; background: var(--g-d); border-color: var(--g-d); color: #fff;
    font-weight: 600; font-size: 13px;
}
.ban-refrescar:hover { background: var(--g); border-color: var(--g); }
/* Mientras trae el correo: el boton lo dice y no se puede volver a pulsar. */
.ban-refrescar.trabajando { opacity: .75; cursor: progress; }
.ban-refrescar.trabajando svg { animation: av-gira 1.1s linear infinite; }
/* La flecha de actualizar gira al reves, como la de deshacer; la ruedecita de
   «estoy en ello» gira hacia delante, que es como giran todas. */
@keyframes av-gira { to { transform: rotate(-360deg); } }
@keyframes av-gira-der { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .ban-refrescar.trabajando svg { animation: none; }
}
@media (min-width: 768px) {
    .ban-refrescar { width: auto; padding: 0 14px; }
}

/* La casilla va fuera del enlace: dentro, pulsarla abriria el correo. La raya
   de separacion se la queda la caja, que ahora es la fila de verdad. */
.ban-fila-caja { display: flex; align-items: center; border-bottom: 1px solid var(--line); }
.ban-fila-caja:last-child { border-bottom: 0; }
.ban-fila-caja .row { flex: 1; min-width: 0; border-bottom: 0; }
.ban-fila-caja.marcada { background: var(--wash); }
/* El correo sobre el que esta el teclado. Es una marca distinta de la del
   correo abierto y de la de los señalados: son tres cosas que pueden pasar a
   la vez y hay que poder distinguirlas. */
.ban-fila-caja.enfocada { background: var(--wash); box-shadow: inset 0 0 0 2px var(--g-d); }
/* Con raton no hace falta subrayar ademas la fila: ya la marca el enfoque. */
.ban-fila-caja .row:hover { background: none; }
.ban-tic {
    display: flex; align-items: center; justify-content: center;
    flex: none; width: 34px; align-self: stretch; cursor: pointer;
}
.ban-tic input { width: 16px; height: 16px; accent-color: var(--g-d); cursor: pointer; }

/* La fila de las pestañas, con la casilla de señalarlos todos a la izquierda:
   en la misma columna que las casillas de los correos, que es donde la busca
   el ojo. */
.ban-tabs { display: flex; align-items: stretch; }
.ban-tabs .tabs { flex: 1; min-width: 0; }
.ban-tic-todos { align-self: center; height: 34px; }

/* La barra de los señalados: aparece donde estaban las pestañas, sin empujar
   la lista hacia abajo mas de una fila. */
.ban-varios {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 8px 12px; border-bottom: 1px solid var(--line); background: var(--wash);
}
.ban-varios .cuantos { font-weight: 800; }
.ban-varios .grow { flex: 1; color: var(--mut); font-size: 13px; }
.ban-varios[hidden] { display: none; }

/* ── Filtros ─────────────────────────────────────────────────────────────
   Cerrados salvo que haya alguno puesto: la mayoria de las veces con buscar
   basta, y una fila de campos siempre abierta se come la lista. */
.ban-filtros {
    display: grid; grid-template-columns: 1fr; gap: 10px;
    padding: 12px; border-bottom: 1px solid var(--line); background: var(--wash);
}
.ban-filtros[hidden] { display: none; }
.ban-filtros label { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ban-filtros label > span { font-size: 11.5px; color: var(--mut); font-weight: 600; }
.ban-filtros input[type="text"], .ban-filtros input[type="date"], .ban-filtros select {
    height: 36px; padding: 0 10px; min-width: 0;
    border: 1px solid var(--line); border-radius: calc(9px * var(--rr));
    background: var(--surf); color: var(--ink); font: inherit; font-size: 13.5px;
}
.ban-filtro-si { flex-direction: row !important; align-items: center; gap: 8px; }
.ban-filtro-si input { width: 16px; height: 16px; accent-color: var(--g-d); }
.ban-filtro-si > span { font-size: 13.5px !important; color: var(--ink) !important; font-weight: 400 !important; }
.ban-filtros-pie { display: flex; gap: 8px; justify-content: flex-end; }
/* El embudo se enciende cuando hay filtros puestos: es la unica manera de
   saber por que la lista sale corta sin abrir el panel. */
.ban-btn.puesto { background: var(--g-d); border-color: var(--g-d); color: #fff; }

@media (min-width: 768px) {
    .ban-filtros { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ban-filtros-pie { grid-column: 1 / -1; }
}

/* La etiqueta de un correo: un «keyword» de IMAP, asi que se ve igual desde
   Outlook o desde el movil. En la lista caben dos; las demas estan en el
   menu del boton derecho. */
.ban-eti {
    font-size: 10.5px; font-weight: 700; padding: 1px 6px; flex: none;
    border-radius: 999px; background: var(--wash); color: var(--g-d);
    border: 1px solid var(--line); max-width: 110px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* El redondel de quien manda. El color sale de la propia direccion, asi que el
   mismo remitente lleva siempre el mismo: eso es lo que hace que se reconozca
   de un vistazo sin leer el nombre, que es para lo que sirve.

   No se baja ninguna foto de fuera: pedirle el avatar a un servicio ajeno seria
   contarle con quien se cartea el negocio, correo a correo. */
.ban-avatar {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 34px; height: 34px; border-radius: 999px;
    background: var(--tinta); color: #fff;
    font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
}
.ban-avatar.grande { width: 40px; height: 40px; font-size: 14.5px; margin-right: 10px; }
.ban-de { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }

/* El redondel de quien manda. El color sale de la propia direccion, asi que el
   mismo remitente lleva siempre el mismo: eso es lo que hace que se reconozca
   de un vistazo sin leer el nombre, que es para lo que sirve.

   No se baja ninguna foto de fuera: pedirle el avatar a un servicio ajeno seria
   contarle con quien se cartea el negocio, correo a correo. */
.ban-avatar {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 34px; height: 34px; border-radius: 999px;
    background: var(--tinta); color: #fff;
    font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
}
.ban-avatar.grande { width: 40px; height: 40px; font-size: 14.5px; margin-right: 10px; }
.ban-de { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }

.ban-fila .t { display: flex; align-items: center; gap: 6px; }
.ban-clip { color: var(--mut); display: inline-flex; }
/* Sin leer: en negrita y con una marca a la izquierda. Es la misma señal que
   usa cualquier bandeja, y se entiende sin explicarla. */
.ban-fila.nueva { box-shadow: inset 3px 0 0 var(--g-d); }
.ban-fila.nueva .t { font-weight: 800; }
.ban-fila.nueva .s { color: var(--ink); }
/* El dia arriba y la hora debajo: con el correo de trabajo la hora importa
   tanto como el dia, y una debajo de otra no roban ancho al asunto. */
.ban-cuando {
    flex: none; display: flex; flex-direction: column; align-items: flex-end;
    gap: 1px; font-size: 11.5px; color: var(--mut); white-space: nowrap; line-height: 1.25;
}
.ban-cuando .d { font-weight: 600; }
.ban-cuando .h { font-variant-numeric: tabular-nums; opacity: .85; }
.ban-fila.nueva .ban-cuando .d { color: var(--ink); font-weight: 800; }
.ban-paginas { display: flex; gap: 8px; justify-content: center; padding: 12px; }

.ban-cab { padding: 14px 14px 10px; border-bottom: 1px solid var(--line); }
.ban-cab h2 { margin: 0 0 6px; font-size: 17px; letter-spacing: -.01em; }
.ban-de { font-size: 13.5px; }
.ban-de .mono { color: var(--mut); font-size: 12.5px; }
.ban-meta { margin-top: 4px; font-size: 12px; color: var(--mut); }
.ban-acciones { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 14px; }
.ban-acciones form { margin: 0; }
.ban-adjuntos {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 0 14px 12px; border-bottom: 1px solid var(--line);
}
.ban-adjuntos .pill { display: inline-flex; align-items: center; gap: 5px; }

/* El cuerpo del mensaje, encerrado.

   Un boletín trae su propia hoja de estilo y sus propias anchuras; sin este
   marco se lleva por delante la pantalla entera. Aislado tampoco puede pedir
   nada a ningún sitio, que es lo que hacen las imágenes espía de la
   publicidad para saber si has abierto el correo. */
.ban-cuerpo {
    display: block; width: 100%; height: 52vh; min-height: 280px;
    border: 0; background: #fff;
}
.ban-texto {
    margin: 0; padding: 14px; white-space: pre-wrap; word-break: break-word;
    font: inherit; font-size: 13.5px; line-height: 1.55;
}

@media (min-width: 1100px) {
    .ban-3col {
        display: grid;
        grid-template-columns: var(--ban-c1, 186px) minmax(0, 1fr);
        gap: 0; align-items: start;
    }
    /* Con un correo abierto entra la tercera columna. Sin el, la lista se
       queda con todo el ancho, que es lo que se quiere al repasar. */
    .ban-3col.con-mensaje {
        grid-template-columns: var(--ban-c1, 186px) 10px var(--ban-c2, 390px) 10px minmax(0, 1fr);
    }
    .ban-3col:not(.con-mensaje) { grid-template-columns: var(--ban-c1, 186px) 10px minmax(0, 1fr); }

    /* La raya de en medio: estrecha, pero con sitio para el raton. */
    .ban-tirador {
        display: block; align-self: stretch; min-height: 200px;
        cursor: col-resize; position: relative;
    }
    .ban-tirador::after {
        content: ''; position: absolute; top: 0; bottom: 0; left: 4px;
        width: 2px; background: transparent; border-radius: 2px;
    }
    .ban-tirador:hover::after, .ban-tirador.tirando::after { background: var(--g-d); }
    /* Mientras se arrastra, que no se seleccione medio correo sin querer. */
    body.tirando, body.tirando * { user-select: none; cursor: col-resize !important; }
    /* En el ordenador no hay cajon: la columna esta siempre a la vista, y
       sin z-index propio, que si no se pone por delante de los menus. */
    .ban-carpetas {
        position: sticky; z-index: auto; top: 74px; inset: auto; width: auto; max-width: none;
        padding: 0; transform: none; overflow: visible;
        background: none; border-right: 0; box-shadow: none;
    }
    .ban-velo { display: none; }
    .ban-carpeta {
        border: 0; background: none; padding: 8px 11px; border-radius: calc(10px * var(--rr));
    }
    .ban-carpeta:hover { background: var(--wash); }
    .ban-carpeta .nom { flex: 1; overflow: hidden; text-overflow: ellipsis; }
    .ban-carpeta.dentro { padding-left: 26px; font-size: 12.5px; }

    /* Con el mensaje abierto la lista se queda quieta y se desplaza sola: se
       pasa de un correo al siguiente sin que el de al lado se mueva. */
    .ban-lista { position: sticky; top: 74px; max-height: calc(100vh - 92px); overflow: auto; }
    .ban-lista .row { padding: 9px 12px; }
    .ban-lista.ocultar-movil { display: block; }
    .ban-cuerpo { height: calc(100vh - 340px); min-height: 360px; }
}

/* ── Las plantillas dibujadas ───────────────────────────────────────────────
   Se enseñan por su cara y no por su nombre: en un negocio con treinta, todas
   se llaman «Albarán» y la única manera de saber cuál es cuál es verlas.

   La miniatura es la plantilla pintada de verdad dentro de un iframe, así que
   se escala con una transformación; el marco recorta y enseña la mitad de
   arriba, que es donde está lo que se reconoce: el membrete y las líneas. */
.plant-galeria {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px; margin-top: 4px;
}
.plant-tarjeta {
    position: relative; display: block; background: var(--surf);
    border: 1px solid var(--line); border-radius: calc(14px * var(--rr)); overflow: hidden;
    transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.plant-tarjeta:hover { transform: translateY(-2px); border-color: var(--g); box-shadow: 0 10px 22px -12px rgba(14, 26, 23, .3); }
.plant-hoja { position: relative; display: block; width: 100%; background: #fff; overflow: hidden; border-bottom: 1px solid var(--line); }
.plant-marco {
    position: absolute; top: 0; left: 0; width: 794px; height: 1123px; border: 0;
    transform-origin: top left; pointer-events: none; background: #fff;
}
.plant-pie { display: block; padding: 9px 11px; }
.plant-pie b { display: block; font-size: 13px; line-height: 1.3; }
.plant-pie .s { display: block; color: var(--mut); font-size: 11.5px; margin-top: 2px; }
.plant-marca {
    position: absolute; top: 7px; right: 7px; background: var(--wash); color: var(--g-d);
    font-size: 10.5px; font-weight: 700; padding: 3px 7px; border-radius: 99px;
}

/* Los filtros de la galería de plantillas.

   En una sola fila: son cuatro desplegables cortos y apilados ocupaban media
   pantalla. `.input` es de ancho completo en toda la app —está pensada para
   formularios de móvil— así que aquí hay que quitárselo a mano. */
.plant-filtros { display: flex; flex-flow: row wrap; gap: 8px; align-items: center; margin: 4px 0 10px; }
.plant-filtros .input,
.plant-filtros select.input { width: auto; flex: 0 0 auto; height: 38px; font-size: 13.5px; padding: 0 10px; }

/* Ojo: la app cambia cada desplegable por uno propio y lo envuelve en un
   `.av-sel-campo`, que es de ancho completo. Sin esto, la fila se rompe: lo
   que se ve no es el <select> sino su envoltorio. */
.plant-filtros .av-sel { flex: 0 0 auto; }
.plant-filtros .av-sel-campo { width: auto; }
.plant-filtros .av-sel-campo .av-sel-boton { height: 38px; font-size: 13.5px; padding: 0 10px; }
.plant-solo { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--ink-2); font-weight: 600; }
.plant-cuenta { margin-left: auto; color: var(--mut); font-size: 12.5px; font-variant-numeric: tabular-nums; }

/* ── La IA en el correo ─────────────────────────────────────────────────────
   Los dos botones que llaman a la IA van marcados: lo que devuelven es un
   borrador y conviene que se note que no lo ha escrito una persona. */
.ban-herramientas button.con-ia { width: auto; padding: 0 9px; gap: 5px; font-weight: 650; color: var(--g-d); }
.btn.con-ia { color: var(--g-d); }

/* El resumen, encima del correo y con la marca de que lo ha hecho la máquina. */
.ban-resumen {
    background: var(--wash); color: var(--ink); border-radius: calc(12px * var(--rr));
    padding: 12px 14px; margin: 0 0 12px; font-size: 13.5px; line-height: 1.5;
    border-left: 3px solid var(--g);
}

/* ── Los idiomas de una página de la tienda ─────────────────────────────────
   Las siglas encendidas son los idiomas en los que la página está escrita; las
   apagadas, los que faltan. Pulsando una apagada se escribe esa versión, así
   que son botones, no etiquetas: por eso se marcan al pasar por encima. */
.idiomas-pag { display: flex; gap: 5px; flex: none; }
.idiomas-pag .pill { font-size: 11px; padding: 3px 7px; letter-spacing: .02em; }
.idiomas-pag .pill.vacia {
    background: transparent; color: var(--mut);
    border: 1px dashed var(--line); font-weight: 600;
}
.idiomas-pag .pill:hover { outline: 2px solid color-mix(in srgb, var(--g) 35%, transparent); }

/* ── Una línea de «rótulo … importe» ────────────────────────────────────────
   La usan las obras y los partes desde hace tiempo, pero la clase no estaba
   escrita en ninguna parte: el rótulo y el número salían pegados —«Contratado13
   336,00 €»— y había que separarlos con la vista. Un número que se lee mal en
   una obra es un número en el que nadie confía. */
.lin {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 14px;
}
.lin:last-child { border-bottom: none; }
.lin > span:first-child { color: var(--ink-2); min-width: 0; }
.lin > b, .lin > span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.lin .rojo, .lin b.rojo { color: var(--red); }

/* ── El color de la carpeta, donde se elige a dónde mover ───────────────────
   En la columna de la izquierda cada carpeta lleva su color; en el menú de
   «Mover a» salían todas grises y había que leerlas una a una. Quien ha pintado
   «Client Reus» de rojo la busca por el rojo. */
.ban-menu button[data-color] svg { color: var(--car-color); }
.ban-menu button[data-color] { box-shadow: inset 3px 0 0 var(--car-color); }

/* ── Buscar un artículo desde un campo de referencia ────────────────────────
   Se teclea el código o un trozo del nombre y sale la lista con la foto de cada
   uno. Antes estos campos eran una caja de texto a pelo: había que saberse la
   referencia de memoria o ir a buscarla a otra pantalla y volver. */
.av-sug-ref {
    position: relative; z-index: 30; margin-top: 4px;
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(12px * var(--rr)); overflow: hidden;
    box-shadow: 0 10px 24px -14px rgba(14, 26, 23, .35); max-height: 320px; overflow-y: auto;
}
.av-sug-ref button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    padding: 9px 11px; background: none; border: none; border-bottom: 1px solid var(--line);
    cursor: pointer; color: inherit;
}
.av-sug-ref button:last-child { border-bottom: none; }
.av-sug-ref button:hover { background: var(--wash); }
.av-sug-ref img,
.av-sug-ref .sin-foto {
    width: 34px; height: 34px; flex: none; border-radius: calc(8px * var(--rr));
    object-fit: cover; background: var(--canvas); border: 1px solid var(--line);
}
.av-sug-ref .que { flex: 1; min-width: 0; }
.av-sug-ref .t { display: block; font-weight: 650; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.av-sug-ref .s { display: block; font-size: 12px; color: var(--mut); }
.av-sug-ref .pre { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── El ojo de la contraseña ───────────────────────────────────────────────
   Escrita a ciegas en un móvil, con las mayúsculas puestas sin querer, uno
   prueba tres veces antes de darse cuenta de que estaba bien escrita.
   ------------------------------------------------------------------------ */
.av-clave { position: relative; }
.av-clave .input { padding-right: 46px; }
.av-ojo {
    position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
    width: 36px; height: 36px; display: grid; place-items: center;
    border: none; background: none; color: var(--mut); cursor: pointer;
    border-radius: calc(10px * var(--rr));
}
.av-ojo:hover { color: var(--ink-2); background: var(--wash); }
.av-ojo[aria-pressed="true"] { color: var(--g-d); }

/* La caja que acaba de rellenar la IA: se ve que ha cambiado y que falta
   guardarla. Sin esto, la traducción aparecía y no parecía haber pasado nada. */
.input.av-tocado { border-color: var(--g); box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 14%, transparent); }
.icobtn.trabajando { opacity: .6; cursor: progress; }


/* ── Los papeles: la rejilla de miniaturas ──────────────────────────
   Una lista de nombres de fichero no dice nada: lo que se reconoce de un
   papel es su pinta. Las fotos salen enteras; lo demás, con su icono y la
   palabra —PDF, Word, Excel—, que a tamaño de móvil un icono solo se
   confunde con otro.
   ------------------------------------------------------------------------ */
.pa-rejilla {
    display: grid; gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(172px, 1fr));
}
.pa-papel {
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(14px * var(--rr)); overflow: hidden;
    display: flex; flex-direction: column;
}
.pa-mini {
    display: grid; place-items: center; aspect-ratio: 4 / 3;
    background: var(--wash); color: var(--g-d); overflow: hidden;
    text-decoration: none;
}
.pa-mini { position: relative; }
/* `contain` y no `cover`: de un contrato escaneado interesa ver la hoja
   entera —el membrete de arriba es lo que se reconoce—, no un recorte del
   centro. El fondo de la baldosa hace de marco. */
.pa-mini img { width: 100%; height: 100%; object-fit: contain; display: block; background: #fff; }
.pa-mini.pa-icono { gap: 4px; }
/* El icono está siempre en el sitio, escondido detrás de la miniatura. Si la
   miniatura no llega, el JS le pone `pa-icono` a la caja y aparece él: así una
   imagen rota nunca se ve. */
.pa-mini:not(.pa-icono) .pa-ico-falso { display: none; }
.pa-mini.pa-icono img { display: none; }
.pa-ext {
    font-size: 10px; font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; color: var(--ink-2);
}
/* Sobre la miniatura, la palabra va en una esquina y no encima del papel. */
.pa-mini:not(.pa-icono) .pa-ext {
    position: absolute; right: 5px; bottom: 5px;
    background: color-mix(in srgb, var(--surf) 88%, transparent);
    border-radius: calc(6px * var(--rr)); padding: 1px 5px; font-size: 9.5px;
}
.pa-mini.chica .pa-ext { display: none; }
/* La del buscador va en una fila, no en una tarjeta. */
.pa-mini.chica {
    width: 46px; height: 46px; aspect-ratio: auto; flex: none;
    border-radius: calc(10px * var(--rr));
}
.pa-pie { padding: 8px 9px 9px; display: flex; flex-direction: column; gap: 3px; }
.pa-pie .t {
    font-size: 11.5px; font-weight: 700; color: var(--ink); line-height: 1.25;
    overflow-wrap: anywhere;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.pa-pie .s { font-size: 10.5px; color: var(--mut); }
.pa-btns { display: flex; align-items: center; gap: 5px; margin-top: 4px; }
.pa-btns form { display: flex; min-width: 0; }
.pa-btns form:has(select) { flex: 1; }
/* Ojo: NO tocar `select` a secas. La app esconde el select nativo con
   `position:absolute; width:1px` y monta el suyo encima; darle aquí un
   `width:100%` lo estiraba a lo ancho de la página y la desbordaba. */
.pa-btns .av-sel, .pa-btns .av-sel-campo { width: 100%; min-width: 0; }
.pa-nombre { display: flex; align-items: center; gap: 5px; margin-top: 4px; }
.pa-nombre .input { flex: 1; min-width: 0; }
.pa-in-nombre { font-size: 10.5px; letter-spacing: -.01em; padding-left: 7px; padding-right: 7px; }
/* «Hacer una foto» solo donde hay cámara. En un ordenador de sobremesa con
   pantalla grande el botón abría un explorador de ficheros, que es lo que ya
   hace el recuadro de al lado: dos botones para lo mismo.

   El corte es el mismo que usa la app para lo de móvil (768 px), y además se
   pide dedo —`pointer: coarse`—, que es lo que distingue una tableta de un
   portátil con pantalla táctil pequeña. */
@media (min-width: 768px) and (pointer: fine) {
    .solo-camara { display: none; }

    /* Esas parejas de botones —«Hacer foto» y «Subir PDF»— van en una rejilla
       de dos columnas puesta en el propio HTML. Al esconder la cámara, el que
       queda se quedaba a media anchura con un hueco al lado. El !important es
       para ganarle al estilo en línea del HTML, que si no manda él. */
    .btn-fila:has(.solo-camara) { grid-template-columns: 1fr !important; }
}

/* ── Las puertas de una caja del TPV ───────────────────────────────────────
   Cada una con su QR: es como se monta de verdad una tableta o una comandera
   —se enfoca con el aparato y entra sola—, porque nadie va a teclear a mano
   una dirección con un token de veintidós letras.
   ------------------------------------------------------------------------ */
.tpv-puertas {
    display: grid; gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.tpv-puerta {
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(14px * var(--rr)); overflow: hidden;
    display: flex; flex-direction: column;
}
/* Fondo blanco siempre: un QR sobre color no lo lee ningún móvil. */
.tpv-qr {
    /* Con una sola puerta el código se comía la pantalla del móvil entera. Un
       QR se lee igual de bien a 220 px, y encima cabe con su rotulo debajo. */
    width: 100%; max-width: 220px; margin: 0 auto; aspect-ratio: 1; object-fit: contain;
    background: #fff; padding: 10px; display: block;
}
.tpv-puerta-pie { padding: 9px 10px 11px; display: flex; flex-direction: column; gap: 6px; }
.tpv-puerta-pie .t { font-size: 12.5px; font-weight: 750; color: var(--ink); }
.tpv-url { font-size: 10px; letter-spacing: -.02em; color: var(--mut); }

.pa-carpeta { margin-top: 5px; }
.pa-carpeta .av-sel, .pa-carpeta .av-sel-campo { width: 100%; min-width: 0; }

/* ── La rectificativa ──────────────────────────────────────────────────────
   La factura cerrada no se corrige: se le hace otra en negativo. En la
   pantalla, cada línea con su casilla de cuánto se devuelve, que casi siempre
   se deja como viene —la factura entera— y de vez en cuando se pone a cero. */
.rect-linea { display: flex; align-items: center; gap: 10px; }
.rect-desc { font-weight: 600; overflow-wrap: anywhere; }
/* La foto del articulo en la lista de reponer. Del tamano del cuadrito del
   icono, para que las filas con foto y sin foto midan igual. */
.rect-foto { flex: none; display: block; line-height: 0; }
.rect-foto img { width: 42px; height: 42px; border-radius: calc(13px * var(--rr));
    object-fit: cover; background: var(--wash); display: block; }
.rect-cant { width: 92px; flex: none; text-align: right; }
.rect-otra { display: flex; align-items: center; gap: 11px; text-decoration: none; color: inherit; }
.rect-otra .s { display: block; }

/* Reclamar la deuda: por correo con su detalle, o por el compartir del
   telefono. En el movil los botones se apilan; en fila no caben tres. */
.reclama-fila { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* ── Lo que deja el documento ──────────────────────────────────────────────
   El margen sale tapado y se destapa de un toque: en el mostrador el cliente
   mira la pantalla, y ahi no puede estar a la vista a cuanto se compra. */
.ben-caja {
    position: relative; display: flex; gap: 18px; width: 100%; text-align: left;
    border: 1px solid var(--line); background: var(--surf); cursor: pointer;
    border-radius: calc(14px * var(--rr)); font: inherit; color: inherit;
}
.ben-uno { display: flex; flex-direction: column; gap: 2px; }
.ben-uno .s { font-size: 11.5px; color: var(--mut); }
.ben-v { font-size: 17px; font-weight: 800; letter-spacing: -.02em; }
.ben-v.verde { color: var(--g-d); }
.ben-v.rojo { color: var(--red); }
/* Tapado: los numeros se difuminan y encima va el rotulo. */
.ben-caja:not(.abierta) .ben-v { filter: blur(7px); user-select: none; }
.ben-tapa {
    position: absolute; inset: 0; display: flex; align-items: center;
    justify-content: center; gap: 6px; font-size: 12.5px; font-weight: 700;
    color: var(--g-d); border-radius: calc(14px * var(--rr));
}
.ben-caja.abierta .ben-tapa { display: none; }

/* La zona de preparacion, editable en su propia fila: no tiene ficha aparte
   porque son tres o cuatro campos y nunca mas de cinco zonas. */
.zona-fila { align-items: flex-start; }
.zona-form { min-width: 0; }
.zona-form .field { margin-bottom: 8px; }

/* La cantidad de un ingrediente, corregible en su propia fila: es como se
   ajusta un escandallo de verdad, a base de «no son 120 g, son 80». */
.ing-cant { display: flex; align-items: center; gap: 4px; flex: none; }
.ing-cant .input { width: 84px; text-align: right; height: 36px; }

/* El recado tal y como va a salir: se lee antes de mandarlo, con sus saltos
   de linea donde toca. */
.recado {
    margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
    font: inherit; font-size: 13px; color: var(--ink-2); line-height: 1.5;
}

/* ── El control horario: la gente, el calendario y los aparatos ──────────
   Todo lo que antes solo se podía hacer sentado delante de GestioERP. Las
   piezas que se repiten son tres: el bloque de «cómo entra el trabajador»
   (QR + enlace + botones), la fila de un día con sus tramos, y la línea de
   poner algo rápido. */

.ct-entrar { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
.ct-entrar .grow { flex: 1 1 220px; min-width: 0; }
.ct-qr {
    width: 132px; height: 132px; flex: none; border-radius: calc(10px * var(--rr));
    background: #fff; padding: 6px; border: 1px solid var(--line);
}
.ct-qr.chico { width: 92px; height: 92px; }

/* La dirección se parte donde haga falta: en un móvil no cabe entera y no
   puede empujar la pantalla de lado. */
.ct-enlace {
    font-size: 12.5px; color: var(--ink-2); word-break: break-all; line-height: 1.45;
}

.ct-botones { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.ct-botones form { margin: 0; }

/* El verde de WhatsApp, que es el que la gente reconoce. */
.btn.wa { background: #25D366; border-color: #25D366; color: #06301A; }
.btn.wa:hover { background: #1FB855; border-color: #1FB855; }

/* La contraseña recién hecha: grande, para leerla en voz alta sin fallar. */
.ct-clave { border: 2px solid var(--g); }
.ct-clave-grande {
    font-size: 30px; font-weight: 800; letter-spacing: 3px; text-align: center;
    color: var(--g-d); padding: 10px 0; user-select: all;
}

/* Un día de la semana con sus tramos. */
.ct-dia {
    display: flex; align-items: center; gap: 10px; padding: 7px 0;
    border-bottom: 1px solid var(--line);
}
.ct-dia:last-of-type { border-bottom: 0; }
.ct-dia-n { flex: none; width: 92px; font-weight: 650; font-size: 13px; color: var(--ink-2); }
.ct-dia .grow { flex: 1; display: flex; gap: 6px; flex-wrap: wrap; min-width: 0; }
.ct-dia .chip { display: inline-flex; align-items: center; gap: 4px; }
.ct-dia .chip form { display: inline; margin: 0; }
.chip-x {
    border: 0; background: none; color: var(--mut); font-size: 15px; line-height: 1;
    cursor: pointer; padding: 0 2px;
}
.chip-x:hover { color: var(--red); }

/* La línea de poner algo de una vez: se estira y se parte sola. */
.ct-poner { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.ct-poner .input { flex: 1 1 130px; min-width: 0; }
.ct-poner .btn { flex: none; }

.ct-semana { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; margin: 10px 0; }
@media (max-width: 599px) {
    .ct-semana { grid-template-columns: repeat(4, 1fr); }
}
.ct-semana .field label { font-size: 11.5px; }

.ct-dias-marcar { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.ct-tramos { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
@media (max-width: 599px) {
    .ct-tramos { grid-template-columns: repeat(2, 1fr); }
}

/* El resumen del mes: una tarjetita por persona. */
.ct-resumen { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin-top: 10px; }
.ct-persona {
    display: block; padding: 10px 12px; border: 1px solid var(--line);
    border-radius: calc(12px * var(--rr)); background: var(--surf);
}
.ct-persona .t { display: block; font-weight: 650; font-size: 13px; }
.ct-persona .n { display: block; font-size: 17px; font-weight: 800; color: var(--g-d); }
.ct-persona .s { display: block; font-size: 11.5px; color: var(--mut); }

/* La cadena de sellos: verde si está entera, rojo si no. */
.ct-bien { border: 1.5px solid var(--g); }
.ct-mal { border: 1.5px solid var(--red); }

/* ── El Panel de control dentro de la app ───────────────────────────────
   Treinta y ocho campos en una columna son treinta y ocho pantallazos de
   movil. En cuanto hay sitio van de dos en dos y de tres en tres; las casillas
   y los textos largos ocupan la fila entera, que es donde se leen. */
.pt-campos { display: grid; grid-template-columns: 1fr; gap: 12px 16px; }
@media (min-width: 620px) { .pt-campos { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1100px) { .pt-campos { grid-template-columns: repeat(3, 1fr); } }
.pt-campos .field { margin: 0; }
.pt-ancho { grid-column: 1 / -1; }
.pt-campos .check { margin: 0; align-self: center; }

/* ── La marca de la app ─────────────────────────────────────────────────
   El movil con la flecha dentro, en los colores que tenga puesta la app. El
   cuadro va en el color VIVO y no en el oscuro, porque la barra y el menu ya
   son el oscuro y un cuadro del mismo color sobre el mismo color no se ve. */
.av-marca { display: block; flex: none; border-radius: calc(9px * var(--rr)); }
.av-marca .marca-fondo { fill: var(--g); }
.av-marca .marca-movil { stroke: #fff; }
.av-marca .marca-flecha { stroke: color-mix(in srgb, var(--g-l) 70%, #fff); }
.av-marca .marca-punta { fill: color-mix(in srgb, var(--g-l) 70%, #fff); }

/* ── El salto rapido: Ctrl+K ────────────────────────────────────────────
   Una caja centrada arriba, como la del programa. En el movil ocupa la
   pantalla entera, que es lo unico que funciona con el teclado abierto. */
.wsalto {
    display: inline-flex; align-items: center; gap: 6px;
    width: auto; padding: 0 9px;
}
/* El texto de dentro solo sale cuando la barra da de si. */
.wsalto .wsalto-txt { display: none; }

/* ── Con pantalla ancha, el Ctrl+K se ensancha ──────────────────────────
   De boton redondo a caja de buscar, con su texto y el atajo a la derecha.
   Un icono solo no dice para que sirve, y este es el atajo que lleva a
   cualquiera de los ciento veinte apartados: cuanto mas se parezca a un
   buscador, mas se usa. Por debajo de 1280 vuelve a ser el icono, que ahi la
   barra ya va justa con el menu y los desplegables. */
@media (min-width: 1280px) {
    .wsalto {
        width: 210px; justify-content: flex-start; padding: 0 11px;
        background: rgba(255, 255, 255, .15);
        border-radius: calc(10px * var(--rr));
    }
    .wsalto:hover { background: rgba(255, 255, 255, .24); }
    .wsalto .wsalto-txt {
        display: block; flex: 1; text-align: left; font-size: 13px;
        font-weight: 600; white-space: nowrap; overflow: hidden;
        color: color-mix(in srgb, var(--g-l) 90%, #fff);
    }
}

@media (min-width: 1600px) {
    .wsalto { width: 280px; }
}
.wsalto kbd {
    font: inherit; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
    padding: 2px 5px; border-radius: calc(5px * var(--rr));
    background: rgba(255, 255, 255, .16); color: inherit;
}

.av-salto {
    position: fixed; inset: 0; z-index: 70;
    background: rgba(10, 26, 22, .45);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 10vh 16px 16px;
}
.av-salto[hidden] { display: none; }

.salto-caja {
    width: 100%; max-width: 560px; background: var(--surf);
    border-radius: calc(14px * var(--rr));
    box-shadow: 0 18px 50px rgba(10, 26, 22, .28);
    display: flex; flex-direction: column; max-height: 70vh; overflow: hidden;
}

.salto-arriba {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 14px; border-bottom: 1px solid var(--line);
}
.salto-lupa { color: var(--mut); display: flex; flex: none; }
.salto-texto {
    flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
    font: inherit; font-size: 16px; color: var(--ink);
}
.salto-texto::placeholder { color: var(--mut); }

.salto-lista { overflow-y: auto; padding: 6px; flex: 1; }

.salto-grupo {
    font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
    text-transform: uppercase; color: var(--mut);
    padding: 10px 10px 4px;
}

.salto-fila {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: calc(9px * var(--rr));
    color: var(--ink); text-decoration: none; cursor: pointer;
}
.salto-fila.on { background: var(--wash); }
.salto-ico { display: flex; width: 18px; flex: none; color: var(--g-d); }
.salto-txt { flex: 1; min-width: 0; font-weight: 620; font-size: 14px; }
.salto-en { font-size: 11.5px; color: var(--mut); flex: none; }

.salto-nada { padding: 22px 14px; text-align: center; color: var(--mut); font-size: 13.5px; }

.salto-pie {
    display: flex; gap: 14px; flex-wrap: wrap;
    padding: 9px 14px; border-top: 1px solid var(--line);
    font-size: 11.5px; color: var(--mut);
}
.salto-pie kbd {
    font: inherit; font-size: 10.5px; font-weight: 700;
    padding: 1px 5px; margin-right: 3px;
    border: 1px solid var(--line); border-radius: calc(4px * var(--rr));
    background: var(--canvas);
}

@media (max-width: 640px) {
    .av-salto { padding: 0; }
    .salto-caja { max-width: none; max-height: 100%; height: 100%; border-radius: 0; }
    .salto-pie { display: none; }
}

/* En pantalla ancha, la caja se ensancha.
   Los 560 px salían de un diseño pensado para el móvil, y en un monitor
   dejaban un cuadradito en medio de la nada con los nombres largos —«Asientos
   que se repiten», «Terminales e impresoras»— partidos o cortados, y ocho
   resultados a la vista cuando cabían quince. Lo que se busca aquí es un
   apartado entre ciento veinte: cuanta más lista se vea de golpe, antes se
   acierta. Se ensancha en dos tramos y no de golpe, que en un portátil de 1280
   una caja de 860 px queda desproporcionada. */
@media (min-width: 1000px) {
    .salto-caja { max-width: 720px; max-height: 76vh; }
}

@media (min-width: 1500px) {
    .salto-caja { max-width: 880px; max-height: 80vh; }
    /* Con sitio de sobra, el buscador se lee más grande: es donde está el
       cursor y donde se mira mientras se escribe. */
    .salto-texto { font-size: 17px; }
    .salto-txt { font-size: 14.5px; }
}

/* ── Las cifras del negocio en el inicio ────────────────────────────────
   Las mismas tarjetas que el Panel de control del programa: la cifra del mes,
   cuanto sube o baja, la linea del año y los tres meses de antes. En el movil
   van de una en una, en tableta de dos y en pantalla ancha de cuatro. */
.pc-rejilla { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 620px) { .pc-rejilla { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1100px) { .pc-rejilla { grid-template-columns: repeat(4, 1fr); } }

.pc-tarjeta { display: block; color: inherit; text-decoration: none; }
.pc-tarjeta:hover { background: color-mix(in srgb, var(--wash) 40%, #fff); }

.pc-alto { display: flex; align-items: center; gap: 8px; }
.pc-alto .lab {
    flex: 1; font-size: 11px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--mut);
}
.pc-alto .sq { width: 26px; height: 26px; flex: none; }
.sq.pc-verde { background: var(--wash); color: var(--g-d); }

.pc-cifra { font-size: 21px; font-weight: 800; margin-top: 6px; line-height: 1.15; }
.pc-cifra.rojo { color: var(--red); }

.pc-var { margin-top: 3px; font-size: 11.5px; display: flex; gap: 5px; flex-wrap: wrap; }
.pc-var .sube { color: var(--g-d); font-weight: 700; }
.pc-var .baja { color: var(--red); font-weight: 700; }
.pc-var .s { color: var(--mut); }

/* La linea del año. Va en el color de la marca y muy fina: es un apoyo para
   leer la cifra de arriba, no un grafico que haya que estudiar. */
.pc-linea {
    display: block; width: 100%; height: 34px; margin: 9px 0 4px;
    color: var(--g-l); overflow: visible;
}

.pc-meses { display: grid; gap: 1px; font-size: 11.5px; }
.pc-meses > div { display: flex; justify-content: space-between; gap: 8px; }
.pc-meses .n { color: var(--mut); letter-spacing: .03em; }
.pc-meses .v { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.pc-meses .ahora .n, .pc-meses .ahora .v { font-weight: 750; color: var(--ink); }

/* ── El filtro de formas de pago de Cobros ──────────────────────────────
   Un desplegable de casillas, como el del programa, pero que cabe en un movil:
   la lista se desliza y cada forma de pago lleva al lado lo que tiene
   pendiente, que es para lo que se abre. */
.fp-filtro { margin-bottom: 12px; }
.fp-filtro > summary {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 14px; cursor: pointer; list-style: none;
}
.fp-filtro > summary::-webkit-details-marker { display: none; }
.fp-filtro[open] > summary { border-bottom: 1px solid var(--line); }
.fp-filtro[open] .chev { transform: rotate(90deg); }

.fp-caja { padding: 10px 14px 12px; }
.fp-todas { display: flex; gap: 6px; margin-bottom: 8px; }
.fp-lista { max-height: 260px; overflow-y: auto; display: grid; gap: 2px; }

.fp-una {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 4px; cursor: pointer; border-radius: calc(8px * var(--rr));
}
.fp-una:hover { background: var(--canvas); }
.fp-una input { width: 17px; height: 17px; flex: none; accent-color: var(--g-d); }
.fp-una .t { display: block; font-size: 13.5px; font-weight: 600; }
.fp-una .s { display: block; font-size: 11.5px; color: var(--mut); }

.fp-pie { display: flex; gap: 6px; align-items: center; margin-top: 10px; }

@media (min-width: 760px) {
    .fp-lista { grid-template-columns: 1fr 1fr; gap: 2px 14px; }
}

/* El resumen mensual: el sabado y el domingo, mas apagados; el saldo del dia
   en rojo cuando falta y en verde cuando sobra. */
.row.ct-finde { background: var(--canvas); }
.row.ct-finde .t { color: var(--mut); }
.amt .s { display: block; font-size: 11.5px; color: var(--g-d); font-weight: 650; }
.amt .s.warn { color: var(--red); }

.ct-espera { background: var(--amber-w); }
.ct-acciones { display: flex; gap: 6px; align-items: center; flex: none; }
.ct-acciones form { margin: 0; }

.ct-aparato { border-bottom: 1px solid var(--line); }
.ct-aparato:last-of-type { border-bottom: 0; }

/* Una lista de pares «qué es» / «cuánto», para las tripas de una jornada. */
.datos { display: grid; gap: 7px; margin-top: 8px; font-size: 13.5px; }
.datos .s { display: inline-block; min-width: 150px; color: var(--mut); }
.ct-hash .mono { font-size: 11px; word-break: break-all; }

/* Lo apagado se ve, pero se ve apagado. */
.row.apagada { opacity: .55; }

/* El título de una tarjeta del control horario: un rótulo y, al lado, la
   frase que dice de qué va. En el móvil la frase baja debajo. */
.ct-cab {
    display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
    margin-bottom: 8px;
}
.ct-cab b { font-size: 14.5px; }
.ct-cab .s { font-size: 12.5px; color: var(--mut); }
.ct-cab.pad { padding: 12px 14px 4px; margin-bottom: 0; }

/* ── La chapa de «te queda algo por mandar» ───────────────────────────────
   Sale cuando hay algo apuntado sin cobertura esperando red. Va por encima
   del menú inferior y encima de la franja segura del móvil, porque si queda
   medio tapada no sirve para nada: es justo lo que hay que ver antes de
   guardar el teléfono y marcharse de la obra. */
.av-cola-chapa {
    position: fixed; z-index: 30; left: 50%; transform: translateX(-50%);
    /* Por encima del menú inferior Y del botón redondo de añadir, que está
       flotando justo en medio: a 76px la chapa le caía encima. */
    bottom: calc(132px + env(safe-area-inset-bottom));
    background: var(--g-d); color: #fff; border: 0;
    border-radius: calc(20px * var(--rr));
    padding: 8px 15px; font-size: 12.5px; font-weight: 650;
    box-shadow: 0 6px 18px rgba(9, 46, 38, .28); cursor: pointer;
}
.av-cola-chapa:hover { background: var(--g-dd); }

/* En el ordenador no hay menú inferior que esquivar. */
@media (min-width: 900px) {
    .av-cola-chapa { bottom: 18px; }
}

/* ── La biblioteca: miniaturas, galería y visor ───────────────────────────
   Casi todo lo que hay en la biblioteca son fotos y papeles escaneados. En una
   lista de nombres (`IMG_20240312.jpg`) no se reconoce ninguno; con la
   miniatura delante se reconocen todos sin abrirlos. */

/* El enlace de acción en un título de sección: «Ver en galería». */
.sec-acc {
    float: right; text-transform: none; letter-spacing: 0; font-size: 12px;
    font-weight: 700; color: var(--g-d);
}

/* La miniatura de una fila. Cuadrada y recortada, para que la columna de
   texto empiece siempre en el mismo sitio aunque las fotos sean apaisadas. */
.bib-mini {
    flex: 0 0 auto; width: 42px; height: 42px; margin-right: 10px;
    border-radius: calc(8px * var(--rr)); overflow: hidden;
    background: var(--canvas); display: grid; place-items: center; color: var(--mut);
}
.bib-mini img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Una fila de la biblioteca es un botón, no un enlace: abre el visor encima
   en vez de sacar al usuario de la pantalla. Hay que devolverle la pinta de
   fila, que un <button> viene con lo suyo puesto. */
.rows > button.row {
    width: 100%; text-align: left; background: none; border: 0; font: inherit;
    color: inherit; cursor: pointer;
}

/* ── La galería ──────────────────────────────────────────────────────── */
.bib-galeria {
    display: grid; gap: 10px;
    /* Baldosas que se reparten el ancho: tres en un móvil, seis o siete en un
       ordenador, sin un solo salto escrito a mano. */
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}
.bib-baldosa {
    background: var(--surf); border: 1px solid var(--line); cursor: pointer;
    border-radius: calc(12px * var(--rr)); overflow: hidden; padding: 0;
    display: flex; flex-direction: column; font: inherit; color: inherit;
}
.bib-baldosa:hover { border-color: var(--g); }
.bib-baldosa img {
    width: 100%; aspect-ratio: 1; object-fit: cover; display: block;
    background: var(--canvas);
}
.bib-icono {
    width: 100%; aspect-ratio: 1; display: grid; place-items: center;
    background: var(--canvas); color: var(--mut);
}
.bib-pie {
    padding: 6px 8px 8px; font-size: 11px; font-weight: 650; line-height: 1.3;
    color: var(--ink-2); text-align: left;
    /* Dos líneas y a otra cosa: los nombres de los escaneos son larguísimos y
       sin esto cada baldosa tendría una altura distinta. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; word-break: break-word;
}

/* ── El visor ────────────────────────────────────────────────────────── */
.bib-visor {
    position: fixed; inset: 0; z-index: 85; background: var(--canvas);
    display: flex; flex-direction: column;
}
.bib-visor-barra {
    display: flex; align-items: center; gap: 10px; padding: 10px 12px;
    background: var(--surf); border-bottom: 1px solid var(--line);
    padding-top: calc(10px + env(safe-area-inset-top));
}
.bib-visor-nombre {
    flex: 1; font-size: 13.5px; font-weight: 700; word-break: break-all;
    line-height: 1.3;
}
.bib-visor-cuerpo {
    flex: 1; min-height: 0; display: grid; place-items: center; overflow: auto;
    padding: 12px; background: #1B211F;
}
.bib-visor-cuerpo img { max-width: 100%; max-height: 100%; display: block; }
.bib-visor-cuerpo iframe { width: 100%; height: 100%; border: 0; background: #fff; }
.bib-visor-cuerpo .nada {
    color: #C8D2CE; font-size: 13.5px; font-weight: 600; text-align: center;
    max-width: 30ch; line-height: 1.5;
}

/* De dónde viene el fichero. Abajo y siempre a la vista: es la razón de abrir
   el visor, no un detalle. Con tope de altura, que un logotipo puede estar en
   cuarenta sitios y no puede comerse la pantalla. */
.bib-visor-traza {
    background: var(--surf); border-top: 1px solid var(--line);
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
    max-height: 34vh; overflow: auto; font-size: 12.5px;
}
.bib-visor-traza .etiqueta { margin-bottom: 6px; }
.bib-visor-traza a, .bib-visor-traza div.uso {
    display: block; padding: 7px 0; border-top: 1px solid var(--line);
    color: var(--ink); font-weight: 600;
}
.bib-visor-traza a:first-of-type, .bib-visor-traza div.uso:first-of-type { border-top: 0; }
.bib-visor-traza .s { display: block; font-size: 11.5px; color: var(--mut); font-weight: 600; }

/* ── Los botones rápidos del inicio ──────────────────────────────────────
   Los mismos que el negocio elige en el Panel de control. Se reparten el ancho
   solos: dos en un móvil, tres en una tableta y cuatro en el ordenador, sin un
   solo salto escrito a mano. */
/* `auto-fit` y no `auto-fill`: con `auto-fill` el navegador reserva columnas
   vacias y ocho botones se partian en dos filas teniendo sitio de sobra para
   una. Y 118 px de minimo en vez de 150: ocho botones mas sus huecos caben en
   1.000 px, que es lo que hay en cualquier portatil. El nombre ya se corta con
   puntos suspensivos cuando aprieta, asi que al estrecharse los botones se
   hacen mas pequeños antes de bajar a otra fila. */
.av-rapidos {
    display: grid; gap: 8px;
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
}
.av-rapido {
    display: flex; align-items: center; gap: 9px;
    background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(11px * var(--rr)); padding: 10px 12px;
    color: var(--ink); text-decoration: none; min-width: 0;
}
.av-rapido:hover { border-color: var(--g); background: var(--wash); }
.av-rapido .sq {
    flex: none; width: 28px; height: 28px; border-radius: calc(8px * var(--rr));
    background: var(--wash); color: var(--g-d);
    display: grid; place-items: center;
}
/* El nombre puede ser largo -«Albaranes de compra»- y no puede partir la
   fila: se corta con puntos suspensivos, que es lo que hace que todos los
   botones midan igual. */
.av-rapido .t {
    font-size: 13px; font-weight: 650; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── El desplegable de categoría en cada movimiento del banco ────────────
   Estrecho a propósito: la fila del extracto es concepto + fecha + importe, y
   la categoría no puede comerse el sitio del importe, que es lo que se lee
   primero. En el móvil se baja a su propia línea. */
.tes-cat { flex: none; margin: 0 10px; min-width: 0; }
.tes-cat select {
    max-width: 160px; height: 30px; font-size: 12px; padding: 0 8px;
    border: 1px solid var(--line); border-radius: calc(8px * var(--rr));
    background: var(--canvas); color: var(--ink-2); font-weight: 600;
}
.tes-cat select:hover { border-color: var(--g); }
/* El cartelito de «guardado» del autoguardado, que aquí no cabe. */
.tes-cat .av-guardado { display: none; }

@media (max-width: 720px) {
    /* La fila pasa a dos lineas: arriba el concepto y el importe, abajo la
       categoria. Meter un desplegable de 160 px en una fila de movil deja el
       concepto en dos caracteres. */
    .rows .row:has(.tes-cat) { flex-wrap: wrap; }
    .tes-cat { margin: 6px 0 0; order: 3; width: 100%; }
    .tes-cat select { max-width: 100%; width: 100%; }
}

/* ── Las plantillas de sector de la tienda ──────────────────────────────────
   Once tarjetas: en el móvil una debajo de otra, y en cuanto hay sitio en
   rejilla, que es como se comparan —se elige mirando los colores y los rasgos
   de tres o cuatro a la vez, no leyéndolas en fila—. */
.av-plantillas { display: grid; grid-template-columns: 1fr; gap: 10px; }
.av-plantilla { margin: 0; }
.av-plantilla.puesta { border-color: var(--ge-1); }

@media (min-width: 700px) {
    .av-plantillas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1100px) {
    .av-plantillas { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* El número de versión, ahora que lleva a «Acerca de»: se comporta como un
   enlace sin dejar de parecer lo que era, una etiqueta discreta. */
a.wver { text-decoration: none; }
a.wver:hover, a.wver.on { color: var(--ge-1); }

/* ── Listas que se ordenan a mano ───────────────────────────────────────────
   El asa es grande a propósito: en un móvil, un asa de dieciséis píxeles no se
   coge, se falla. Y se puede enfocar con el teclado, que es como de verdad se
   reordenan cuarenta cosas. */
.orden-fila { display: flex; align-items: center; gap: 10px; }
.orden-asa {
    flex: none; width: 34px; height: 34px; display: flex; align-items: center;
    justify-content: center; cursor: grab; border-radius: 8px; color: var(--mut);
    background: none; border: 0; touch-action: none;
}
.orden-asa:hover { background: var(--ge-a25); color: var(--ge-2); }
.orden-asa:focus-visible { outline: 2px solid var(--ge-1); outline-offset: 1px; }
.orden-asa:active { cursor: grabbing; }
.orden-num {
    flex: none; min-width: 26px; text-align: right; font-weight: 700;
    color: var(--mut); font-variant-numeric: tabular-nums;
}
.llevando { opacity: .45; }
.orden-dice {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
}


/* En el movil los botones rapidos aprietan un poco mas: el icono y el nombre
   piden menos sitio del que ocupaban, y con tres por fila se ven los ocho sin
   desplazar la pantalla. */
@media (max-width: 560px) {
    .av-rapidos { grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 6px; }
    .av-rapido { padding: 8px 9px; gap: 7px; }
    .av-rapido .sq { width: 24px; height: 24px; }
    .av-rapido .t { font-size: 12px; }
}

/* ── La pantalla de entrada a medida ────────────────────────────────────────
   El fondo va con un velo encima: una foto cualquiera detrás de un formulario
   deja el texto ilegible, y quien la pone no lo ve hasta que alguien no puede
   entrar. El velo se encarga de que siempre se lea. */
.av-login[style*="--av-login-fondo"]::before {
    content: ""; position: fixed; inset: 0; z-index: -1;
    background: var(--av-login-fondo) center / cover no-repeat;
}
.av-login[style*="--av-login-fondo"]::after {
    content: ""; position: fixed; inset: 0; z-index: -1;
    background: color-mix(in srgb, var(--bg) 78%, transparent);
}
.av-login-tit { font-size: 17px; font-weight: 700; margin: 6px 0 2px; text-align: center; }

/* Doble columna: el texto a un lado y el formulario al otro. En el móvil se
   apilan, que es lo único que cabe. */
.av-login.doble { display: grid; gap: 18px; align-content: center; }
.av-login.doble .av-login-lado { text-align: center; }
.av-login.doble .av-login-lado h2 { font-size: 22px; margin: 0 0 6px; }
.av-login.doble .av-login-lado p { color: var(--mut); margin: 0; }

@media (min-width: 860px) {
    .av-login.doble {
        grid-template-columns: minmax(0, 1fr) 420px;
        align-items: center; max-width: 980px; margin: 0 auto; gap: 40px;
    }
    .av-login.doble .av-login-lado { text-align: left; }
}

/* Un dibujo intercalado en el texto de la ayuda. El marco va dentro de la
   tarjeta del artículo, así que se separa de los párrafos y se sangra igual
   que ellos; el pie explica qué se está mirando. */
.ayuda-dib { margin: 14px 0; }
.ayuda-dib .dib-caja-marco { border: 1px solid var(--line); border-radius: 10px; padding: 10px; }
.ayuda-dib figcaption {
    margin-top: 6px; font-size: 12.5px; color: var(--mut); text-align: center;
}

/* El artículo de la ayuda, a dos columnas cuando hay sitio.
   El texto no puede crecer sin freno -un renglón de 1.200 px se pierde al
   volver-, pero dejar media pantalla en blanco al lado tampoco vale. Con la
   lista del capítulo a la derecha, la pantalla se usa entera y el texto se
   sigue leyendo a su anchura. Por debajo de 1.100 px vuelve a ir todo
   seguido, que es como se lee en el móvil. */
.ayuda-2col { gap: 18px; }
.ayuda-2col > div { display: flex; flex-direction: column; gap: 12px; }
.ayuda-2col .sec-t:first-child { margin-top: 0; }

/* La ayuda se pone a dos columnas ANTES que las demas pantallas: a 900 px ya
   hay sitio. Esperar a 1.100 dejaba media pantalla en blanco en un portatil
   normal -y con el Windows al 125 %, en un monitor grande tambien-, que es
   justo lo que hace pensar que la pantalla esta a medio hacer. */
@media (min-width: 900px) {
    .ayuda-2col {
        display: grid; grid-template-columns: minmax(0, 1fr) 280px;
        gap: 18px; align-items: start;
    }
}

@media (min-width: 1100px) {
    .ayuda-2col { grid-template-columns: minmax(0, 1fr) 330px; }
    /* La lista del capítulo se queda a la vista al bajar por el texto: es el
       índice de por dónde vas. */
    .ayuda-2col > div:last-child { position: sticky; top: 14px; }
}

/* Con pantalla de sobra el texto se lee a dos columnas, como un manual de
   papel: el renglon sigue siendo corto y no queda hueco al lado. Los dibujos,
   los cuadros y las notas no se parten por la mitad. */
@media (min-width: 1500px) {
    .ayuda-art { columns: 2; column-gap: 30px; }
    .ayuda-art p, .ayuda-art ul, .ayuda-art figure,
    .ayuda-art .ayuda-cuadros, .ayuda-art .ayuda-enlaces,
    .ayuda-art .ayuda-nota, .ayuda-art .ayuda-teclas { break-inside: avoid; }
    /* Con la columna ya estrecha, el tope de renglon sobra. */
    .ayuda-art p, .ayuda-art .ayuda-teclas { max-width: none; }
    /* Lo que se compara se mira entero: cruza las dos columnas. */
    .ayuda-art .ayuda-cuadros { column-span: all; }
    .ayuda-art .ayuda-dice { column-span: all; }
}

/* ── Los dibujos, con pinta de pantalla de verdad ─────────────────────────
   Los primeros eran rectángulos grises: se entendía la forma pero no se
   reconocía la pantalla. Con texto de verdad, importes y los colores del
   tema, se mira el dibujo y se sabe cuál es antes de leer el pie.
   ------------------------------------------------------------------------ */
.dib-blanco { fill: var(--surf); }
.dib-fondo { fill: var(--wash); }
.dib-sep { stroke: var(--line); stroke-width: 1; }
/* Texto alineado a la izquierda: en una fila de lista, el nombre empieza
   donde empieza la fila, no en su centro. */
.dib-tl { text-anchor: start; }
.dib-tr { text-anchor: end; }
/* Un texto pequeño de verdad, para las líneas de detalle. */
.dib-txt.dib-min { font-size: 7px; font-weight: 600; }
.dib-txt.dib-gordo { font-size: 11px; font-weight: 800; fill: var(--ink); }
.dib-txt.dib-rojo-t { fill: var(--red); }
.dib-txt.dib-verde-t { fill: var(--g-d); }
.dib-chapa { fill: var(--g-w, var(--wash)); }
.dib-boton { fill: var(--g); }
.dib-foto { fill: currentColor; opacity: .13; }

/* En la ayuda el dibujo puede ser más grande: lleva texto pequeño dentro
   —referencias, importes— y a 420 px no se lee. Ocupa la columna. */
.ayuda-dib .dib, .dib-caja-marco .dib { max-width: 100%; }
.ayuda-dib .dib-caja-marco, .card.pad.dib-caja-marco { background: var(--wash); }

/* Las horas del panel del mostrador: columnas, no lista.
   A qué hora entra la gente se lee de pie; en una lista de veinticuatro
   filas hay que comparar números a mano. */
.horas { display: flex; align-items: flex-end; gap: 4px; height: 120px; }
.hora { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; height: 100%; }
.hora-barra {
    flex: 1; width: 100%; display: flex; align-items: flex-end;
    background: var(--wash); border-radius: calc(5px * var(--rr)); overflow: hidden;
}
.hora-barra > span { width: 100%; background: var(--g); border-radius: calc(5px * var(--rr)); min-height: 2px; }
/* La hora punta, marcada: es el dato por el que se mira este gráfico. */
.hora.punta .hora-barra > span { background: var(--g-dd); }
.hora-rot { font-size: 9.5px; color: var(--mut); font-weight: 650; margin-top: 4px; }
@media (max-width: 639px) {
    .horas { height: 96px; gap: 2px; }
    .hora-rot { font-size: 8px; }
}

/* Los dos quesitos de gasto: el entero y el de funcionar.
   Uno al lado del otro cuando hay sitio; apilados en el móvil. El anillo se
   pinta con «stroke-dasharray» sobre un círculo de r=15,915, que mide 100 de
   circunferencia: el porcentaje es la longitud y no hace falta librería. */
.quesitos { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 900px) { .quesitos { grid-template-columns: 1fr 1fr; } }
.quesito { display: flex; align-items: center; gap: 14px; margin: 8px 0 10px; }
.quesito-svg { width: 116px; height: 116px; flex: none; }
.quesito-total { display: flex; flex-direction: column; }
.quesito-total .v { font-size: 22px; font-weight: 800; color: var(--ink); }
.quesito-total .s { font-size: 12px; color: var(--mut); }
.quesito-leyenda { display: flex; flex-direction: column; gap: 5px; }
.quesito-leyenda > div { display: flex; align-items: center; gap: 7px; font-size: 12.5px; }
.quesito-leyenda .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quesito-leyenda .punto { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.quesito-leyenda .mono { color: var(--mut); font-weight: 700; }

/* Lo que solo tiene sentido con pantalla. En el móvil se recorta todo lo que
   no se usa a diario: menos cosas por delante de lo de hoy. */
.solo-ancho { display: none; }
@media (min-width: 900px) { .solo-ancho { display: block; } }

/* El mes del inicio: pinchar un día abre su agenda. Va DENTRO de la rejilla
   de tarjetas, en el hueco que deja, así que es del tamaño de una tarjeta y no
   una pantalla aparte. Y los días son números, no fichas: sin caja ni sombra,
   que con cuarenta y dos cajas el mes pesa más que el negocio. */
.mes-mini { padding: 10px 12px; }
.mes-mini .mes-dia {
    background: none; border: 0; box-shadow: none; padding: 0;
    aspect-ratio: auto; min-height: 22px; font-size: 11.5px;
}
.mes-mini .mes-dia:hover { background: var(--wash); }
.mes-mini .mes-dia.hoy { background: var(--g-dd); color: #fff; }
.mes-mini .mes-rejilla { gap: 1px; }
.mes-mini .mes-titulo { font-size: 13px; margin-bottom: 6px; }
.mes-mini .mes-cab { font-size: 9px; }
.mes-mini .mes-dia .punto { bottom: 1px; width: 3px; height: 3px; }
.mes-titulo { text-align: center; font-weight: 800; font-size: 14px; margin-bottom: 8px; }
.mes-rejilla { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.mes-cab {
    text-align: center; font-size: 10px; font-weight: 800; color: var(--mut);
    letter-spacing: .06em; padding-bottom: 3px;
}
.mes-dia {
    position: relative; display: flex; align-items: center; justify-content: center;
    aspect-ratio: 1; border-radius: calc(8px * var(--rr));
    font-size: 12.5px; font-weight: 650; color: var(--ink-2);
    text-decoration: none; cursor: pointer;
}
.mes-dia:hover { background: var(--wash); }
.mes-dia.fuera { color: var(--mut); opacity: .45; }
.mes-dia.hoy { background: var(--g-dd); color: #fff; font-weight: 800; }
.mes-dia.tiene { color: var(--g-d); font-weight: 800; }
.mes-dia.hoy.tiene { color: #fff; }
/* El punto de «aquí hay algo»: debajo del número, sin moverlo. */
.mes-dia .punto {
    position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%);
    width: 4px; height: 4px; border-radius: 50%; background: var(--g);
}
.mes-dia.hoy .punto { background: #fff; }

/* El panel del mostrador, en naranja: es la entrada nueva de la fila del TPV
   y tiene que distinguirse de «vendido hoy» y del arqueo, que son de otra
   cosa. El naranja es el mismo de los avisos, no un color suelto. */
.kpi.naranja { border-color: color-mix(in srgb, var(--amber, #c77700) 45%, #fff); }
.kpi.naranja .lab, .kpi.naranja .foot { color: var(--amber, #c77700); }
.kpi.naranja .val { color: var(--amber, #c77700); }
.kpi.naranja .kpi-chev { color: var(--amber, #c77700); }

/* Lo que solo tiene sentido con el dedo. Al revés que «.solo-ancho». */
@media (min-width: 900px) { .top .solo-movil { display: none; } }

/* ── El año, en tres cifras ───────────────────────────────────────────────
   Lo que ha entrado, lo que ha salido y lo que queda. El resultado se pinta
   del color que es —verde si se gana, rojo si se pierde—, que es lo único
   que hay que ver desde la puerta.
   ------------------------------------------------------------------------ */
.anyo { display: grid; grid-template-columns: 1fr; gap: 9px; }
@media (min-width: 720px) { .anyo { grid-template-columns: repeat(3, 1fr); } }
.anyo-caja {
    border-radius: calc(14px * var(--rr)); padding: 14px 16px; color: #fff;
    background: var(--g-d);
}
.anyo-caja .lab {
    font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
    font-weight: 750; opacity: .9;
}
.anyo-caja .val { font-size: 26px; font-weight: 800; margin: 4px 0 2px; }
.anyo-caja .foot { font-size: 12px; opacity: .88; }
.anyo-caja.verde { background: linear-gradient(135deg, var(--g) 0%, var(--g-dd) 100%); }
.anyo-caja.ambar { background: linear-gradient(135deg, #d98a2b 0%, #a85f14 100%); }
.anyo-caja.gana { background: linear-gradient(135deg, #1f9d6b 0%, #0e6b47 100%); }
.anyo-caja.pierde { background: linear-gradient(135deg, #d9534f 0%, #8f2d2a 100%); }

/* La gráfica del año: tres polilíneas y la raya del cero. */
.grafica-anyo { margin-top: 10px; }
.ga-svg { width: 100%; height: 150px; display: block; overflow: visible; }
.ga-cero { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; }
.ga-linea { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round;
    vector-effect: non-scaling-stroke; }
.ga-ventas { stroke: var(--g); }
.ga-gastos { stroke: #d98a2b; }
.ga-resultado { stroke: var(--g-dd); }
.ga-meses {
    display: grid; grid-template-columns: repeat(12, 1fr); margin-top: 6px;
    font-size: 9.5px; color: var(--mut); font-weight: 650; text-align: center;
}
.ga-leyenda { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; color: var(--mut); }
.ga-leyenda span { display: flex; align-items: center; gap: 6px; }
.ga-p { width: 14px; height: 3px; border-radius: 2px; display: inline-block; }
.ga-p.ga-ventas { background: var(--g); }
.ga-p.ga-gastos { background: #d98a2b; }
.ga-p.ga-resultado { background: var(--g-dd); }

/* Las dos gráficas del año: la forma de los doce meses y el detalle de los
   cuatro últimos. Una al lado de la otra con sitio; apiladas en el móvil. */
.graficas { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 10px; }
@media (min-width: 1000px) { .graficas { grid-template-columns: 1.6fr 1fr; } }
.grafica-anyo { margin-top: 0; }

.cuatro .lab {
    font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--mut); font-weight: 750;
}
.cuatro-meses { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 10px; }
.cm { display: flex; flex-direction: column; align-items: center; }
.cm-barras {
    display: flex; align-items: flex-end; gap: 3px; height: 110px; width: 100%;
    justify-content: center;
}
.cm-b { width: 12px; border-radius: 3px 3px 0 0; min-height: 2px; }
.cm-ventas { background: var(--g); }
.cm-gastos { background: #d98a2b; }
.cm-gana { background: var(--g-dd); }
/* Un mes en pérdidas dibuja barra igual, pero en rojo: quedarse a cero
   escondería justo el mes que hay que mirar. */
.cm-pierde { background: var(--red); }
.cm-rot { font-size: 10.5px; color: var(--mut); font-weight: 700; margin-top: 5px; }
.cm-val { font-size: 11.5px; font-weight: 800; }
.cm-val.ok { color: var(--g-d); }
.cm-val.bad { color: var(--red); }

/* El saludo y el «dónde estoy», en la misma línea con pantalla: son dos
   renglones cortos y apilados dejaban una franja vacía a la derecha. */
.saludo { flex: 1; min-width: 0; }
@media (min-width: 900px) {
    .saludo { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
    .saludo h1 { margin: 0; }
    .saludo .sub { margin: 0; }
}

/* El número de cuenta en la leyenda del quesito: «628» dice más que
   «Suministros» a quien lleva la contabilidad, y es por donde se busca. */
.quesito-leyenda .cuenta {
    color: var(--mut); font-weight: 700; font-size: 11px; flex: none;
    min-width: 26px;
}

/* El título del mes lleva a la agenda de hoy: que se note que se puede pulsar. */
a.mes-titulo { display: block; color: var(--ink); text-decoration: none; }
a.mes-titulo:hover { color: var(--g-d); }


/* ── La vista apretada del editor ──────────────────────────────────────────
   Un albaran de cuarenta lineas no cabe en pantalla con la fila comoda: se
   baja, se sube, y para corregir el precio de la linea 30 hay que buscarla
   otra vez. Apretada, la fila mide lo que el campo que lleva dentro y siguen
   editandose todas: es la misma fila, no una tabla de solo mirar.

   Es la MISMA vista en presupuestos, pedidos, albaranes y facturas, de venta
   y de compra: el editor es uno solo para todos los documentos.
   ------------------------------------------------------------------------ */
.lineas.compacta .linea { padding: 5px 12px; gap: 5px 8px; }
.lineas.compacta .linea .lin-desc .s { display: none; }
.lineas.compacta .linea .input { height: 32px; font-size: 13px; padding: 0 9px; }
.lineas.compacta .linea .input.desc {
    min-height: 32px; padding-top: 6px; padding-bottom: 6px; font-size: 13px;
}
.lineas.compacta .linea .imp { font-size: 13.5px; }

@media (min-width: 1200px) {
    /* Sin la foto: en apretada lo que se busca es la descripcion y el numero,
       y 34 px por fila son 34 px menos de nombre del articulo. */
    .lineas.compacta { --c-minia: 0px; }
    .lineas.compacta .linea > .minia { display: none; }
    .lineas.compacta .linea { padding: 3px 12px; }

    /* La cabecera se queda pegada arriba mientras se baja: sin ella, en la
       linea treinta no se sabe si la casilla es el precio o el descuento. */
    .lin-cab { position: sticky; top: 0; z-index: 6; }
}

/* ── Las columnas que este negocio no usa ─────────────────────────────────
   «Que hace cada modulo → Las lineas» decide que se ve en la fila. Lo que se
   apaga NO se saca del formulario: la casilla del descuento sigue ahi, con su
   valor, escondida. Si se quitara, una linea con un 10 % se guardaria a cero
   y el importe de la pantalla mentiria mientras se teclea.

   Por eso se tapa con la anchura de la columna a cero y un display:none: la
   fila se coloca por nombre de area (grid-template-areas), asi que esconder
   una casilla no descoloca a las demas. Es el mismo truco de la vista
   apretada con la foto, que ya estaba.
   ------------------------------------------------------------------------ */
.lineas.sin-foto, .lin-cab.sin-foto { --c-minia: 0px; }
.lineas.sin-foto .linea > .minia { display: none; }

.lineas.sin-dto, .lin-cab.sin-dto { --c-dto: 0px; }
.lineas.sin-dto .linea .field[data-col="dtopor"] { display: none; }
/* La cabecera se queda en su sitio —quitarla correria las demas columnas—,
   pero sin nada que leer en una columna de cero pixeles. */
.lin-cab.sin-dto .cab-dto { visibility: hidden; }

.lineas.sin-iva .linea .lin-desc .lin-iva { display: none; }

/* El titulo de un campo que lleva a su mantenimiento. Discreto: es una
   etiqueta, no un boton; el lapiz aparece al pasar por encima y dice que ahi
   se puede entrar a crear o corregir lo que falte en el desplegable. */
.lab-ir { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.lab-ir svg { opacity: .4; }
.lab-ir:hover { color: var(--g-d); text-decoration: none; }
.lab-ir:hover svg { opacity: 1; }


/* El elegidor del color de los botones: titulo, desplegable y una muestra
   con el color puesto, que es la unica forma de elegir un color sin tener
   que guardar para verlo. */
/* El nombre a la izquierda y el color AL LADO, no debajo: apiladas, seis
   ranuras se comian pantalla y media y habia que bajar para ver que se
   estaba cambiando. El desplegable cabe en 150 px hasta en un movil. */
.ranura-boton {
    display: grid; grid-template-columns: minmax(0, 1fr) 150px;
    gap: 7px 10px; align-items: center;
}
.ranura-boton label { margin-bottom: 0; }
.ranura-boton .boton-muestra {
    width: auto; justify-self: end; pointer-events: none;
    height: 32px; padding: 0 12px; font-size: 12.5px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* En estrecho la muestra va debajo del desplegable, en su misma columna. */
.ranura-boton .boton-muestra { grid-column: 2; }

@media (min-width: 760px) {
    .ranura-boton { grid-template-columns: minmax(0, 1fr) 170px 180px; }
    .ranura-boton .boton-muestra { grid-column: 3; }
}

/* ── El plan contable: todo en una fila ────────────────────────────────────
   El enlace se lleva el sitio que sobra y los botones se quedan al final, para
   que borrar no ocupe una fila entera debajo de cada cuenta.
   ------------------------------------------------------------------------ */
.plan-fila { display: flex; align-items: center; gap: 6px; }
.plan-fila .plan-ir {
    display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0;
    color: inherit; text-decoration: none;
}
.plan-fila .plan-borrar { display: flex; flex: none; }
.plan-fila .icobtn { flex: none; background: var(--wash); color: var(--ink-2); }
.plan-fila .icobtn.peligro { background: var(--red-w); color: var(--red); }
.plan-fila .icobtn.peligro:hover { background: var(--red); color: #fff; }
.plan-fila .icobtn.apagado { background: none; color: var(--mut); opacity: .55; cursor: not-allowed; }
.plan-fila .plan-abrir svg { transition: transform .15s; }
.plan-fila .plan-abrir[aria-expanded="true"] svg { transform: rotate(90deg); }

/* Las subcuentas que se abren dentro de la propia fila de la cuenta. */
.plan-dentro { padding: 2px 14px 10px 58px; }
.plan-dentro a {
    display: flex; align-items: center; gap: 10px; padding: 6px 8px;
    border-radius: calc(9px * var(--rr)); color: var(--ink-2); text-decoration: none;
    font-size: 13.5px;
}
.plan-dentro a:hover { background: var(--wash); }
.plan-dentro .mono { flex: none; }
.plan-dentro .des { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-dentro .amt { flex: none; font-weight: 700; }
.plan-dentro .vacio { padding: 6px 8px; color: var(--mut); font-size: 13px; }

/* La franja del saldo de la cuenta, encima de sus subcuentas. */
.plan-resumen { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.plan-resumen .amt.grande { font-size: 19px; font-weight: 750; }
.orden-subs { display: flex; align-items: center; gap: 8px; margin: 0 2px 10px; }
.orden-subs .flecha { display: inline-flex; transition: transform .15s; }
.orden-subs .btn.activo { border-color: var(--g); color: var(--g-d); }
.orden-subs .btn.activo.desc .flecha { transform: rotate(180deg); }

/* ── Los colores, en dos columnas cuando caben ─────────────────────────────
   Se parte solo: con 360 px por columna hay dos, y si no cabe vuelve a una
   sin necesidad de saber el ancho de la ventana —esto vive dentro de la
   columna derecha de Configuración, que ya es media pantalla—.
   ------------------------------------------------------------------------ */
.cfg-colores {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
    gap: 0 20px; align-items: start;
}

/* Dentro, la fila del botón se queda en dos columnas: el media query de arriba
   mira la VENTANA, no esta columna, y con tres se apretaban el desplegable y
   la muestra. La muestra pasa debajo del desplegable, que es donde ya va en
   pantalla estrecha. */
.cfg-colores .ranura-boton { grid-template-columns: minmax(0, 1fr) 160px; }
.cfg-colores .ranura-boton .boton-muestra { grid-column: 2; }

/* Y las paletas, algo más estrechas: en media columna entraban dos por fila y
   quedaba un hueco a la derecha. */
.cfg-colores .paletas { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }


/* ── Montar el panel de entrada ────────────────────────────────────────────
   Cada fila es un bloque de la portada: el asa para moverlo, el nombre con
   una linea que dice que trae, y la casilla de si se ve. #}
   ------------------------------------------------------------------------ */
.pt-bloque { align-items: center; gap: 10px; padding: 11px 13px; }
.pt-bloque .s { display: block; font-size: 12px; color: var(--mut); margin-top: 2px; }
.pt-bloque .pt-sale {
    display: inline-flex; align-items: center; gap: 7px; flex: none;
    font-size: 12.5px; font-weight: 650; color: var(--ink-2); cursor: pointer;
    white-space: nowrap;
}
.pt-bloque .pt-sale input { width: 17px; height: 17px; }
/* El bloque que no se puede mover: el asa se ve, pero apagada y sin gesto. */
.pt-bloque.suelto { background: var(--wash); }
.orden-asa.fijo { cursor: default; opacity: .45; }
@media (max-width: 599px) {
    .pt-bloque .pt-sale span { display: none; }
}

/* El mini-dibujo de cada bloque del panel: lo justo para reconocerlo. Se
   pinta con los colores del tema, asi que sigue al negocio. */
.pt-mini { width: 72px; height: 46px; flex: none; }
.pt-mini .f { fill: var(--wash); }
.pt-mini .c { fill: color-mix(in srgb, var(--g) 22%, #fff); }
.pt-mini .c2 { fill: color-mix(in srgb, var(--g) 38%, #fff); }
.pt-mini .c3 { fill: var(--amber-w); }
.pt-mini .c3v { fill: color-mix(in srgb, var(--mut) 30%, transparent); }
.pt-mini .ok { fill: #DCF1E5; }
.pt-mini .mal { fill: var(--red-w); }
.pt-mini .mal2 { fill: var(--red); opacity: .75; }
.pt-mini .l { fill: color-mix(in srgb, var(--mut) 45%, transparent); }
.pt-mini .l2 { fill: color-mix(in srgb, var(--mut) 22%, transparent); }
.pt-mini .b { fill: var(--g); }
.pt-mini .p, .pt-mini .p3 { fill: var(--g-d); }
.pt-mini .p2 { stroke: var(--g-d); stroke-width: 1.6; stroke-linecap: round; }
.pt-mini .t { fill: none; stroke: var(--g-d); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pt-mini .t.fina { stroke-width: 1.3; }
.pt-mini .r { stroke: color-mix(in srgb, var(--mut) 35%, transparent); stroke-width: 1; }
.pt-mini .q { fill: color-mix(in srgb, var(--g) 25%, #fff); }
.pt-mini .q2 { fill: var(--g-d); }
@media (max-width: 599px) {
    .pt-mini { width: 54px; height: 35px; }
}

/* Ordenar el menu: una tarjeta por nivel. La cabecera dice donde se esta
   colocando, que con nueve tarjetas es lo unico que las distingue. */
.mo-caja { margin-bottom: 12px; }
.mo-cab {
    display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
    padding: 11px 14px; border-bottom: 1px solid var(--line); background: var(--canvas);
    border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
}
.mo-cab b { font-size: 13.5px; color: var(--ink); }
.mo-cab span { font-size: 12px; color: var(--mut); }
.mo-caja .orden-fila .s {
    display: block; font-size: 11.5px; color: var(--mut); margin-top: 2px;
}

/* ── El editor visual del panel de entrada ─────────────────────────────────
   El panel dibujado en piezas que se arrastran. El lienzo es una rejilla
   como la de la portada: asi lo que se monta aqui se parece a lo que se va a
   ver, que es de lo que sirve un editor visual.
   ------------------------------------------------------------------------ */
.pv-tabs { margin-bottom: 10px; }
.pv-tabs a { padding: 11px 0; font-size: 13px; font-weight: 650; color: var(--mut);
    border-bottom: 2.5px solid transparent; cursor: pointer; }
.pv-tabs a.on { color: var(--g-d); border-bottom-color: var(--g); }

.pv-lienzo, .pv-cajon {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px; padding: 12px; border-radius: calc(16px * var(--rr));
    min-height: 96px; align-content: start;
}
.pv-lienzo { background: var(--wash); border: 1.5px dashed var(--line); }
.pv-cajon { background: var(--canvas); border: 1.5px dashed var(--line); opacity: .92; }

.pv-pieza {
    position: relative; display: flex; flex-direction: column; gap: 6px;
    padding: 10px 10px 9px; background: var(--surf); border: 1px solid var(--line);
    border-radius: calc(13px * var(--rr)); cursor: grab; touch-action: none;
    box-shadow: 0 1px 2px rgba(9, 46, 38, .05);
}
.pv-pieza:hover { border-color: var(--g); }
.pv-pieza .pt-mini { width: 100%; height: auto; }
.pv-pieza .pv-t { font-size: 12.5px; font-weight: 650; color: var(--ink); line-height: 1.25; }
.pv-pieza .pv-fijo { font-size: 11px; color: var(--mut); }
.pv-pieza.cogida { opacity: .35; }
/* El que no se mueve de sitio: se puede quitar, pero no colocar. */
.pv-pieza.fijo { cursor: default; }

.pv-btn {
    position: absolute; top: 5px; right: 5px; width: 22px; height: 22px;
    border: 0; border-radius: 50%; background: var(--wash); color: var(--ink-2);
    font-size: 15px; line-height: 1; cursor: pointer; padding: 0;
}
.pv-btn:hover { background: var(--g-d); color: #fff; }

/* La pieza que va con el puntero: por encima de todo y sin estorbar al
   `elementFromPoint` de debajo. */
.pv-fantasma {
    position: fixed; z-index: 9000; pointer-events: none; opacity: .92;
    transform: rotate(-1.5deg); box-shadow: 0 16px 34px rgba(9, 46, 38, .22);
}
body.pv-arrastrando { user-select: none; cursor: grabbing; }
.pv-dice { margin: 6px 2px 0; }

/* El nombre de la pieza, arriba y a una linea: si no cabe, tres puntos. Lo
   que hay que leer es cual es, no la frase entera. */
.pv-pieza .pv-t {
    order: -1; padding-right: 24px; min-height: 32px;
    /* Hasta dos lineas: «Los cuatro numeros del mes» cortado a la primera
       palabra no dice cual es, que es justo para lo que esta el nombre. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}

/* La ventana de previsualizar: el panel de verdad, encima de todo. */
.pv-ventana {
    position: fixed; inset: 0; z-index: 9500; background: rgba(9, 46, 38, .55);
    display: flex; align-items: center; justify-content: center; padding: 16px;
}
.pv-marco {
    width: min(1180px, 100%); height: min(88vh, 900px); display: flex; flex-direction: column;
    background: var(--surf); border-radius: calc(16px * var(--rr)); overflow: hidden;
    box-shadow: 0 28px 70px rgba(9, 46, 38, .4);
}
.pv-barra {
    display: flex; align-items: center; gap: 10px; padding: 9px 12px;
    border-bottom: 1px solid var(--line); background: var(--canvas);
}
.pv-barra b { flex: 1; font-size: 13.5px; }
.pv-marco iframe { flex: 1; width: 100%; border: 0; background: var(--canvas); }

/* ── Los campos de fichero ─────────────────────────────────────────────────
   El «Seleccionar archivo / Ningun archivo seleccionado» que pinta el
   navegador es lo unico de la app que no se parece a la app: letra del
   sistema, botoncito gris y bordes cuadrados en medio de una pantalla de
   campos redondeados. Aqui se le da la misma forma que al resto.

   Solo se puede tocar la CAJA y el BOTON: el texto de «ningun archivo» lo
   pone el navegador en su idioma y no hay manera de cambiarlo, asi que al
   lado de cada campo va su propia frase de ayuda, que es la que de verdad
   dice que hay que poner.
   ------------------------------------------------------------------------ */
input[type="file"] {
    width: 100%; min-height: 46px; padding: 0 12px 0 0;
    border: 1px solid var(--line); background: var(--surf);
    border-radius: calc(12px * var(--rr));
    font-family: inherit; font-size: 13px; color: var(--mut);
    display: flex; align-items: center; cursor: pointer;
}
input[type="file"]:hover { border-color: var(--g); }
input[type="file"]:focus { border-color: var(--g); outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--g) 14%, transparent); }

input[type="file"]::file-selector-button {
    height: 44px; margin: 0 12px 0 0; padding: 0 15px;
    border: 0; border-right: 1px solid var(--line);
    border-radius: calc(11px * var(--rr)) 0 0 calc(11px * var(--rr));
    background: var(--wash); color: var(--g-d);
    font: inherit; font-weight: 650; font-size: 13px; cursor: pointer;
}
input[type="file"]::file-selector-button:hover { background: var(--g-d); color: #fff; }

/* El de dentro de un boton con icono —la camara, el adjunto— sigue oculto:
   ahi el boton es otro y este solo recoge el fichero. */
input[type="file"][hidden] { display: none !important; }

/* Las dos listas del bloque de visitas: lo mas visto y de donde entran. */
.vis-listas { display: grid; gap: 14px; margin-top: 12px; }
.vis-listas .lab { font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    font-weight: 700; color: var(--mut); margin-bottom: 6px; }
.vis-fila { display: flex; justify-content: space-between; gap: 10px; font-size: 13px;
    padding: 4px 0; border-bottom: 1px solid var(--line); }
.vis-fila:last-child { border-bottom: 0; }
.vis-fila span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 760px) {
    .vis-listas { grid-template-columns: 1fr 1fr; gap: 22px; }
}

/* ── Saldos de envases ─────────────────────────────────────────────────────
   Los filtros del informe del programa, en una fila que se parte sola, y la
   tabla envase a envase cuando se pide el detalle.
   ------------------------------------------------------------------------ */
.env-filtros { display: grid; gap: 10px; align-items: end; }
.env-filtros .field { margin-bottom: 0; }
.env-filtros .env-casillas { display: grid; gap: 4px; }
.env-filtros .btn { width: 100%; }
@media (min-width: 900px) {
    .env-filtros { grid-template-columns: 170px 170px 170px minmax(0, 1fr) 150px; }
}

.env-totales { display: flex; flex-wrap: wrap; gap: 7px; margin: 10px 2px; }
.env-totales .pill b { font-weight: 800; }

.tabla-envases .env-cab,
.tabla-envases .env-fila {
    display: grid; gap: 8px; padding: 9px 13px; align-items: center;
    grid-template-columns: minmax(0, 1.4fr) 80px minmax(0, 1.6fr) 80px 80px 80px;
}
.tabla-envases .env-cab { display: none; }
.tabla-envases .env-fila { border-bottom: 1px solid var(--line); color: var(--ink); }
.tabla-envases .env-fila:last-child { border-bottom: 0; }
.tabla-envases .env-fila:hover { background: var(--wash); text-decoration: none; }
.tabla-envases .env-fila .t { font-weight: 650; overflow: hidden; text-overflow: ellipsis; }
.tabla-envases .env-fila .s { font-size: 12.5px; color: var(--mut); overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
.tabla-envases .env-fila .n { text-align: right; font-variant-numeric: tabular-nums; }
.tabla-envases .env-fila .fuerte { font-weight: 750; }
.tabla-envases .env-fila .bad { color: var(--red); }

/* En el movil, cada saldo es un bloque: seis columnas de 60 px no se leen. */
@media (max-width: 759px) {
    .tabla-envases .env-fila {
        grid-template-columns: minmax(0, 1fr) 70px; gap: 2px 8px;
    }
    .tabla-envases .env-fila .t { grid-column: 1; }
    .tabla-envases .env-fila .fuerte { grid-column: 2; grid-row: 1 / span 2; font-size: 17px; }
}
@media (min-width: 760px) {
    .tabla-envases .env-cab {
        display: grid; border-bottom: 1px solid var(--line); background: var(--canvas);
        border-radius: calc(16px * var(--rr)) calc(16px * var(--rr)) 0 0;
        font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
        font-weight: 700; color: var(--mut);
    }
    .tabla-envases .env-cab span:nth-child(n+4) { text-align: right; }
}

/* ── Cómo va un proyecto ───────────────────────────────────────────────────
   La barra del presupuesto consumido: verde mientras hay margen, ámbar al
   80 % y roja pasada. Es lo que se mira antes que ninguna cifra.
   ------------------------------------------------------------------------ */
.pr-barra {
    height: 14px; border-radius: 99px; background: var(--wash);
    border: 1px solid var(--line); overflow: hidden;
}
.pr-barra span { display: block; height: 100%; background: var(--g); border-radius: 99px; }
.pr-barra.ambar span { background: var(--amber); }
.pr-barra.rojo span { background: var(--red); }
.pr-barra-pie {
    display: flex; justify-content: space-between; gap: 10px;
    font-size: 12px; color: var(--mut); margin-top: 6px;
}

/* ── La wiki tecnica, leida delante de la maquina ─────────────────────────

   El cuerpo de una ficha es un procedimiento: pasos, claves, numeros de
   puerto. Se lee de pie, con una mano, y a veces se copia un trozo. Por eso
   va algo mas grande que el texto de apoyo, con la linea suelta y respetando
   los saltos tal como los escribio quien la redacto.
   ------------------------------------------------------------------------ */
.wiki-cuerpo {
    margin: 10px 0 0; font-size: 15px; line-height: 1.65;
    color: var(--ink); white-space: pre-wrap; word-break: break-word;
}

/* ── La fila del artículo, con dos destinos ────────────────────────────────
   La fila entera lleva a la ficha y el relojito de la derecha, al historial
   de ventas y compras. Se hace con una «tapa» que cubre la fila por debajo
   en vez de con un enlace que envuelva todo, porque un <a> dentro de otro
   <a> no es HTML válido: el navegador lo deshace y la fila deja de pulsarse
   entera. La tapa no recibe el foco del teclado —tiene su propio orden— y el
   relojito sí, que es el que hay que poder alcanzar con el tabulador.
   ------------------------------------------------------------------------ */
.fila-art { position: relative; }
.fila-art .tapa-art {
    position: absolute; inset: 0; z-index: 1; border-radius: inherit;
}
/* El contenido no se queda el clic: si lo hiciera, pulsar sobre el nombre
   del artículo no abriría nada —la tapa está debajo— y la fila dejaría de
   pulsarse entera. Lo dejan pasar todos menos los dos que sí tienen destino
   propio: la foto, que se amplía, y el relojito. */
.fila-art > *:not(.tapa-art) { position: relative; z-index: 2; pointer-events: none; }
.fila-art .reloj-art,
.fila-art img.ampliable { pointer-events: auto; }
/* `.icobtn` nace para la barra verde de arriba: blanco sobre blanco. Dentro
   de una fila de la lista hay que devolverle el color de la letra, o el icono
   está pero no se ve. */
.fila-art .reloj-art {
    flex: none; margin-left: 2px; width: 36px; height: 36px;
    background: none; color: var(--ink-2);
}
.fila-art .reloj-art svg { width: 17px; height: 17px; }
.fila-art .reloj-art:hover { background: var(--wash); color: var(--g-d); }

/* ── El pliego de etiquetas ────────────────────────────────────────────────
   La hoja A4 con su cuadrícula, o la tira del rollo. Se deja alto para que la
   hoja se vea entera de un golpe —que es de lo que se trata: ver en qué
   casilla cae la primera— y con fondo gris claro detrás, para que el papel
   blanco se distinga del fondo de la tarjeta.
   ------------------------------------------------------------------------ */
.etq-pliego {
    background: var(--wash2, #F3F6F5); border: 1px solid var(--line);
    border-radius: calc(14px * var(--rr)); padding: 12px;
    display: flex; justify-content: center;
}
.etq-pliego .etq-svg { width: auto; max-width: 100%; }
.etq-pliego .pliego-hoja { max-height: 520px; }
.etq-pliego .pliego-rollo { max-height: 360px; }

/* ── La mesa de conciliación ────────────────────────────────────────────────
   Dos columnas: el extracto del banco y los papeles que podrían explicarlo.
   En pantalla ancha, una al lado de la otra y cada una con su propio scroll,
   que es lo que permite ir bajando por una sin perder de vista la otra. En el
   móvil se apilan y la barra de casar se queda pegada abajo, siempre visible:
   es el sitio donde se mira si cuadra. */
.mesa { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 10px; }
@media (min-width: 900px) { .mesa { grid-template-columns: 1fr 1fr; } }

.mesa-panel { display: flex; flex-direction: column; overflow: hidden; }
.mesa-cab {
    display: flex; align-items: center; gap: 8px; padding: 10px 12px;
    border-bottom: 1px solid var(--line); background: var(--wash);
}
.mesa-cab b { font-size: 13.5px; letter-spacing: -.01em; }
.mesa-cab .s { color: var(--mut); font-size: 12px; }
.mesa-cab .mesa-busca { margin-left: auto; max-width: 160px; }

.mesa-lista { max-height: 46vh; overflow-y: auto; }
@media (min-width: 900px) { .mesa-lista { max-height: 58vh; } }

.mesa-fila {
    display: grid; grid-template-columns: auto 1fr auto; align-items: center;
    gap: 4px 10px; width: 100%; padding: 9px 12px; text-align: left;
    background: none; border: none; border-bottom: 1px solid var(--line);
    font: inherit; color: var(--ink); cursor: pointer;
}
.mesa-fila:last-child { border-bottom: none; }
.mesa-fila:hover { background: var(--wash); }
.mesa-fila.oculta { display: none; }

.mesa-f { font-size: 12px; color: var(--mut); white-space: nowrap; }
.mesa-c { min-width: 0; font-weight: 600; font-size: 13.5px; }
.mesa-c .s { display: block; font-weight: 500; font-size: 11.5px; color: var(--mut); }
.mesa-i { font-weight: 700; white-space: nowrap; letter-spacing: -.02em; }
.mesa-i.malo { color: var(--red); }

/* Lo elegido, con el color de selección del negocio. */
.mesa-fila.elegida { background: color-mix(in srgb, var(--ge-sel, var(--g)) 13%, #fff); }
.mesa-fila.elegida .mesa-c { color: var(--ink); }
.mesa-banco.elegida { box-shadow: inset 3px 0 0 var(--ge-sel, var(--g)); }
/* El papel lleva una casilla delante: cuatro columnas, no tres. */
.mesa-doc { grid-template-columns: auto auto 1fr auto; }
.mesa-doc input[type="checkbox"] { margin: 0; }
.mesa-fila.hecho { opacity: .55; }

/* La barra: los dos importes y lo que falta para que cuadre. */
.mesa-barra {
    position: sticky; bottom: 0; z-index: 5; margin-top: 10px;
    display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    padding: 10px 14px; border-radius: calc(14px * var(--rr));
    background: var(--surf); border: 1px solid var(--line);
    box-shadow: 0 -6px 22px -12px rgba(9, 46, 38, .45);
}
.mesa-val { font-weight: 700; font-size: 15px; letter-spacing: -.02em; }
.mesa-val.cuadra { color: var(--g); }
.mesa-val.falta { color: var(--red); }
.mesa-acciones { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mesa-acciones .s { color: var(--mut); font-size: 12.5px; }

/* En el movil, por encima de la barra de abajo de la app: pegada al borde, el
   boton de casar quedaba debajo del pie y no se podia pulsar. */
@media (max-width: 767.98px) {
    .mesa-barra { bottom: 68px; }
    .mesa-acciones { width: 100%; margin-left: 0; }
    .mesa-acciones .btn { margin-left: auto; }
}

