/* =============================================================================
   IDENTIDAD VISUAL — PRODUCCIÓN DEL DÍA
   =============================================================================
   Manual: docs/identidad-visual.md. Proyecto: docs/RUNBOOK-PRODUCCION-DIA.md.
   La forma está APROBADA y no se rediscute: es el mockup
   `docs/produccion-dia/15-ronda6-tarjetas-tolva.html` (ronda 6, rev. 2), votado
   por Hernán el 12/08/2026 — la B, la máquina como baldosa con su tendencia.
   (La ronda 5 rev. 3, `13-ronda5-rev3-prototipo.html`, sigue siendo la forma de
   la cinta, la playa y los modales: la 6 cambió la PORTADA, no el vocabulario.)

   LA PANTALLA ESTÁ EN UNA SOLA COLUMNA Y ARRANCA POR LAS MÁQUINAS: las cuatro
   tarjetas de tolva (`.pd-banda` → `.pd-tolvac` → `.pd-maq` + `.pd-bal`), el día
   compacto en un renglón (`.pd-dia`) y la playa a lo ancho (`.pd-posgrid`, tres
   por fila). Se murió el carril de la derecha (`.pd-rail` / `.pd-rcard`).

   LO QUE SE CAE ES EL ORDEN, NO EL PESO: «la producción manda la pantalla»
   sigue valiendo —la playa es el bloque más grande y ahora ocupa más superficie
   que antes—, pero las máquinas van primero porque con la etapa 10 en camino la
   línea tiene algo que decir minuto a minuto.

   TODO va scopeado bajo `.pd-ui` y con prefijo `pd-`, como manda el §6 del
   manual: el resto de Producción sigue en Tailwind y una clase suelta lo
   rompería. Es el segundo .css de la carpeta `produccion/`, después de
   `fraccionado-ui.css` (Balanzas).

   Tratamiento PLANO (la vara de Facturación y Balanzas): superficie blanca
   sobre `--canvas`, separación por trazo y una sola sombra. La única
   superficie navy rellena de la pantalla es el botón primario de la barra del
   armazón, que pone `shell-ui.css`. Acá el navy es TEXTO (el número de la
   posición) y TRAZO (el segmento activo, el tramo «de hoy» de la barra).

   La paleta NO está acá: sale entera de core/tokens.css. Ningún token nuevo.
   ========================================================================== */

/* EL `box-sizing` ES PROPIO, NO HEREDADO — y esto lo destapó el banco.
   Las tarjetas del carril llevan `width:100%` con padding y borde: sin
   `border-box` miden 30 px más que su columna y la pantalla desborda 8 px a
   1440. En la aplicación no se veía porque el preflight de Tailwind lo pone
   para todo el documento, pero apoyarse en el reset de OTRO framework es una
   dependencia invisible: el día que Tailwind se vaya —que es a donde va esta
   migración— se rompen los once módulos a la vez y nadie sabe por qué. */
.pd-ui, .pd-ui *, .pd-ui *::before, .pd-ui *::after { box-sizing: border-box; }

.pd-ui .material-symbols-outlined { font-variation-settings: 'wght' 400; vertical-align: middle; }

/* Trampa §7 del manual, para el ROOT de los modales, que llevan `.pd-ui` ellos
   mismos y por eso no los alcanza la regla agrupada de tokens.css. */
.pd-ui.pd-velo.hidden { display: none; }

/* =============================================================================
   1. EL CUERPO — una sola medida de margen lateral (--gutter)
   ========================================================================== */
.pd-ui { background: var(--canvas); }

.pd-ui .pd-body {
    padding: 14px var(--gutter) 30px;
    max-width: 1440px; margin: 0 auto;
    display: flex; flex-direction: column; gap: 14px;
}

/* Un dato ausente es información (§1.4): gris, más chico, y dice qué falta. */
.pd-ui .pd-vacio { color: var(--faint); font-style: italic; font-weight: 500; }

/* =============================================================================
   2. LA CINTA DEL TURNO — el estado del día en un renglón
   ========================================================================== */
.pd-ui .pd-cinta {
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow);
    display: flex; align-items: center; gap: 10px;
    padding: 10px 16px; flex-wrap: wrap;
}
.pd-ui .pd-estado {
    display: inline-flex; align-items: center; gap: 7px;
    border-radius: 999px; padding: 5px 12px;
    font-weight: 700; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
    background: var(--ok-050); border: 1px solid var(--ok-hair); color: var(--ok);
}
.pd-ui .pd-estado::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pd-ui .pd-estado.warn { background: var(--warn-050); border-color: var(--warn-hair); color: var(--warn); }
.pd-ui .pd-estado.mut  { background: var(--canvas);   border-color: var(--hair-strong); color: var(--faint); border-style: dashed; }

.pd-ui .pd-cinta .quien { color: var(--muted); font-size: 12.5px; }
.pd-ui .pd-falta { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pd-ui .pd-falta .cap {
    font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint);
}

.pd-ui .pd-chip {
    display: inline-flex; align-items: center; gap: 6px;
    border-radius: 999px; padding: 4px 11px;
    font-size: 12px; font-weight: 600;
    border: 1px solid var(--hair-strong); color: var(--muted); background: var(--surface);
}
.pd-ui .pd-chip.warn { background: var(--warn-050); border-color: var(--warn-hair); color: var(--warn); }
.pd-ui .pd-chip.crit { background: var(--crit-050); border-color: var(--crit-hair); color: var(--crit); }
.pd-ui .pd-chip.ok   { background: var(--ok-050);   border-color: var(--ok-hair);   color: var(--ok);   }
.pd-ui button.pd-chip { font-family: inherit; cursor: pointer; transition: transform .15s var(--curva); }
.pd-ui button.pd-chip:hover, .pd-ui button.pd-chip:focus-visible { transform: translateY(-1px); }

/* =============================================================================
   3-4. EL DÍA, COMPACTO ARRIBA — ronda 6 (§3 ter), 12/08/2026
   -----------------------------------------------------------------------------
   LA PANTALLA QUEDÓ EN UNA SOLA COLUMNA. Acá vivían `.pd-cols` y `.pd-main`, la
   grilla de dos columnas cuyo carril de la derecha se murió con la ronda 6: sus
   siete tarjetas se repartieron entre la cinta del turno («Para cerrar»), este
   renglón (azúcar, golpes, micronaje, desvío) y la fila de herramientas.

   Cada celda conserva la forma de la tarjeta del carril —rótulo · cifra · nota—
   porque es lo que permite que un dato ausente diga CUÁNDO va a estar. Los
   filetes verticales separan sin dibujar cinco cajas.
   ========================================================================== */
.pd-ui .pd-dia {
    display: flex; align-items: stretch; gap: 16px; flex-wrap: wrap;
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow); padding: 12px 16px;
}
.pd-ui .pd-dia .sep { width: 1px; flex: none; background: var(--hair); }
/* EN UN CELULAR EL RENGLÓN SE APILA. Con `flex-wrap` a 390 px la celda grande
   —que envuelve sus propios artículos— se estiraba por debajo de la fila y el
   «Azúcar ingresada» del renglón siguiente le quedaba ENCIMA: dos cifras
   superpuestas, que es peor que no mostrar ninguna. El filete se acuesta. */
@media (max-width: 760px) {
    .pd-ui .pd-dia { flex-direction: column; align-items: stretch; gap: 10px; }
    .pd-ui .pd-dia .sep { width: auto; height: 1px; }
    .pd-ui .pd-dia .c.grande { flex: none; align-items: flex-start; }
}
.pd-ui .pd-dia .c {
    min-width: 0; border: 0; background: none; padding: 0;
    text-align: left; font: inherit; color: inherit; border-radius: 8px;
    transition: background .15s var(--curva);
}
.pd-ui .pd-dia button.c { cursor: pointer; padding: 2px 8px; margin: -2px -8px; }
.pd-ui .pd-dia button.c:hover, .pd-ui .pd-dia button.c:focus-visible { background: var(--navy-050); outline: none; }
.pd-ui .pd-dia .c.grande { flex: 1; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.pd-ui .pd-dia .l {
    font-size: 10px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint); white-space: nowrap;
}
.pd-ui .pd-dia .l .abre { color: var(--navy-500); }
/* «Números gigantes, no» (memoria feedback_evitar_numeros_gigantes): esto es un
   KPI de ABM, no un display. Que grite el color. */
