@import url('company-create.css');

.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-lg);
}

.page-header__title {
    font-size: 1.75rem;
    font-weight: 700;
}

.page-header__subtitle {
    color: var(--color-text-muted);
    margin: 0;
}

.page-header__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    align-items: center;
}

.breadcrumbs__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    list-style: none;
    padding: 0;
    margin: 0 0 var(--spacing-md);
    color: var(--color-text-muted);
    font-size: 0.875rem;
}

.breadcrumbs__link {
    color: var(--color-text-muted);
}

.breadcrumbs__current {
    color: var(--color-text);
    font-weight: 500;
}

.status-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: max-content;
    max-width: 100%;
    padding: 0.2rem 0.75rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.25;
    text-transform: none;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

.status-badge--commercial {
    background: #dbeafe;
    color: var(--color-primary);
}

.status-badge--neutral { background: #f1f5f9; color: var(--color-neutral); }
.status-badge--success { background: #dcfce7; color: var(--color-success); }
.status-badge--warning { background: #fef9c3; color: var(--color-warning); }
.status-badge--danger { background: #fee2e2; color: var(--color-danger); }
.status-badge--info { background: #cffafe; color: var(--color-info); }
.status-badge--primary { background: #dbeafe; color: var(--color-primary); }

.empty-state,
.error-state,
.loading-state,
.permission-denied {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--spacing-2xl);
    background: var(--color-surface);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-lg);
}

.error-state,
.permission-denied {
    border-color: #fecaca;
    background: #fff1f2;
}

.loading-state__spinner {
    width: 2rem;
    height: 2rem;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    margin-bottom: var(--spacing-md);
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.65rem 0.85rem;
    align-items: end;
    justify-content: flex-start;
    margin-bottom: var(--spacing-md);
    padding: 0.75rem 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.filter-bar label {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8125rem;
    min-width: 8rem;
    flex: 1 1 8rem;
    max-width: 16rem;
}

.filter-bar .btn {
    align-self: end;
    flex: 0 0 auto;
}

.filter-bar--stock {
    display: flex;
    flex-wrap: wrap;
    gap: 0.65rem 0.85rem;
    align-items: end;
}

.filter-bar--stock .filter-bar__search {
    position: relative;
    flex: 1 1 14rem;
    min-width: 12rem;
    max-width: 22rem;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 0.2rem;
}

.filter-bar--stock > label:not(.filter-bar__search) {
    flex: 1 1 8.5rem;
    min-width: 7.5rem;
    max-width: 13rem;
}

.filter-bar--stock .filter-bar__submit {
    align-self: end;
    flex: 0 0 auto;
    margin-left: 0;
}

.search-input__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

.search-input__field {
    width: 100%;
    min-width: 0;
    min-height: 2.375rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    line-height: 1.25;
    box-sizing: border-box;
}

.filter-bar--stock select,
.filter-bar--stock .search-input__field {
    min-height: 2.375rem;
}

.stock-col-num,
.stock-col-available,
.stock-col-total-empresa {
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.stock-col-cost {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.stock-total-row th {
    background: var(--color-surface-muted, #f3f4f6);
    font-weight: 700;
    vertical-align: middle;
}

.stock-total-row__label {
    text-align: right;
    padding-right: 0.75rem;
}

/* MOVIMIENTOS — consulta transversal del libro de inventario.
   Reutiliza filter-bar y paginated-table del Design System; aquí solo se declara lo propio de
   esta pantalla. Ámbito acotado con el prefijo .movements-.

   Compactación: la pantalla es de auditoría, así que en un escritorio estándar deben caber
   título, acciones, filtros, indicadores, resumen por tipo, cabecera y varias filas antes de
   necesitar scroll. El scroll vertical se reserva para recorrer registros, no para atravesar
   márgenes. Se recortan separaciones y alturas de caja SIN bajar el cuerpo de texto de los
   controles ni reducir su zona de toque. */
.page--movements .page-header {
    margin-bottom: 0.6rem;
    align-items: center;
}

/* El bloque de título cede ancho a las acciones antes que empujarlas a un renglón propio:
   a 1280 px eso recupera dos filas de la tabla sin tocar el tamaño de ningún control.
   Sólo a partir de tableta: en móvil la cabecera apila en columna y una base de 18rem
   pasaría a interpretarse como altura. */
@media (min-width: 768px) {
    .page--movements .page-header > div:first-child {
        flex: 1 1 18rem;
        min-width: 0;
    }
}

.page--movements .page-header__subtitle {
    margin-bottom: 0;
}

.page--movements .page-header__title {
    font-size: 1.35rem;
}

.movements-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.movements-actions__secondary {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    text-decoration: underline;
}

.filter-bar--movements {
    /* REJILLA, no reparto flexible.
       Con flex, el ancho de cada control dependía de su contenido y del de sus vecinos: al
       elegir un producto el control cambiaba de tamaño y empujaba «Documento» y «Consultar» a
       otro renglón. Con una rejilla de columnas declaradas, la posición de cada filtro es la
       misma haya o no producto seleccionado. */
    display: grid;
    align-items: end;
    padding: 0.55rem 0.7rem;
    gap: 0.45rem 0.5rem;
    margin-bottom: 0.6rem;
    /* Por omisión (tabletas y pantallas intermedias): dos renglones de cuatro columnas. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* Escritorio ancho: los ocho controles en un solo renglón. El reparto no es uniforme, sino
   proporcional a lo que cada control tiene que mostrar: «Todas las autorizadas» necesita más
   sitio que «Todos», y el producto elegido más que una fecha. */
@media (min-width: 1570px) {
    .filter-bar--movements {
        grid-template-columns:
            minmax(0, 1.45fr)   /* Sucursal   */
            minmax(0, 1.3fr)    /* Almacén    */
            minmax(0, 1fr)      /* Desde      */
            minmax(0, 1fr)      /* Hasta      */
            minmax(0, 1fr)      /* Movimiento */
            minmax(0, 1.7fr)    /* Producto   */
            minmax(0, 1.4fr)    /* Documento  */
            auto;               /* Consultar  */
    }
}

/* Pantallas intermedias (1280–1569): dos renglones deliberados de cuatro columnas.
       FILA 1   Sucursal | Almacén | Desde | Hasta
       FILA 2   Movimiento | Producto | Documento | Consultar
   Las columnas NO son iguales: la 2.ª y la 3.ª —que alojan Producto y Documento— reciben más
   ancho que la 1.ª, que aloja Movimiento. Ambas filas ocupan todo el ancho disponible y la
   geometría es la misma con y sin producto seleccionado. */
@media (min-width: 900px) and (max-width: 1569px) {
    .filter-bar--movements {
        grid-template-columns:
            minmax(0, 1.25fr)   /* Sucursal   · Movimiento */
            minmax(0, 1.35fr)   /* Almacén    · Producto   */
            minmax(0, 1.35fr)   /* Desde      · Documento  */
            minmax(0, 1.05fr);  /* Hasta      · Consultar  */
    }

    /* El botón ocupa su celda entera: así queda alineado con la rejilla en lugar de dejar un
       hueco muerto a su derecha. */
    .filter-bar--movements .filter-bar__submit {
        justify-self: stretch;
        text-align: center;
    }
}

@media (max-width: 899px) {
    .filter-bar--movements {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.filter-bar--movements > label {
    /* En rejilla el ancho lo fija la columna; el label sólo ordena su etiqueta y su control. */
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    max-width: none;
}

/* TODOS los controles de la barra miden exactamente lo mismo de alto. Es lo que impide que
   elegir o quitar un producto altere la altura del bloque: la fila de la rejilla la fija el
   control más alto, y aquí no hay ninguno más alto que otro. */
.filter-bar--movements {
    --mov-control-h: 2.25rem;
}

.filter-bar--movements select,
.filter-bar--movements input,
.filter-bar--movements .movements-product-picker .customer-picker__input,
.filter-bar--movements .movements-product-picker .product-card--compact {
    box-sizing: border-box;
    min-height: var(--mov-control-h);
    height: var(--mov-control-h);
    padding: 0.3rem 0.5rem;
    width: 100%;
    min-width: 0;
}

.filter-bar--movements .filter-bar__submit {
    align-self: end;
    justify-self: start;
    min-height: 2.1rem;
    padding: 0.3rem 0.85rem;
    white-space: nowrap;
}

@media (max-width: 899px) {
    /* El botón cierra la rejilla ocupando su propio renglón completo. */
    .filter-bar--movements .filter-bar__submit {
        grid-column: 1 / -1;
        justify-self: stretch;
        text-align: center;
    }
}


.movements-summary {
    margin-bottom: 0.6rem;
}

/* Cinco indicadores en una sola fila cuando hay sitio; por debajo, se reparten solos. */
.movements-summary__cards {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.5rem;
}

@media (max-width: 1099px) {
    .movements-summary__cards {
        grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    }
}

.movements-summary__card {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--color-border);
    border-left-width: 3px;
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.movements-summary__card--in { border-left-color: var(--color-success, #16a34a); }
.movements-summary__card--out { border-left-color: var(--color-danger, #dc2626); }

.movements-summary__label {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.movements-summary__value {
    font-size: 1.05rem;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.movements-summary__by-type,
.movements-documents {
    margin-top: 0.4rem;
}

.movements-summary__by-type > summary,
.movements-documents > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--color-primary, #2563eb);
    list-style: none;
}

.movements-summary__by-type > summary::-webkit-details-marker,
.movements-documents > summary::-webkit-details-marker {
    display: none;
}

.movements-summary__table,
.movements-document__table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 0.35rem;
    font-size: 0.8125rem;
}

.movements-summary__table th,
.movements-summary__table td,
.movements-document__table th,
.movements-document__table td {
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
}

.movements-summary__table th.stock-col-num,
.movements-summary__table td.stock-col-num,
.movements-document__table th.stock-col-num,
.movements-document__table td.stock-col-num {
    text-align: center;
}

.movements-document {
    margin-top: 0.6rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.movements-document__head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    align-items: baseline;
    font-size: 0.8125rem;
    color: var(--color-text-muted);
}

/* La tabla no comprime sus columnas: por debajo del ancho legible se desplaza dentro de su
   contenedor, igual que se resolvió en el Kardex. La página nunca arrastra scroll. */
.movements-table-wrap {
    overflow-x: auto;
    width: 100%;
    max-width: 100%;
}

.paginated-table__table.movements-table {
    table-layout: fixed;
    width: 100%;
    /* 60 rem = 960 px. Medido columna a columna con la tipografía real de la tabla, el
       contenido más ancho exige 750 px en total (el mayor: «Administrador», 92 px, que no se
       puede partir). 960 px deja holgura sobre ese suelo y entra completo en el contenedor a
       1280 px, que mide 966 px: la tabla ya no obliga a desplazarse a mano para ver Salida,
       Costo unit. y Usuario. No se reduce la tipografía en ningún caso. */
    min-width: 60rem;
}

.movements-table-wrap .paginated-table__table.movements-table th,
.movements-table-wrap .paginated-table__table.movements-table td {
    padding: 0.3rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    vertical-align: top;
    word-break: normal;
    overflow-wrap: break-word;
}

/* Comprobado a 960 px, el ancho mínimo de la tabla (px reales / mínimo medido):
     Fecha 96/91 · Documento 192/103 · Producto 144/98 · Sucursal-Almacén 154/103
     Entrada 79/79 · Salida 79/65 · Costo unit. 106/103 · Usuario 110/108              */
.movements-col-date { width: 10%; }
.movements-col-doc { width: 20%; }
.movements-col-product { width: 15%; }
.movements-col-place { width: 16%; }
/* «Entrada» es la palabra más ancha de estas dos columnas y no se parte: 8.25 % = 79 px. */
.movements-col-qty { width: 8.25%; text-align: center; }
.movements-col-cost { width: 11%; text-align: right; }
/* «Administrador» ocupa 92 px y es indivisible; con el relleno, 108 px. 11.5 % = 110 px. */
.movements-col-user { width: 11.5%; }

.movements-table .is-numeric { font-variant-numeric: tabular-nums; }

.movements-doc-head {
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
}

.movements-doc-number {
    font-weight: 600;
}

.movements-doc-link {
    font-size: 0.75rem;
    white-space: nowrap;
}

/* El trayecto se resume en un solo renglón lógico (origen → destino). Si la columna es
   estrecha puede ocupar dos líneas, pero nunca las seis del formato anterior. No se recorta
   con ellipsis: el dato debe poder leerse completo en pantalla. */
.movements-doc-meta {
    overflow-wrap: break-word;
}

.movements-doc-meta--obs {
    font-style: italic;
}


.movements-doc-meta,
.movements-product-sku,
.movements-place-warehouse {
    display: block;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}


.movements-product-name,
.movements-place-branch {
    display: block;
}

/* FILTRO PRODUCTO: buscador dinámico (componente canónico product-picker).
   La columna del filtro es estrecha por diseño, pero la lista de coincidencias no puede heredar
   ese ancho: «MONTURA CLÁSICA NEGRA» se partiría en tres renglones. Se le da ancho propio,
   acotado al viewport para que nunca se salga de la pantalla. Ámbito: sólo este filtro. */
.movements-product-picker {
    position: relative;
}

.filter-bar--movements .movements-product-picker .customer-picker__results {
    min-width: 20rem;
    max-width: min(28rem, calc(100vw - 2rem));
    max-height: 20rem;
    overflow-y: auto;
    /* Anclada al borde derecho del control: el filtro Producto queda a la derecha de la barra
       y, anclada a la izquierda, la lista se salía de la pantalla a 1280 px. */
    right: 0;
    left: auto;
}

/* En móvil el filtro ocupa el ancho completo: la lista se ajusta al control en lugar de
   reclamar un mínimo que se saldría por la izquierda. */
@media (max-width: 767px) {
    .filter-bar--movements .movements-product-picker .customer-picker__results {
        min-width: 0;
        max-width: none;
        left: 0;
        right: 0;
    }
}

/* Mismo caso ya resuelto en el selector de líneas de transferencia: el JS marca el buscador
   con [hidden] al elegir producto, pero «.customer-picker__control { display: flex }» lo
   volvía a mostrar y quedaba una caja de búsqueda encima de la tarjeta. Manda el atributo. */
/* El atributo [hidden] tiene que mandar sobre el display del componente, tanto en el buscador
   como en la caja del producto elegido. Si no, el contenedor vacío sigue ocupando altura y la
   barra cambia de tamaño según el estado. */
.filter-bar--movements .movements-product-picker .customer-picker__control[hidden],
.filter-bar--movements .movements-product-picker .customer-picker__selected[hidden] {
    display: none;
}

.filter-bar--movements .movements-product-picker .customer-picker__control {
    margin: 0;
}

/* El producto elegido se muestra compacto dentro de la columna del filtro. NO se recorta con
   elipsis: en esta columna estrecha el recorte dejaba «MONTUR…», que no permite confirmar qué
   se ha seleccionado. Se deja que el nombre se reparta en dos renglones cortos. */
.filter-bar--movements .movements-product-picker .customer-picker__selected {
    display: block;
    padding: 0;
    border: 0;
    background: transparent;
}

.filter-bar--movements .movements-product-picker .product-card--compact {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.filter-bar--movements .movements-product-picker .product-card__compact-main {
    min-width: 0;
    flex: 1 1 auto;
}

/* Una sola línea: la tarjeta del producto elegido debe medir lo mismo que un desplegable, o
   la barra daría un salto de altura al seleccionar. El nombre completo sigue disponible en el
   propio control por el comportamiento canónico del componente. */
.filter-bar--movements .movements-product-picker .product-card__title--inline {
    display: block;
    font-size: 0.8125rem;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-bar--movements .movements-product-picker .product-card__clear-x {
    flex: 0 0 auto;
}

/* PISTA DE AYUDA DEL BUSCADOR DE PRODUCTO.
 *
 * Es una nota breve que el componente muestra mientras se escribe («escriba al menos 2
 * caracteres», «seleccione un producto de la lista»). Dos exigencias que parecen opuestas:
 *
 *   1. NO puede empujar la barra: si ocupara sitio, la altura de la fila de filtros cambiaría
 *      al escribir y volvería el salto que ya se corrigió. Por eso sigue fuera del flujo.
 *   2. NO puede invadir los filtros vecinos. Antes se anclaba al borde DERECHO del control y
 *      con el texto en una sola línea: medido, se extendía 314 px hacia la izquierda y se
 *      montaba encima del filtro «Movimiento» a 1920, 1366 y 1280.
 *
 * Se resuelve anclándola a las dos aristas de SU PROPIA columna y dejándola repartirse en
 * varios renglones: la nota queda debajo del buscador, dentro de la zona del filtro Producto,
 * y no puede salirse de ella por ningún lado. Con borde y sombra se lee como una etiqueta de
 * ayuda del propio control y no como texto suelto sobre la pantalla.
 */
.filter-bar--movements .movements-product-picker .customer-picker__hint {
    position: absolute;
    top: calc(100% - 0.1rem);
    left: 0;
    right: 0;
    z-index: 21;
    box-sizing: border-box;
    max-width: 100%;
    margin: 0;
    padding: 0.2rem 0.4rem;
    font-size: 0.7rem;
    line-height: 1.25;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm, 4px);
    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.1);
    /* El texto se reparte en renglones dentro de la columna en vez de desbordarla. */
    white-space: normal;
    overflow-wrap: break-word;
}

/* TABLA DOCUMENTAL: una operación por fila. Cabe holgada porque son ocho columnas cortas,
   así que no necesita el ancho mínimo de la tabla de asientos. */
.paginated-table__table.movements-docs-table {
    table-layout: fixed;
    width: 100%;
    /* 60rem = 960 px: el mínimo con el que las ocho columnas siguen siendo legibles y, a la vez,
       la tabla entra completa en el contenedor a 1280 px sin desplazamiento interno. Con 64rem
       sobresalían 58 px y la columna Acciones quedaba fuera de la zona visible. */
    min-width: 60rem;
}

.movements-table-wrap .paginated-table__table.movements-docs-table th,
.movements-table-wrap .paginated-table__table.movements-docs-table td {
    padding: 0.35rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    vertical-align: top;
    word-break: normal;
    overflow-wrap: break-word;
}

/* Los porcentajes suman exactamente 100. El ancho va donde está la información larga
   —Documento y Almacén / Origen-Destino—; Tipo, Ítems, Usuario y Acciones se mantienen
   compactos porque su contenido es corto y fijo. */
/* Los porcentajes están calculados sobre el ancho mínimo de la tabla (60 rem = 960 px) contra
   el ancho REAL que necesita el texto más largo de cada columna, medido en el navegador:
   «18/08/2026» 88 px, «Transferencia» 101 px, «15 ítems» 71 px, «Administrador» 108 px,
   «Acciones» + botón 76 px. Ojo: con `table-layout: fixed` un `min-width` en la celda NO
   dimensiona la columna —se ignora—, así que el suelo tiene que salir del porcentaje. */
.movdoc-col-date { width: 9.5%; }
.movdoc-col-doc { width: 20.5%; }
/* 11 %, no 10: con 10 % la palabra «Transferencia» se partía por la mitad al ancho mínimo. */
.movdoc-col-type { width: 11%; }
.movdoc-col-branch { width: 11.5%; }
.movdoc-col-place { width: 19.5%; }
/* «15 ítems» debe caber en un renglón: partir el número de la unidad se lee fatal. */
.movdoc-col-items { width: 7.5%; text-align: right; white-space: nowrap; }
/* 11.5 % = 111 px al ancho mínimo: «Administrador» necesita 108 y con 11 % se quedaba en 106,
   dos píxeles cortos, y se partía por la mitad. */
.movdoc-col-user { width: 11.5%; }

/* ACCIONES no depende de que sobre espacio: su 9 % da 87 px al ancho mínimo de la tabla, dentro
   de la referencia pedida (70–90 px) y suficiente para el botón de 2.25 rem, su separación del
   borde y el rótulo «Acciones» de la cabecera. */
.movdoc-col-actions {
    width: 9%;
    text-align: center;
    white-space: nowrap;
}

.movements-docs-table .is-numeric { font-variant-numeric: tabular-nums; }

.movdoc-col-actions .ds-icon-actions {
    display: flex;
    justify-content: center;
    align-items: center;
}

/* El botón canónico mide 1.75 rem (28 px). En una tabla de auditoría, donde es la única acción
   de la fila, se le da un área de toque más cómoda sin cambiar el icono ni el componente:
   2.25 rem = 36 px, por encima del mínimo recomendado de accesibilidad para puntero fino. */
.movdoc-col-actions .ds-icon-btn {
    width: 2.25rem;
    height: 2.25rem;
    min-height: 2.25rem;
}

/* Separación del borde derecho: la celda no pega el botón contra el filo de la tabla. */
.movements-table-wrap .paginated-table__table.movements-docs-table td.movdoc-col-actions,
.movements-table-wrap .paginated-table__table.movements-docs-table th.movdoc-col-actions {
    padding-right: 0.75rem;
}

/* El panel del asistente es `position: fixed` con `z-index: 1100` y NO reserva espacio en el
   documento: mientras está abierto se superpone a los 420 px de la derecha de cualquier
   pantalla. Aquí no se modifica el asistente —no es de esta pantalla—, pero sí se evita que la
   columna Acciones quede debajo: las tablas de Movimientos ceden ese ancho mientras el panel
   está abierto y lo recuperan al cerrarlo. Sólo en pantallas anchas: por debajo, el panel ocupa
   prácticamente todo el ancho y reservar espacio no tendría sentido. */
/* El umbral 1710 px no es arbitrario: es el ancho a partir del cual, tras ceder los 420 px del
   panel, siguen quedando los 60 rem que la tabla necesita para mostrarse entera. Por debajo,
   reservar espacio sólo encogería la tabla sin liberar la columna Acciones, así que no se hace
   y el solapamiento queda documentado como lo que es: un asunto del asistente, no de esta
   pantalla. */
@media (min-width: 1710px) {
    body:has(.assistant-shell--open) .page--movements .movements-table-wrap {
        /* max() y no calc() a secas: la reserva se aplica SÓLO si después sigue cabiendo la
           tabla completa. Si no cabe, el contenedor conserva su ancho y no se empeora el caso
           —encoger por debajo del mínimo sólo añadiría desplazamiento interno y alejaría más la
           columna Acciones—. */
        max-width: max(60rem, calc(100% - var(--assistant-panel-width, 420px)));
    }
}

/* DETALLE DE UNA OPERACIÓN */
.movdoc-card {
    padding: 0.9rem 1rem;
    margin-bottom: 0.9rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.movdoc-card__title {
    margin: 0 0 0.7rem;
    font-size: 1rem;
}

.movdoc-card__enlace {
    margin: 0.7rem 0 0;
    font-size: 0.8125rem;
}

.movdoc-datos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.5rem 1.2rem;
    margin: 0;
}

.movdoc-datos > div {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.movdoc-datos__ancho {
    grid-column: 1 / -1;
}

.movdoc-datos dt {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
}

.movdoc-datos dd {
    margin: 0;
    font-size: 0.875rem;
    overflow-wrap: break-word;
}

.paginated-table__table.movdoc-lineas {
    table-layout: fixed;
    width: 100%;
    min-width: 60rem;
}

.movements-table-wrap .paginated-table__table.movdoc-lineas th,
.movements-table-wrap .paginated-table__table.movdoc-lineas td {
    padding: 0.35rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    vertical-align: top;
    word-break: normal;
    overflow-wrap: break-word;
}

/* Los porcentajes suman exactamente 100: si suman de más, table-layout: fixed los reparte
   proporcionalmente y las columnas quedan más estrechas de lo declarado. */
/* El SKU es un identificador: se lee entero o no se lee. No se parte por sus guiones. */
.movdoc-lin-sku { width: 11%; white-space: nowrap; }
.movdoc-lin-product { width: 21%; }
.movdoc-lin-place { width: 17%; }
.movdoc-lin-qty { width: 10%; text-align: right; }
.movdoc-lin-cost { width: 9%; text-align: right; }
.movdoc-lin-time { width: 12%; }

.movdoc-lineas .is-numeric { font-variant-numeric: tabular-nums; }

@media (max-width: 767px) {
    .movdoc-datos {
        grid-template-columns: 1fr;
    }
}

/* Entradas y salidas se distinguen por un filete lateral, no solo por el color del texto. */
.movements-row--in > td:first-child { box-shadow: inset 3px 0 0 0 var(--color-success, #16a34a); }
.movements-row--out > td:first-child { box-shadow: inset 3px 0 0 0 var(--color-danger, #dc2626); }

.movements-pager {
    display: inline-flex;
    gap: 0.4rem;
}

@media (max-width: 767px) {
    /* En móvil no se fuerzan seis filtros en una fila: cada uno ocupa su línea. */
    .filter-bar--movements > label,
    .filter-bar--movements > label:nth-child(7) {
        flex: 1 1 100%;
        max-width: none;
    }

    .filter-bar--movements .filter-bar__submit {
        width: 100%;
    }

    .movements-actions {
        width: 100%;
    }

    .movements-actions .btn {
        flex: 1 1 auto;
        text-align: center;
    }
}

/* Vista «Por sucursal» del stock: una fila por producto + sucursal y el desglose por almacén
   dentro de un <details>, el mismo patrón de despliegue que ya usa el catálogo. Ámbito
   acotado: solo la tabla anidada del desglose. */
/* Anchos del listado por sucursal: al desplegar el detalle, la tabla anidada se llevaba casi
   todo el ancho y las columnas de la izquierda se estrechaban hasta partir el nombre. Con
   layout fijo las cabeceras no se mueven al abrir o cerrar el desglose. */
.paginated-table__table.stock-table--branch {
    table-layout: fixed;
}

.stock-table--branch th:nth-child(1),
.stock-table--branch td:nth-child(1) { width: 12%; }

.stock-table--branch th:nth-child(2),
.stock-table--branch td:nth-child(2) { width: 28%; }

.stock-table--branch th:nth-child(3),
.stock-table--branch td:nth-child(3) { width: 27%; }

.stock-table--branch th:nth-child(4),
.stock-table--branch td:nth-child(4),
.stock-table--branch th:nth-child(5),
.stock-table--branch td:nth-child(5),
.stock-table--branch th:nth-child(6),
.stock-table--branch td:nth-child(6) { width: 12%; }


/* La fila del desglose ocupa el ancho completo y no hereda los anchos fijos. */
.stock-table--branch .stock-branch-detail-row > td {
    width: auto;
    padding-top: 0;
}

.stock-branch-detail > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--color-primary, #2563eb);
    list-style: none;
}

.stock-branch-detail > summary::-webkit-details-marker {
    display: none;
}

.stock-branch-detail__body {
    margin-top: 0.35rem;
}

.stock-branch-detail__table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 0.35rem;
    font-size: 0.8125rem;
}

.stock-branch-detail__table th,
.stock-branch-detail__table td {
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
}

/* Las columnas numéricas conservan su alineación pese a la regla anterior. */
.stock-branch-detail__table th.stock-col-num,
.stock-branch-detail__table td.stock-col-num,
.stock-branch-detail__table th.stock-col-available,
.stock-branch-detail__table td.stock-col-available {
    text-align: center;
}

.stock-branch-detail__table th.stock-col-cost,
.stock-branch-detail__table td.stock-col-cost {
    text-align: right;
}

.stock-branch-detail__table th:first-child,
.stock-branch-detail__table td:first-child {
    width: 34%;
}

.stock-branch-detail__table tfoot th {
    background: var(--color-surface-muted, #f3f4f6);
    font-weight: 700;
}

.stock-total-row__value,
.stock-total-row .stock-col-num,
.stock-total-row .stock-col-available,
.stock-total-row .stock-col-total-empresa {
    text-align: center;
}

.paginated-table__wrapper {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.page--branches-ui .catalog-table-card.paginated-table__wrapper {
    overflow-x: hidden;
}

.paginated-table__table {
    width: 100%;
    border-collapse: collapse;
}

.paginated-table__table th,
.paginated-table__table td {
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--color-border);
}

.paginated-table__table th {
    background: #f8fafc;
    font-size: 0.875rem;
    font-weight: 600;
}

.paginated-table__pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    margin-top: var(--spacing-md);
}

.paginated-table__page-link {
    display: inline-flex;
    padding: 0.5rem 0.875rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
}

.responsive-data-list {
    display: grid;
    gap: var(--spacing-sm);
    margin: 0;
}

.responsive-data-list__item {
    display: grid;
    gap: 0.25rem;
    padding: var(--spacing-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.responsive-data-list__label {
    margin: 0;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.responsive-data-list__value {
    margin: 0;
    font-size: 1rem;
}

.modal,
.confirm-dialog {
    position: fixed;
    inset: 0;
    z-index: 1000;
}

.modal__backdrop,
.confirm-dialog__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
}

.modal__dialog,
.confirm-dialog__panel {
    position: relative;
    width: min(32rem, calc(100% - 2rem));
    margin: 10vh auto 0;
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: var(--spacing-lg);
}

.modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--spacing-md);
}

.modal__close,
.confirm-dialog__cancel,
.confirm-dialog__confirm,
.tenant-selector__submit,
.branch-selector__submit {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.875rem;
    background: var(--color-surface);
    cursor: pointer;
}

.confirm-dialog__confirm {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.confirm-dialog__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-lg);
}

/* NAVEGACIÓN POR PESTAÑAS
 *
 * El componente existía en roles-ui.css, hoja que sólo carga la administración de plataforma:
 * en Óptica el mismo marcado se veía como una fila de enlaces sueltos. Aquí queda una sola
 * definición para toda la aplicación. La tipografía se hereda a propósito —no se reduce para
 * hacer caber pestañas— y el contenedor no fija display ni gap porque platform-forms.css, que
 * carga después, ya los resuelve.
 */
.tab-nav {
    align-items: center;
    padding: 0.25rem;
    margin-bottom: var(--spacing-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    max-width: 100%;
}

.tab-nav__item {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 0.875rem;
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
}

.tab-nav__item:hover {
    background: var(--color-surface-alt, #f1f5f9);
    color: var(--color-text);
    text-decoration: none;
}

/* Foco visible para quien navega con teclado: el color por sí solo no basta. */
.tab-nav__item:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.tab-nav__item--active,
.tab-nav__item[aria-current="page"] {
    background: var(--color-primary-soft, #eff6ff);
    color: var(--color-primary);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}

.tabs__list {
    display: flex;
    gap: var(--spacing-sm);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--spacing-md);
}

.tabs__tab {
    border: none;
    background: transparent;
    padding: 0.75rem 1rem;
    cursor: pointer;
    color: var(--color-text-muted);
    border-bottom: 2px solid transparent;
}

.tabs__tab--active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.money-display__currency {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-right: 0.25rem;
}

.datetime-display {
    font-variant-numeric: tabular-nums;
}

.tenant-selector,
.branch-selector {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.tenant-selector__select,
.branch-selector__select {
    min-width: 10rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.shell-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-lg);
    width: 100%;
}

.shell-header__brand {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.shell-header__tenant {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.shell-header__user {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin-left: auto;
}

.shell-header__user-name {
    font-weight: 600;
}

.shell-header__logout {
    margin: 0;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.625rem 1rem;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    background: var(--color-surface);
    color: var(--color-text);
}

.btn:hover {
    text-decoration: none;
}

.btn--primary {
    background: var(--color-primary);
    color: #fff;
}

.btn--secondary {
    border-color: var(--color-border);
    background: #f8fafc;
}

.btn--ghost {
    border-color: var(--color-border);
    background: transparent;
}

/* Una acción destructiva tiene que parecerlo. Se venía usando en varias pantallas sin estilo. */
.btn--danger {
    background: var(--color-danger, #dc2626);
    border-color: var(--color-danger, #dc2626);
    color: #fff;
}

.btn--danger:hover,
.btn--danger:focus-visible {
    background: color-mix(in srgb, var(--color-danger, #dc2626) 88%, black);
    color: #fff;
}

.btn--sm {
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
}

.alert {
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    margin-bottom: var(--spacing-md);
}

.alert--success {
    background: #dcfce7;
    border: 1px solid #86efac;
    color: var(--color-success);
}

.alert--error {
    background: #fee2e2;
    border: 1px solid #fca5a5;
    color: var(--color-danger);
}

.form-card,
.detail-card,
.totals-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    margin-bottom: var(--spacing-lg);
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--spacing-md);
}

.form-grid__full {
    grid-column: 1 / -1;
}

/* Un campo con su etiqueta encima, ocupando su celda entera: así no se queda encogido al tamaño
   por defecto del navegador mientras su vecino sí crece. */
.form-field {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}

.form-field > label {
    /* Bloque, no columna: el asterisco de obligatorio acompaña al texto en la misma línea. */
    display: block;
    font-weight: 500;
}

.form-field > input,
.form-field > select,
.form-field > textarea {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.form-field--full {
    grid-column: 1 / -1;
}

.form-stack {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    max-width: 36rem;
}

.form-stack label,
.form-stack .form-actions {
    width: 100%;
}

.section-title {
    margin: var(--spacing-md) 0 var(--spacing-sm);
    font-size: 1.125rem;
}

.form-grid--customer,
.form-grid--catalog-3,
.form-grid--kardex,
.form-grid--receipt-line,
.form-grid--task {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.kardex-filter-form {
    padding: 0.75rem 1rem;
    margin-bottom: var(--spacing-md);
}

.kardex-filter-form .form-stack {
    max-width: none;
}

/* DOS FILAS, NO TRES. Con cuatro columnas iguales el producto ocupaba media fila, los
   cuatro campos de período/tipo/documento la siguiente y el botón se quedaba solo en una
   tercera: tres franjas de alto para siete campos. Sobre doce columnas cabe todo en dos:

     fila 1   Producto (6)  ·  Sucursal (3)  ·  Almacén (3)
     fila 2   Desde (2) · Hasta (2) · Tipo (3) · Documento (3) · Consultar (2)

   El botón viaja en la segunda fila, alineado con los campos, no en una franja propia. */
.kardex-filter-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 0.45rem 0.6rem;
    align-items: end;
    width: 100%;
}

.kardex-filter-grid > label,
.kardex-filter-grid > .form-actions {
    min-width: 0;
    margin: 0;
}

.kardex-filter-grid__product { grid-column: span 6; }
.kardex-filter-grid__branch { grid-column: span 3; }
.kardex-filter-grid__warehouse { grid-column: span 3; }
.kardex-filter-grid__from,
.kardex-filter-grid__to { grid-column: span 2; }
.kardex-filter-grid__type,
.kardex-filter-grid__document { grid-column: span 3; }
.kardex-filter-grid__submit { grid-column: span 2; }

.kardex-filter-grid__submit .btn {
    width: 100%;
}

.page--kardex .product-card--compact {
    max-width: 100%;
    padding: 0.3rem 0.5rem;
}

/* «MONTURAS DE CAMP…» no es un nombre de producto: es una promesa a medias. El nombre
   completo se lee entero, envolviendo si hace falta —dos líneas cuestan menos que una
   consulta equivocada—. El SKU baja a segundo plano, que es donde le corresponde. */
.page--kardex .product-card__title--inline {
    display: block;
    font-size: 0.875rem;
    font-weight: 600;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.25;
    word-break: break-word;
}

.page--kardex .product-card__meta,
.page--kardex .product-card__sku {
    font-size: 0.75rem;
    color: var(--color-text-muted, #64748b);
}

.page--kardex .kardex-stock-summary {
    padding: 0.65rem 0.85rem;
    margin-bottom: var(--spacing-md);
}

.page--kardex .section-title--compact {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}

.kardex-stock-summary__product {
    margin: 0 0 0.5rem;
    font-size: 0.875rem;
}

.kardex-stock-summary__table .paginated-table__table th,
.kardex-stock-summary__table .paginated-table__table td {
    padding: 0.4rem 0.65rem;
    font-size: 0.8125rem;
}

.kardex-ledger-meta {
    margin: 0 0 0.5rem;
    font-size: 0.8125rem;
}

.kardex-ledger-meta p {
    margin: 0;
}

.paginated-table__table.kardex-table {
    table-layout: fixed;
    width: 100%;
    /* ── ANCHO MÍNIMO: 66rem, ANTES 80rem ──────────────────────────────────────────────
       Aquí vivía la decisión contraria —«legibilidad antes que meter once columnas a la
       fuerza»— y con ella la tabla medía 1280 px dentro de un contenedor de 1128 a 1440 px
       de ancho: barra horizontal en cada consulta. Medido en pantalla, no supuesto.

       El Product Owner ha invertido esa prioridad para el uso de escritorio, así que la
       tabla ahora cabe: se fusionaron «Referencia» y «Observaciones» —la referencia es un
       enlace corto— y los mínimos se recortaron a lo que de verdad ocupa cada contenido.
       Por debajo de 66rem sigue desplazándose dentro de su contenedor, que es lo correcto
       en una pantalla pequeña; lo que ya no ocurre es en un monitor normal. */
    min-width: 52rem;
    font-size: 0.75rem;
    line-height: 1.25;
}

/* El prefijo .kardex-table-wrap NO es decorativo: sin él estas reglas perdían la cascada.
   design-system-shell.css declara «.ds-shell__main .paginated-table__table th, td»
   (especificidad 0,2,2) y ganaba a «.paginated-table__table.kardex-table th, td» (0,2,1),
   así que el interlineado y el relleno compactos del Kardex nunca llegaban a aplicarse y la
   fila se dibujaba con el relleno genérico. Con el contenedor delante son (0,3,1) y mandan.
   El ámbito sigue acotado al Kardex: ninguna otra tabla usa .kardex-table-wrap. */
.kardex-table-wrap .paginated-table__table.kardex-table th,
.kardex-table-wrap .paginated-table__table.kardex-table td {
    padding: 0.3rem 0.45rem;
    font-size: 0.8125rem;
    vertical-align: middle;
    /* El salto se hace POR PALABRAS. «anywhere» partía «Proveedor / Ingreso documental»
       letra a letra en cuanto la columna se quedaba estrecha, y con ello la fila crecía
       hasta triplicar su altura. «break-word» solo interviene si una única palabra no
       cabe; nunca se usa break-all. */
    word-break: normal;
    overflow-wrap: break-word;
    hyphens: none;
    min-height: 0;
    height: auto;
    line-height: 1.3;
}

.kardex-table-wrap .paginated-table__table.kardex-table thead th {
    white-space: nowrap;
    font-size: 0.8125rem;
    line-height: 1.2;
    vertical-align: bottom;
}

/* Los DOS encabezados largos sí envuelven. Con `table-layout: fixed` un encabezado en
   `nowrap` más ancho que su columna no la ensancha: desborda el contenido y devuelve la
   barra horizontal por la puerta de atrás. Se midió: «Observaciones / referencia» en una
   sola línea empujaba el desplazamiento a 1181 px dentro de un contenedor de 1126. */
.kardex-table-wrap .paginated-table__table.kardex-table thead th.kardex-col-obs,
.kardex-table-wrap .paginated-table__table.kardex-table thead th.kardex-col-doc {
    white-space: normal;
}

/* Reparto del ancho.
   La tabla es de layout fijo, así que los porcentajes NO se eligen «a ojo»: cada uno es la
   proporción del ancho mínimo que esa columna necesita para que su contenido más largo quepa
   sin invadir a la vecina («18/08/2026 05:09» en Fecha, «Costo unit.» en el encabezado,
   «Ver documento» en Referencia…). Sumados dan el ancho mínimo total de la tabla, que se
   declara en .kardex-table como min-width. Por encima de ese ancho todas crecen a la vez y
   mantienen la separación; por debajo, la tabla NO se comprime: se desplaza dentro de su
   contenedor. Es la prioridad que fijó el Product Owner: legibilidad antes que meter once
   columnas a la fuerza.

   mínimos:  fecha 8 · tipo 6.5 · cantidades 4.25×3 · costo 5.5 · documento 7.5 ·
             origen 11 · usuario 6.5 · observaciones/referencia 8.75   =  66rem

   «Referencia» ya no es una columna: su enlace vive dentro de Observaciones. */
.kardex-col-date { width: 11.5%; }
.kardex-col-type { width: 10%; }
.kardex-col-qty { width: 7%; text-align: center; white-space: nowrap; }
.kardex-col-cost { width: 8.5%; text-align: center; white-space: nowrap; }
.kardex-col-doc { width: 25%; }
.kardex-col-obs { width: 24%; }

/* Cada una de las dos columnas apiladas lleva DOS pisos: el dato principal arriba y el
   secundario debajo, más pequeño y en gris. No es decoración: es lo que permite que
   «Documento» y «Origen / Destino» compartan una columna sin que se confundan al leer. */
.kardex-table .kardex-cell__main {
    display: block;
    font-weight: 500;
}

.kardex-table .kardex-cell__sub,
.kardex-table .kardex-th__sub {
    display: block;
    font-size: 0.85em;
    line-height: 1.35;
    color: var(--color-text-muted, #6b7280);
    font-weight: 400;
    white-space: normal;
    word-break: break-word;
}

.kardex-table .kardex-th__sub {
    text-transform: none;
    letter-spacing: 0;
}

.kardex-table-wrap .paginated-table__table.kardex-table td.kardex-col-qty,
.kardex-table-wrap .paginated-table__table.kardex-table th.kardex-col-qty,
.kardex-table-wrap .paginated-table__table.kardex-table td.kardex-col-cost,
.kardex-table-wrap .paginated-table__table.kardex-table th.kardex-col-cost {
    text-align: center;
}

.kardex-table-wrap .paginated-table__table.kardex-table .kardex-col-doc,
.kardex-table-wrap .paginated-table__table.kardex-table .kardex-col-obs {
    white-space: normal;
    line-height: 1.3;
}

/* «Ver documento» es una etiqueta atómica: partirla en dos líneas solo sirve para estirar
   la fila. Es la única excepción de nowrap sobre texto, y va sobre el enlace, no sobre la
   celda. */
.kardex-table-wrap .paginated-table__table.kardex-table .kardex-obs__link {
    white-space: nowrap;
    font-size: 0.75rem;
}

/* El desplazamiento horizontal vive SIEMPRE dentro del contenedor de la tabla, en cualquier
   resolución. responsive.css lo ponía en «visible» a partir de 1366 px y se carga después,
   así que hace falta más especificidad —no !important— para recuperarlo. Con esto la página
   nunca arrastra scroll horizontal: lo hace la tabla, y solo cuando de verdad no cabe. */
.kardex-table-wrap,
.page--kardex .paginated-table__wrapper.kardex-table-wrap {
    overflow-x: auto;
    width: 100%;
    max-width: 100%;
}

/* Impresión: sin desplazamientos y con el mismo reparto de columnas. */
@media print {
    .kardex-table-wrap {
        overflow-x: visible;
    }

    .paginated-table__table.kardex-table {
        min-width: 0;
    }
}

.transfer-detail-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 1.5rem;
}

.transfer-detail-notes {
    grid-column: 1 / -1;
}

.form-actions--inline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: end;
}

.page--kardex .form-card {
    padding: var(--spacing-md);
}

.paginated-table__table {
    width: 100%;
}

.paginated-table__wrapper {
    overflow-x: auto;
}

@media (max-width: 1199px) {
    .form-grid--customer,
    .form-grid--catalog-3,
    .form-grid--kardex,
    .form-grid--receipt-line,
    .form-grid--task {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 1024px) {
    .form-grid--customer {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .form-grid--customer,
    .form-grid--catalog-3,
    .form-grid--kardex,
    .form-grid--receipt-line,
    .form-grid--task {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 640px) {
    .form-grid--customer {
        grid-template-columns: minmax(0, 1fr);
    }

    .customer-form .form-actions .btn {
        min-height: 44px;
        width: 100%;
    }
}

.customer-form__details {
    margin-block: var(--spacing-md);
}

.customer-form__details > summary.section-title {
    cursor: pointer;
    list-style: none;
}

.customer-form__details > summary.section-title::-webkit-details-marker {
    display: none;
}

.customer-form .phone-country-select {
    width: 100%;
    max-width: 100%;
}

.customer-form .phone-country-field {
    min-width: 12rem;
}

.customer-form__document-lookup {
    display: grid;
    gap: 0.375rem;
}

.customer-form__document-number {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    font-weight: 500;
    margin: 0;
}

.document-lookup-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: stretch;
}

.document-lookup-row input {
    flex: 1 1 12rem;
    min-width: 0;
}

.document-lookup-row .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

.form-hint.document-lookup-status {
    margin: 0;
    min-height: 1.25rem;
}

.customer-form__registration-mode {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    border: 0;
    padding: 0;
    margin: 0;
}

.customer-form__radio,
.customer-form__checkbox {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 500;
}

.customer-document-badge {
    display: inline-block;
    margin-left: 0.375rem;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    background: var(--color-surface-muted, #eef2f7);
    color: var(--color-text-muted, #475569);
}

.customer-detail-blocks {
    display: grid;
    gap: var(--spacing-md);
}

.customer-detail-block h3 {
    margin: 0 0 var(--spacing-sm);
    font-size: 1rem;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 640px) {
    .document-lookup-row {
        flex-direction: column;
    }

    .document-lookup-row input,
    .document-lookup-row .btn {
        width: 100%;
    }
}

.form-grid label,
.form-card label {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    font-weight: 500;
}

/* Alineación global de checkbox, radio y switch en formularios */
.form-option-row,
.checkbox-label,
.checkbox-inline,
.form-grid label.form-option-row,
.form-card label.form-option-row,
.form-grid .form-option-row,
.form-card .form-option-row,
.form-grid label:has(> input[type="checkbox"]:only-of-type),
.form-grid label:has(> input[type="radio"]:only-of-type),
.form-card label:has(> input[type="checkbox"]:only-of-type),
.form-card label:has(> input[type="radio"]:only-of-type) {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    font-weight: 500;
    margin: 0;
    cursor: pointer;
    width: fit-content;
    max-width: 100%;
}

.form-option-row input[type="checkbox"],
.form-option-row input[type="radio"],
.checkbox-label input[type="checkbox"],
.checkbox-label input[type="radio"],
.checkbox-inline input[type="checkbox"],
.checkbox-inline input[type="radio"],
.form-grid label:has(> input[type="checkbox"]) > input[type="checkbox"],
.form-grid label:has(> input[type="radio"]) > input[type="radio"],
.form-card label:has(> input[type="checkbox"]) > input[type="checkbox"],
.form-card label:has(> input[type="radio"]) > input[type="radio"] {
    width: auto;
    min-width: 1rem;
    max-width: none;
    margin: 0;
    flex: 0 0 auto;
}

.form-grid input,
.form-grid select,
.form-grid textarea,
.form-card input,
.form-card select,
.form-card textarea {
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: #fff;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-lg);
}

.detail-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--spacing-md);
    margin: 0;
}

.detail-list div {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.detail-list dt {
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.detail-list dd {
    margin: 0;
    font-weight: 600;
}

.table-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.totals-card {
    display: grid;
    gap: var(--spacing-sm);
    max-width: 24rem;
    margin-left: auto;
}

.totals-card div {
    display: flex;
    justify-content: space-between;
    gap: var(--spacing-md);
}

.totals-card__total {
    border-top: 1px solid var(--color-border);
    padding-top: var(--spacing-sm);
    font-size: 1.125rem;
}

.metrics-grid,
.panel-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-lg);
}

.metric-card,
.panel-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
}

.metric-card span {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.875rem;
}

.metric-card strong {
    font-size: 1.5rem;
}

a.metric-card {
    display: block;
    text-decoration: none;
    color: inherit;
}

a.metric-card:hover {
    border-color: var(--color-primary, #2563eb);
}

.quick-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
}

/* Tres atajos no necesitan una tarjeta con título propio: en una sola línea, con su etiqueta
   alineada al centro, ocupan la altura de un botón en vez de la de un bloque entero. */
.quick-links--inline {
    align-items: center;
    margin-bottom: var(--spacing-md);
}

.page--transfer-create .form-stack,
.page--transfer-receive .form-stack,
.page--transfer-pending .paginated-table__wrapper {
    max-width: 48rem;
}

.transfer-cart.form-stack {
    max-width: 52rem;
}

.transfer-cart__picker {
    display: grid;
    gap: 0.65rem;
    padding: 0.75rem 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-muted, #f8f9fb);
}

.transfer-cart__product {
    margin: 0;
    width: 100%;
}

.transfer-cart__qty-row {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 0.5rem 0.65rem;
}

.transfer-cart__qty {
    flex: 0 1 8rem;
    min-width: 6rem;
    margin: 0;
}

.transfer-cart__qty input {
    width: 100%;
    min-height: 2.375rem;
}

.transfer-cart__add {
    flex: 0 0 auto;
    align-self: end;
    white-space: nowrap;
}

.transfer-cart__stock-hint {
    display: none;
}

/* Producto seleccionado en la creación de transferencias.
   Antes: «max-width: 28rem» + «margin: … auto» + «justify-content: center» +
   «text-align: center». El resultado era una tarjeta de 201 px flotando en el centro de un
   contenedor de 795 px —el 25 % del ancho— con el texto centrado y la acción de quitar
   pegada al lado. Ahora ocupa el ancho disponible y se lee como una fila: los datos del
   producto a la izquierda y la acción a la derecha.
   Ámbito: la clase la usa únicamente el selector de líneas de transferencia. */
.product-card--transfer-selected {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0.65rem 0.85rem;
    text-align: left;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.product-card--transfer-selected .product-card__compact-main {
    min-width: 0;
    flex: 1 1 14rem;
    display: grid;
    gap: 0.1rem;
}

/* El contenedor del selector ya dibujaba su propio borde y relleno: con la tarjeta dentro
   quedaban dos cajas anidadas. Se deja una sola, la de la tarjeta. */
[data-transfer-line-picker] .customer-picker__selected {
    display: block;
    padding: 0;
    border: 0;
    background: transparent;
}

/* Tras elegir el producto, el JS marca el buscador con [hidden], pero
   «.customer-picker__control { display: flex }» lo volvía a mostrar: quedaba un campo de
   búsqueda vacío encima de la tarjeta. El atributo tiene que mandar. */
[data-transfer-line-picker] .customer-picker__control[hidden] {
    display: none;
}

/* La acción de quitar deja de ser solo un aspa: lleva etiqueta visible y se alinea al
   extremo derecho de la fila. */
.product-card--transfer-selected .product-card__clear-x {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: 0 0 auto;
    font-size: 0.875rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.product-card--transfer-selected .product-card__clear-glyph {
    font-size: 1.1rem;
    line-height: 1;
}

.product-card--transfer-selected .product-card__title {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 600;
}

.product-card--transfer-selected .product-card__meta {
    margin: 0.1rem 0 0;
    font-size: 0.8125rem;
    color: var(--color-text-muted);
}

.transfer-cart__table td:last-child,
.transfer-receive__table td:last-child {
    width: 6rem;
    text-align: right;
}

.transfer-receive__qty-readonly {
    width: 5rem;
    text-align: center;
    background: var(--color-surface-muted, #f3f4f6);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 0.375rem 0.5rem;
}

.transfer-receive__meta p {
    margin: 0.25rem 0;
}

.shell-header__notifications {
    position: relative;
    margin-right: var(--spacing-sm);
}

.shell-header__notifications-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    text-decoration: none;
    padding: 0.25rem 0.5rem;
}

.shell-header__badge,
.sidebar-nav__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.35rem;
    margin-left: 0.35rem;
    border-radius: 999px;
    background: var(--color-danger, #c0392b);
    color: #fff;
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
}

.shell-header__badge {
    position: absolute;
    top: -0.15rem;
    right: -0.15rem;
    margin-left: 0;
}

.shell-header__notifications-panel {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    width: min(20rem, 90vw);
    padding: var(--spacing-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    z-index: 20;
}

.shell-header__notifications:hover .shell-header__notifications-panel,
.shell-header__notifications:focus-within .shell-header__notifications-panel {
    display: grid;
    gap: var(--spacing-xs);
}

.shell-header__notification-item {
    display: grid;
    gap: 0.15rem;
    padding: 0.5rem 0.625rem;
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: inherit;
    font-size: 0.8125rem;
}

.shell-header__notification-item:hover {
    background: var(--color-surface-muted, #f3f4f6);
}

.status-badge--warning {
    background: #fff3cd;
    color: #856404;
}

@media (max-width: 640px) {
    .transfer-cart__picker {
        padding: var(--spacing-sm);
    }

    .transfer-cart__qty-row {
        flex-direction: column;
        align-items: stretch;
    }

    .transfer-cart__qty,
    .transfer-cart__add {
        width: 100%;
        max-width: none;
    }

    .table-actions {
        display: flex;
        flex-direction: column;
        gap: 0.35rem;
    }
}

.quick-links a {
    padding: 0.5rem 0.875rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.page .page-header__title {
    margin-bottom: 0.25rem;
}

/* Catalog product detail — controlled image size */
.detail-card__grid--product {
    display: grid;
    grid-template-columns: minmax(240px, 280px) minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.detail-card__media {
    width: min(280px, 100%);
    max-width: 320px;
}

.catalog-product-image,
.detail-card__media img.catalog-product-image,
.detail-card__media img {
    display: block;
    width: 100%;
    max-width: 320px;
    max-height: 320px;
    height: auto;
    object-fit: contain;
    background: var(--color-surface-muted, #f3f4f6);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.catalog-image-placeholder--detail {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 240px;
    height: 240px;
    max-width: 100%;
    color: var(--color-text-muted);
    background: var(--color-surface-muted, #f3f4f6);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
}

.detail-list--product-main {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1.25rem;
    margin: 0;
}

.detail-list--product-main > div {
    min-width: 0;
}

.catalog-list-thumb {
    width: 56px;
    height: 56px;
    object-fit: contain;
    border-radius: 4px;
    background: var(--color-surface-muted, #f3f4f6);
    border: 1px solid var(--color-border);
    display: block;
}

.catalog-products-table th,
.catalog-products-table td,
.receipt-lines-table th,
.receipt-lines-table td {
    padding: 0.45rem 0.6rem;
    vertical-align: middle;
    white-space: nowrap;
}

.catalog-products-table td:nth-child(3),
.receipt-lines-table td:nth-child(2) {
    white-space: normal;
    min-width: 10rem;
}

.receipt-lines-table input {
    width: 100%;
    min-width: 4.5rem;
    max-width: 8rem;
}

@media (max-width: 1100px) {
    .catalog-products-table .col-secondary {
        display: none;
    }
}

@media (max-width: 767px) {
    .detail-card__grid--product {
        grid-template-columns: minmax(0, 1fr);
    }

    .detail-list--product-main {
        grid-template-columns: minmax(0, 1fr);
    }

    .detail-card__media,
    .catalog-product-image,
    .detail-card__media img {
        max-width: 280px;
        max-height: 280px;
    }
}

/* Compact operational density (catalog / inventory / forms) */
.page-header {
    margin-bottom: var(--spacing-md);
    gap: var(--spacing-sm);
}

.page-header__title {
    font-size: clamp(1.25rem, 2vw, 1.5rem);
}

.form-card,
.detail-card {
    padding: 1rem 1.15rem;
    margin-bottom: 1rem;
}

.section-title {
    margin: 0.75rem 0 0.5rem;
    font-size: 1rem;
}

.form-grid {
    gap: 0.65rem 0.85rem;
}

.form-grid label,
.filter-bar label {
    font-size: 0.8125rem;
    gap: 0.2rem;
}

.form-grid input,
.form-grid select,
.form-grid textarea,
.filter-bar input,
.filter-bar select {
    min-height: 2.25rem;
    padding: 0.35rem 0.55rem;
}

.paginated-table__table th,
.paginated-table__table td,
.data-table th,
.data-table td {
    padding: 0.4rem 0.55rem;
    font-size: 0.875rem;
}

.table-actions {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    white-space: nowrap;
}

.table-actions .btn--sm,
.table-actions a {
    font-size: 0.8125rem;
    padding: 0.2rem 0.45rem;
}

.is-numeric,
td.is-numeric,
th.is-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.receipt-lines-table--hide-lot th:nth-child(6),
.receipt-lines-table--hide-lot td[data-col="lot"],
.receipt-lines-table--hide-serial th:nth-child(7),
.receipt-lines-table--hide-serial td[data-col="serial"],
.receipt-lines-table--hide-expiry th:nth-child(8),
.receipt-lines-table--hide-expiry td[data-col="expiry"] {
    display: none;
}

.receipt-line-editing {
    background: var(--color-surface-muted, #f8fafc);
}

.product-card {
    padding: 0.65rem 0.75rem;
}

.product-card__actions {
    margin-top: 0.4rem;
    display: flex;
    gap: 0.35rem;
}

.product-card--compact {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.45rem 0.65rem;
}

.product-card__compact-main {
    min-width: 0;
}

.product-card--compact .product-card__title {
    font-size: 0.95rem;
    margin: 0;
}

.product-card--compact .product-card__meta {
    font-size: 0.8125rem;
    color: var(--color-text-muted);
}

.product-card__clear-x {
    border: 0;
    background: transparent;
    color: var(--color-text-muted);
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.15rem 0.4rem;
}

.product-card__clear-x:hover {
    color: var(--color-danger, #dc2626);
}

.receipt-totals {
    margin-top: 0.85rem;
    margin-left: auto;
    width: min(20rem, 100%);
    display: grid;
    gap: 0.35rem;
}

.receipt-totals__row {
    display: flex;
    justify-content: flex-end;
    align-items: baseline;
    gap: 0.45rem;
    font-size: 0.95rem;
}

.receipt-totals__row--grand {
    font-size: 1.1rem;
    padding-top: 0.35rem;
    border-top: 1px solid var(--color-border);
}

.receipt-detail-total {
    font-size: 1.15rem;
    font-weight: 700;
}

.receipts-table td.table-actions {
    white-space: nowrap;
}

.receipts-table .col-secondary {
    max-width: 7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kardex-period-hint {
    font-size: 0.8125rem;
    margin: 0.35rem 0 0;
}

.kardex-period-hint__detail {
    color: var(--color-text-muted);
}

.nowrap {
    white-space: nowrap;
}

@media (min-width: 1200px) {
    .receipts-table-wrap {
        overflow-x: visible;
    }
}

.page--quotations-commercial {
    min-width: 0;
    width: 100%;
    max-width: none;
    overflow-x: visible;
}

.page--quotations-commercial .filter-bar--quotations {
    display: grid;
    gap: 0.65rem 0.85rem;
    align-items: end;
    grid-template-columns: minmax(0, 1fr);
}

.page--quotations-commercial .filter-bar--quotations label,
.page--quotations-commercial .filter-bar--quotations .search-input {
    min-width: 0;
}

.page--quotations-commercial .filter-bar--quotations .filter-bar__submit {
    justify-self: start;
}

@media (min-width: 900px) {
    .page--quotations-commercial .filter-bar--quotations {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (min-width: 1400px) {
    .page--quotations-commercial .filter-bar--quotations {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-end;
        gap: 0.65rem 0.85rem;
    }

    .page--quotations-commercial .filter-bar--quotations .search-input {
        flex: 1 1 14rem;
        min-width: 14rem;
        max-width: 22rem;
    }

    .page--quotations-commercial .filter-bar--quotations label {
        flex: 1 1 8rem;
        min-width: 7.5rem;
        max-width: 11rem;
    }

    .page--quotations-commercial .filter-bar--quotations .filter-bar__submit {
        flex: 0 0 auto;
        margin-left: 0;
    }
}

.page--quotations-commercial .quotations-table-card {
    overflow-x: visible;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.page--quotations-commercial .quotations-table {
    width: 100%;
    max-width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    box-sizing: border-box;
}

.shell__main:has(.page--quotations-commercial) {
    overflow-x: visible;
}

.shell__main .page--quotations-commercial .quotations-table,
.shell__main .page--quotations-commercial .quotations-table.paginated-table__table {
    min-width: 0;
    width: 100%;
    max-width: 100%;
    table-layout: fixed;
}

.page--quotations-commercial .quotations-table th,
.page--quotations-commercial .quotations-table td {
    vertical-align: top;
    padding: 0.18rem 0.2rem;
    font-size: 0.75rem;
    line-height: 1.2;
    overflow: visible;
    box-sizing: border-box;
}

.page--quotations-commercial .quotations-table th {
    font-size: 0.6875rem;
    line-height: 1.2;
    white-space: normal;
}

.page--quotations-commercial .quotations-table .col-number {
    white-space: normal;
    font-size: 0.6875rem;
}

.page--quotations-commercial .quotations-number {
    display: inline-block;
    user-select: all;
}

.page--quotations-commercial .quotations-number__line {
    display: block;
    white-space: nowrap;
}

.page--quotations-commercial .quotations-datetime {
    display: inline-block;
    line-height: 1.15;
    font-size: 0.6875rem;
}

.page--quotations-commercial .quotations-datetime__date,
.page--quotations-commercial .quotations-datetime__time {
    display: block;
    white-space: nowrap;
}

.page--quotations-commercial .quotations-table .col-date,
.page--quotations-commercial .quotations-table .col-updated {
    font-size: 0.6875rem;
}

.page--quotations-commercial .quotations-table .col-total {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.page--quotations-commercial .quotations-table .col-next-action {
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
    font-size: 0.6875rem;
}

.page--quotations-commercial .quotations-table .col-actions {
    white-space: normal;
    overflow: visible;
}

.page--quotations-commercial .quotations-cell--text {
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
    line-height: 1.2;
    font-size: 0.75rem;
}

.page--quotations-commercial .col-status .status-badge {
    display: inline-block;
    max-width: 100%;
    white-space: normal;
    text-align: center;
    line-height: 1.15;
    overflow-wrap: break-word;
    font-size: 0.625rem;
    padding: 0.12rem 0.3rem;
}

.page--quotations-commercial .quotations-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem;
    width: 100%;
    min-width: 0;
}

.page--quotations-commercial .quotations-actions > .btn--sm {
    flex: 0 0 auto;
    box-sizing: border-box;
    white-space: nowrap;
    padding: 0.14rem 0.32rem;
    font-size: 0.6875rem;
    line-height: 1.15;
    min-height: 0;
}

.page--quotations-commercial .quotations-actions__menu {
    flex: 0 0 auto;
}

.page--quotations-commercial .quotations-actions__toggle {
    min-height: 0;
    padding: 0.1rem 0.3rem;
    font-size: 0.9375rem;
    line-height: 1;
}

.page--quotations-commercial .quotations-actions__dropdown {
    min-width: 9.5rem;
}

.page--quotations-commercial .quotations-discard-panel > summary {
    list-style: none;
}

.page--quotations-commercial .quotations-discard-panel > summary::-webkit-details-marker {
    display: none;
}

.page--quotations-commercial .quotations-discard-form {
    padding: 0.45rem 0.75rem 0.65rem;
    border-top: 1px solid var(--color-border);
    min-width: 14rem;
}

.page--quotations-commercial .quotations-discard-form label {
    font-size: 0.75rem;
}

.page--quotations-commercial .table-actions--compact {
    display: block;
    white-space: normal;
    overflow: visible;
}

@media (min-width: 1024px) {
    .page--quotations-commercial .quotations-table-card.paginated-table__wrapper {
        overflow-x: visible;
    }

    .page--quotations-commercial .quotations-table td.col-actions {
        vertical-align: middle;
    }

    .page--quotations-commercial .quotations-actions {
        flex-wrap: nowrap;
        gap: 0.12rem;
    }

    .page--quotations-commercial .quotations-table col.col-number { width: 6%; }
    .page--quotations-commercial .quotations-table col.col-customer { width: 10%; }
    .page--quotations-commercial .quotations-table col.col-branch { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-seller { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-date { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-updated { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-status { width: 9%; }
    .page--quotations-commercial .quotations-table col.col-total { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-next-action { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-actions { width: 15%; }
}

@media (min-width: 1200px) {
    .page--quotations-commercial .quotations-table col.col-number { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-customer { width: 11%; }
    .page--quotations-commercial .quotations-table col.col-branch { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-seller { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-date { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-updated { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-status { width: 9%; }
    .page--quotations-commercial .quotations-table col.col-total { width: 7%; }
    .page--quotations-commercial .quotations-table col.col-next-action { width: 8%; }
    .page--quotations-commercial .quotations-table col.col-actions { width: 14%; }
}

.page--quotations-commercial .table-actions__disclosure > summary {
    list-style: none;
    cursor: pointer;
}

.page--quotations-commercial .table-actions__disclosure > summary::-webkit-details-marker {
    display: none;
}

.page--quotations-commercial .table-actions__disclosure > summary:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

@media (max-width: 1023px) {
    .page--quotations-commercial .filter-bar--quotations {
        grid-template-columns: minmax(0, 1fr);
    }

    .page--quotations-commercial .quotations-table-card {
        overflow-x: visible;
        border: none;
        background: transparent;
    }

    .page--quotations-commercial .quotations-table {
        min-width: 0;
        table-layout: auto;
    }

    .page--quotations-commercial .quotations-table thead {
        display: none;
    }

    .page--quotations-commercial .quotations-table tbody tr {
        display: block;
        margin-bottom: var(--spacing-md);
        padding: var(--spacing-md);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        background: var(--color-surface);
    }

    .page--quotations-commercial .quotations-table tbody td {
        display: flex;
        justify-content: space-between;
        gap: var(--spacing-sm);
        width: 100%;
        padding: 0.35rem 0;
        border: none;
        text-align: right;
        white-space: normal;
        max-width: none;
        overflow: visible;
    }

    .page--quotations-commercial .quotations-table tbody td::before {
        content: attr(data-label);
        flex: 0 0 42%;
        font-size: 0.75rem;
        font-weight: 600;
        text-transform: uppercase;
        color: var(--color-text-muted);
        text-align: left;
    }

    .page--quotations-commercial .quotations-table tbody td.col-number,
    .page--quotations-commercial .quotations-table tbody td.col-customer {
        display: block;
        text-align: left;
        padding-top: 0;
    }

    .page--quotations-commercial .quotations-table tbody td.col-number::before,
    .page--quotations-commercial .quotations-table tbody td.col-customer::before {
        display: none;
    }

    .page--quotations-commercial .quotations-table tbody td.col-number {
        font-size: 1rem;
        font-weight: 700;
        padding-bottom: 0.15rem;
    }

    .page--quotations-commercial .quotations-table tbody td.col-customer {
        font-weight: 600;
        padding-bottom: 0.5rem;
        margin-bottom: 0.35rem;
        border-bottom: 1px solid var(--color-border);
    }

    .page--quotations-commercial .quotations-table .col-actions {
        flex-direction: column;
        align-items: stretch;
        text-align: left;
        min-width: 0;
        white-space: normal;
    }

    .page--quotations-commercial .quotations-table .col-actions::before {
        margin-bottom: 0.25rem;
    }

    .page--quotations-commercial .quotations-actions {
        width: 100%;
        min-width: 0;
    }

    .page--quotations-commercial .quotations-actions > .btn--sm {
        flex: 1 1 auto;
    }

    .page--quotations-commercial .quotations-actions__menu {
        width: 100%;
    }

    .page--quotations-commercial .quotations-actions__toggle {
        width: 100%;
    }

    .page--quotations-commercial .col-status .status-badge {
        margin-left: auto;
        white-space: normal;
    }
}

/* Cuentas Corrientes — tablas operativas compactas */
.current-accounts-table {
    overflow-x: auto;
}

.current-accounts-table .data-table,
.current-accounts-table .paginated-table__table {
    width: 100%;
}

.current-accounts-table th,
.current-accounts-table td {
    vertical-align: middle;
}

.current-accounts-table .table-actions {
    white-space: nowrap;
}

/* Cuentas por pagar — panel financiero compacto */
.page--accounts-payable .page-header--compact {
    margin-bottom: 0.75rem;
}

.page--accounts-payable .page-header__subtitle {
    margin-top: 0.15rem;
}

.page--accounts-payable .metrics-grid--accounts-payable {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.65rem;
    margin-bottom: 0.75rem;
}

.page--accounts-payable .metric-card--compact {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 4.25rem;
    padding: 0.55rem 0.75rem;
}

.page--accounts-payable .metric-card--compact span {
    font-size: 0.75rem;
    line-height: 1.2;
}

.page--accounts-payable .metric-card--compact strong {
    font-size: 1.15rem;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.page--accounts-payable .filter-bar--accounts-payable {
    display: grid;
    grid-template-columns: minmax(10rem, 1.4fr) minmax(7rem, 0.9fr) minmax(7rem, 0.9fr) minmax(7rem, 0.9fr) auto;
    gap: 0.55rem 0.65rem;
    align-items: end;
    margin-bottom: 0.75rem;
    padding: 0.65rem 0.75rem;
}

.page--accounts-payable .filter-bar--accounts-payable label {
    margin: 0;
    gap: 0.2rem;
    font-size: 0.8125rem;
}

.page--accounts-payable .filter-bar--accounts-payable input,
.page--accounts-payable .filter-bar--accounts-payable select,
.page--accounts-payable .filter-bar--accounts-payable .btn {
    min-height: 2.15rem;
}

.page--accounts-payable .filter-bar--accounts-payable .filter-bar__submit {
    display: flex;
    align-items: end;
}

.page--accounts-payable .accounts-payable-table {
    margin-bottom: 0.75rem;
}

.page--accounts-payable .accounts-payable-table .data-table {
    table-layout: auto;
    width: 100%;
    border-collapse: collapse;
}

.page--accounts-payable .accounts-payable-table th,
.page--accounts-payable .accounts-payable-table td {
    word-break: normal;
    overflow-wrap: normal;
    hyphens: none;
    white-space: normal;
    padding: 0.4rem 0.45rem;
    font-size: 0.8125rem;
    line-height: 1.25;
    vertical-align: middle;
}

.page--accounts-payable .accounts-payable-table thead th {
    white-space: nowrap;
    font-weight: 600;
}

.page--accounts-payable .accounts-payable-table .col-check {
    width: 2rem;
    text-align: center;
}

.page--accounts-payable .accounts-payable-table .col-provider {
    min-width: 8.5rem;
    max-width: 11rem;
}

.page--accounts-payable .accounts-payable-table .col-origin {
    min-width: 7.5rem;
    max-width: 9rem;
}

.page--accounts-payable .accounts-payable-table .col-document {
    white-space: nowrap;
}

.page--accounts-payable .accounts-payable-table .col-branch {
    min-width: 7rem;
    max-width: 10rem;
}

.page--accounts-payable .accounts-payable-table .col-date,
.page--accounts-payable .accounts-payable-table .col-status,
.page--accounts-payable .accounts-payable-table .col-action {
    white-space: nowrap;
}

.page--accounts-payable .accounts-payable-table .col-money {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    min-width: 5.5rem;
}

.page--accounts-payable .accounts-payable-table .nowrap {
    white-space: nowrap;
}

.page--accounts-payable .accounts-payable-table .origin-stack {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    line-height: 1.2;
}

.page--accounts-payable .accounts-payable-table td.col-provider,
.page--accounts-payable .accounts-payable-table td.col-branch {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    word-break: keep-all;
    overflow-wrap: break-word;
}

.page--accounts-payable .status-badge {
    display: inline-block;
    padding: 0.12rem 0.45rem;
    font-size: 0.75rem;
    line-height: 1.2;
}

.page--accounts-payable .accounts-payable-payment-form {
    padding: 0.75rem;
    margin-top: 0;
}

.page--accounts-payable .accounts-payable-payment-form__title {
    margin: 0 0 0.55rem;
    font-size: 1rem;
}

.page--accounts-payable .accounts-payable-payment-form__grid {
    display: grid;
    grid-template-columns: minmax(10rem, 1.3fr) minmax(6rem, 0.8fr) minmax(8rem, 1fr) minmax(8rem, 1fr);
    gap: 0.55rem 0.65rem;
    align-items: end;
}

.page--accounts-payable .accounts-payable-payment-form__grid label {
    margin: 0;
    gap: 0.2rem;
    font-size: 0.8125rem;
}

.page--accounts-payable .accounts-payable-payment-form__grid input,
.page--accounts-payable .accounts-payable-payment-form__grid select {
    min-height: 2.15rem;
}

.page--accounts-payable .accounts-payable-payment-form__actions {
    margin-top: 0.65rem;
}

.page--accounts-payable .accounts-payable-payment-form__help,
.page--accounts-payable .accounts-payable-payment-form__note {
    margin: 0.4rem 0 0;
    font-size: 0.75rem;
    line-height: 1.3;
}

.page--accounts-payable .accounts-payable-payment-form__grid--provider {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.page--accounts-payable .accounts-payable-providers-table .col-count {
    width: 6%;
    text-align: center;
    white-space: nowrap;
}

.page--accounts-payable .accounts-payable-providers-table .col-provider {
    width: 28%;
}

.page--accounts-payable .accounts-payable-providers-table .col-action,
.page--accounts-payable .accounts-payable-obligations-table .col-action,
.page--accounts-payable .accounts-payable-payments-table .col-action {
    width: 7%;
    white-space: nowrap;
}

.page--accounts-payable .accounts-payable-obligations-table .col-customer {
    width: 16%;
    max-width: 12rem;
    overflow-wrap: break-word;
    word-break: keep-all;
}

.page--accounts-payable .section-title--compact {
    margin: 0.5rem 0 0.35rem;
    font-size: 1rem;
}

.page--provider-account .accounts-payable-payment-form {
    margin-top: 0.5rem;
}

@media (max-width: 1100px) {
    .page--accounts-payable .accounts-payable-payment-form__grid--provider {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .page--accounts-payable .filter-bar--accounts-payable {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .page--accounts-payable .filter-bar--accounts-payable .filter-bar__submit {
        grid-column: 1 / -1;
    }

    .page--accounts-payable .accounts-payable-payment-form__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .page--accounts-payable .metrics-grid--accounts-payable {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .page--accounts-payable .filter-bar--accounts-payable,
    .page--accounts-payable .accounts-payable-payment-form__grid {
        grid-template-columns: 1fr;
    }

    .page--accounts-payable .accounts-payable-table .data-table thead {
        display: none;
    }

    .page--accounts-payable .accounts-payable-table .data-table tr {
        display: block;
        margin-bottom: 0.65rem;
        border: 1px solid var(--color-border, #ddd);
        border-radius: 0.5rem;
        padding: 0.5rem 0.65rem;
    }

    .page--accounts-payable .accounts-payable-table .data-table td {
        display: flex;
        justify-content: space-between;
        gap: 0.75rem;
        border: 0;
        padding: 0.3rem 0;
        text-align: right;
        max-width: none;
        -webkit-line-clamp: unset;
        overflow: visible;
    }

    .page--accounts-payable .accounts-payable-table .data-table td::before {
        content: attr(data-label);
        font-weight: 600;
        text-align: left;
        color: var(--color-text-muted, #666);
    }

    .page--accounts-payable .accounts-payable-table .data-table td[data-label=""]::before {
        content: none;
    }

    .page--accounts-payable .accounts-payable-table .col-check {
        justify-content: flex-start;
    }

    .page--accounts-payable .accounts-payable-table .col-money {
        text-align: right;
    }
}

/* ============================================================================
   RESERVAS
   Pantalla de control y auditoría del stock comprometido. Su geometría sigue el mismo
   criterio ya validado en Movimientos —rejilla declarada, no reparto flexible—, pero con
   selectores propios: Movimientos está aprobado y no se toca desde aquí.
   ============================================================================ */

.filter-bar--reservations {
    /* Rejilla: la posición de cada filtro no puede depender de lo que mida su contenido, o al
       elegir un producto la barra se reorganizaría. */
    display: grid;
    align-items: end;
    padding: 0.55rem 0.7rem;
    gap: 0.45rem 0.5rem;
    margin-bottom: 0.6rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Escritorio: los cinco controles en un renglón. Producto recibe más ancho porque muestra el
   nombre completo del artículo elegido; el resto son listas cortas. */
@media (min-width: 1200px) {
    .filter-bar--reservations {
        grid-template-columns:
            minmax(0, 1.3fr)    /* Sucursal  */
            minmax(0, 1.3fr)    /* Almacén   */
            minmax(0, 1fr)      /* Estado    */
            minmax(0, 1.8fr)    /* Producto  */
            auto;               /* Consultar */
    }
}

/* Tabletas y pantallas intermedias: dos renglones de dos, con el botón cerrando la rejilla. */
@media (min-width: 640px) and (max-width: 1199px) {
    .filter-bar--reservations {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 639px) {
    .filter-bar--reservations {
        grid-template-columns: minmax(0, 1fr);
    }
}

.filter-bar--reservations > label {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    max-width: none;
}

.filter-bar--reservations select,
.filter-bar--reservations input {
    min-height: 2.1rem;
    padding: 0.3rem 0.5rem;
    width: 100%;
    min-width: 0;
}

.filter-bar--reservations .filter-bar__submit {
    align-self: end;
    justify-self: start;
    min-height: 2.1rem;
    padding: 0.3rem 0.85rem;
    white-space: nowrap;
}

@media (max-width: 1199px) {
    .filter-bar--reservations .filter-bar__submit {
        grid-column: 1 / -1;
        justify-self: stretch;
        text-align: center;
    }
}

/* --- Buscador de producto: mismas reglas ya validadas en Movimientos ------------------------ */

.filter-bar--reservations .reservations-product-picker {
    position: relative;
}

/* El atributo [hidden] manda sobre el display del componente: si no, el contenedor vacío sigue
   ocupando altura y la barra cambia de tamaño según el estado. */
.filter-bar--reservations .reservations-product-picker .customer-picker__control[hidden],
.filter-bar--reservations .reservations-product-picker .customer-picker__selected[hidden] {
    display: none;
}

.filter-bar--reservations .reservations-product-picker .customer-picker__control {
    margin: 0;
}

.filter-bar--reservations .reservations-product-picker .customer-picker__selected {
    display: block;
    padding: 0;
    border: 0;
    background: transparent;
}

.filter-bar--reservations .reservations-product-picker .product-card--compact {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    width: 100%;
    min-height: 2.1rem;
    padding: 0.2rem 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.filter-bar--reservations .reservations-product-picker .product-card__compact-main {
    min-width: 0;
    flex: 1 1 auto;
}

/* Una sola línea: la tarjeta del producto elegido mide lo mismo que un desplegable y la barra
   no da un salto de altura al seleccionar. */
.filter-bar--reservations .reservations-product-picker .product-card__title--inline {
    display: block;
    font-size: 0.8125rem;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-bar--reservations .reservations-product-picker .product-card__clear-x {
    flex: 0 0 auto;
}

.filter-bar--reservations .reservations-product-picker .customer-picker__results {
    min-width: 20rem;
    max-width: min(28rem, calc(100vw - 2rem));
    max-height: 20rem;
    overflow-y: auto;
    left: 0;
    right: auto;
}

@media (max-width: 767px) {
    .filter-bar--reservations .reservations-product-picker .customer-picker__results {
        min-width: 0;
        max-width: none;
        left: 0;
        right: 0;
    }
}

/* La ayuda queda anclada a las dos aristas de su propia columna y con el texto repartido en
   renglones: fuera del flujo para no empujar la barra, pero sin poder invadir a los vecinos. */
.filter-bar--reservations .reservations-product-picker .customer-picker__hint {
    position: absolute;
    top: calc(100% - 0.1rem);
    left: 0;
    right: 0;
    z-index: 21;
    box-sizing: border-box;
    max-width: 100%;
    margin: 0;
    padding: 0.2rem 0.4rem;
    font-size: 0.7rem;
    line-height: 1.25;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm, 4px);
    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.1);
    white-space: normal;
    overflow-wrap: break-word;
}

/* --- Tabla ---------------------------------------------------------------------------------- */

.reservations-table-wrap {
    overflow-x: auto;
    width: 100%;
    max-width: 100%;
}

.paginated-table__table.reservations-table {
    table-layout: fixed;
    width: 100%;
    /* 60 rem = 960 px, el mismo suelo que ya se midió para las tablas de Movimientos: por debajo
       las palabras largas se partirían, y por encima no cabría en el contenedor a 1280 px. */
    min-width: 60rem;
}

.reservations-table-wrap .paginated-table__table.reservations-table th,
.reservations-table-wrap .paginated-table__table.reservations-table td {
    padding: 0.3rem 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    vertical-align: top;
    word-break: normal;
    overflow-wrap: break-word;
}

/* Los porcentajes suman exactamente 100: si no llegan a 100 el navegador reparte el resto y las
   columnas se encogen de forma imprevisible.
   Comprobado al ancho mínimo de la tabla, 960 px (px reales / mínimo medido con la tipografía
   real; la píldora del estado añade su propio relleno al texto):
     Producto 163/98 · Sucursal 96/83 · Almacén 91/80 · Cantidad 91/88 · Origen 86/66
     Documento 139/123 · Estado 110/107 · Reservada 96/94 · Vence 86/77                   */
.rsv-col-product { width: 17%; }
.rsv-col-branch { width: 10%; }
.rsv-col-warehouse { width: 9.5%; }
/* «Cantidad» es la palabra más ancha de su columna y no se parte. */
.rsv-col-qty { width: 9.5%; text-align: right; white-space: nowrap; }
.rsv-col-origin { width: 9%; }
.rsv-col-doc { width: 14.5%; }
/* «Consumida» dentro de su píldora ocupa 107 px y tampoco se parte. */
.rsv-col-status { width: 11.5%; }
/* La fecha se reparte en dos renglones —día y hora—; lo que no puede partirse es «19/08/2026». */
.rsv-col-date { width: 10%; }
.rsv-col-expires { width: 9%; }

.reservations-table .is-numeric { font-variant-numeric: tabular-nums; }

.rsv-empty {
    text-align: center;
    color: var(--color-text-muted);
    padding: 1.25rem 0.5rem;
}

/* El estado se lee de un vistazo: activo compromete stock, consumido ya salió, liberado lo
   devolvió a disponible. El color acompaña a la palabra, no la sustituye. */
.rsv-estado {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid transparent;
}

.rsv-estado--active {
    color: #92400e;
    background: #fef3c7;
    border-color: #fcd34d;
}

.rsv-estado--consumed {
    color: #1e40af;
    background: #dbeafe;
    border-color: #93c5fd;
}

.rsv-estado--released {
    color: #166534;
    background: #dcfce7;
    border-color: #86efac;
}

.rsv-estado--expired,
.rsv-estado--cancelled {
    color: #475569;
    background: #f1f5f9;
    border-color: #cbd5e1;
}

/* Móvil: la tabla se lee desplazándose en horizontal DENTRO de su contenedor, nunca arrastrando
   la página entera. No se reduce el mínimo de 60 rem: medido, por debajo de 940 px la columna
   Estado y la columna Cantidad recortan su texto, y un dato recortado es peor que un
   desplazamiento. */

/* ============================================================================
   CUENTA POR COBRAR — CRONOGRAMA
   En el escritorio, una tabla. En el teléfono no cabe: seis columnas estrechas obligan a
   arrastrar de lado para leer una sola cuota. Se usa el mismo patrón ya validado en Cuentas
   por pagar —cada fila pasa a ser una ficha con su etiqueta delante— sin tocar aquella
   pantalla: selector propio.
   ============================================================================ */

@media (max-width: 767px) {
    .page--receivable-detail .paginated-table__wrapper thead {
        display: none;
    }

    .page--receivable-detail .paginated-table__wrapper tr {
        display: block;
        margin-bottom: 0.65rem;
        border: 1px solid var(--color-border, #ddd);
        border-radius: 0.5rem;
        padding: 0.5rem 0.65rem;
    }

    .page--receivable-detail .paginated-table__wrapper td {
        display: flex;
        justify-content: space-between;
        gap: 0.75rem;
        border: 0;
        padding: 0.2rem 0;
        white-space: normal;
    }

    .page--receivable-detail .paginated-table__wrapper td::before {
        content: attr(data-label);
        font-weight: 600;
        text-align: left;
        color: var(--color-text-muted, #666);
    }

    .page--receivable-detail .paginated-table__wrapper td[data-label=""]::before {
        content: none;
    }
}

/* ============================================================================
   LISTADO DE ÓRDENES DE SERVICIO — QUE QUEPA SIN ARRASTRAR Y SIGA LEYÉNDOSE
   La tabla tiene ocho columnas y ninguna decía cuánto debía medir: el navegador repartía el
   ancho según el contenido, y bastaba un nombre largo o una columna de acciones con dos
   enlaces y un botón para empujar la tabla hasta 887 px y obligar a arrastrar de lado.

   El ancho útil no es el de la pantalla. Con la barra lateral abierta, a 1366 px quedan
   1110 px útiles y la tabla mide 1052. Pero a 1024 px la barra se pliega y quedan 768 px
   útiles —exactamente los mismos que a 768 px—, y ahí las ocho columnas no caben leyéndose:
   sumando el mínimo real de cada una (documento 91, fecha 89, estado 116 por la palabra
   «comercialmente», cliente 130, documento cliente 73, vendedor 100, total 79 y acción 89)
   hacen falta 767 px de contenido y sólo hay 718 disponibles. Forzar la tabla ahí es lo que
   partía las palabras carácter a carácter.

   Por eso el corte está en 1280 px: por encima, tabla con el ancho repartido a propósito;
   por debajo, cada fila es una ficha —el mismo patrón ya validado en Cuentas por pagar y en
   el cronograma de la cuenta por cobrar—. No se oculta ninguna columna en ningún ancho.
   ============================================================================ */

/* --- De 1280 px en adelante hay sitio de sobra: tabla. --- */
@media (min-width: 1280px) {
    .page--quotation-listing .paginated-table__table {
        width: 100%;
        table-layout: fixed;
    }

    .page--quotation-listing .paginated-table__table th,
    .page--quotation-listing .paginated-table__table td {
        padding: 0.45rem 0.5rem;
        vertical-align: top;
        /* «break-word», no «anywhere»: parte la palabra sólo si por sí sola no cabe. */
        overflow-wrap: break-word;
    }

    .page--quotation-listing .paginated-table__table th:nth-child(1),
    .page--quotation-listing .paginated-table__table td:nth-child(1) { width: 12%; }
    .page--quotation-listing .paginated-table__table th:nth-child(2),
    .page--quotation-listing .paginated-table__table td:nth-child(2) { width: 10%; }
    .page--quotation-listing .paginated-table__table th:nth-child(3),
    .page--quotation-listing .paginated-table__table td:nth-child(3) { width: 14%; }
    .page--quotation-listing .paginated-table__table th:nth-child(4),
    .page--quotation-listing .paginated-table__table td:nth-child(4) { width: 18%; }
    .page--quotation-listing .paginated-table__table th:nth-child(5),
    .page--quotation-listing .paginated-table__table td:nth-child(5) { width: 11%; }
    .page--quotation-listing .paginated-table__table th:nth-child(6),
    .page--quotation-listing .paginated-table__table td:nth-child(6) { width: 13%; }
    .page--quotation-listing .paginated-table__table th:nth-child(7),
    .page--quotation-listing .paginated-table__table td:nth-child(7) { width: 10%; }
    .page--quotation-listing .paginated-table__table th:nth-child(8),
    .page--quotation-listing .paginated-table__table td:nth-child(8) { width: 12%; }

    /* Sólo los nombres propios pueden partirse por donde sea: son los únicos ilimitados. */
    .page--quotation-listing .paginated-table__table .is-wrappable {
        overflow-wrap: anywhere;
    }

    .page--quotation-listing .paginated-table__table .is-numeric {
        text-align: right;
        white-space: nowrap;
    }

    /* La etiqueta de estado puede ocupar dos líneas, pero no salirse de su columna: se le
       recorta el acolchado lateral para que «comercialmente» quepa entera dentro del 14 %. */
    .page--quotation-listing .paginated-table__table .status-badge {
        display: inline-block;
        max-width: 100%;
        white-space: normal;
        padding-left: 0.3rem;
        padding-right: 0.3rem;
    }

    /* Las acciones, una debajo de otra: dos enlaces en línea son los que ensanchaban la columna.
       La celda NO se convierte en contenedor flexible. Un «display: flex» sobre un <td> lo saca
       del reparto de la tabla —el navegador lo envuelve en una celda anónima— y entonces el
       «width: 12 %» se calcula contra esa celda y no contra la tabla: la columna se quedaba en
       16 px y «No eliminable» salía en vertical, una letra por línea. Se apilan como bloques. */
    .page--quotation-listing .paginated-table__table .table-actions {
        /* La celda tiene que seguir siendo celda. «.table-actions» está declarado como
           «inline-flex» más arriba en esta misma hoja, y cualquier «display» que no sea
           «table-cell» saca al <td> del reparto de la tabla: el navegador lo envuelve en una
           celda anónima y entonces el «width: 12 %» se calcula contra esa caja en vez de contra
           la tabla. Medido: la celda quedaba en 17,6 px mientras su cabecera medía 126, y por
           eso «Ver» y «No eliminable» salían en vertical, una letra por línea. */
        display: table-cell;
        white-space: normal;
        font-size: 0.86rem;
    }

    .page--quotation-listing .paginated-table__table .table-actions > a,
    .page--quotation-listing .paginated-table__table .table-actions > form,
    .page--quotation-listing .paginated-table__table .table-actions > .btn,
    .page--quotation-listing .paginated-table__table .table-actions > .form-help {
        display: block;
        max-width: 100%;
        margin-top: 0.2rem;
        padding-left: 0;
        padding-right: 0;
        white-space: normal;
        overflow-wrap: break-word;
        text-align: left;
    }

    .page--quotation-listing .paginated-table__table .table-actions > *:first-child {
        margin-top: 0;
    }

    .page--quotation-listing .paginated-table__table .table-actions .btn {
        width: 100%;
        padding-left: 0.35rem;
        padding-right: 0.35rem;
    }
}

/* --- Hasta 1279 px, cada fila es una ficha: se ve todo y se lee todo. --- */
@media (max-width: 1279px) {
    .page--quotation-listing .paginated-table__wrapper thead {
        display: none;
    }

    .page--quotation-listing .paginated-table__table,
    .page--quotation-listing .paginated-table__table th,
    .page--quotation-listing .paginated-table__table td {
        width: auto;
    }

    .page--quotation-listing .paginated-table__wrapper tr {
        display: block;
        margin-bottom: 0.65rem;
        border: 1px solid var(--color-border, #ddd);
        border-radius: 0.5rem;
        padding: 0.5rem 0.65rem;
    }

    .page--quotation-listing .paginated-table__wrapper td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        border: 0;
        padding: 0.2rem 0;
        white-space: normal;
        overflow-wrap: break-word;
        text-align: right;
    }

    .page--quotation-listing .paginated-table__wrapper td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-weight: 600;
        text-align: left;
        color: var(--color-text-muted, #666);
    }

    .page--quotation-listing .paginated-table__wrapper td[data-label=""]::before {
        content: none;
    }

    .page--quotation-listing .paginated-table__table .table-actions {
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-end;
        gap: 0.5rem;
    }

    .page--quotation-listing .paginated-table__table .table-actions form {
        display: inline-block;
    }
}

/* --- Entre 768 y 1279 px la ficha tiene sitio para dos campos por línea: no se estira. --- */
@media (min-width: 768px) and (max-width: 1279px) {
    .page--quotation-listing .paginated-table__wrapper tbody tr {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 1.5rem;
    }

    .page--quotation-listing .paginated-table__wrapper tbody tr td.table-actions {
        grid-column: 1 / -1;
        border-top: 1px solid var(--color-border, #ddd);
        margin-top: 0.35rem;
        padding-top: 0.4rem;
    }
}

/* ============================================================================
   ENTREGAS — LO QUE TODAVÍA HAY QUE IR A RECOGER
   Las Órdenes que el laboratorio ya terminó entran en la cola de entregas antes de que nadie las
   haya recibido. Se marcan para que se distingan de las que ya están en la óptica: son las únicas
   de la lista cuya siguiente acción no ocurre en el mostrador, sino yendo a por el trabajo.
   ============================================================================ */

.delivery-pending-reception {
    margin-bottom: 0.85rem;
}

.delivery-pending-reception .form-help {
    margin: 0.25rem 0 0;
}

.paginated-table__table tr.delivery-row--pending-reception > td {
    background: var(--color-surface-muted, #f8fafc);
}

.paginated-table__table tr.delivery-row--pending-reception > td:first-child {
    box-shadow: inset 3px 0 0 0 var(--color-primary, #1e4b8f);
}

/* ── ESTADO «ESTOY TRABAJANDO» ──────────────────────────────────────────────────────────
   La ruedecilla reutiliza la animación `spin` que ya define este mismo archivo para
   `.loading-state__spinner`: es el mismo gesto visual del sistema, en tamaño de botón. */
.btn__spinner {
    display: inline-block;
    width: 0.85em;
    height: 0.85em;
    margin-right: 0.45em;
    vertical-align: -0.08em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
    opacity: 0.85;
    flex: 0 0 auto;
}

.btn__label-enviando {
    vertical-align: middle;
}

/* Un botón apagado por envío en curso NO debe parecer roto: sigue siendo el mismo botón,
   sólo que ocupado. Y no acepta más clics ni con el ratón ni con el teclado. */
.esta-enviando [aria-disabled="true"],
button[data-envio-en-curso="1"] {
    cursor: progress;
    opacity: 0.75;
    pointer-events: none;
}

.envio-en-curso {
    margin: 0.5rem 0 0;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--color-text-muted, #64748b);
}

/* Quien prefiere no ver animaciones tampoco tiene por qué perder el aviso: el texto del
   botón y la línea de estado siguen ahí, y la rueda simplemente deja de girar. */
@media (prefers-reduced-motion: reduce) {
    .btn__spinner {
        animation: none;
    }
}

/* ── STOCK: UNA SOLA ALINEACIÓN POR COLUMNA ────────────────────────────────────────────
   Medido en pantalla: la columna «Disponible» se veía con tres alineaciones a la vez
   —cabecera a la izquierda, celdas a la izquierda y el total centrado—, y por eso el número
   parecía desplazado respecto a su rótulo. La causa es una colisión de especificidad:
   `.paginated-table__table th` (0,1,1) gana a `.stock-col-num` (0,1,0), así que la regla de
   la columna nunca llegaba a aplicarse. Se declara con la misma especificidad que la regla
   genérica para que toda la columna hable el mismo idioma, del encabezado al total.

   La celda del total YA caía bajo su columna —el colspan era correcto—; lo que estaba mal
   era el rótulo, tirado al extremo izquierdo de las seis columnas que abarca. */
.stock-table th.stock-col-num,
.stock-table td.stock-col-num,
.stock-table th.stock-col-available,
.stock-table td.stock-col-available,
.stock-table th.stock-col-total-empresa,
.stock-table td.stock-col-total-empresa,
.paginated-table__table th.stock-col-num,
.paginated-table__table td.stock-col-num,
.paginated-table__table th.stock-col-available,
.paginated-table__table td.stock-col-available,
.paginated-table__table th.stock-col-total-empresa,
.paginated-table__table td.stock-col-total-empresa {
    text-align: center;
}

/* Y el rótulo del total pegado a su número, no en la otra punta de la fila. */
.paginated-table__table th.stock-total-row__label,
.stock-table th.stock-total-row__label,
.data-table th.stock-total-row__label {
    text-align: right;
    padding-right: 0.75rem;
}


/* ── CAJA · TOTALES AL FINAL DE LA LISTA Y DESGLOSE POR CONCEPTO ─────────────────────
   Quien cierra la caja busca los totales debajo de la última fila, no arriba: ahí están,
   alineados bajo las mismas columnas de Ingreso y Egreso. El desglose por concepto va
   pegado al resumen por medio porque responde a la siguiente pregunta, no a otra. */
.cash-movements__totals th {
    background: var(--color-surface-alt, #f8fafc);
    border-top: 2px solid var(--color-border, #e2e8f0);
    font-weight: 700;
}

/* ── RESUMEN POR FORMA DE PAGO · COMPACTO ────────────────────────────────────────────
   Es un bloque de apoyo, no el protagonista de la pantalla: título discreto, tabla estrecha
   y el efectivo esperado en UNA línea. El desglose por concepto va plegado — está a un clic
   para quien lo necesite y no ocupa alto para quien no. */
.cash-by-method {
    margin-top: 0.9rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: var(--radius-md, 8px);
    background: var(--color-surface, #fff);
}

.cash-by-method__title {
    margin: 0 0 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted, #64748b);
}

.cash-by-method__table {
    margin: 0;
    max-width: 46rem;
}

.cash-by-method__table th,
.cash-by-method__table td {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
}

.cash-by-method__total td {
    font-weight: 700;
    border-top: 2px solid var(--color-border, #e2e8f0);
}

.cash-by-method__empty {
    margin: 0;
    font-size: 0.8125rem;
    color: var(--color-text-muted, #64748b);
}

/* El efectivo esperado, pegado a la tabla y en una sola línea: no puede confundirse con el
   TOTAL de arriba, que suma todos los medios. */
.cash-by-method__expected {
    margin: 0.6rem 0 0;
    font-size: 0.875rem;
}

.cash-by-method__expected-amount {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.cash-by-method__expected-detail {
    color: var(--color-text-muted, #64748b);
    font-size: 0.8125rem;
}

.cash-by-method__note {
    margin: 0.5rem 0 0;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--color-text-muted, #64748b);
}

.cash-by-method__concepts {
    margin-top: 0.6rem;
}

.cash-by-method__concepts > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    color: var(--color-text-muted, #64748b);
}

.cash-by-method__concept-table {
    margin: 0.5rem 0 0;
    max-width: 46rem;
}

.cash-by-method__concept-table thead th:first-child {
    font-weight: 700;
}

.cash-by-method__indent,
.cash-report__cell--indent {
    padding-left: 1.5rem;
}

/* La explicación larga de trazabilidad, plegada: la línea visible dice lo imprescindible
   y el resto está a un clic. No se pierde nada; deja de ocupar cuatro líneas de alto. */
.cash-movements__note-more {
    margin-top: 0.15rem;
}

.cash-movements__note-more > summary {
    cursor: pointer;
    display: list-item;
    width: fit-content;
}

/* Menos aire entre bloques: filtros → totales → movimientos → resumen, sin franjas vacías. */
.page .filter-bar--cash-movements {
    margin-bottom: 0.75rem;
}

.page .metrics-grid + .table-card--cash-movements {
    margin-top: 0.75rem;
}

.table-card--cash-movements .cash-movements__note {
    margin: 0.5rem 0 0;
    font-size: 0.75rem;
}

.cash-by-method__group th,
.cash-report__row--group th,
.cash-report__row--group td {
    background: var(--color-surface-alt, #f8fafc);
    font-weight: 700;
    text-align: left;
}

/* ── TRANSFERENCIAS · MOTIVO A LA VISTA CUANDO NO SE PUEDE ──────────────────────────
   Esconder la operación entera dejaba al usuario sin saber para qué sirve esta sección.
   Ahora el botón se ve siempre y, cuando no hay destino posible, este bloque dice por qué. */
.cash-transfer-blocked {
    border-left: 3px solid var(--color-warning, #ca8a04);
    margin-bottom: 1rem;
}

.cash-transfer-blocked p {
    margin: 0 0 0.4rem;
}

/* ── EL DESPLEGABLE DE CONCEPTO NO PUEDE TAPAR LA PANTALLA ──────────────────────────
   Con once conceptos, el `select` nativo desplegado ocupaba casi todo el alto útil. Se
   limita a ocho opciones visibles: el resto se alcanza con la rueda, como en cualquier
   lista larga, y no se pierde ningún concepto. */
.filter-bar--cash-movements select[name="concept_code"] {
    max-height: 12rem;
}

/* ── TRANSFERIR DINERO · DOS COLUMNAS Y EL BOTÓN EN SU PROPIA FILA ──────────────────
   El botón caía pegado al párrafo informativo, casi encima. La causa no era el margen del
   botón: era que los cuatro campos y el botón compartían una rejilla que los repartía a su
   aire. Con colocación explícita cada cosa cae donde debe, y la explicación se fue fuera
   del formulario, con separación real. */
.cash-transfer-form__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem 1.25rem;
    align-items: end;
}

.cash-transfer-form__grid > label,
.cash-transfer-form__actions {
    min-width: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.cash-transfer-form__grid > label input,
.cash-transfer-form__grid > label select {
    width: 100%;
}

.cash-transfer-form__origin { grid-column: 1; grid-row: 1; }
.cash-transfer-form__destination { grid-column: 2; grid-row: 1; }
.cash-transfer-form__amount { grid-column: 1; grid-row: 2; }
.cash-transfer-form__reason { grid-column: 2; grid-row: 2; }

/* Tercera fila para el botón, y espacio propio por debajo: es lo que impide que toque el
   texto que viene después. */
.cash-transfer-form__actions {
    grid-column: 1 / -1;
    grid-row: 3;
    flex-direction: row;
    margin-top: 0.35rem;
}

.cash-transfer-form__actions .btn {
    min-width: 12rem;
}

.cash-transfer-note {
    margin: 1.1rem 0 0;
    padding: 0.7rem 0.9rem;
    border-left: 3px solid var(--color-border, #e2e8f0);
    background: var(--color-surface-alt, #f8fafc);
    border-radius: var(--radius-sm, 6px);
    font-size: 0.8125rem;
    line-height: 1.5;
}

/* Por debajo de tablet, una columna: origen, destino, monto, motivo, botón. */
@media (max-width: 767px) {
    .cash-transfer-form__grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .cash-transfer-form__origin,
    .cash-transfer-form__destination,
    .cash-transfer-form__amount,
    .cash-transfer-form__reason,
    .cash-transfer-form__actions {
        grid-column: 1;
        grid-row: auto;
    }

    .cash-transfer-form__actions .btn {
        width: 100%;
    }
}

/* ── EL LISTADO DE TRANSFERENCIAS TIENE DIEZ COLUMNAS ───────────────────────────────
   Medido a 1366 px: la tabla pedía 1084 px dentro de una tarjeta de 1054 y, como la tarjeta
   no se desplaza, la última columna se CORTABA — no se perdía en un scroll, se perdía a
   secas. Con layout fijo y anchos declarados cabe entera; por debajo de tablet se desplaza
   dentro de su propia tarjeta, nunca ensanchando la página. */
/* La tarjeta se desplaza por dentro antes que recortar. Con los anchos de abajo la tabla
   cabe entera desde 1152 px, así que esta barra NO llega a aparecer en escritorio; está
   como red de seguridad, para que ningún dato futuro más largo se pierda a secas. */
.table-card--cash-transfers {
    max-width: 100%;
    overflow-x: auto;
}

.cash-transfers__table {
    table-layout: fixed;
    width: 100%;
}

.cash-transfers__table th,
.cash-transfers__table td {
    overflow-wrap: break-word;
    word-break: normal;
    vertical-align: top;
}

/* ── LOS OCHO PÍXELES QUE SOBRABAN ──────────────────────────────────────────────────
   Medidos, no supuestos: la tabla encajaba en la tarjeta (1032 px de columnas + 22 de
   border-spacing = 1054), pero la celda «Estado» pedía 72 px y sólo tenía 62. La culpa no
   era de la tabla sino de la píldora de estado: `.status-badge` obedece `max-width: 100%`
   y encogía su caja a 44 px, pero su CONTENIDO —la palabra «Completada», que no parte, más
   0.75rem de relleno a cada lado— no baja de 63 px, así que desbordaba su propia celda.
   Dos cambios, los dos acotados a esta tabla: la columna recibe el ancho que de verdad
   necesita, y aquí la píldora lleva un relleno más ajustado. No se toca `.status-badge`
   en general: la usan muchas pantallas y ahí está bien. */
.cash-transfers__table .status-badge {
    padding: 0.2rem 0.45rem;
    letter-spacing: 0;
}

.cash-transfers__table th:nth-child(1),
.cash-transfers__table td:nth-child(1) { width: 8%; }
.cash-transfers__table th:nth-child(2),
.cash-transfers__table td:nth-child(2) { width: 8%; }
.cash-transfers__table th:nth-child(3),
.cash-transfers__table td:nth-child(3) { width: 12%; }
.cash-transfers__table th:nth-child(4),
.cash-transfers__table td:nth-child(4) { width: 10%; }
.cash-transfers__table th:nth-child(5),
.cash-transfers__table td:nth-child(5) { width: 12%; }
.cash-transfers__table th:nth-child(6),
.cash-transfers__table td:nth-child(6) { width: 10%; }
.cash-transfers__table th:nth-child(7),
.cash-transfers__table td:nth-child(7) { width: 10%; }
.cash-transfers__table th:nth-child(8),
.cash-transfers__table td:nth-child(8) { width: 10%; }
.cash-transfers__table th:nth-child(9),
.cash-transfers__table td:nth-child(9) { width: 10%; }
.cash-transfers__table th:nth-child(10),
.cash-transfers__table td:nth-child(10) { width: 10%; }

@media (max-width: 900px) {
    .table-card--cash-transfers { overflow-x: auto; }
    .cash-transfers__table { table-layout: auto; min-width: 60rem; }
    .cash-transfers__table th,
    .cash-transfers__table td { width: auto; }
}
