/* ===========================================================================
   PORTAL DEL CAÑERO — identidad del rol 4
   ---------------------------------------------------------------------------
   Público: alguien de AFUERA. Es la única pantalla de GS que no ve un empleado
   de Moyco, y la ve una vez por mes, desde el teléfono, para saber cuánta plata
   le entró. Todo lo de acá se decide con eso en la cabeza.

   TRATAMIENTO: cabecera PLENA (§3 del runbook, rama "trabajo mixto"). No es una
   pantalla-tabla que se mira veinte minutos seguidos: son fichas, tarjetas y
   tablas cortas que se recorren. Y como es la cara de Moyco al productor, la
   franja navy con la razón social arriba hace un trabajo que la cabecera lite
   no haría — decir de quién es esta pantalla.

   SIN ACENTO PROPIO. La regla del acento (§3) pide que un color interactivo
   propio sólo se justifique cuando navy ya está gastado en la estructura. Acá
   navy pinta la cabecera y nada más: no hay cuatro zonas apiladas como en el
   ABM. Así que navy alcanza y NO se inventa un segundo azul. El indigo que
   había era exactamente eso, un segundo azul, y sin motivo.

   SCOPE: todo cuelga de `.ptl-ui` y las clases van prefijadas `ptl-`. El scope
   está declarado en core/tokens.css en las tres listas (base tipográfica,
   .hidden y .tnum) — si alguna vez se agrega otro módulo, van las tres o
   ninguna.

   OJO CON EL ESPACIO: si el scope y la clase van en el MISMO elemento, el
   selector va sin espacio (`.ptl-ui.ptl-modal`). Con espacio no matchea nada y
   el bloque se cae en silencio.
   =========================================================================== */

.ptl-ui {
    background: var(--canvas);
    color: var(--ink);
}

/* Los íconos heredan tamaño del contexto salvo que alguien diga otra cosa. */
.ptl-ui .material-symbols-outlined {
    font-size: 19px;
    line-height: 1;
    vertical-align: middle;
}

/* ===========================================================================
   1. ARMAZÓN DE PANTALLA
   ===========================================================================
   Una columna: cabecera plena, barra de secciones (sólo la cuenta corriente la
   usa) y el lienzo que scrollea. El `min-height: 0` no es opcional — sin él el
   lienzo estira en vez de scrollear y la barra se va abajo del pliegue. */
.ptl-ui.ptl-shell {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

/* Y ESTA LÍNEA ES LA QUE HACE QUE LA APP NAVEGUE.
   ---------------------------------------------------------------------------
   El router oculta una pantalla con `classList.add('hidden')`, o sea con el
   `.hidden` de Tailwind, que es UNA clase de especificidad (0,1,0). La regla de
   acá arriba son DOS (0,2,0) y le gana: la pantalla del portal **nunca se
   ocultaba**. Como es `height: 100%` adentro de un wrapper `overflow: hidden`,
   Mi Stock se quedaba ocupando el alto entero y las otras tres se dibujaban
   abajo del pliegue, invisibles. El síntoma desde afuera era «los botones del
   rail no hacen nada» — y no era el rail: era esta línea, que faltaba.

   POR QUÉ ACÁ Y NO EN tokens.css. Ahí vive `.ptl-ui .hidden` —CON espacio— que
   cubre lo que está ADENTRO de un `.ptl-ui`. Esto es el caso simétrico: el
   elemento que lleva la clase del módulo ÉL MISMO. Es la misma trampa del
   `.x-ui .foo` contra `.x-ui.foo`, pero al revés: no un selector que no matchea
   nada, sino uno que matchea de más.

   Y ES DEL PORTAL Y NO DE LOS OTROS MÓDULOS porque el ABM y Configuración
   escriben su armazón en un `<div>` HIJO (`<div class="abm-ui abm-shell">`
   adentro de `#page-abm`), así que su `.page-content` queda limpio y el
   `.hidden` le pega sin pelear. El portal se lo pone al `#page-…` directamente
   —que ahorra un nivel en la cadena de alto— y el precio es esta línea. */
.ptl-ui.ptl-shell.hidden { display: none; }

.ptl-ui .ptl-lienzo {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--gutter);
}

/* Ancho de lectura. El portal tiene tablas de 6 columnas y tarjetas: más de
   esto y la vista queda con las cifras en una punta y las etiquetas en la otra. */
.ptl-ui .ptl-ancho { max-width: 1080px; margin: 0 auto; }

/* ===========================================================================
   2. CABECERA PLENA
   =========================================================================== */
.ptl-ui .ptl-hero {
    background: var(--navy);
    color: #fff;
    padding: 18px var(--gutter) 16px;
    flex: 0 0 auto;
}
.ptl-ui .ptl-hero-fila {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    max-width: 1080px; margin: 0 auto;
}
.ptl-ui .ptl-hero h3 {
    margin: 0;
    font-size: 1.3rem; font-weight: 700; letter-spacing: -.01em;
}
.ptl-ui .ptl-hero p {
    margin: 3px 0 0;
    font-size: .78rem; color: #b8cbe6;
}