.pd-ui .pd-dia .v { font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
.pd-ui .pd-dia .grande .v { font-size: 24px; }
.pd-ui .pd-dia .v small { font-size: 11.5px; font-weight: 600; color: var(--muted); }
/* El dato que todavía no existe NO es un cero: dice cuándo va a existir. */
.pd-ui .pd-dia .v.ausente { font-size: 13px; font-weight: 600; font-style: italic; color: var(--faint); letter-spacing: 0; }
.pd-ui .pd-dia .v.warn { color: var(--warn); }
.pd-ui .pd-dia .v.crit { color: var(--crit); }
.pd-ui .pd-dia .s { font-size: 11px; color: var(--muted); margin-top: 2px; }
.pd-ui .pd-dia .s.warn { color: var(--warn); font-weight: 600; }
.pd-ui .pd-dia .s.crit { color: var(--crit); font-weight: 600; }
.pd-ui .pd-dia .s.ok   { color: var(--ok);   font-weight: 600; }

.pd-ui .pd-arts { display: flex; gap: 10px; flex-wrap: wrap; flex: 1; }
.pd-ui .pd-artc {
    display: flex; align-items: center; gap: 9px; min-width: 0;
    border: 1px solid var(--hair); border-radius: 11px;
    padding: 6px 12px 6px 6px; background: var(--surface);
}
.pd-ui .pd-artc img,
.pd-ui .pd-artc .noimg {
    width: 40px; height: 40px; flex: none;
    object-fit: contain; border-radius: 8px;
    background: var(--surface); border: 1px solid var(--hair);
}
.pd-ui .pd-artc .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-artc .n {
    font-size: 10.5px; font-weight: 700; color: var(--muted); line-height: 1.2;
    max-width: 17ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pd-ui .pd-artc .k { font-size: 15px; font-weight: 700; letter-spacing: -.01em; line-height: 1.15; }
.pd-ui .pd-artc.warn { border-color: var(--warn-hair); background: var(--warn-050); }
.pd-ui .pd-artc.warn .k, .pd-ui .pd-artc.warn .n { color: var(--warn); }

/* =============================================================================
   5. LA CABECERA DE PRODUCCIÓN Y EL SEGMENTO DE LAS DOS VISTAS (regla 28)
   ========================================================================== */
.pd-ui .pd-prodhead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0 2px; }
.pd-ui .pd-prodhead h5 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.pd-ui .pd-prodhead .dep { font-size: 11.5px; color: var(--muted); }
.pd-ui .pd-prodhead .dep button {
    background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
    color: var(--navy-500); font-weight: 600;
}
.pd-ui .pd-prodhead .dep button:hover { text-decoration: underline; }

/* El activo por TINTE + sombra, no por relleno navy (§1.2). */
.pd-ui .pd-seg {
    display: inline-flex; background: var(--surface);
    border: 1px solid var(--hair-strong); border-radius: 10px; padding: 2px; margin-left: auto;
}
.pd-ui .pd-seg button {
    padding: 4px 12px; font: inherit; font-size: 12px; font-weight: 600;
    border: 0; background: none; border-radius: 8px; color: var(--muted); cursor: pointer;
    transition: background .15s var(--curva), color .15s var(--curva);
}
.pd-ui .pd-seg button:hover { background: var(--navy-050); }
.pd-ui .pd-seg button.on {
    background: var(--navy-050); color: var(--navy);
    box-shadow: 0 1px 2px rgba(16, 32, 64, .10);
}
.pd-ui .pd-seg button .n { font-variant-numeric: tabular-nums; opacity: .7; margin-left: 4px; }

/* =============================================================================
   6. LAS TARJETAS DE POSICIÓN — el objeto grande de la pantalla
   -----------------------------------------------------------------------------
   El filete superior dice el ESTADO, no la categoría (§1.1): ámbar arrastre,
   verde completa, azul informativo abierta, gris vacía.
   ========================================================================== */
/* SIN EL CARRIL, LA PLAYA COBRA EL ANCHO ENTERO: tres posiciones por fila en vez
   de dos (§3 ter). Es la compensación real por haber bajado la producción abajo
   del pliegue — cuando aparece, se ve una vez y media de lo que se veía. */
.pd-ui .pd-posgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pd-ui .pd-posgrid > * { min-width: 0; }
@media (max-width: 1100px) { .pd-ui .pd-posgrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 700px)  { .pd-ui .pd-posgrid { grid-template-columns: 1fr; } }

.pd-ui .pd-pcard {
    background: var(--surface); border: 1px solid var(--hair);
    border-top: 3px solid var(--hair-strong);
    border-radius: var(--r-card); box-shadow: var(--shadow);
    padding: 14px 16px 13px; display: flex; flex-direction: column; gap: 8px;
    min-width: 0; text-align: left; font: inherit; color: inherit; width: 100%;
    transition: transform .15s var(--curva), box-shadow .15s var(--curva);
}
.pd-ui button.pd-pcard { cursor: pointer; }
.pd-ui button.pd-pcard:hover, .pd-ui button.pd-pcard:focus-visible { transform: translateY(-2px); box-shadow: var(--e2); }
.pd-ui button.pd-pcard:focus-visible { outline: 2px solid var(--navy-500); outline-offset: 2px; }
.pd-ui .pd-pcard.arr  { border-top-color: var(--warn); }
.pd-ui .pd-pcard.ok   { border-top-color: var(--ok); }
.pd-ui .pd-pcard.ab   { border-top-color: var(--navy-300); }
.pd-ui .pd-pcard.desp { border-top-color: var(--navy-500); }

.pd-ui .pd-pcard .fila1 { display: flex; align-items: center; gap: 10px; }

/* LA POSICIÓN COMPLETA SE VE DE LEJOS. Es el único estado terminal de la
   playa —el camión está listo— y con un filete de 3 px había que buscarlo.
   La banda rellena es del ESTADO, no de una categoría, así que no rompe la
   regla 1.1: ninguna otra tarjeta se tiñe por lo que ES, sólo por cómo está.
   Blanco sobre `--ok` da 5,4 : 1, que pasa AA. */
.pd-ui .pd-pcard.ok .fila1 {
    margin: -14px -16px 0;
    padding: 11px 16px;
    background: var(--ok);
    border-radius: 11px 11px 0 0;
}
.pd-ui .pd-pcard.ok .fila1 .pn { color: #fff; }
.pd-ui .pd-pcard.ok .fila1 .st.ok { color: #fff; opacity: .92; }
.pd-ui .pd-pcard.ok .fila1 .pd-marca { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .38); color: #fff; }
.pd-ui .pd-pcard .pn { font-size: 24px; font-weight: 700; letter-spacing: -.02em; color: var(--navy); line-height: 1; }
.pd-ui .pd-pcard .st {
    font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .07em; margin-left: auto; color: var(--faint);
}
.pd-ui .pd-pcard .st.arr  { color: var(--warn); }
.pd-ui .pd-pcard .st.ok   { color: var(--ok); }
.pd-ui .pd-pcard .st.ab   { color: var(--navy-500); }
.pd-ui .pd-pcard .st.desp { color: var(--navy-500); }
.pd-ui .pd-pcard .lock { color: var(--crit); font-size: 15px; }

.pd-ui .pd-pcard .cuerpo { display: flex; gap: 12px; align-items: flex-start; }
.pd-ui .pd-pcard .cuerpo img,
.pd-ui .pd-pcard .cuerpo .noimg {
    width: 52px; height: 52px; flex: none; object-fit: contain;
    border-radius: 10px; border: 1px solid var(--hair); background: var(--surface);
}
.pd-ui .pd-pcard .cuerpo .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-pcard .art  { font-size: 14px; font-weight: 700; line-height: 1.25; }
.pd-ui .pd-pcard .lote { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.pd-ui .pd-pcard .kg   { font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1.1; margin-top: 2px; }
.pd-ui .pd-pcard .kg small { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.pd-ui .pd-pcard .nota { font-size: 11px; color: var(--muted); line-height: 1.35; }
.pd-ui .pd-pcard .nota.warn { color: var(--warn); font-weight: 600; }
.pd-ui .pd-pcard .nota.crit { color: var(--crit); font-weight: 600; }
.pd-ui .pd-pcard.vacia { opacity: .72; }

/* LA BARRA DE DOS TRAMOS (regla 27): lo que quedó de días anteriores y lo que
   entró hoy. Dibujar el arrastre es la mitad de por qué esta tarjeta existe —
   una sola barra no distingue «viene lleno de ayer» de «lo hicimos hoy». */
.pd-ui .pd-barra {
    height: 12px; border-radius: 6px; background: var(--canvas);
    border: 1px solid var(--hair); overflow: hidden; display: flex;
}
.pd-ui .pd-barra i { display: block; }
.pd-ui .pd-barra .ayer { background: var(--navy-300); opacity: .45; }
.pd-ui .pd-barra .hoy  { background: var(--navy); }

/* La tarjeta-aviso: lo producido que todavía no tiene dónde ir. */
.pd-ui .pd-pcard.aviso {
    border: 1px solid var(--warn-hair); border-top: 3px solid var(--warn);
    background: var(--warn-050); justify-content: center; align-items: flex-start; gap: 5px;
}
.pd-ui .pd-pcard.aviso .t { font-size: 13px; font-weight: 700; color: var(--warn); }
.pd-ui .pd-pcard.aviso .d { font-size: 12px; color: var(--warn); }

.pd-ui .pd-nada {
    grid-column: 1 / -1; text-align: center; padding: 26px 14px;
    border: 1px dashed var(--hair-strong); border-radius: var(--r-card);
    background: var(--surface); color: var(--faint); font-size: 12.5px;
}

/* =============================================================================
   7. LAS HERRAMIENTAS DEL TURNO — una fila de trazo fino
   -----------------------------------------------------------------------------
   ACÁ VIVÍA EL CARRIL (`.pd-rail`, `.pd-rcard`, `.pd-rk2`), y se murió entero
   con la ronda 6 (§3 ter, 12/08/2026): sus siete tarjetas se mudaron a la cinta
   del turno, al renglón del día y a las tolvas de la portada. Lo único que no
   tenía dónde ir en un renglón de cifras son estas cuatro herramientas, porque
   no son datos del día sino actos de una vez. Van en FILA, debajo del día:
   siempre a mano, sin competir con la acción principal de la barra
   (§«una acción principal por momento») y sin inventar un menú desplegable que
   el sistema no usa en ningún otro lado.
   ========================================================================== */
.pd-ui .pd-tools { display: flex; gap: 4px; flex-wrap: wrap; margin: -6px 2px 0; }
.pd-ui .pd-tools button {
    display: inline-flex; align-items: center; gap: 7px;
    background: none; border: 0; font: inherit; text-align: left; cursor: pointer;
    padding: 5px 10px; border-radius: 8px; color: var(--muted); font-size: 12.5px; font-weight: 600;
    border-bottom: 2px solid transparent;
    transition: background .15s var(--curva), color .15s var(--curva), border-color .15s var(--curva);
}
.pd-ui .pd-tools button:hover, .pd-ui .pd-tools button:focus-visible {
    background: var(--navy-050); color: var(--navy); border-bottom-color: var(--navy); outline: none;
}
.pd-ui .pd-tools button:disabled { opacity: .45; cursor: not-allowed; }
.pd-ui .pd-tools button:disabled:hover { background: none; color: var(--muted); border-bottom-color: transparent; }
.pd-ui .pd-tools .material-symbols-outlined { font-size: 17px; }

/* =============================================================================
   8. EL HISTORIAL — está, pero no compite (etapa 1 del runbook)
   ========================================================================== */
.pd-ui .pd-hist {
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow);
}
.pd-ui .pd-hist > summary {
    list-style: none; cursor: pointer; padding: 11px 16px;
    display: flex; align-items: center; gap: 9px;
    font-size: 11px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint);
}
.pd-ui .pd-hist > summary::-webkit-details-marker { display: none; }
/* El chevron va DIBUJADO, no es una ligadura de la fuente de íconos. Con
   `content:"expand_more"` una fuente que no carga no deja un hueco: escribe la
   PALABRA «expand_more» en el medio de la pantalla. Con dos bordes no puede
   pasar, y de paso el giro queda sobre `transform`, que no reflowea. */
.pd-ui .pd-hist > summary::after {
    content: ""; margin-left: auto; width: 8px; height: 8px; flex: none;
    border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .15s var(--curva);
}
.pd-ui .pd-hist[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.pd-ui .pd-hist > summary:hover, .pd-ui .pd-hist > summary:focus-visible { color: var(--navy); outline: none; }
.pd-ui .pd-hist .cuerpo { padding: 0 16px 16px; display: flex; flex-direction: column; gap: 16px; }

/* =============================================================================
   9. TABLAS — alineación a la izquierda, `.n` a la derecha; cabecera por regla
   ========================================================================== */
.pd-ui .pd-tabla { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.pd-ui .pd-tabla th {
    font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--faint); text-align: left; padding: 8px 10px;
    border-bottom: 2px solid var(--hair-strong); background: var(--surface); white-space: nowrap;
}
.pd-ui .pd-tabla td { padding: 8px 10px; border-bottom: 1px solid var(--hair); vertical-align: top; }
.pd-ui .pd-tabla tr:last-child td { border-bottom: none; }
/* La fila de una parada ABIERTA. Es la única que traba el cierre del turno, así
   que se tiñe entera: en una tabla de doce renglones, una insignia sola en la
   columna del medio no se encuentra. Fondo suave y no relleno —el relleno es de
   la posición completa y de la línea detenida, que son estados de UN objeto
   grande; acá lo que hay que poder es barrer la lista con la vista. */
.pd-ui .pd-tabla tr.crit td { background: var(--crit-050); }
.pd-ui .pd-tabla th.n, .pd-ui .pd-tabla td.n { text-align: right; font-variant-numeric: tabular-nums; }
.pd-ui .pd-tabla th.c, .pd-ui .pd-tabla td.c { text-align: center; }
.pd-ui .pd-tabla .cod { font-weight: 700; font-variant-numeric: tabular-nums; }
/* La caja recortaba a secas (`overflow: hidden`) y en una pantalla angosta la
   tabla del cierre se pasaba 154 px: el navegador la corría solo para mostrar el
   campo que recibía el foco, y la columna del LOTE —cuál de los tres estás
   devolviendo— se iba de la pantalla sin forma de traerla con el dedo. Una tabla
   ancha se corre DENTRO de su caja; el eje vertical sigue recortado, que es lo
   que le da el borde redondeado. */
.pd-ui .pd-caja {
    border: 1px solid var(--hair); border-radius: 11px;
    overflow-x: auto; overflow-y: hidden;
}
.pd-ui .pd-subt {
    font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint); margin: 0 0 7px;
}

/* =============================================================================
   10. LOS MODALES — velo + tarjeta, el vocabulario del ABM
   -----------------------------------------------------------------------------
   Cuelgan del <body>, así que su root lleva `.pd-ui` él mismo (trampa §7).
   ========================================================================== */
.pd-ui.pd-velo {
    position: fixed; inset: 0; z-index: 60;
    background: rgba(10, 20, 45, .44);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 4vh 18px; overflow-y: auto;
    animation: pdFade .16s ease;
}
.pd-ui .pd-modal {
    background: var(--surface); border-radius: 16px; box-shadow: var(--e3);
    width: 100%; max-width: 980px; margin-bottom: 4vh;
    animation: pdRise .2s var(--curva);
    display: flex; flex-direction: column; max-height: 92vh;
}
.pd-ui .pd-modal.ch { max-width: 640px; }
.pd-ui .pd-modal.md { max-width: 800px; }
/* LA TARJETA RECIBE EL FOCO cuando el modal no tiene ningún campo —es una
   pantalla de lectura— y por eso lleva `tabindex="-1"`. Sin esto se dibujaría
   un anillo alrededor del modal entero al abrirlo. NO se apaga el
   `:focus-visible` de nada de adentro: los controles siguen mostrando el suyo. */
.pd-ui .pd-modal:focus { outline: none; }
@keyframes pdFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pdRise { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }

.pd-ui .pd-moh {
    display: flex; align-items: center; gap: 12px;
    padding: 16px 20px; border-bottom: 1px solid var(--hair); flex: none;
}
.pd-ui .pd-moh .t { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.pd-ui .pd-moh .s { font-size: 11.5px; color: var(--muted); }
.pd-ui .pd-moh .x {
    margin-left: auto; background: var(--surface); border: 1px solid var(--hair-strong);
    border-radius: 9px; width: 32px; height: 32px; flex: none;
    font-size: 15px; font-weight: 700; color: var(--muted); line-height: 1; cursor: pointer;
    transition: background .15s var(--curva), color .15s var(--curva);
}
.pd-ui .pd-moh .x:hover, .pd-ui .pd-moh .x:focus-visible { background: var(--canvas); color: var(--ink); }

/* `min-height: 0` NO es decorativo acá: sin él este hijo flex crece con su
   contenido en vez de activar su propio scroll, y el pie del modal se va abajo
   del pliegue (trampa §7 del manual). */
.pd-ui .pd-mob { padding: 16px 20px 20px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }

/* EL MODAL QUE LLEVA UN BUSCADOR NO PUEDE RECORTAR.
   El desplegable del smart selector es `position: absolute`, así que un
   ancestro con `overflow: auto` lo corta — y el `z-index` no salva de un
   recorte, que es una trampa ya pagada. Se veía escribiendo «azucel»: las
   opciones aparecían cortadas contra el borde de abajo del modal.
   La salida es la que ya usaba el código viejo: que el cuerpo NO scrollee y
   crezca, y que el que scrollee sea el velo, que para eso es toda la pantalla.
   El precio es que el pie deja de quedar fijo, así que esto va SÓLO en los
   modales cortos que piden un lote o un artículo — no en el del cierre, que
   es una tabla larga y necesita su pie a la vista. */
.pd-ui .pd-modal.libre { max-height: none; }
.pd-ui .pd-modal.libre .pd-mob { overflow: visible; }
.pd-ui .pd-mopie {
    padding: 12px 20px 14px; border-top: 1px solid var(--hair); flex: none;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.pd-ui .pd-mopie .nota { font-size: 11.5px; color: var(--muted); flex: 1; min-width: 180px; }
.pd-ui .pd-mopie .der { margin-left: auto; display: flex; gap: 8px; }

/* =============================================================================
   11. CONTROLES
   ========================================================================== */
.pd-ui .pd-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    height: 36px; padding: 0 14px; border-radius: 10px;
    border: 1px solid transparent; font: inherit; font-size: .82rem; font-weight: 600;
    white-space: nowrap; cursor: pointer;
    background: var(--navy); color: #fff;
    transition: background .15s var(--curva), transform .15s var(--curva), border-color .15s var(--curva);
}
.pd-ui .pd-btn:hover  { background: var(--navy-700); transform: translateY(-1px); }
.pd-ui .pd-btn:active { transform: none; }
.pd-ui .pd-btn:focus-visible { outline: 2px solid var(--navy-500); outline-offset: 2px; }
.pd-ui .pd-btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.pd-ui .pd-btn.sec { background: var(--surface); color: var(--ink); border-color: var(--hair-strong); }
.pd-ui .pd-btn.sec:hover:not(:disabled) { background: var(--canvas); border-color: var(--muted); }
.pd-ui .pd-btn.peligro { background: var(--surface); color: var(--crit); border-color: var(--crit-hair); }
.pd-ui .pd-btn.peligro:hover:not(:disabled) { background: var(--crit); color: #fff; border-color: var(--crit); }
.pd-ui .pd-btn.chico { height: 30px; padding: 0 10px; font-size: .76rem; }

/* Acción de fila: crece al apuntarla, se achica al presionarla (§5). */
.pd-ui .pd-ico {
    background: none; border: 0; font: inherit; cursor: pointer; padding: 4px 6px;
    border-radius: 8px; color: var(--muted); font-size: 11.5px; font-weight: 600;
    display: inline-flex; align-items: center; gap: 5px;
    transition: background .15s var(--curva), color .15s var(--curva), transform .15s var(--curva);
}
.pd-ui .pd-ico:hover, .pd-ui .pd-ico:focus-visible { background: var(--navy-050); color: var(--navy); outline: none; }
.pd-ui .pd-ico:active { transform: scale(.94); }
.pd-ui .pd-ico.del { color: var(--crit); }
.pd-ui .pd-ico.del:hover, .pd-ui .pd-ico.del:focus-visible { background: var(--crit-050); color: var(--crit); }
.pd-ui .pd-ico:disabled { opacity: .4; cursor: not-allowed; }
.pd-ui .pd-ico .material-symbols-outlined { font-size: 16px; }

.pd-ui .pd-lbl {
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint); margin-bottom: 5px;
}
.pd-ui .pd-in, .pd-ui .pd-sel {
    width: 100%; font: inherit; font-size: 13px; color: var(--ink);
    padding: 8px 10px; border-radius: 9px;
    border: 1px solid var(--hair-strong); background: var(--surface);
    transition: border-color .15s var(--curva), box-shadow .15s var(--curva);
}
.pd-ui .pd-in:focus, .pd-ui .pd-sel:focus {
    outline: none; border-color: var(--navy-500); box-shadow: 0 0 0 3px var(--navy-050);
}
.pd-ui .pd-in.n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.pd-ui .pd-in.mal { border-color: var(--crit); box-shadow: 0 0 0 3px var(--crit-050); }
.pd-ui .pd-campo { margin-bottom: 13px; }
/* La casilla con su frase al lado — «parar también la línea 4, que comparte la
   tolva». Va envuelta en el <label> entero para que se pueda tocar la frase y
   no sólo el cuadradito, que en la planta se usa con guantes. */
.pd-ui .pd-check {
    display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
    font-size: 12.5px; font-weight: 600; line-height: 1.35; margin-bottom: 4px;
}
.pd-ui .pd-check input { margin-top: 2px; flex: none; }
.pd-ui .pd-ayuda { font-size: 11px; color: var(--muted); margin-top: 4px; }
.pd-ui .pd-ayuda.mal { color: var(--crit); font-weight: 600; }
.pd-ui .pd-ayuda.ok  { color: var(--ok);   font-weight: 600; }

/* El aviso contextual dentro de un modal. El color es del estado. */
.pd-ui .pd-aviso {
    border-radius: 10px; padding: 9px 13px; font-size: 12px; line-height: 1.4;
    border: 1px solid var(--hair); background: var(--canvas); color: var(--muted);
}
.pd-ui .pd-aviso.warn { background: var(--warn-050); border-color: var(--warn-hair); color: var(--warn); font-weight: 600; }
.pd-ui .pd-aviso.crit { background: var(--crit-050); border-color: var(--crit-hair); color: var(--crit); font-weight: 600; }
.pd-ui .pd-aviso.ok   { background: var(--ok-050);   border-color: var(--ok-hair);   color: var(--ok);   font-weight: 600; }

/* EL AVISO QUE ADEMÁS LLEVA (etapa 5). Los bloqueos del cierre se dibujaban
   como texto y tiraban su `onclick`: se leía qué faltaba y había que salir a
   buscar dónde se arreglaba. Es el mismo cartel, con la puerta puesta — hereda
   todo el color de `.pd-aviso` y sólo agrega el gesto de que se puede tocar. */
.pd-ui button.pd-aviso-btn {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; text-align: left; font-family: inherit; cursor: pointer;
    transition: transform .15s var(--curva);
}
.pd-ui button.pd-aviso-btn .ir { flex: none; font-size: 11px; opacity: .8; white-space: nowrap; }
.pd-ui button.pd-aviso-btn:hover,
.pd-ui button.pd-aviso-btn:focus-visible { transform: translateY(-1px); }

/* =============================================================================
   11 bis. LAS LECTURAS DE CONTADOR — etapa 5
   -----------------------------------------------------------------------------
   Son DOS máquinas por renglón —la envasadora y su enfardadora— y la tabla lo
   dice con una cabecera de dos pisos en vez de seis rótulos largos: sin el
   agrupador, «Arrastre», «Lectura de hoy» y «Avance» aparecen dos veces cada
   uno y no hay forma de saber cuál es de cuál.
   ============================================================================= */
.pd-ui .pd-tabla.pd-lect th.grupo {
    border-bottom: 1px solid var(--hair);
    font-size: 10.5px; letter-spacing: .04em;
}
/* El filete que separa las dos máquinas: sin él las seis columnas son una sola
   mancha y el ojo no encuentra dónde termina la envasadora. Va por CLASE y no
   por `nth-child` — la cabecera tiene dos pisos y el de arriba usa `colspan`,
   así que la columna 5 de una fila no es la columna 5 de la otra y el filete
   salía corrido. */
.pd-ui .pd-tabla.pd-lect .parte { border-left: 1px solid var(--hair); }
.pd-ui .pd-tabla.pd-lect tbody td { vertical-align: middle; }
/* La casilla del reset vive PEGADA a su casillero, no en una columna propia:
   es un atributo de esa lectura y separarlos obligaría a cruzar la vista. */
.pd-ui .pd-tabla.pd-lect .pd-check {
    justify-content: flex-end; margin: 4px 0 0; font-size: 11px; font-weight: 600;
    color: var(--muted);
}

/* =============================================================================
   12. EL REPARTO — el corazón del único camino para cargar producción
   -----------------------------------------------------------------------------
   Regla 27: la posición incompleta se completa PRIMERO y el excedente abre la
   siguiente. La pantalla propone el reparto y deja cambiarlo; por eso cada
   renglón muestra de dónde salió la propuesta.
   ========================================================================== */
.pd-ui .pd-rep { display: flex; flex-direction: column; gap: 8px; }
.pd-ui .pd-rep-row {
    display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
    border: 1px solid var(--hair); border-radius: 11px; padding: 9px 12px;
}
.pd-ui .pd-rep-row.arr { border-color: var(--warn-hair); background: var(--warn-050); }
.pd-ui .pd-rep-row.nueva { border-style: dashed; }
.pd-ui .pd-rep-row .pn { font-size: 17px; font-weight: 700; color: var(--navy); line-height: 1; min-width: 34px; }
.pd-ui .pd-rep-row .q { min-width: 0; flex: 1; }
.pd-ui .pd-rep-row .q .t { font-size: 12.5px; font-weight: 600; }
.pd-ui .pd-rep-row .q .d { font-size: 11px; color: var(--muted); margin-top: 1px; }
.pd-ui .pd-rep-row.arr .q .d { color: var(--warn); font-weight: 600; }
.pd-ui .pd-rep-row .pd-in { width: 116px; flex: none; }
.pd-ui .pd-rep-row .pd-sel { width: 190px; flex: none; }

/* La fila de imputación de azúcar (MP → PT). */
.pd-ui .pd-mp-row {
    display: flex; align-items: center; gap: 11px;
    border: 1px solid var(--hair); border-radius: 11px; padding: 9px 12px;
}
.pd-ui .pd-mp-row.hab { border-color: var(--ok-hair); background: var(--ok-050); }
.pd-ui .pd-mp-row.ajena { border-color: var(--warn-hair); background: var(--warn-050); }
.pd-ui .pd-mp-row .q { min-width: 0; flex: 1; }
.pd-ui .pd-mp-row .cod { font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pd-ui .pd-mp-row .a { font-size: 11px; color: var(--muted); }
.pd-ui .pd-mp-row .pd-in { width: 116px; flex: none; }
.pd-ui .pd-marca {
    display: inline-block; font-size: 9px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; padding: 2px 6px; border-radius: 5px;
    border: 1px solid var(--hair-strong); color: var(--muted); background: var(--surface);
}
.pd-ui .pd-marca.ok   { border-color: var(--ok-hair);   color: var(--ok);   background: var(--ok-050); }
.pd-ui .pd-marca.warn { border-color: var(--warn-hair); color: var(--warn); background: var(--warn-050); }
.pd-ui .pd-marca.crit { border-color: var(--crit-hair); color: var(--crit); background: var(--crit-050); }

/* =============================================================================
   EL BUSCADOR DE PRODUCTO — con la foto, porque así se reconoce
   -----------------------------------------------------------------------------
   Los PT de Moyco se distinguen por el envase antes que por el nombre: «Azúcar
   1 kg Azucel» y «Azúcar 1 kg M&K» se leen casi igual y el paquete no se
   confunde nunca. Por eso acá no va el buscador genérico —que muestra una
   línea de texto y un pedazo del id— sino una lista con la imagen del
   producto. Y de paso resuelve de raíz el recorte: es una lista EN el modal,
   no un desplegable flotante que un `overflow` pueda cortar.
   ========================================================================== */
.pd-ui .pd-artgrid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    max-height: 268px; overflow-y: auto;
    margin-top: 8px; padding: 2px;
}
@media (max-width: 620px) { .pd-ui .pd-artgrid { grid-template-columns: 1fr; } }
.pd-ui .pd-artopt {
    display: flex; align-items: center; gap: 10px; width: 100%;
    border: 1px solid var(--hair); border-radius: 11px; padding: 7px 10px 7px 7px;
    background: var(--surface); font: inherit; text-align: left; cursor: pointer;
    transition: border-color .15s var(--curva), background .15s var(--curva), transform .15s var(--curva);
}
.pd-ui .pd-artopt:hover, .pd-ui .pd-artopt:focus-visible {
    border-color: var(--navy-300); background: var(--navy-050); transform: translateY(-1px); outline: none;
}
.pd-ui .pd-artopt img, .pd-ui .pd-artopt .noimg {
    width: 42px; height: 42px; flex: none; object-fit: contain;
    border-radius: 8px; border: 1px solid var(--hair); background: var(--surface);
}
.pd-ui .pd-artopt .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-artopt .q { min-width: 0; }
.pd-ui .pd-artopt .n { font-size: 12.5px; font-weight: 700; line-height: 1.25; }
.pd-ui .pd-artopt .c { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Elegido: la ficha, con el botón de cambiarlo al lado. */
.pd-ui .pd-artelegido {
    display: flex; align-items: center; gap: 11px;
    border: 1px solid var(--ok-hair); background: var(--ok-050);
    border-radius: 11px; padding: 8px 12px 8px 8px;
}
.pd-ui .pd-artelegido img, .pd-ui .pd-artelegido .noimg {
    width: 46px; height: 46px; flex: none; object-fit: contain;
    border-radius: 9px; border: 1px solid var(--ok-hair); background: var(--surface);
}
.pd-ui .pd-artelegido .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-artelegido .q { min-width: 0; flex: 1; }
.pd-ui .pd-artelegido .n { font-size: 13.5px; font-weight: 700; }
.pd-ui .pd-artelegido .c { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* =============================================================================
   LOS LOTES DE UNA POSICIÓN — una lista, no una tabla
   -----------------------------------------------------------------------------
   Estaban como filas de tabla con las acciones apretadas en la última celda,
   partiéndose en dos renglones y todas del mismo tamaño: no se sabía cuál era
   la que se usa. Acá cada lote es un bloque con sus datos a la izquierda y sus
   acciones a la derecha, y hay UNA principal —cargarle kilos, que es a lo que
   se entra— con el resto en trazo fino. Es el §«una acción principal por
   momento» aplicado adentro de la fila.
   ========================================================================== */
.pd-ui .pd-lotes { display: flex; flex-direction: column; gap: 9px; }
.pd-ui .pd-lote {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    border: 1px solid var(--hair); border-radius: 12px; padding: 12px 14px;
    background: var(--surface);
}
.pd-ui .pd-lote.espera { border-color: var(--navy-300); background: var(--navy-050); }
.pd-ui .pd-lote.ajeno  { background: var(--canvas); }
.pd-ui .pd-lote .q { min-width: 170px; flex: 1; }
.pd-ui .pd-lote .cod {
    font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums;
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pd-ui .pd-lote .cifras { display: flex; gap: 18px; margin-top: 5px; }
.pd-ui .pd-lote .cifras .d .dl {
    font-size: 9px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--faint);
}
.pd-ui .pd-lote .cifras .d .dv { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pd-ui .pd-lote .acc { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }

/* La ficha de la posición dentro de su modal. Va sobre el lienzo y con su
   filete de estado: es el encabezado del documento que se está mirando, no un
   renglón más — y sin eso el modal arrancaba plano y todo pesaba igual. */
.pd-ui .pd-ficha { display: flex; gap: 14px; align-items: flex-start; }
.pd-ui .pd-ficha.destacada {
    background: var(--canvas); border: 1px solid var(--hair);
    border-left: 3px solid var(--navy-300);
    border-radius: 12px; padding: 14px;
}
.pd-ui .pd-ficha.destacada.ok   { border-left-color: var(--ok); }
.pd-ui .pd-ficha.destacada.warn { border-left-color: var(--warn); }
.pd-ui .pd-ficha img, .pd-ui .pd-ficha .noimg {
    width: 64px; height: 64px; flex: none; object-fit: contain;
    border: 1px solid var(--hair); border-radius: 12px; background: var(--surface);
}
.pd-ui .pd-ficha .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-ficha .q { min-width: 0; flex: 1; }
.pd-ui .pd-ficha .art { font-size: 15px; font-weight: 700; }
.pd-ui .pd-ficha .lote { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.pd-ui .pd-ficha .kg { font-size: 22px; font-weight: 700; margin-top: 6px; letter-spacing: -.02em; }
.pd-ui .pd-ficha .kg small { font-size: 12px; color: var(--muted); font-weight: 600; }
.pd-ui .pd-leyenda { display: flex; gap: 16px; margin-top: 8px; font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.pd-ui .pd-leyenda .sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }
.pd-ui .pd-leyenda .sw.ayer { background: var(--navy-300); opacity: .45; }
.pd-ui .pd-leyenda .sw.hoy  { background: var(--navy); }

/* El esqueleto de la espera: cuatro tarjetas, que es lo primero que aparece
   desde la ronda 6 —la banda de tolvas—, y con SU alto real. Declarar una forma
   obliga a que mida lo que va a medir (§5 del manual): un esqueleto más bajo
   que el contenido hace saltar la pantalla justo cuando llega. El banco lo mide
   contra la tarjeta REAL en vez de creerle a este número. */
.pd-ui .pd-sk-card {
    border: 1px solid var(--hair);
    border-radius: var(--r-card); background: var(--surface);
    padding: 14px 16px 13px; height: 700px; box-sizing: border-box;   /* 345 → 520 (ronda 7-B) → 700 (ronda 12: el pulso por máquina + el medidor) */
    display: flex; flex-direction: column; gap: 11px;
}

/* =============================================================================
   LAS CUATRO TOLVAS — LA PORTADA (ronda 6, §3 ter, 12/08/2026)
   -----------------------------------------------------------------------------
   Hasta la ronda 5 una línea era un RENGLÓN del carril («sanas son un punto,
   sólo la excepción habla») y la vista completa de las tolvas era una segunda
   pantalla. Hernán lo dio vuelta: una tarjeta por tolva ARRIBA DE TODO, con sus
   dos envasadoras como baldosas y su balanza al pie, y un clic en una máquina
   abre su pantalla completa. Acá vivían `.pd-lins` / `.pd-lin`, que se fueron
   con el carril.

   El color es del ESTADO, nunca de la categoría: verde produce, rojo detenida,
   ámbar fuera de servicio, gris sin usar. Ningún token nuevo.
   ========================================================================== */
.pd-ui .pd-banda { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
/* `min-width: 0` NO ES DECORACIÓN: el mínimo automático de un ítem de grid es
   su contenido, así que sin esto la columna se ESTIRA hasta que entre el nombre
   de producto más largo y la banda desborda la pantalla. Trampa ya pagada. */
.pd-ui .pd-banda > * { min-width: 0; }
@media (max-width: 1180px) { .pd-ui .pd-banda { grid-template-columns: 1fr 1fr; } }
@media (max-width: 660px)  { .pd-ui .pd-banda { grid-template-columns: 1fr; } }

.pd-ui .pd-tolvac {
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow);
    display: flex; flex-direction: column; min-width: 0; overflow: hidden;
}
/* La cabecera lleva lo COMPARTIDO por el par: producto y maquinista son de la
   MÁQUINA (regla 7), así que sólo suben acá cuando las dos coinciden.
   -----------------------------------------------------------------------------
   VA EN CINTA NAVY, y el motivo no es decorativo: la tarjeta es una PILA de
   cosas distintas —el par arriba, las dos máquinas, la balanza al pie— y con
   todo sobre blanco separado por filetes de un píxel, las cuatro columnas se
   leían como un solo bloque plano. La cinta le devuelve el rótulo a la tarjeta.
   Es el patrón que ya usa la ficha de Comerciales (`--navy` + `#fff`, los
   secundarios por opacidad) — ningún token nuevo.
   NO COMPITE CON EL COLOR DE ESTADO: navy no es ninguno de los cuatro (verde
   produce, rojo detenida, ámbar fuera de servicio, gris sin usar), así que el
   filete de la baldosa sigue siendo lo único que dice cómo está la máquina.
   Acá el color es ESTRUCTURA, igual que en la barra lateral.
   Se probó contra una variante TEÑIDA (`--navy-050` con filete navy arriba) y
   se descartó mirándolas juntas: al lado de la sólida casi no se despega del
   blanco, que es justo lo que había que arreglar.  */
.pd-ui .pd-tolvac > .th {
    display: flex; align-items: center; gap: 9px; min-width: 0;
    padding: 9px 12px;
    background: var(--navy); color: #fff;
    border-bottom: 1px solid var(--navy);
}
.pd-ui .pd-tolvac > .th .nom { font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; }
.pd-ui .pd-tolvac > .th img,
.pd-ui .pd-tolvac > .th .noimg {
    width: 26px; height: 26px; flex: none; object-fit: contain;
    /* El borde del hairline gris desaparece sobre navy: sobre oscuro el trazo
       que separa la foto del fondo tiene que ser claro, no más oscuro todavía. */
    border: 1px solid rgba(255, 255, 255, .28); border-radius: 7px; background: var(--surface);
}
.pd-ui .pd-tolvac > .th .noimg { display: flex; align-items: center; justify-content: center; color: var(--hair-strong); }
.pd-ui .pd-tolvac > .th .q { min-width: 0; flex: 1; }
.pd-ui .pd-tolvac > .th .pr { font-size: 12px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Los secundarios van por OPACIDAD y no por un gris: `--muted` y `--faint` son
   grises calculados para leerse sobre BLANCO y sobre navy quedan turbios. */
.pd-ui .pd-tolvac > .th .op { font-size: 11px; opacity: .82; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ui .pd-tolvac > .th .dim { color: inherit; opacity: .78; }
.pd-ui .pd-tolvac > .th .pr.dim { font-style: italic; font-weight: 500; opacity: .8; }


/* La acción del par, en su propio renglón: en la cabecera no entraba. */
.pd-ui .pd-tolvac > .acc { padding: 0 12px 10px; }
.pd-ui .pd-tolvac > .acc .pd-btn { width: 100%; }

/* LA BALDOSA DE UNA MÁQUINA. El filete de la izquierda es del estado — el mismo
   recurso que usa la posición en la playa. */
.pd-ui .pd-maq {
    display: flex; flex-direction: column; gap: 6px; width: 100%; min-width: 0;
    padding: 9px 12px; text-align: left; font: inherit; color: inherit; cursor: pointer;
    background: none; border: 0; border-left: 3px solid var(--hair-strong);
    transition: background .15s var(--curva);
}
.pd-ui .pd-maq + .pd-maq { border-top: 1px solid var(--hair); }
.pd-ui .pd-maq:hover, .pd-ui .pd-maq:focus-visible { background: var(--navy-050); outline: none; }
.pd-ui .pd-maq:focus-visible { box-shadow: inset 0 0 0 2px var(--navy-500); }
.pd-ui .pd-maq.ok  { border-left-color: var(--ok); }
.pd-ui .pd-maq.det { border-left-color: var(--crit); }
.pd-ui .pd-maq.fs  { border-left-color: var(--warn); background: var(--canvas); }
.pd-ui .pd-maq.off { opacity: .75; }
.pd-ui .pd-maq .top { display: flex; align-items: baseline; gap: 8px; min-width: 0; }

/* UNA LÍNEA DETENIDA SE VE DE LEJOS — pedido de Hernán al votar la ronda 6. Es
   el mismo recurso que la posición completa de la playa: banda RELLENA, no un
   filete. Blanco sobre `--crit` da 5,9 : 1 y pasa AA. Y es del ESTADO —«está
   parada AHORA»—, no de una categoría, así que no rompe la regla 1.1.
   SE LA QUEDA SÓLO LA DETENIDA: si «fuera de servicio» y «no se usa hoy»
   también se tiñeran, ninguno de los tres se vería, que es justo lo que la
   banda viene a evitar. */
.pd-ui .pd-maq.det .top {
    margin: -9px -12px 0; padding: 9px 12px;
    background: var(--crit); align-items: center;
}
.pd-ui .pd-maq.det .top .nn, .pd-ui .pd-maq.det .top .fr { color: #fff; }
.pd-ui .pd-maq.det .top .pd-marca { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .38); color: #fff; }
.pd-ui .pd-maq.det:hover, .pd-ui .pd-maq.det:focus-visible { background: var(--crit-050); }

.pd-ui .pd-maq .nn { font-size: 13px; font-weight: 700; color: var(--navy); flex: none; }
.pd-ui .pd-maq .fr {
    font-size: 12.5px; flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pd-ui .pd-maq .fr.ok  { color: var(--ok);   font-weight: 600; }
.pd-ui .pd-maq .fr.det { color: var(--crit); font-weight: 600; }
.pd-ui .pd-maq .fr.fs  { color: var(--warn); font-weight: 600; }
.pd-ui .pd-maq .fr.off { color: var(--faint); font-style: italic; }
.pd-ui .pd-maq .sub { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* LA CINTA DE LA JORNADA (ronda 11, propuesta A — 19/08/2026). Diez píxeles de
   estado minuto a minuto, y su frase debajo.
   -----------------------------------------------------------------------------
   `line-height: 0` en el contenedor del SVG: un `<svg>` es `inline` por defecto
   y el navegador le reserva el descuelgue de una línea de texto, así que sin
   esto la cinta arrastra 4 px de aire abajo y las ocho baldosas dejan de
   alinearse entre sí. El SVG ya viene con `display:block`, pero el hueco lo pone
   la CAJA, no el elemento. */
.pd-ui .pd-maq .cinta { line-height: 0; margin: 1px 0 0; }
.pd-ui .pd-maq .cinta svg { border-radius: 2px; }
.pd-ui .pd-maq .cinta .pie {
    line-height: 1.3; font-size: 9.5px; color: var(--faint); margin-top: 3px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Las cifras son una GRILLA de tres y no un renglón flexible: con `flex-wrap`
   cada máquina rompía en un lugar distinto según el largo de sus números y las
   ocho baldosas dejaban de alinearse entre sí.
   `align-items: start` y no `end`: las celdas tienen distinta cantidad de
   renglones —el contador trae su procedencia debajo, los golpes no— y alineadas
   al pie los RÓTULOS quedaban a tres alturas distintas dentro de la misma fila. */
.pd-ui .pd-maq .cnt { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px 10px; align-items: start; }
.pd-ui .pd-maq .cnt .d { min-width: 0; }
.pd-ui .pd-maq .cnt .dl { font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.pd-ui .pd-maq .cnt .dv { font-size: 12px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }

/* EL RITMO DE AHORA (ronda 12, tarjeta A — 19/08/2026): el último minuto medido,
   con su hora. El punto late sólo con la máquina leyendo; el cuerpo queda por
   debajo del techo de KPI (nada de números gigantes) porque el display de la
   pantalla sigue siendo uno solo, el peso de la balanza. */
.pd-ui .pd-maq .ritmo { display: flex; align-items: baseline; gap: 7px; min-width: 0; margin-top: 1px; }
.pd-ui .pd-maq .ritmo .lat { width: 7px; height: 7px; border-radius: 999px; background: var(--ok);
    align-self: center; flex: none; }
.pd-ui .pd-maq .ritmo .v { font-size: 17px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; flex: none; }
.pd-ui .pd-maq .ritmo .v small { font-size: 10.5px; font-weight: 600; color: var(--muted); }
.pd-ui .pd-maq .ritmo .cons { font-size: 10px; color: var(--faint); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (prefers-reduced-motion: no-preference) {
    .pd-ui .pd-maq .ritmo .lat { animation: pd-lat 1.6s var(--curva) infinite; }
    @keyframes pd-lat { 50% { opacity: .25; } }
}

/* EL MEDIDOR «REAL CONTRA LO PACTADO» (§4 del manual, ronda 12): la media de la
   balanza contra el nominal, y los tres factores de la ficha. El cero/objetivo
   es la marca de tinta; la banda es la tolerancia; la aguja es el dato. */
.pd-ui .pd-gau { margin-top: 7px; min-width: 0; }
.pd-ui .pd-gau .head { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; min-width: 0; }
.pd-ui .pd-gau .big { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.pd-ui .pd-gau .big small { font-size: 10.5px; font-weight: 600; color: var(--muted); }
.pd-ui .pd-gau .x { font-size: 10.5px; color: var(--muted); min-width: 0; }
.pd-ui .pd-gau .x.kg { margin-left: auto; text-align: right; }
.pd-ui .pd-gau .track { position: relative; height: 8px; border-radius: 999px;
    background: var(--surface); border: 1px solid var(--hair-strong); margin-top: 5px; }
.pd-ui .pd-gau .band { position: absolute; top: 0; bottom: 0; background: var(--ok-050); }
.pd-ui .pd-gau .fill { position: absolute; top: 0; bottom: 0; border-radius: 999px; background: var(--navy-300); }
.pd-ui .pd-gau .fill.okc { background: var(--ok); }
.pd-ui .pd-gau .fill.wrn { background: var(--warn); }
.pd-ui .pd-gau .mark { position: absolute; top: -4px; width: 2px; height: 15px; background: var(--ink); }
.pd-ui .pd-gau .scale { display: flex; justify-content: space-between; gap: 8px;
    font-size: 9px; color: var(--faint); margin-top: 3px; font-variant-numeric: tabular-nums; }

/* Los tres factores de la ficha (ronda 12): tres medidores, un renglón. */
.pd-ui .pd-g3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 700px) { .pd-ui .pd-g3 { grid-template-columns: 1fr; } }

/* EL PIE: LA BALDOSA DE LA BALANZA (ronda 7-B, 14/08/2026). Es del par, así que
   entra exactamente una por tarjeta. `margin-top:auto` la clava abajo aunque una
   tolva tenga la baldosa más corta — si no, las cuatro quedan a cuatro alturas.
   -----------------------------------------------------------------------------
   EL PESO Y LA CAMPANA VAN EN UN RENGLÓN —los dos hablan de gramos— y el RELOJ
   abajo a lo ancho, porque habla de horas. Puestos los tres juntos, el reloj se
   parte en dos filas y deja de leerse: una columna de la banda mide ~340 px. */
.pd-ui .pd-bal {
    margin-top: auto; width: 100%; min-width: 0; display: block;
    text-align: left; font: inherit; color: inherit;
    border: 0; border-top: 1px solid var(--hair);
    background: var(--canvas); padding: 9px 12px 10px;
    transition: background .15s var(--curva);
}
.pd-ui button.pd-bal { cursor: pointer; }
.pd-ui button.pd-bal:hover, .pd-ui button.pd-bal:focus-visible { background: var(--navy-050); outline: none; }
.pd-ui .pd-bal .tt { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pd-ui .pd-bal .material-symbols-outlined { font-size: 18px; color: var(--muted); flex: none; }
.pd-ui .pd-bal .tt .nn { font-size: 11px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--faint); }
.pd-ui .pd-bal .nota { font-size: 11px; color: var(--muted); margin-top: 4px; line-height: 1.35; }

/* EL PESO EN VIVO ES UN DISPLAY, NO UN KPI: es el único número de la pantalla
   que cambia solo, y el color es del ESTADO de la balanza. Por eso dobla la
   regla de «nada de números gigantes» — y por eso está escrito acá. */
.pd-ui :is(.pd-bal, .pd-balmod) .peso { display: flex; align-items: flex-end; justify-content: space-between;
    gap: 10px; margin: 3px 0 2px; }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo { min-width: 0; flex: 1; }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo .n { font-size: 26px; font-weight: 700; letter-spacing: -.02em;
    line-height: 1.1; font-variant-numeric: tabular-nums; }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo .n small { font-size: 12px; font-weight: 600; color: var(--muted); }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo .e { font-size: 11px; color: var(--muted); margin-top: 1px; }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.ok .n      { color: var(--ok); }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.pesando .n { color: var(--navy); }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.pesando .e { color: var(--navy-500); font-weight: 600; }
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.desvio .n  { color: var(--warn); }
/* «Libre» y «Sin señal» NO son cifras: no pueden tener el cuerpo de una. */
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.libre .n,
.pd-ui :is(.pd-bal, .pd-balmod) .vivo.muda .n { font-size: 17px; color: var(--faint); font-style: italic; letter-spacing: 0; }

/* La campana vive en el MODAL de la balanza desde la ronda 12 (la baldosa la
   cambió por el medidor de la media); las reglas quedan por si un día vuelve. */
.pd-ui :is(.pd-bal, .pd-balmod, .pd-bloque) .campana { flex: none; max-width: 100%; }
.pd-ui :is(.pd-bal, .pd-balmod, .pd-bloque) .campana.vacia { width: 96px; font-size: 9.5px; color: var(--faint);
    font-style: italic; line-height: 1.25; text-align: center;
    border: 1px dashed var(--hair-strong); border-radius: 4px; padding: 6px 4px; }
.pd-ui :is(.pd-bal, .pd-balmod, .pd-bloque) .campana.vacia span { color: var(--hair-strong); }

/* EL MODAL DE LA BALANZA DEL PAR (ronda 12-B): la deriva se corre con el dedo,
   como el resto de los gráficos anchos; la campana comparte renglón con ella
   en escritorio y se apila en angosto. */
.pd-ui .pd-balmod .peso { align-items: center; }
.pd-ui .pd-der { overflow-x: auto; line-height: 0; }
.pd-ui .pd-der svg { min-width: 560px; }
.pd-ui .pd-g2der { display: grid; grid-template-columns: 1fr 320px; gap: 14px; align-items: start; }
/* Sin `min-width: 0` el mínimo del ítem es su contenido, así que la columna de
   la deriva se estira hasta los 560 px del SVG y el modal entero desborda el
   celular con los textos recortados. Trampa ya pagada, otra vez. */
.pd-ui .pd-g2der > * { min-width: 0; }
@media (max-width: 820px) { .pd-ui .pd-g2der { grid-template-columns: 1fr; } }

.pd-ui .pd-bal .cnt { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px 10px; margin-top: 6px; }
.pd-ui .pd-bal .cnt .d { min-width: 0; }
.pd-ui .pd-bal .dl { font-size: 9px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--faint); }
.pd-ui .pd-bal .dv { font-size: 15px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.pd-ui .pd-bal .dv .u { font-size: 10.5px; font-weight: 600; color: var(--muted); }
.pd-ui .pd-bal .dv .aus { color: var(--faint); font-weight: 600; }
.pd-ui .pd-bal .ds { font-size: 10px; color: var(--muted); margin-top: 1px; line-height: 1.3; }
.pd-ui .pd-bal .pd-reloj { margin-top: 9px; }
.pd-ui .pd-bal .pie { font-size: 11px; color: var(--navy-500); font-weight: 700; margin-top: 7px; }
.pd-ui .pd-bal .abre { color: var(--navy-500); }

/* «No hay balanza acá» y «hay balanza y nadie controló» son dos cosas distintas
   (regla 47): la ausencia se dice en gris y sin acusar a nadie. */
.pd-ui .pd-bal.muda { background: var(--canvas); }
.pd-ui .pd-bal.muda .nn { color: var(--faint); font-style: italic; font-weight: 600;
    text-transform: none; letter-spacing: 0; font-size: 12px; }
.pd-ui .pd-bal.muda .material-symbols-outlined { color: var(--hair-strong); }

/* El chip del encabezado: cuándo fue el último control. */
.pd-ui .pd-bchip { font-size: 10px; font-weight: 700; border-radius: 999px;
    padding: 2px 8px; white-space: nowrap; }
.pd-ui .pd-bchip.ok   { background: var(--ok-050);   color: var(--ok);   border: 1px solid var(--ok-hair); }
.pd-ui .pd-bchip.warn { background: var(--warn-050); color: var(--warn); border: 1px solid var(--warn-hair); }
.pd-ui .pd-bchip.crit { background: var(--crit-050); color: var(--crit); border: 1px solid var(--crit-hair); }
.pd-ui .pd-bchip.mut  { background: var(--canvas);   color: var(--faint); border: 1px solid var(--hair-strong); }

/* Las tolvas del FORMULARIO de apertura: en columna, una debajo de la otra. */
.pd-ui .pd-tolvas { display: flex; flex-direction: column; gap: 12px; }

.pd-ui .pd-tolva {
    border: 1px solid var(--hair); border-radius: 12px; background: var(--surface);
    padding: 10px 12px 12px; min-width: 0;
}
.pd-ui .pd-tolva .th {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: 12px; font-weight: 700; color: var(--ink);
    padding-bottom: 8px; margin-bottom: 8px; border-bottom: 1px solid var(--hair);
}
.pd-ui .pd-tolva .th .dim { font-weight: 600; color: var(--muted); font-size: 11px; }
.pd-ui .pd-tolva .th .pd-btn { margin-left: auto; }

/* El renglón de una máquina en un formulario (apertura, arranque). */
.pd-ui .pd-lfila { display: flex; align-items: flex-start; gap: 12px; padding: 7px 0; }
.pd-ui .pd-lfila + .pd-lfila { border-top: 1px dashed var(--hair); }
.pd-ui .pd-lfila.off { opacity: .6; }
.pd-ui .pd-lfila .q { display: flex; align-items: center; gap: 8px; width: 190px; flex: none; padding-top: 6px; }
.pd-ui .pd-lfila .q .nn {
    width: 22px; height: 22px; flex: none; border-radius: 6px;
    background: var(--canvas); border: 1px solid var(--hair);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: var(--navy);
}
.pd-ui .pd-lfila .q .nm { font-size: 12.5px; font-weight: 600; }
.pd-ui .pd-lfila .w { flex: 1; min-width: 0; }
@media (max-width: 640px) {
    .pd-ui .pd-lfila { flex-direction: column; gap: 4px; }
    .pd-ui .pd-lfila .q { width: auto; padding-top: 0; }
}

/* La fila del formulario de arranque: tilde + campos. */
.pd-ui .pd-mrow { border: 1px solid var(--hair); border-radius: 11px; padding: 9px 12px; }
.pd-ui .pd-mrow + .pd-mrow { margin-top: 8px; }
.pd-ui .pd-mrow.off { background: var(--canvas); }
.pd-ui .pd-mrow .cab { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12.5px; font-weight: 600; }
.pd-ui .pd-mrow .cab .nn { font-weight: 700; color: var(--navy); }
.pd-ui .pd-mrow .campos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 9px; }
.pd-ui .pd-mrow .campos .pd-campo:first-child { grid-column: 1 / -1; }
@media (max-width: 640px) { .pd-ui .pd-mrow .campos { grid-template-columns: 1fr; } }

/* =============================================================================
   LA PANTALLA COMPLETA DE UNA MÁQUINA — la ficha (ronda 6)
   -----------------------------------------------------------------------------
   «Clic en una máquina → pantalla completa con toda la info que tengamos de
   ella» (Hernán, 12/08/2026). Es el mismo vocabulario del resto del módulo:
   bloques con su rótulo, cuadraditos de cifra y una ficha de dos columnas. Lo
   que todavía no existe tiene su bloque igual, diciendo CUÁNDO.
   ========================================================================== */
.pd-ui .pd-g4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.pd-ui .pd-g2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pd-ui .pd-g4 > *, .pd-ui .pd-g2 > * { min-width: 0; }
@media (max-width: 820px) { .pd-ui .pd-g4 { grid-template-columns: 1fr 1fr; } .pd-ui .pd-g2 { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .pd-ui .pd-g4 { grid-template-columns: 1fr; } }

.pd-ui .pd-bloque {
    border: 1px solid var(--hair); border-radius: 12px;
    padding: 12px 14px; min-width: 0; margin-top: 14px;
}
.pd-ui .pd-bloque .pd-subt { margin-bottom: 8px; }
.pd-ui .pd-g2 .pd-bloque { margin-top: 0; }

.pd-ui .pd-tile {
    border: 1px solid var(--hair); border-radius: 12px;
    padding: 10px 12px; background: var(--surface); min-width: 0;
}
.pd-ui .pd-tile .l { font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.pd-ui .pd-tile .v { font-size: 15px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; margin-top: 2px; overflow-wrap: anywhere; }
.pd-ui .pd-tile .v .ok  { color: var(--ok); }
.pd-ui .pd-tile .v .det { color: var(--crit); }
.pd-ui .pd-tile .v .fs  { color: var(--warn); }
.pd-ui .pd-tile .s { font-size: 11px; color: var(--muted); margin-top: 3px; line-height: 1.35; }
.pd-ui .pd-tile.crit { border-color: var(--crit-hair); background: var(--crit-050); }
.pd-ui .pd-tile.warn { border-color: var(--warn-hair); background: var(--warn-050); }

/* =============================================================================
   LA FICHA CON RELIEVE — propuesta A de la ronda 13, votada el 20/08/2026
   -----------------------------------------------------------------------------
   La lámina es `docs/produccion-dia/25-ronda13-ficha-envasadora-jerarquia.html`.
   El reclamo que la ordena, textual: «amén de los gráficos, el resto del modal
   es en un solo color y está todo como en la misma jerarquía».
   Y era literal: cuerpo blanco, ocho bloques blancos, veinte baldosas blancas
   separadas por un pelo de `--hair`, todos los rótulos del mismo gris y **todas
   las cifras a 15 px** — los golpes del turno y la MAC del PLC pesaban igual.

   TRES COSAS, Y NINGUNA INVENTA UN COLOR (la paleta sigue saliendo entera de
   tokens.css, §6 del manual):

   1. FIGURA Y FONDO. El cuerpo del modal se pinta de `--canvas` y los bloques
      flotan encima en `--surface` con `--e1`. Hoy bloque y fondo son el mismo
      blanco, así que lo único que los separa es el trazo — y con ocho bloques
      seguidos ese trazo deja de leerse como un borde y pasa a ser un renglón.
   2. TRES ALTURAS DE TIPOGRAFÍA, no una: `--dato` (26 px) para la cifra de la
      jornada, los 15 px del `.pd-tile` para el dato de bloque, 11 px para la
      nota. Una jerarquía se hace con una escala; sin escala, el color de estado
      tampoco resalta (un tile ámbar entre veinte idénticos es un tile más).
   3. CADA BLOQUE DICE SU ESTADO EN LA CABECERA («1 sin explicar», «falta la
      consigna»), así que se sabe dónde hay algo que hacer ANTES de llegar.

   EL NAVY RELLENO DE LA CABECERA NO ES UN RECURSO NUEVO: es exactamente el de
   la tarjeta de tolva (`.pd-tcab`) de la pantalla de atrás. Y de paso resuelve
   por diseño que la ficha abra por arriba, que era el otro reclamo.
   ========================================================================== */
/* `display: block` NO ES DECORACIÓN, y esto lo destapó el banco a 390 px.
   El cuerpo del modal resuelve a `display: flex`, y un ítem flex NO SE ENCOGE
   POR DEBAJO DE SU `min-content`: el `<div>` de la ficha se plantaba en 375 px
   dentro de un cuerpo de 354 y la ficha se salía 21 px del celular. Es la misma
   trampa del `min-width: 0` de siempre, por la puerta del contenedor. Se
   arreglan las dos puntas —el cuerpo vuelve a ser un bloque y el hijo declara
   que puede encogerse— porque cualquiera de las dos sola se puede perder en un
   refactor y el síntoma tarda meses en volver a aparecer. */
.pd-ui .pd-mob.pd-ficha { padding: 0; background: var(--canvas); display: block; }
.pd-ui .pd-mob.pd-ficha > * { min-width: 0; max-width: 100%; }

.pd-ui .pd-hero { background: var(--navy); color: #fff; padding: 12px 20px 14px; }
.pd-ui .pd-hero .f1 { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
/* UN `flex` PARTE LA ORACIÓN, y a 390 px esto se paga: un hijo de texto no se
   encoge por debajo de su `min-content` sin `min-width: 0`, así que la frase de
   la línea —que puede ser «Parada desde las 09:12 · Falta de azúcar en tolva»—
   empujaba la cabecera 21 px fuera del celular. Lo agarró el banco, no el ojo. */
.pd-ui .pd-hero .f1 > * { min-width: 0; }
.pd-ui .pd-hero .pd-marca { flex: none; }
.pd-ui .pd-hero .est { font-size: 14.5px; font-weight: 700; letter-spacing: -.01em; overflow-wrap: anywhere; }
.pd-ui .pd-hero .des { font-size: 11.5px; color: rgba(255, 255, 255, .72); min-width: 0; overflow-wrap: anywhere; }
/* Las marcas de adentro del navy se re-tiñen enteras: un `.pd-marca` con su
   fondo blanco sobre el navy es un parche, y uno `warn` sobre navy no se lee. */
.pd-ui .pd-hero .pd-marca { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .34); color: #fff; flex: none; }
.pd-ui .pd-hero .pd-vacio { color: rgba(255, 255, 255, .6); }
.pd-ui .pd-hero .cifras { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 11px; }
.pd-ui .pd-hero .cifras > * { min-width: 0; }
/* EN DOS COLUMNAS LA CELDA MIDE 160 px Y LA CIFRA NO ENTRA. Sin esto se pasaba
   tres píxeles por celda —«6 h 47 m» a 24 px no envuelve— y esos tres píxeles
   se propagan como `scrollWidth` hasta el cuerpo del modal: veintiún píxeles de
   ficha fuera del celular. La cifra baja a 20 px y se permite partir. */
@media (max-width: 640px) {
    .pd-ui .pd-hero .cifras { grid-template-columns: 1fr 1fr; }
    .pd-ui .pd-hero .pd-dato { font-size: 20px; }
}
.pd-ui .pd-hero .pd-cifra { min-width: 0; }
.pd-ui .pd-hero .pd-dato,
.pd-ui .pd-hero .s { overflow-wrap: anywhere; }
/* LA MISMA PIEZA `dato()` QUE USAN LOS BLOQUES, re-teñida por el navy. Que sea
   la misma es el punto: la cifra de la cabecera y la del bloque de paradas
   tienen que pesar igual, o la escala de tres alturas no existe. */
.pd-ui .pd-hero .pd-rot { color: rgba(255, 255, 255, .6); font-size: 9px; }
.pd-ui .pd-hero .pd-dato { font-size: 24px; }
.pd-ui .pd-hero .pd-dato small { color: rgba(255, 255, 255, .68); }
.pd-ui .pd-hero .s { font-size: 10px; color: rgba(255, 255, 255, .62); line-height: 1.3; }
/* La cifra que duele va en rojo CLARO, no en `--crit`: el crit del maestro está
   pensado sobre blanco y sobre navy queda casi negro. */
.pd-ui .pd-hero .pd-dato.mal { color: #ffb3b3; }
.pd-ui .pd-hero .pd-dato.mal small { color: rgba(255, 179, 179, .8); }
/* EL PUNTO QUE LATE es el mismo de la baldosa: verde claro para que se vea
   sobre navy, y quieto si el sistema pide menos movimiento. */
.pd-ui .pd-hero .lat { width: 8px; height: 8px; border-radius: 99px; background: #69d6a6; flex: none; }
@media (prefers-reduced-motion: no-preference) {
    .pd-ui .pd-hero .lat { animation: pdLat 1.6s var(--curva) infinite; }
    @keyframes pdLat { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
}
/* LA CINTA DE LA JORNADA — marcha / parada / sin dato, a lo ancho. Es el mismo
   reparto que el gráfico dibuja minuto a minuto, en una sola línea: contesta
   «¿cómo viene el día?» sin leer un solo número. */
.pd-ui .pd-hero .cinta { display: flex; height: 6px; border-radius: 99px; overflow: hidden;
    margin-top: 11px; background: rgba(255, 255, 255, .16); }
.pd-ui .pd-hero .cinta i { display: block; height: 100%; }
.pd-ui .pd-hero .cintal { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
    font-size: 9.5px; color: rgba(255, 255, 255, .6); margin-top: 3px; }

.pd-ui .pd-fcuerpo { padding: 14px 20px 20px; display: flex; flex-direction: column; gap: 12px; }
.pd-ui .pd-bl {
    background: var(--surface); border: 1px solid var(--hair); border-radius: 12px;
    box-shadow: var(--e1); overflow: hidden; min-width: 0;
}
.pd-ui .pd-blh {
    display: flex; align-items: center; gap: 9px; padding: 9px 13px;
    border-bottom: 1px solid var(--hair);
}
.pd-ui .pd-blh .material-symbols-outlined { font-size: 17px; color: var(--navy-500); flex: none; }
.pd-ui .pd-blh .tt { font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; flex: 1; min-width: 0; }
.pd-ui .pd-blh .estado { font-size: 10.5px; font-weight: 600; color: var(--muted); text-align: right; }
.pd-ui .pd-blc { padding: 12px 13px 13px; }
/* EL BLOQUE QUE PIDE ALGO se pinta; el que sólo informa, no. Si se tiñeran
   todos volveríamos al punto de partida con otro color. */
.pd-ui .pd-bl.alerta { border-left: 3px solid var(--warn); }
.pd-ui .pd-bl.alerta .pd-blh { background: var(--warn-050); border-bottom-color: var(--warn-hair); }
.pd-ui .pd-bl.alerta .pd-blh .material-symbols-outlined,
.pd-ui .pd-bl.alerta .pd-blh .estado { color: var(--warn); }
.pd-ui .pd-bl.grave { border-left: 3px solid var(--crit); }
.pd-ui .pd-bl.grave .pd-blh { background: var(--crit-050); border-bottom-color: var(--crit-hair); }
.pd-ui .pd-bl.grave .pd-blh .material-symbols-outlined,
.pd-ui .pd-bl.grave .pd-blh .estado { color: var(--crit); }

/* LA CIFRA DE LA JORNADA — el escalón que faltaba entre el tile de 15 px y la
   nota de 11. Va SUELTA, sin caja: si además llevara borde volvería a ser un
   tile, y lo que la hace pesar es el tamaño, no el marco. */
.pd-ui .pd-rot { font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.pd-ui .pd-dato { font-size: 26px; font-weight: 700; letter-spacing: -.025em; line-height: 1.05;
    font-variant-numeric: tabular-nums; }
.pd-ui .pd-dato small { font-size: 12px; font-weight: 600; color: var(--muted); letter-spacing: 0; }
.pd-ui .pd-dato.wrn { color: var(--warn); }
.pd-ui .pd-dato.mal { color: var(--crit); }
.pd-ui .pd-dato.chico { font-size: 19px; }
.pd-ui .pd-dato + .s { font-size: 11px; color: var(--muted); line-height: 1.35; }

/* EL RENGLÓN DE LAS MICRO-PARADAS — lo que reemplaza a once renglones que
   decían «0 min · Sin explicar». Va DENTRO de la caja de la tabla y pegado
   abajo: es el pie de esa tabla, no un bloque nuevo. */
.pd-ui .pd-micro {
    display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
    padding: 8px 10px; background: var(--canvas); border-top: 1px solid var(--hair);
    font-size: 12px; color: var(--muted);
}
.pd-ui .pd-micro .material-symbols-outlined { font-size: 16px; color: var(--faint); flex: none; }
.pd-ui .pd-micro b { color: var(--ink); font-variant-numeric: tabular-nums; }
.pd-ui .pd-micro .pd-btn { margin-left: auto; }

/* ── LA LÍNEA MINUTO A MINUTO (etapa 10b) ─────────────────────────────────────
   El gráfico es un SVG con `width:100%; height:auto`, así que el panel sólo
   pone el marco y el rótulo. NADA de ancho fijo: el modal ya se salió 45 px a
   390 una vez por una columna de grid sin `min-width: 0`, y un gráfico de
   cuatrocientos minutos es justo lo que vuelve a empujar. */
.pd-ui .pd-serie { display: grid; gap: 10px; min-width: 0; }
.pd-ui .pd-serie > * { min-width: 0; }
.pd-ui .pd-serie-panel {
    border: 1px solid var(--hair); border-radius: 10px; padding: 8px 10px 4px; min-width: 0;
}
.pd-ui .pd-serie-panel .ct {
    display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 3px;
}
.pd-ui .pd-serie-panel .ct .t {
    font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--navy);
}
.pd-ui .pd-serie-panel .ct .e { font-size: 10px; color: var(--faint); font-variant-numeric: tabular-nums; }
/* EL GRAFICO SE CORRE CON EL DEDO. Escalado al ancho del modal, en un celular
   queda de 55 px de alto: las barras, las horas del eje y el rayado del hueco
   dejan de distinguirse, y un grafico que esta pero no se lee es peor que
   ninguno. `min-width: 0` en el contenedor es obligatorio — sin el, la columna
   de grid se estira hasta el contenido mas ancho y saca el modal de la
   pantalla, que es la trampa ya pagada de la ronda 6. */
.pd-ui .pd-serie-panel .plot { overflow-x: auto; min-width: 0; }
.pd-ui .pd-serie-panel .plot svg { min-width: 620px; }
.pd-ui .pd-serie-ley {
    display: flex; flex-wrap: wrap; gap: 5px 14px; margin-top: 7px; font-size: 10.5px; color: var(--muted);
}
.pd-ui .pd-serie-ley span { display: inline-flex; align-items: center; gap: 5px; }
.pd-ui .pd-serie-ley i { width: 11px; height: 11px; border-radius: 2px; flex: none; }

.pd-ui .pd-ficha-dl { display: grid; grid-template-columns: auto 1fr; gap: 5px 14px; font-size: 12px; margin: 0; }
.pd-ui .pd-ficha-dl dt { color: var(--faint); font-weight: 600; }
.pd-ui .pd-ficha-dl dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 520px) { .pd-ui .pd-ficha-dl { grid-template-columns: 1fr; gap: 0 0; } .pd-ui .pd-ficha-dl dd { margin-bottom: 6px; } }

/* =============================================================================
   LA BANDA DEL CONTROL DE PESO — etapa 8 (mockup ronda 1, ganó la A)
   =============================================================================
   «El control es una banda más adentro de la pantalla, sin entrada nueva en el
   rail.» Va debajo de las tolvas y repite su grilla de cuatro columnas, porque
   habla de las mismas cuatro balanzas que cada tarjeta nombra al pie.

   EL COLOR ES DEL ESTADO Y NADA MÁS: verde el cuarto de hora que tuvo control,
   ámbar el que la línea anduvo y nadie pesó, gris el que la máquina estaba
   parada — ése no reprocha nada. Ningún token nuevo.
   ========================================================================== */
.pd-ui .pd-mues { margin-top: 14px; }
.pd-ui .pd-mues .mh {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 0 2px 8px;
}
.pd-ui .pd-mues .mh .nom { font-size: 13px; font-weight: 700; letter-spacing: -.01em; }
.pd-ui .pd-mues .mh .s { font-size: 11.5px; color: var(--muted); flex: 1; min-width: 0; }
.pd-ui .pd-mues .mh .abre {
    border: 0; background: none; padding: 0; cursor: pointer;
    font: inherit; font-size: 11.5px; font-weight: 700; color: var(--navy-500);
}
.pd-ui .pd-mues .mh .abre:hover, .pd-ui .pd-mues .mh .abre:focus-visible { text-decoration: underline; outline: none; }

.pd-ui .pd-mues .mg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.pd-ui .pd-mues .mg > * { min-width: 0; }
@media (max-width: 1180px) { .pd-ui .pd-mues .mg { grid-template-columns: 1fr 1fr; } }
@media (max-width: 660px)  { .pd-ui .pd-mues .mg { grid-template-columns: 1fr; } }

.pd-ui .pd-mues .mc {
    display: block; width: 100%; text-align: left; font: inherit; color: inherit;
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow);
    padding: 10px 12px 11px; min-width: 0;
    transition: background .15s var(--curva), border-color .15s var(--curva);
}
.pd-ui button.mc { cursor: pointer; }
.pd-ui button.mc:hover, .pd-ui button.mc:focus-visible { background: var(--navy-050); border-color: var(--hair-strong); outline: none; }
.pd-ui .pd-mues .mc.muda { background: var(--canvas); }
.pd-ui .pd-mues .mc .t { font-size: 11.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-ui .pd-mues .mc .t .b { font-weight: 600; color: var(--muted); }
.pd-ui .pd-mues .mc .v { font-size: 20px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; margin-top: 3px; }
.pd-ui .pd-mues .mc .v small { font-size: 11px; font-weight: 600; color: var(--muted); }
.pd-ui .pd-mues .mc .v.ausente { font-size: 13px; font-weight: 600; font-style: italic; color: var(--faint); letter-spacing: 0; }
.pd-ui .pd-mues .mc .s { font-size: 11px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.pd-ui .pd-mues .mc .s.warn { color: var(--warn); font-weight: 600; }
.pd-ui .pd-mues .mc .s.ok { color: var(--ok); font-weight: 600; }

/* EL RELOJ DE CUARTOS DE HORA — el componente que se mudó del mockup tal cual.
   Cuatro casillas por hora: la distribución se mide DENTRO de la hora (regla 3),
   así que las horas no se funden en una barra continua — se separan. */
.pd-ui .pd-reloj { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 2px; }
.pd-ui .pd-reloj .hr { display: flex; flex-direction: column; gap: 3px; align-items: center; }
.pd-ui .pd-reloj .cs { display: flex; gap: 2px; }
.pd-ui .pd-reloj .q {
    width: 10px; height: 15px; border-radius: 2px;
    border: 1px solid var(--hair-strong); background: var(--canvas);
}
.pd-ui .pd-reloj .q.ok    { background: var(--ok); border-color: var(--ok); }
.pd-ui .pd-reloj .q.falta { background: var(--warn-050); border-color: var(--warn-hair); }
.pd-ui .pd-reloj .q.off   { background: repeating-linear-gradient(45deg, var(--canvas) 0 3px, var(--hair) 3px 4px); border-color: var(--hair); }
.pd-ui .pd-reloj .hl { font-size: 9.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
.pd-ui .pd-reloj.chico .q { width: 7px; height: 11px; }
.pd-ui .pd-reloj.chico { gap: 6px; }

/* §5: no se apaga la información, se apaga el MOVIMIENTO. */
@media (prefers-reduced-motion: reduce) {
    .pd-ui .pd-pcard, .pd-ui .pd-maq, .pd-ui .pd-bal, .pd-ui .pd-dia .c, .pd-ui .pd-mues .mc,
    .pd-ui button.pd-chip,
    .pd-ui .pd-btn, .pd-ui .pd-ico, .pd-ui .pd-velo, .pd-ui .pd-modal,
    .pd-ui .pd-hist > summary::after, .pd-ui .pd-tools button {
        transition: none; animation: none;
    }
    .pd-ui button.pd-pcard:hover,
    .pd-ui button.pd-chip:hover, .pd-ui .pd-btn:hover { transform: none; }
}