/* El sello de sincronización. Es un DATO, no una acción: contorno tenue sobre
   la franja, sin fondo macizo que lo haga parecer un botón. */
.ptl-ui .ptl-sello {
    font-size: .72rem;
    color: #cfe0f5;
    border: 1px solid rgba(255,255,255,.22);
    background: rgba(255,255,255,.06);
    padding: 5px 11px;
    border-radius: 7px;
    white-space: nowrap;
}
.ptl-ui .ptl-sello b { color: #fff; font-weight: 600; }

/* LA CIFRA ADENTRO DE LA FRANJA (25/08/2026). Reemplaza a la banda blanca con
   tres tarjetas que vivía entre la cabecera y las pestañas.

   El argumento no es de gusto: esas tres tarjetas repetían, con las mismas
   etiquetas, los tres números que la tabla del estado de cuenta ya cierra en su
   `<tfoot>`, y para hacerlo se comían 90 px y metían un TERCER plano blanco
   —navy, blanco, blanco, blanco— que es exactamente lo que hace que una
   pantalla se lea chata. Acá la cifra aprovecha el contraste que la franja ya
   tiene, y las pestañas quedan pegadas al navy, que es lo que las hace saltar.

   El blanco sobre navy es 15,4:1. El pie va #b8cbe6 (el mismo del nombre de la
   empresa): 7,9:1, texto secundario de verdad y no un gris apagado. */
/* Con la cifra adentro, la columna derecha mide tres renglones y el
   `align-items: flex-end` de la fila —que estaba bien cuando a la derecha sólo
   había un sello de un renglón— dejaba el título flotando abajo, alineado
   contra el sello en vez de contra el rótulo del saldo. Arriba con arriba. */
.ptl-ui .ptl-hero-fila.con-saldo { align-items: flex-start; }
.ptl-ui .ptl-hero-der {
    display: flex; flex-direction: column; align-items: flex-end; gap: 7px;
    min-width: 0;
}
.ptl-ui .ptl-hero-saldo { text-align: right; }
.ptl-ui .ptl-hero-saldo .lbl {
    font-size: .62rem; font-weight: 700;
    letter-spacing: .11em; text-transform: uppercase;
    color: #b8cbe6;
}
.ptl-ui .ptl-hero-saldo .val {
    font-size: 1.76rem; font-weight: 700; letter-spacing: -.02em;
    color: #fff; margin-top: 1px;
    font-variant-numeric: tabular-nums;
}
.ptl-ui .ptl-hero-saldo .pie { font-size: .72rem; color: #b8cbe6; margin-top: 2px; }
/* EL COLOR ES DEL DATO: sólo si el saldo está EN CONTRA del cañero. Sobre navy
   el --crit (#c62828) no se lee —2,1:1—, así que va el rosa claro: 7,4:1. */
.ptl-ui .ptl-hero-saldo.crit .val { color: #ffb4b4; }

/* LA FRANJA EN CHICO — la usa la auditoría del gerente, que no tiene cabecera
   plena propia y aun así tiene que mostrar lo mismo que el cañero tiene
   delante. Mismo navy, mismo bloque; sólo cambia el envase. */
.ptl-ui .ptl-hero.ptl-hero-mini {
    padding: 12px 16px;
    border-radius: 10px;
    margin-bottom: 14px;
}
.ptl-ui .ptl-hero-mini .ptl-hero-saldo { text-align: left; }
.ptl-ui .ptl-hero-mini .ptl-hero-saldo .val { font-size: 1.5rem; }

/* ===========================================================================
   3. SECCIONES — por TRAZO, nunca por píldora
   ===========================================================================
   Regla de oro del color: el navy sólo rellena la cabecera y el botón de la
   acción principal. Todo lo demás que indique estado usa trazo. La pestaña
   activa es un subrayado, no un bloque relleno. */
.ptl-ui .ptl-nav {
    display: flex; gap: 2px;
    padding: 0 var(--gutter);
    background: var(--surface);
    border-bottom: 1px solid var(--hair);
    overflow-x: auto;
    flex: 0 0 auto;
}
.ptl-ui .ptl-nav-in { display: flex; gap: 2px; max-width: 1080px; margin: 0 auto; width: 100%; }

/* EL REFUERZO DE CONTRASTE (25/08/2026), copiado de las pestañas de unidad de
   Comerciales (`.cm-tab`), que ya habían pasado por esto.

   Estaban en 600 con un trazo de 2 px y la única diferencia entre la activa y
   las otras tres era el color del texto: --muted contra --navy. Sobre blanco,
   con cuatro rótulos largos y sin ninguna otra pieza alrededor, la fila se leía
   como un renglón de texto y no como un control. Tres cambios, ninguno rompe la
   regla de oro:

     · el peso sube a 700 en TODAS —la activa no se distingue por engordar—;
     · el trazo pasa a 3 px y se declara transparente en las inactivas, así que
       ninguna se corre un píxel al activarse;
     · la activa suma un lavado de --navy-050 que MUERE hacia arriba. Sigue sin
       ser una píldora rellena: es la sombra que proyecta el subrayado.

   El hover también tiñe, porque una zona clicable tiene que avisar que lo es. */
.ptl-ui .ptl-nav button {
    border: 0; background: none;
    font-family: inherit; font-size: .82rem; font-weight: 700;
    color: var(--muted);
    padding: 12px 15px 9px;
    border-bottom: 3px solid transparent;
    border-radius: 8px 8px 0 0;
    cursor: pointer;
    white-space: nowrap;
    transition: color .16s var(--curva), border-color .16s var(--curva),
                background-color .16s var(--curva);
}
.ptl-ui .ptl-nav button:hover { color: var(--navy-500); background: var(--navy-050); }
.ptl-ui .ptl-nav button.on {
    color: var(--navy);
    border-bottom-color: var(--navy);
    background: linear-gradient(180deg, rgba(237,242,250,0) 35%, var(--navy-050) 100%);
}
.ptl-ui .ptl-nav button:focus-visible { outline: 2px solid var(--navy-300); outline-offset: -2px; }

/* ===========================================================================
   4. TARJETAS
   =========================================================================== */
.ptl-ui .ptl-card {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
}
.ptl-ui .ptl-card-h {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--hair);
}
.ptl-ui .ptl-card-h h4 {
    margin: 0;
    font-size: .78rem; font-weight: 700; letter-spacing: .03em;
    text-transform: uppercase;
}
.ptl-ui .ptl-card-h .ptl-nota { font-size: .72rem; color: var(--faint); font-weight: 400; }
.ptl-ui .ptl-card-acts {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 12px; flex-wrap: wrap;
    min-width: 0;
}
.ptl-ui .ptl-card-acts .ptl-nota { text-align: right; }
.ptl-ui .ptl-card-h .ptl-btn { height: 30px; padding: 0 11px; font-size: .74rem; }
.ptl-ui .ptl-card-b { padding: 16px; }

/* ===========================================================================
   5. KPIs — acento por trazo a la izquierda
   ===========================================================================
   El color de la barrita dice el ESTADO del dato, nunca su categoría. Un saldo
   no es verde por ser un saldo; es ámbar si hay kilos sin liquidar. */
.ptl-ui .ptl-kpis {
    display: grid; gap: 12px;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    margin-bottom: 16px;
}
.ptl-ui .ptl-kpi {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-left: 3px solid var(--navy);
    border-radius: 10px;
    padding: 11px 14px;
    box-shadow: var(--shadow);
}
.ptl-ui .ptl-kpi .ptl-lbl {
    font-size: .62rem; font-weight: 700;
    letter-spacing: .11em; text-transform: uppercase;
    color: var(--faint);
}
.ptl-ui .ptl-kpi .ptl-val {
    font-size: 1.45rem; font-weight: 700; letter-spacing: -.02em;
    margin-top: 3px;
    font-variant-numeric: tabular-nums;
}
.ptl-ui .ptl-kpi .ptl-val small { font-size: .78rem; font-weight: 600; color: var(--muted); margin-left: 2px; }
.ptl-ui .ptl-kpi .ptl-pie { font-size: .72rem; color: var(--faint); margin-top: 2px; }

.ptl-ui .ptl-kpi.ok   { border-left-color: var(--ok); }
.ptl-ui .ptl-kpi.warn { border-left-color: var(--warn); }
.ptl-ui .ptl-kpi.crit { border-left-color: var(--crit); }
.ptl-ui .ptl-kpi.crit .ptl-val { color: var(--crit); }

/* LA TIRA DE LA CUENTA CORRIENTE (etapa 2). Los KPIs de Mi Stock viven ADENTRO
   del lienzo y se van con el scroll, porque ahí son el encabezado de una lista.
   Acá son la respuesta a la pregunta que trae al cañero, así que viven FUERA:
   entre la cabecera y las pestañas, y no se mueven.

   Va sobre `--surface` y no sobre el lienzo: es una continuación de la
   cabecera, no la primera tarjeta del contenido. El filete de abajo lo pone la
   barra de secciones, que arranca justo debajo. */
.ptl-ui .ptl-tira {
    flex: 0 0 auto;
    background: var(--surface);
    border-bottom: 1px solid var(--hair);
    padding: 14px var(--gutter) 15px;
}
/* Adentro de la tira los KPIs no llevan su margen de abajo: el padding de la
   banda ya lo pone, y sumados dejaban un escalón contra las pestañas.

   Y LAS TARJETAS TIENEN TECHO. El `auto-fit` reparte TODO el ancho entre las
   que haya, así que cuando el desglose se colapsa a dos, cada una se estiraba a
   540 px: media pantalla para decir «$0,00». El cero se sigue mostrando —que no
   te deban nada sin liquidar es una respuesta, no un dato faltante— pero
   alineado a la izquierda y del mismo tamaño que cuando son tres. Una tarjeta
   no crece porque sobre lugar. */
.ptl-ui .ptl-tira .ptl-kpis {
    margin-bottom: 0;
    grid-template-columns: repeat(auto-fit, minmax(210px, 340px));
    justify-content: start;
}
/* La cifra que contesta la pregunta pesa más que las dos que la explican. */
.ptl-ui .ptl-tira .ptl-kpi:first-child .ptl-val { font-size: 1.72rem; }

/* ===========================================================================
   6. TABLAS
   ===========================================================================
   Encabezado: regla de 2px sobre blanco, NO franja navy. Una franja de color
   fija arriba de una tabla larga es la mayor fuente de fatiga visual del
   sistema, y acá la tabla de movimientos se pagina hasta donde el cañero
   quiera. */
.ptl-ui .ptl-tabla-wrap { overflow-x: auto; }
.ptl-ui table.ptl-tabla { width: 100%; border-collapse: collapse; font-size: .8rem; }
.ptl-ui table.ptl-tabla thead th {
    text-align: left;
    font-size: .62rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--faint);
    padding: 9px 14px;
    background: var(--surface);
    border-bottom: 2px solid var(--hair-strong);
    white-space: nowrap;
    position: sticky; top: 0; z-index: 1;
}
.ptl-ui table.ptl-tabla tbody td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--hair);
    vertical-align: middle;
}
.ptl-ui table.ptl-tabla tbody tr:last-child td { border-bottom: 0; }
.ptl-ui table.ptl-tabla tbody tr:hover { background: var(--navy-050); }

/* Columnas numéricas. El portal es plata y kilos: casi todas alinean derecha. */
.ptl-ui .ptl-tabla .n {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.ptl-ui .ptl-tabla .c { text-align: center; }

/* Rótulo de sección adentro de la tabla. Separa dos especies de fila sin
   sacarlas de la pantalla: los comprobantes facturados de las OC entregadas y
   todavía sin liquidar. Va en NEUTRO, y las píldoras de esas filas TAMBIÉN:
   en la columna «Tipo» el color significaría «esta fila es de otra clase», que
   es color-categoría con otro nombre. Lo que esa sección tiene de distinto lo
   dicen el rótulo, el subtotal y el KPI ámbar de arriba — que sí es un estado. */
.ptl-ui table.ptl-tabla tbody tr.ptl-seccion td {
    background: #f4f6f9;
    border-top: 1px solid var(--hair-strong);
    border-bottom: 1px solid var(--hair-strong);
    padding: 7px 14px;
    font-size: .62rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--faint);
}
.ptl-ui table.ptl-tabla tbody tr.ptl-seccion:hover td { background: #f4f6f9; }

/* EL PIE ES DONDE SE CIERRA LA CUENTA. Sin él, el cañero tiene que sumar de
   memoria lo facturado con lo que entregó y todavía no le liquidaron — que es
   justamente la pregunta que lo trae al portal, y la que un estado de cuenta
   sólo contable no contesta. */
.ptl-ui table.ptl-tabla tfoot td {
    padding: 7px 14px;
    font-size: .78rem;
    color: var(--muted);
    text-align: right;
}
.ptl-ui table.ptl-tabla tfoot td.v {
    color: var(--ink); font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.ptl-ui table.ptl-tabla tfoot tr.total td {
    background: #f6f8fb;
    border-top: 2px solid var(--hair-strong);
    padding: 12px 14px;
    font-size: .92rem; font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
}

.ptl-ui .ptl-mono {
    font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
    font-size: .72rem; color: var(--muted);
}

/* Un dato que existe pero vale cero, y el guion del que no existe. Los dos
   tienen que pesar MENOS que una cifra de verdad, o una columna de «$0,00»
   compite con la de la deuda, que es la que hay que leer. */
.ptl-ui .ptl-tenue { color: var(--faint); font-weight: 400; }

/* ===========================================================================
   6b. FILAS — una lista que no es una tabla
   ===========================================================================
   Las liquidaciones son archivos: un nombre y un botón para bajarlo. Meterlas
   en una tabla obligaría a inventar columnas que no existen. */
.ptl-ui .ptl-fila {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--hair);
}
.ptl-ui .ptl-fila:last-child { border-bottom: 0; }
.ptl-ui .ptl-fila:hover { background: var(--navy-050); }
.ptl-ui .ptl-fila-t { min-width: 0; }
.ptl-ui .ptl-fila-t .t {
    margin: 0; font-size: .85rem; font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ptl-ui .ptl-fila-t .s {
    margin: 2px 0 0; font-size: .72rem; color: var(--faint);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ===========================================================================
   6c. SEGMENTOS — un FILTRO, y por eso no se parece a `.ptl-nav`
   ===========================================================================
   «En curso / Cargadas / Todas» comparten el render y sólo cambian un `where`:
   son un filtro, no tres secciones (§7 del manual). Y como son otra cosa,
   tienen que verse como otra cosa — si usaran el subrayado de `.ptl-nav`, el
   cañero leería tres pantallas donde hay una.

   Van adentro del lienzo (el nivel de arriba vive fuera), y el activo se marca
   con TRAZO y fondo teñido, nunca con una píldora navy rellena: el presupuesto
   de azul de la pantalla ya se lo lleva la cabecera. */
.ptl-ui .ptl-seg {
    display: flex; flex-wrap: wrap; gap: 7px;
    margin-bottom: 14px;
}
.ptl-ui .ptl-seg button {
    font-family: inherit; font-size: .76rem; font-weight: 600;
    color: var(--muted);
    background: var(--surface);
    border: 1px solid var(--hair-strong);
    border-radius: 8px;
    padding: 6px 13px;
    cursor: pointer;
    white-space: nowrap;
    transition: color .16s var(--curva), border-color .16s var(--curva),
                background .16s var(--curva), transform .18s var(--curva);
}
.ptl-ui .ptl-seg button:hover { color: var(--ink); border-color: var(--navy-300); transform: translateY(-2px); }
.ptl-ui .ptl-seg button:focus-visible { outline: 2px solid var(--navy-300); outline-offset: 2px; }
.ptl-ui .ptl-seg button.on {
    color: var(--navy);
    border-color: var(--navy);
    background: var(--navy-050);
    transform: none;
}
.ptl-ui .ptl-seg .ptl-seg-n { opacity: .62; font-weight: 700; margin-left: 5px; }

@media (prefers-reduced-motion: reduce) {
    .ptl-ui .ptl-seg button:hover { transform: none; }
}

/* ===========================================================================
   6d. AVANCE — mide CUÁNTO FALTA, no en qué etapa está
   ===========================================================================
   La versión vieja pintaba la barra del color del estado: naranja en cartera,
   violeta en gestión, verde en cargada. O sea que el largo decía una cosa
   (cuánto se cargó) y el color decía otra (en qué etapa está), con el mismo
   recurso y sin que nada lo aclarara.

   Acá la barra dice UNA sola cosa. El color es del dato: navy mientras falte
   algo, verde cuando ya no falta — que es un estado de verdad, «cumplido», y
   no una categoría. */
.ptl-ui .ptl-avance { display: flex; align-items: center; gap: 10px; }
.ptl-ui .ptl-track {
    flex: 1; min-width: 70px; max-width: 280px;
    height: 6px; border-radius: 4px;
    background: #eef1f6;
    overflow: hidden;
}
.ptl-ui .ptl-track .ptl-fill {
    display: block; height: 100%; border-radius: 4px;
    background: var(--navy-300);
    transition: width .5s var(--curva);
}
.ptl-ui .ptl-track .ptl-fill.listo { background: var(--ok); }
.ptl-ui .ptl-pc {
    font-size: .72rem; font-weight: 700; color: var(--muted);
    font-variant-numeric: tabular-nums;
    min-width: 34px; text-align: right;
}
@media (prefers-reduced-motion: reduce) {
    .ptl-ui .ptl-track .ptl-fill { transition: none; }
}

/* ===========================================================================
   6e. ÓRDENES — la fila que se cuenta entera y se abre en el lugar
   ===========================================================================
   Es la opción B de los dos mockups de la etapa 3, y se eligió con un dato:
   el cañero típico tiene DE 2 A 5 órdenes. Con esa cantidad la densidad de una
   tabla no hace falta, y tener el historial de cargas —lo que se coteja contra
   los remitos de papel— a la vista sí. Con veinte órdenes la decisión habría
   sido la contraria.

   El mismo componente sirve en el teléfono. Antes había DOS vistas distintas
   que además se contradecían entre sí. */
.ptl-ui .ptl-ord { border-bottom: 1px solid var(--hair); }
.ptl-ui .ptl-ord:last-child { border-bottom: 0; }

/* LAS COLUMNAS TIENEN PISO, O LOS KILOS NO SE PUEDEN COMPARAR.
   Cada fila es su propio grid, así que con `auto` cada una mide sus columnas
   por separado: «24.000» quedaba en una x y «60.000» en otra, según lo largo
   que fuera la píldora de estado de al lado. Se ve sólo con DOS filas y en la
   foto — el mockup tenía una sola cifra por columna y no lo mostró.

   El `minmax()` le da un piso a las tres columnas de la derecha, así que en el
   caso normal todas las filas coinciden; y si algún día un estado o un número
   es más largo que el piso, crece en vez de recortar. */
.ptl-ui .ptl-ord-h {
    display: grid;
    grid-template-columns:
        minmax(62px, auto)      /* N° de orden */
        1fr                     /* artículo + avance */
        minmax(104px, auto)     /* kg por cargar */
        minmax(150px, auto)     /* estado */
        22px;                   /* chevron */
    gap: 16px; align-items: center;
    width: 100%;
    padding: 13px 16px;
    background: none; border: 0;
    font-family: inherit; text-align: left; color: inherit;
    cursor: pointer;
    transition: background .16s var(--curva);
}
.ptl-ui .ptl-ord-h:hover { background: var(--navy-050); }
.ptl-ui .ptl-ord-h:focus-visible { outline: 2px solid var(--navy-300); outline-offset: -2px; }

.ptl-ui .ptl-ord-num {
    font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
    font-size: .74rem; color: var(--muted); white-space: nowrap;
}
.ptl-ui .ptl-ord-t { min-width: 0; }
.ptl-ui .ptl-ord-t h5 {
    margin: 0; font-size: .88rem; font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ptl-ui .ptl-ord-t p {
    margin: 2px 0 0; font-size: .72rem; color: var(--faint);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ptl-ui .ptl-ord-t .ptl-avance { margin-top: 7px; }

.ptl-ui .ptl-ord-kg { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ptl-ui .ptl-ord-kg b { display: block; font-size: 1.05rem; font-weight: 700; letter-spacing: -.02em; }
.ptl-ui .ptl-ord-kg b.cero { color: var(--faint); font-weight: 400; }
.ptl-ui .ptl-ord-kg small {
    display: block; font-size: .62rem; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase; color: var(--faint);
}
/* El chevron gira: anticipa que se abre para abajo. */
.ptl-ui .ptl-ord-chev { color: var(--faint); transition: transform .18s var(--curva); }
.ptl-ui .ptl-ord.abierta .ptl-ord-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
    .ptl-ui .ptl-ord-chev { transition: none; }
}

.ptl-ui .ptl-ord-cuerpo {
    background: #fafbfd;
    border-top: 1px solid var(--hair);
    padding: 4px 16px 14px;
}
.ptl-ui .ptl-rot {
    font-size: .62rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--faint);
    margin: 0; padding: 11px 0 6px;
}

/* ===========================================================================
   6f. TARJETAS DE DOCUMENTACIÓN
   ===========================================================================
   Cuatro archivos y un botón cada uno. La única decisión de la pantalla es qué
   pasa con el que TODAVÍA no está: antes era un botón gris apagado que decía
   «No disponible» —o sea un control muerto—, y ahora lo dice el texto de la
   tarjeta y el botón directamente no se dibuja. Un dato ausente es información
   (§1.4), pero un botón que no hace nada no es información de nada. */
.ptl-ui .ptl-docs {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.ptl-ui .ptl-doc {
    display: flex; flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    padding: 16px 18px;
}
.ptl-ui .ptl-doc-h { display: flex; align-items: center; gap: 11px; margin-bottom: 7px; }
.ptl-ui .ptl-doc-h .material-symbols-outlined {
    font-size: 22px;
    color: var(--navy);
    background: var(--navy-050);
    border-radius: 9px;
    padding: 7px;
    flex: 0 0 auto;
}
.ptl-ui .ptl-doc-h h4 { margin: 0; font-size: .92rem; font-weight: 700; }
.ptl-ui .ptl-doc p { margin: 0; font-size: .8rem; color: var(--muted); flex: 1; }
.ptl-ui .ptl-doc-pie { margin-top: 14px; }
/* El que todavía no está: sin botón, y el texto en gris itálico dice qué falta. */
.ptl-ui .ptl-doc.pendiente .material-symbols-outlined { color: var(--faint); background: #f4f6f9; }
.ptl-ui .ptl-doc.pendiente p { color: var(--faint); font-style: italic; }

/* ===========================================================================
   7. ESTADO — píldoras. SOLO estado, nunca categoría.
   =========================================================================== */
.ptl-ui .ptl-pill {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: .62rem; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 5px;
    border: 1px solid;
    white-space: nowrap;
}
.ptl-ui .ptl-pill .material-symbols-outlined { font-size: 13px; }
.ptl-ui .ptl-pill.ok   { color: var(--ok);   background: var(--ok-050);   border-color: var(--ok-hair); }
.ptl-ui .ptl-pill.warn { color: var(--warn); background: var(--warn-050); border-color: var(--warn-hair); }
.ptl-ui .ptl-pill.crit { color: var(--crit); background: var(--crit-050); border-color: var(--crit-hair); }
.ptl-ui .ptl-pill.mut  { color: var(--muted); background: #f4f6f9; border-color: var(--hair-strong); }

/* EL PAPEL QUE CERRÓ LA ORDEN — segundo renglón de la celda de estado.
   «Liquidada» dice que el papel existe; esto dice CUÁL es, que es por lo que el
   cañero llama por teléfono. Va tenue y chico a propósito: no compite con la
   píldora, la completa. Cuando el papel es la LQA de Moyco hay PDF y el número
   es un enlace; cuando es la factura DEL proveedor no hay nada que ofrecerle
   —el papel lo hizo él— y queda como texto. */
.ptl-ui .ptl-papel {
    margin-top: 4px;
    font-size: .68rem; color: var(--faint);
    display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
}
.ptl-ui .ptl-papel .ptl-mono { font-size: .68rem; color: var(--muted); }
.ptl-ui .ptl-papel-a {
    display: inline-flex; align-items: center; gap: 3px;
    color: var(--navy-500); font-weight: 600; text-decoration: none;
    font-family: var(--mono, ui-monospace, 'SFMono-Regular', Menlo, monospace);
}
.ptl-ui .ptl-papel-a:hover { color: var(--navy); text-decoration: underline; }
.ptl-ui .ptl-papel-a .material-symbols-outlined { font-size: 14px; }

/* ===========================================================================
   8. AVISO DE DATO DIFERIDO
   ===========================================================================
   Se dice UNA vez por pantalla y siempre con el mismo texto. Antes vivía sólo
   en la cuenta corriente, y es igual de cierto en las otras tres: todo el
   portal lee el snapshot que baja de Flexxus una vez por día.

   Y VA EN GRIS, NO EN ÁMBAR. Nació ámbar —lo era en la versión Tailwind— y en
   Mi Stock no molestaba porque era la única superficie de color de la pantalla.
   En la cuenta corriente la foto lo dejó en evidencia: la banda ámbar quedaba
   entre el KPI ámbar del «entregado sin liquidar» y la píldora ámbar de la OC,
   y era la MÁS GRANDE de las tres. O sea que el color que marca el problema
   perdía contra el que no marca nada.

   Que los datos se sincronicen una vez por día no es un desvío: es cómo
   funciona el portal, siempre, para todos. Es el mismo caso del panel
   «Estado actual del período» que era `bg-amber-50` en Configuración — un
   período cerrado es lo normal, no una advertencia. Un aviso permanente no
   puede gastar el único color que significa «mirá esto». */
.ptl-ui .ptl-aviso {
    display: flex; gap: 9px; align-items: flex-start;
    background: var(--surface);
    border: 1px solid var(--hair);
    color: var(--muted);
    border-radius: 10px;
    padding: 9px 13px;
    font-size: .75rem; line-height: 1.5;
    margin-bottom: 16px;
}
.ptl-ui .ptl-aviso b { font-weight: 600; color: var(--ink); }
.ptl-ui .ptl-aviso .material-symbols-outlined { color: var(--faint); }

/* ===========================================================================
   9. BOTONES
   ===========================================================================
   Uno solo puede ser macizo por pantalla, y sólo si es LA acción. En el portal
   casi nunca hay una: es una pantalla de lectura. Por defecto, contorno. */
.ptl-ui .ptl-btn {
    display: inline-flex; align-items: center; gap: 6px;
    height: 34px; padding: 0 13px;
    border-radius: 9px;
    border: 1px solid var(--hair-strong);
    background: var(--surface);
    color: var(--ink);
    font-family: inherit; font-size: .78rem; font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    /* El de «Descargar» es un <a> de verdad (abre el PDF en otra pestaña), así
       que el subrayado del link hay que sacarlo acá o el botón sale rayado. */
    text-decoration: none;
    transition: background .16s var(--curva), border-color .16s var(--curva);
}
.ptl-ui .ptl-btn:hover:not(:disabled) { background: var(--navy-050); border-color: var(--navy-300); }
.ptl-ui .ptl-btn:focus-visible { outline: 2px solid var(--navy-300); outline-offset: 2px; }
.ptl-ui .ptl-btn:disabled { opacity: .45; cursor: not-allowed; }
.ptl-ui .ptl-btn.pri { background: var(--navy); border-color: var(--navy); color: #fff; }
.ptl-ui .ptl-btn.pri:hover:not(:disabled) { background: var(--navy-700); border-color: var(--navy-700); }

/* "Cargar más": ancho, centrado, y claramente no es la acción de la pantalla. */
.ptl-ui .ptl-mas {
    display: flex; justify-content: center;
    padding: 16px 0 4px;
}

/* ===========================================================================
   10. VACÍOS Y ERRORES
   ===========================================================================
   Un vacío dice QUÉ falta y QUÉ hacer. "Sin datos" no es ninguna de las dos. */
.ptl-ui .ptl-empty {
    text-align: center;
    padding: 44px 20px;
    color: var(--faint);
}
.ptl-ui .ptl-empty .material-symbols-outlined {
    font-size: 40px; opacity: .3; display: block; margin: 0 auto 10px;
}
.ptl-ui .ptl-empty p { margin: 0; font-size: .82rem; font-weight: 600; color: var(--muted); }
.ptl-ui .ptl-empty small { display: block; margin-top: 5px; font-size: .74rem; font-weight: 400; }

/* El vacío que sí es un problema: el usuario no tiene ninguna cuenta vinculada
   y no puede hacer nada solo. Es lo único crítico del portal. */
.ptl-ui .ptl-empty.crit { color: var(--crit); }
.ptl-ui .ptl-empty.crit p { color: var(--crit); }

.ptl-ui .ptl-spin { animation: ptlGirar 1s linear infinite; display: inline-block; }
@keyframes ptlGirar { to { transform: rotate(360deg); } }

/* ===========================================================================
   11. MOBILE
   ===========================================================================
   El rol que más entra desde el teléfono. Las tablas no se achican: se
   convierten en tarjetas, que es una decisión del contenido y no del ancho. */
@media (max-width: 720px) {
    .ptl-ui .ptl-card-acts .ptl-nota { display: none; }
    .ptl-ui .ptl-lienzo { padding: 14px; }
    .ptl-ui .ptl-hero { padding: 14px; }
    .ptl-ui .ptl-hero h3 { font-size: 1.12rem; }
    .ptl-ui .ptl-nav { padding: 0 8px; }
    .ptl-ui .ptl-kpis { grid-template-columns: repeat(2, 1fr); gap: 9px; }
    .ptl-ui .ptl-kpi .ptl-val { font-size: 1.2rem; }
    .ptl-ui .ptl-tira { padding: 12px 14px 13px; }

    /* La fila de una orden deja de ser una grilla de cinco columnas y se apila.
       Es la misma pieza —no hay una vista mobile aparte, que era justamente lo
       que producía dos pantallas que se contradecían. */
    .ptl-ui .ptl-ord-h {
        grid-template-columns: 1fr auto;
        grid-template-areas: 'num chev' 'ttl ttl' 'kg estado';
        gap: 4px 12px;
        align-items: start;
        padding: 13px 15px;
    }
    .ptl-ui .ptl-ord-num  { grid-area: num; }
    .ptl-ui .ptl-ord-chev { grid-area: chev; }
    .ptl-ui .ptl-ord-t    { grid-area: ttl; }
    .ptl-ui .ptl-ord-kg   { grid-area: kg; text-align: left; margin-top: 8px; }
    .ptl-ui .ptl-ord-est  { grid-area: estado; align-self: end; }
    .ptl-ui .ptl-ord-t .ptl-track { max-width: none; }
    .ptl-ui .ptl-ord-cuerpo { padding: 4px 15px 14px; }
    /* En dos columnas, la cifra que manda se lleva la fila entera: partida al
       medio con la de al lado quedaba del mismo tamaño que sus explicaciones. */
    .ptl-ui .ptl-tira .ptl-kpi:first-child { grid-column: 1 / -1; }
    .ptl-ui .ptl-tira .ptl-kpi:first-child .ptl-val { font-size: 1.5rem; }

    /* A 390 px la fila de la cabecera ENVUELVE, y una cifra alineada a la
       derecha abajo del nombre de la empresa se lee como si fuera de otra
       columna que no existe. Envuelta, se alinea con todo lo demás. */
    .ptl-ui .ptl-hero-der { align-items: flex-start; width: 100%; margin-top: 10px; }
    .ptl-ui .ptl-hero-saldo { text-align: left; }
    .ptl-ui .ptl-hero-saldo .val { font-size: 1.5rem; }
}

.ptl-ui .ptl-mcard {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: 12px;
    box-shadow: var(--shadow);
    padding: 13px 15px;
    margin-bottom: 10px;
}
.ptl-ui .ptl-mcard-h {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 9px;
}
.ptl-ui .ptl-mcard-t { min-width: 0; }
.ptl-ui .ptl-mcard-t h5 {
    margin: 0; font-size: .85rem; font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ptl-ui .ptl-mcard-t p { margin: 2px 0 0; font-size: .7rem; color: var(--faint); }
.ptl-ui .ptl-mcard-n {
    text-align: right; flex: 0 0 auto;
    font-size: 1.2rem; font-weight: 700; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}
.ptl-ui .ptl-mcard-n small { display: block; font-size: .62rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.ptl-ui .ptl-mcard-f {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    border-top: 1px solid var(--hair);
    padding-top: 9px;
    font-size: .72rem; color: var(--muted);
}

/* La razón social, cuando el ámbito son varias empresas y hay que saber de
   cuál es cada tarjeta. Va arriba de todo y chica: es la respuesta a una
   pregunta que sólo aparece en el modo consolidado. */
.ptl-ui .ptl-mcard-emp {
    margin: 0 0 8px;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--hair);
    font-size: .65rem; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--faint);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Selector de empresa del MOBILE. El armazón del teléfono no tiene `#app-bar`,
   así que el ámbito no puede vivir en la barra: se dibuja acá arriba, con la
   misma forma que el de escritorio para que se reconozca como la misma cosa. */
.ptl-ui .ptl-msel {
    display: flex; align-items: center; gap: 9px;
    background: var(--navy-050);
    border: 1px solid #cfdcef;
    border-radius: 10px;
    padding: 9px 12px;
    margin-bottom: 12px;
}
.ptl-ui .ptl-msel > span {
    flex: 0 0 auto;
    font-size: .62rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--navy); opacity: .72;
}
.ptl-ui .ptl-msel select {
    flex: 1; min-width: 0;
    border: 0; background: none; outline: none;
    font-family: inherit; font-size: .84rem; font-weight: 600;
    color: var(--navy);
}

.ptl-ui .ptl-mob-pie {
    text-align: center;
    font-size: .68rem; font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--faint);
    padding: 14px 0 26px;
    margin: 0;
}
