/* ============================================================================
   STOCK-HUB (2026-08-01) — hoja PROPIA del hub de stock.
   ----------------------------------------------------------------------------
   Pedido del dueño (textual): "un botón animado más para stock donde se pueda
   modificar, eliminar, cambiar precios, todo bien completo, combos,
   recomendaciones, todo se pueda modificar de ahí. Y que los productos aparezcan
   con foto, y si la foto no es la indicada te permita cambiarla y que quede fija."

   POR QUÉ UNA HOJA PROPIA Y NO mnx.css:
   el panel se monta en LAS DOS casas (/m2/stock/hub y /stock/hub). mnx.css está
   scopeado bajo .mnx-root, que en escritorio no existe; y home.css es del home de
   escritorio. Una hoja autocontenida con sus propios tokens es lo único que se ve
   IGUAL en las dos — y "igual en las dos" es la mitad del pedido: el que aprende
   el hub en el celular de la góndola tiene que reconocerlo en la compu del fondo.

   TOKENS: todos bajo .shb (no en :root) — así no puede pisarle una variable ni a
   MNX ni al catálogo ni al home. Tipografía: SEIS pasos, y ninguno suelto.
   Animación: sólo transform/opacity, nunca infinite, y todo apagado con
   prefers-reduced-motion.
   ⚠️ NADA se dibuja "sólo si el JS corre": el panel entero es HTML del servidor.
   ============================================================================ */

.shb {
    /* superficie */
    --shb-bg: #0e0f12;
    --shb-bg-2: #16181d;
    --shb-bg-3: #1d2027;
    --shb-line: #262a33;
    --shb-line-2: #363c48;
    --shb-fg: #f2f3f5;
    --shb-fg-2: #b6bcc7;
    --shb-fg-3: #7c8492;
    /* marca */
    --shb-red: #ee352b;
    --shb-red-2: #ff5a4f;
    --shb-ok: #35c07a;
    --shb-warn: #f5b301;
    --shb-gold: #edae01;
    /* escala tipográfica: SEIS pasos, apretados abajo (donde vive la UI) */
    --shb-f1: 11px;
    --shb-f2: 12px;
    --shb-f3: 13px;
    --shb-f4: 15px;
    --shb-f5: 18px;
    --shb-f6: 24px;
    /* 16px clavado: con menos, iOS hace auto-zoom al enfocar un input y la
       pantalla salta en la cara del que está cargando. No se baja. */
    --shb-finput: 16px;
    --shb-r: 14px;
    --shb-r-s: 10px;

    color: var(--shb-fg);
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}

/* En escritorio el hub vive dentro del layout claro del sistema: se le da su
   propia caja oscura para que la lectura no dependa del tema de alrededor. */
.shb-page {
    background: var(--shb-bg);
    border-radius: var(--shb-r);
    padding: 16px;
    max-width: 1180px;
    margin: 0 auto;
}

.shb *,
.shb *::before,
.shb *::after { box-sizing: border-box; }

.shb-ic {
    width: 1em;
    height: 1em;
    display: inline-block;
    vertical-align: -0.13em;
    flex: 0 0 auto;
}

/* ── ENCABEZADO ─────────────────────────────────────────────────────────── */
.shb-hd {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 14px;
}
.shb-hd-ico {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--shb-f6);
    color: #fff;
    background: linear-gradient(150deg, #ee352b, #8c0209);
    flex: 0 0 auto;
}
.shb-hd-tx { flex: 1 1 auto; min-width: 0; }
.shb-hd-tx b { display: block; font-size: var(--shb-f5); font-weight: 700; line-height: 1.2; }
.shb-hd-tx span { display: block; font-size: var(--shb-f2); font-weight: 500; color: var(--shb-fg-3); margin-top: 3px; }

/* ── CHIPS DE ESTADO (son el filtro) ─────────────────────────────────────
   Cada chip dice un número Y qué pasa si se lo deja así. Un número sin
   consecuencia no mueve a nadie. */
.shb-chips {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
    margin-bottom: 12px;
    scrollbar-width: thin;
}
.shb-chip {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 104px;
    padding: 9px 12px;
    border-radius: var(--shb-r-s);
    border: 1px solid var(--shb-line);
    background: var(--shb-bg-2);
    color: var(--shb-fg-2);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: transform .14s ease, opacity .14s ease, border-color .14s ease, background-color .14s ease;
}
.shb-chip b { font-size: var(--shb-f5); font-weight: 700; color: var(--shb-fg); line-height: 1; }
.shb-chip span { font-size: var(--shb-f1); font-weight: 500; color: var(--shb-fg-3); }
.shb-chip:active { transform: scale(.97); }
.shb-chip.on { border-color: var(--shb-red); background: var(--shb-bg-3); }
.shb-chip.on b, .shb-chip.on span { color: var(--shb-fg); }
.shb-chip.urge b { color: var(--shb-red-2); }
.shb-chip.avisa b { color: var(--shb-warn); }
.shb-chip.bien b { color: var(--shb-ok); }

/* ── PESTAÑAS ───────────────────────────────────────────────────────────── */
.shb-tabs {
    display: flex;
    gap: 6px;
    background: var(--shb-bg-2);
    border: 1px solid var(--shb-line);
    border-radius: var(--shb-r-s);
    padding: 4px;
    margin-bottom: 12px;
}
.shb-tab {
    flex: 1 1 0;
    min-height: 44px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--shb-fg-3);
    font: inherit;
    font-size: var(--shb-f3);
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: color .14s ease, background-color .14s ease;
}
.shb-tab.on { background: var(--shb-bg-3); color: var(--shb-fg); }

/* ── BUSCADOR ───────────────────────────────────────────────────────────── */
.shb-search {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--shb-bg-2);
    border: 1px solid var(--shb-line);
    border-radius: var(--shb-r-s);
    padding: 0 12px;
    margin-bottom: 12px;
}
.shb-search .shb-ic { font-size: var(--shb-f4); color: var(--shb-fg-3); }
.shb-search input {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 46px;
    border: 0;
    background: transparent;
    color: var(--shb-fg);
    font: inherit;
    font-size: var(--shb-finput);
    outline: none;
}

/* ── LISTA DE PRODUCTOS ─────────────────────────────────────────────────── */
.shb-list { display: flex; flex-direction: column; gap: 8px; }

.shb-card {
    display: grid;
    grid-template-columns: 68px 1fr;
    gap: 12px;
    padding: 10px;
    border-radius: var(--shb-r);
    border: 1px solid var(--shb-line);
    background: var(--shb-bg-2);
}
.shb-card.urge { border-color: rgba(238, 53, 43, .55); }

.shb-fig {
    position: relative;
    width: 68px;
    height: 68px;
    border-radius: var(--shb-r-s);
    overflow: hidden;
    background: var(--shb-bg-3);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--shb-line);
    padding: 0;
    cursor: pointer;
    color: var(--shb-fg-3);
    font-size: var(--shb-f6);
}
.shb-fig img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Chapita "fija": es la respuesta visible a "que quede fija". Sin esto, una foto
   elegida a mano y una del robot se ven exactamente igual, y el que la eligió no
   tiene forma de saber si quedó. */
.shb-fig-tag {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    font-size: var(--shb-f1);
    font-weight: 700;
    text-align: center;
    padding: 2px 0;
    background: rgba(10, 10, 11, .82);
    color: var(--shb-gold);
    letter-spacing: .04em;
}
.shb-fig-tag.bot { color: var(--shb-fg-3); }
.shb-fig-tag.falta { color: var(--shb-red-2); }

.shb-body { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.shb-tit { font-size: var(--shb-f4); font-weight: 700; line-height: 1.2; word-break: break-word; }
.shb-sub { font-size: var(--shb-f2); font-weight: 500; color: var(--shb-fg-3); }

.shb-nums { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.shb-precio { font-size: var(--shb-f5); font-weight: 900; }
.shb-precio.cero { color: var(--shb-red-2); }
.shb-stock { font-size: var(--shb-f3); font-weight: 700; color: var(--shb-ok); }
.shb-stock.avisa { color: var(--shb-warn); }
.shb-stock.urge { color: var(--shb-red-2); }
.shb-costo { font-size: var(--shb-f2); font-weight: 500; color: var(--shb-fg-3); }

.shb-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.shb-tag {
    font-size: var(--shb-f1);
    font-weight: 700;
    padding: 3px 7px;
    border-radius: 999px;
    border: 1px solid var(--shb-line-2);
    color: var(--shb-fg-3);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.shb-tag.oro { border-color: rgba(237, 174, 1, .5); color: var(--shb-gold); }
.shb-tag.roja { border-color: rgba(238, 53, 43, .5); color: var(--shb-red-2); }
.shb-tag.verde { border-color: rgba(53, 192, 122, .5); color: var(--shb-ok); }

.shb-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }

/* ── BOTONES ────────────────────────────────────────────────────────────── */
.shb-btn {
    min-height: 40px;
    padding: 0 13px;
    border-radius: 9px;
    border: 1px solid var(--shb-line-2);
    background: var(--shb-bg-3);
    color: var(--shb-fg);
    font: inherit;
    font-size: var(--shb-f3);
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    cursor: pointer;
    text-decoration: none;
    transition: transform .12s ease, opacity .12s ease, background-color .14s ease, border-color .14s ease;
}
.shb-btn:active { transform: scale(.97); }
.shb-btn:disabled { opacity: .42; cursor: not-allowed; }
.shb-btn.pri { background: linear-gradient(150deg, #ee352b, #8c0209); border-color: transparent; color: #fff; }
.shb-btn.peli { border-color: rgba(238, 53, 43, .55); color: var(--shb-red-2); background: transparent; }
.shb-btn.ghost { background: transparent; }
.shb-btn.full { width: 100%; }

/* El botón lleva la consecuencia adentro: qué hace y qué pasa después. */
.shb-btn.expl {
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    min-height: 52px;
    padding: 8px 13px;
    text-align: left;
}
/* color:inherit a propósito — hay .expl adentro de contenedores con reglas de
   descendencia sobre span, y ésas le ganan a una clase (0,1,1) > (0,1,0). */
.shb-btn.expl .ttl { font-size: var(--shb-f3); font-weight: 700; color: inherit; }
.shb-btn.expl .por { font-size: var(--shb-f1); font-weight: 500; opacity: .78; color: inherit; }

/* ── AVISOS ─────────────────────────────────────────────────────────────── */
.shb-nota {
    display: flex;
    gap: 9px;
    align-items: flex-start;
    padding: 10px 12px;
    border-radius: var(--shb-r-s);
    border: 1px solid var(--shb-line);
    background: var(--shb-bg-2);
    font-size: var(--shb-f2);
    font-weight: 500;
    color: var(--shb-fg-2);
    line-height: 1.4;
    margin-bottom: 10px;
}
.shb-nota .shb-ic { font-size: var(--shb-f4); flex: 0 0 auto; margin-top: 1px; }
.shb-nota.avisa { border-color: rgba(245, 179, 1, .45); color: var(--shb-warn); }
.shb-nota.mala { border-color: rgba(238, 53, 43, .5); color: var(--shb-red-2); }
.shb-nota.bien { border-color: rgba(53, 192, 122, .45); color: var(--shb-ok); }

.shb-vacio {
    text-align: center;
    padding: 34px 16px;
    color: var(--shb-fg-3);
    font-size: var(--shb-f3);
    font-weight: 500;
}
.shb-vacio b { display: block; color: var(--shb-fg); font-size: var(--shb-f4); margin-bottom: 5px; }

/* ── FORMULARIOS ────────────────────────────────────────────────────────── */
.shb-lbl {
    display: block;
    font-size: var(--shb-f1);
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--shb-fg-3);
    margin: 12px 0 5px;
}
.shb-in,
.shb-sel,
.shb-ta {
    width: 100%;
    min-height: 46px;
    padding: 10px 12px;
    border-radius: var(--shb-r-s);
    border: 1px solid var(--shb-line-2);
    background: var(--shb-bg-3);
    color: var(--shb-fg);
    font: inherit;
    font-size: var(--shb-finput);
    outline: none;
}
.shb-ta { min-height: 76px; resize: vertical; }
.shb-in:focus, .shb-sel:focus, .shb-ta:focus { border-color: var(--shb-red); }
.shb-ayuda { font-size: var(--shb-f1); font-weight: 500; color: var(--shb-fg-3); margin: 5px 0 0; line-height: 1.4; }
.shb-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.shb-chk { display: flex; align-items: center; gap: 9px; font-size: var(--shb-f3); font-weight: 500; margin-top: 10px; }
.shb-chk input { width: 20px; height: 20px; accent-color: var(--shb-red); }

/* ── MODAL (propio: MnxSheet vive bajo .mnx-root y en escritorio no existe) ── */
.shb-modal-bd {
    position: fixed;
    inset: 0;
    z-index: 9000;
    background: rgba(0, 0, 0, .66);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 0;
}
.shb-modal {
    width: 100%;
    max-width: 560px;
    max-height: 88vh;
    overflow-y: auto;
    background: var(--shb-bg);
    border: 1px solid var(--shb-line);
    border-bottom: 0;
    border-radius: 20px 20px 0 0;
    padding: 16px 16px calc(20px + env(safe-area-inset-bottom, 0px));
    animation: shbSube .2s ease-out both;
}
.shb-modal-hd {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}
.shb-modal-hd b { flex: 1 1 auto; font-size: var(--shb-f5); font-weight: 700; }
.shb-x {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--shb-line-2);
    background: transparent;
    color: var(--shb-fg-2);
    font-size: var(--shb-f4);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.shb-modal-acts { display: flex; gap: 8px; margin-top: 18px; }
.shb-modal-acts .shb-btn { flex: 1 1 0; }

@keyframes shbSube {
    from { transform: translateY(18px); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

/* ── EL BOTÓN ANIMADO DEL HOME (escritorio) ─────────────────────────────────
   En el celular el botón es un .mnx-copro más (mnx.css). Acá vive la versión de
   escritorio, con el MISMO contenido: estado, avance y consecuencia. */
.shb-copro {
    display: block;
    text-decoration: none;
    color: var(--shb-fg);
    background: linear-gradient(150deg, #16181d, #0e0f12);
    border: 1px solid var(--shb-line-2);
    border-radius: var(--shb-r);
    padding: 14px 16px;
    margin-bottom: 14px;
    animation: shbEntra .34s ease-out both;
    transition: transform .16s ease, border-color .16s ease;
}
.shb-copro:hover { border-color: var(--shb-red); transform: translateY(-2px); }
.shb-copro:active { transform: scale(.99); }
.shb-copro.urge { border-color: var(--shb-red); }
.shb-copro-top { display: flex; align-items: center; gap: 12px; }
.shb-copro-ico {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: linear-gradient(150deg, #ee352b, #8c0209);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--shb-f6);
    flex: 0 0 auto;
}
.shb-copro-hd { flex: 1 1 auto; min-width: 0; }
.shb-copro-hd .tit { display: block; font-size: var(--shb-f5); font-weight: 700; line-height: 1.15; }
.shb-copro-hd .est { display: block; font-size: var(--shb-f2); font-weight: 500; color: var(--shb-fg-3); margin-top: 3px; }
.shb-copro-hd .est.urge { color: var(--shb-red-2); font-weight: 700; }
.shb-copro-hd .est.avisa { color: var(--shb-warn); }
/*  ⚠️ `.ok`, NO `.bien`: el escalón lo escribe CoproCopy (Ok/Avisa/Urge/Neutro)
    y es el MISMO string en las dos casas — sólo cambian los tokens de color.
    Con `.bien` acá, "todo al día" salía sin color en escritorio y con verde en
    el celular, sin un solo error: una clase que no matchea no se queja. */
.shb-copro-hd .est.ok { color: var(--shb-ok); }
.shb-copro-ir { flex: 0 0 auto; font-size: var(--shb-f4); color: var(--shb-fg-3); }
.shb-copro-pasos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.shb-copro-paso {
    font-size: var(--shb-f1);
    font-weight: 500;
    color: var(--shb-fg-3);
    border: 1px solid var(--shb-line);
    border-radius: 999px;
    padding: 4px 9px;
}
.shb-copro-paso b { font-weight: 700; color: var(--shb-fg); }
.shb-copro-paso.vivo b { color: var(--shb-red-2); }
.shb-copro-paso.hecho b { color: var(--shb-ok); }
.shb-copro-por {
    display: block;
    font-size: var(--shb-f1);
    font-weight: 500;
    color: var(--shb-fg-3);
    line-height: 1.35;
    margin-top: 10px;
}

@keyframes shbEntra {
    from { transform: translateY(8px); opacity: 0; }
    to   { transform: translateY(0);   opacity: 1; }
}

/* ── ESCRITORIO: dos columnas de tarjetas ───────────────────────────────── */
@media (min-width: 900px) {
    .shb-list { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: start; }
    .shb-card { grid-template-columns: 88px 1fr; }
    .shb-fig { width: 88px; height: 88px; }
    .shb-modal-bd { align-items: center; padding: 20px; }
    .shb-modal { border-radius: 18px; border-bottom: 1px solid var(--shb-line); max-height: 84vh; }
}

/* ⚠️ Todo lo animado arranca VISIBLE: acá sólo se apaga el movimiento, nunca se
   esconde nada. Si esta regla no llegara, se ve todo igual. */
@media (prefers-reduced-motion: reduce) {
    .shb-copro,
    .shb-modal { animation: none; }
    .shb-btn,
    .shb-chip,
    .shb-copro { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FICHA-POS (2026-08-02) :: "abrir el producto para verlo bien"
   ═══════════════════════════════════════════════════════════════════════════
   Pedido del dueño: "que se pueda abrir el producto para verlo bien y que te
   tire info detallada y una foto HD, cosa de saber perfectamente qué producto
   es. Necesito toda la info que se pueda con un diseño premium best in class".

   ⚠️ PREMIUM ACÁ NO ES ADORNO: es JERARQUÍA. La ficha se abre a mitad de una
   venta, con un cliente adelante. Tiene UN protagonista (la foto grande, que es
   lo que contesta "¿qué producto es?"), UN número de plata dominante y todo lo
   demás en un solo peso, agrupado. Doce datos gritando a la vez se lee igual
   que ninguno — la misma regla que los presupuestos del catálogo.

   ⚠️ NO SE USA NINGÚN TOKEN NUEVO: los seis pasos tipográficos y la paleta ya
   estaban declarados arriba en `.shb`. Una escala paralela es cómo mnx.css
   llegó a tener 27 tamaños distintos, con medios píxeles adentro. */

.shb-ficha { max-width: 560px; width: 100%; }

/* ── LA FOTO, QUE ES EL PROTAGONISTA ─────────────────────────────────────────
   Cuadrada (todas lo son desde que MediaDuenoStore las encuadra) y grande: es
   literalmente lo que el pedido vino a resolver.
   ⚠️ `contain`, nunca `cover`: con cover se le corta el cuello a la botella y la
   marca al paquete, o sea el detalle que se usa para reconocerla. */
.shb-fh {
    position: relative;
    width: 100%; aspect-ratio: 1 / 1; max-height: 340px;
    background: var(--shb-bg-3);
    border-radius: var(--shb-r);
    overflow: hidden;
    display: grid; place-items: center;
}
.shb-fh img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Sin foto NO es un hueco: es una placa que dice el nombre del producto. Un
   cuadrado gris vacío no informa nada; con el nombre adentro, por lo menos se
   sabe qué es. Misma lección que /api/catalogo/ph en el catálogo. */
.shb-fh.vacia { background: linear-gradient(160deg, #1b1e25, #121419); padding: 22px; }
.shb-fh-vac { text-align: center; color: var(--shb-fg-2); }
.shb-fh-vac b { display: block; font-size: var(--shb-f5); font-weight: 700; margin-bottom: 6px; }
.shb-fh-vac span { font-size: var(--shb-f2); color: var(--shb-fg-3); }

/* Origen de la foto, arriba a la izquierda. Se lee de un vistazo si es la que
   eligió una persona o la que puso el robot — que es lo que decide si vale la
   pena cambiarla. */
.shb-fh-tag {
    position: absolute; top: 10px; left: 10px;
    font-size: var(--shb-f1); font-weight: 700; letter-spacing: .3px;
    padding: 4px 9px; border-radius: 999px;
    background: rgba(0,0,0,.62); color: var(--shb-fg-2);
    backdrop-filter: blur(6px);
}
.shb-fh-tag.fija { color: var(--shb-gold); }

/* ── TÍTULO Y PLATA ──────────────────────────────────────────────────────────
   ⚠️ El nombre va COMPLETO y puede ocupar dos renglones. En la grilla del POS se
   corta con ellipsis ("MARLBORO VISTA…"), y esa es justamente la razón por la
   que hace falta abrir la ficha: acá cortarlo otra vez sería no resolver nada. */
.shb-fnom { font-size: var(--shb-f6); font-weight: 800; line-height: 1.15; margin: 14px 0 4px; }
.shb-fsub { font-size: var(--shb-f2); color: var(--shb-fg-3); margin: 0 0 12px; }
.shb-fdet { font-size: var(--shb-f3); color: var(--shb-fg-2); margin: 0 0 12px; }

/* UN solo número protagonista. El costo y el margen, cuando se ven, van en el
   peso de al lado — nunca compitiendo con el precio. */
.shb-fplata {
    display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
    padding: 12px 14px; border-radius: var(--shb-r-s);
    background: var(--shb-bg-2); border: 1px solid var(--shb-line);
    margin-bottom: 12px;
}
.shb-fprecio { font-size: var(--shb-f6); font-weight: 900; letter-spacing: -.5px; }
.shb-fcosto { font-size: var(--shb-f2); color: var(--shb-fg-3); }
.shb-fcosto b { color: var(--shb-fg-2); font-weight: 700; }

/* ── DATOS EN GRILLA ─────────────────────────────────────────────────────────
   Una sola superficie con hairlines adentro, no N cards flotando. Es lo que
   ordena la lectura cuando hay muchos datos (misma idea que `.mnx-group`). */
.shb-fgrid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 1px; background: var(--shb-line);
    border: 1px solid var(--shb-line); border-radius: var(--shb-r-s);
    overflow: hidden; margin-bottom: 12px;
}
.shb-fcel { background: var(--shb-bg-2); padding: 10px 12px; }
.shb-fcel .k { display: block; font-size: var(--shb-f1); color: var(--shb-fg-3); margin-bottom: 3px; }
.shb-fcel .v { font-size: var(--shb-f4); font-weight: 700; }
.shb-fcel .v.ok   { color: var(--shb-ok); }
.shb-fcel .v.warn { color: var(--shb-warn); }
.shb-fcel .v.mal  { color: var(--shb-red-2); }

/* ── STOCK POR LOCAL ─────────────────────────────────────────────────────────
   "No hay acá pero hay en Laprida" es una venta salvada, así que se muestra
   siempre y la propia va marcada. */
.shb-fsuc { display: flex; flex-direction: column; gap: 1px; background: var(--shb-line);
    border: 1px solid var(--shb-line); border-radius: var(--shb-r-s); overflow: hidden; margin-bottom: 12px; }
.shb-fsuc-r { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: var(--shb-bg-2); }
.shb-fsuc-r.mia { background: var(--shb-bg-3); }
.shb-fsuc-r .n { flex: 1; min-width: 0; font-size: var(--shb-f3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shb-fsuc-r .c { font-size: var(--shb-f4); font-weight: 700; }
.shb-fsuc-r .c.cero { color: var(--shb-fg-3); }
.shb-fsuc-r .yo { font-size: var(--shb-f1); font-weight: 700; color: var(--shb-gold); letter-spacing: .3px; }

/* ── AVISOS QUE CAMBIAN LO QUE SE COBRA ──────────────────────────────────────
   Retornable y perecedero no son "más datos": son plata y son fecha. Van
   marcados, no en la grilla gris con el resto. */
.shb-favi { display: flex; gap: 9px; align-items: flex-start; padding: 10px 12px; margin-bottom: 10px;
    border-radius: var(--shb-r-s); font-size: var(--shb-f3); line-height: 1.4;
    background: rgba(245,179,1,.09); border: 1px solid rgba(245,179,1,.28); color: var(--shb-fg); }
.shb-favi svg { flex: 0 0 auto; margin-top: 1px; color: var(--shb-warn); }

/* ── COMBOS ──────────────────────────────────────────────────────────────────
   Lo que se puede ofrecer con esto, a la vista en el momento de cobrarlo. */
.shb-fcombo { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.shb-fcombo span { font-size: var(--shb-f2); padding: 6px 11px; border-radius: 999px;
    background: var(--shb-bg-3); border: 1px solid var(--shb-line-2); color: var(--shb-fg-2); }
.shb-fcombo span b { color: var(--shb-fg); font-weight: 700; }

.shb-fsecc { font-size: var(--shb-f1); font-weight: 700; letter-spacing: .5px;
    text-transform: uppercase; color: var(--shb-fg-3); margin: 0 0 7px; }

/* Alturas chicas (la ficha se abre sobre el POS, que ya ocupa la pantalla):
   la foto cede primero, porque el resto son los datos que se vinieron a leer. */
@media (max-height: 780px) { .shb-fh { max-height: 220px; } .shb-fnom { font-size: var(--shb-f5); } }
@media (max-height: 640px) { .shb-fh { max-height: 160px; } }

/* ── VER LA FOTO ENTERA (2026-08-02) ─────────────────────────────────────────
   Pedido: "que la foto acá también puedas verla completa, apretás una vez más
   para verla completa".

   ⚠️ EL PROBLEMA REAL QUE RESUELVE: la ranura de la ficha es cuadrada y con
   `max-height`, así que una foto muy apaisada (packshots con la etiqueta al
   costado, que es lo que devuelven las APIs de los súper) entra chica y el
   detalle no se lee. Acá se ve a pantalla completa, con su proporción real.

   Va FIJO a la pantalla y por ENCIMA del modal de la ficha (que está en 1000):
   si quedara adentro del modal, heredaría su ancho y no serviría de nada. */
.shb-lupa {
    position: fixed; inset: 0;
    /* ⚠️ 9500, NO 1200. El backdrop del modal está en 9000: con 1200 el visor se
       abría DETRÁS de la ficha — se veía la foto gigante de fondo y el modal
       encima. Todo z-index nuevo se compara contra los que YA existen en el
       archivo, no se elige "un número grande". */
    z-index: 9500;
    background: rgba(0, 0, 0, .93);
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
    cursor: zoom-out;
}
.shb-lupa-img {
    /* ⚠️ `width/height: 100%` + `object-fit: contain`, NO `max-width/max-height`.
       Con max-* adentro de un contenedor de fila AUTOMÁTICA el porcentaje es
       indeterminado y el navegador lo ignora: la imagen se dibujaba a su tamaño
       NATURAL y se desbordaba de la pantalla (así se veía la Coca gigante y
       cortada). Con width/height fijos al contenedor —que es `fixed; inset:0`,
       o sea que SÍ tiene medida— `contain` la mete entera adentro, siempre. */
    width: 100%; height: 100%;
    object-fit: contain;
    /* `contain` deja el sobrante transparente, así que el fondo blanco iría a
       toda la caja y no a la foto. Por eso el blanco NO va acá. */
    background: transparent;
}
.shb-lupa-cerrar {
    position: absolute; top: 16px; right: 16px;
    width: 44px; height: 44px; border-radius: 999px;
    display: grid; place-items: center;
    background: rgba(255, 255, 255, .12); color: #fff;
    border: 1px solid rgba(255, 255, 255, .22);
}
.shb-lupa-pie {
    position: absolute; left: 0; right: 0; bottom: 18px;
    text-align: center; color: var(--shb-fg-2);
    font-size: var(--shb-f2); padding: 0 20px;
}

/* La foto de la ficha avisa que se puede agrandar. Es un <button>, así que
   necesita resetear el chrome del navegador. */
.shb-fh.zoomable { cursor: zoom-in; border: 0; padding: 0; width: 100%; }

/*  ⚠️ LA PISTA TIENE QUE LEERSE, NO INTUIRSE. El dueño reportó que "no se
    entiende que se puede agrandar". La versión anterior era una pastilla gris
    chiquita en una esquina, sobre una foto de góndola que suele ser blanca: se
    perdía. Ahora es una BARRA a lo ancho del pie de la foto, con el glifo de la
    lupa y el texto, sobre un degradé que la despega de cualquier fondo. */
.shb-fh-zoom {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    padding: 10px 12px;
    font-size: var(--shb-f2); font-weight: 700; letter-spacing: .3px;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, .78), rgba(0, 0, 0, 0));
    pointer-events: none;
}
.shb-fh-zoom .lupa {
    display: inline-grid; place-items: center;
    width: 24px; height: 24px; border-radius: 999px;
    background: rgba(255, 255, 255, .16);
    border: 1px solid rgba(255, 255, 255, .3);
    font-size: 12px; line-height: 1;
}
/*  Al pasar el mouse (o con el foco del teclado) la barra se enciende: confirma
    que eso es tocable antes de tocarlo. */
.shb-fh.zoomable:hover .shb-fh-zoom,
.shb-fh.zoomable:focus-visible .shb-fh-zoom {
    background: linear-gradient(to top, rgba(0, 0, 0, .9), rgba(0, 0, 0, .18));
}
.shb-fh.zoomable:hover .lupa { background: rgba(255, 255, 255, .28); }

/* ═══════════════════════════════════════════════════════════════════════════
   EFECTIVO EN EL LOCAL (2026-08-02) :: ítems 67, 85 y 32.
   ---------------------------------------------------------------------------
   Vive en stockhub.css y NO en una hoja nueva a propósito: el panel se monta en
   las DOS casas (celular y escritorio) y ésta es la única hoja autocontenida que
   _Host.cshtml ya sirve en todas las páginas. Una hoja más sería una escala
   tipográfica paralela más — que es exactamente cómo mnx.css llegó a tener 27
   tamaños con medios píxeles adentro.

   ⚠️ CERO tokens nuevos: los seis pasos (--shb-f1..f6) ya alcanzan.
   ═══════════════════════════════════════════════════════════════════════════ */

/*  EL NÚMERO. Un solo protagonista: todo lo demás de la pantalla existe para
    explicar de dónde sale. */
.efl-hero {
    margin: 14px 0 4px; padding: 18px 16px;
    background: linear-gradient(160deg, var(--shb-bg-2), var(--shb-bg-3));
    border: 1px solid var(--shb-line); border-radius: var(--shb-r);
    display: flex; flex-direction: column; gap: 6px;
}
/*  ⚠️ En rojo SÓLO si el esperado es negativo, que significa que salió más plata
    de la que entró: eso no es "poco efectivo", es que hay algo mal cargado. */
.efl-hero.neg { border-color: var(--shb-red); }
.efl-hero-lbl {
    font-size: var(--shb-f2); font-weight: 700; letter-spacing: .6px;
    text-transform: uppercase; color: var(--shb-fg-3);
}
.efl-hero-n {
    font-size: var(--shb-f6); font-weight: 900; line-height: 1.05;
    font-variant-numeric: tabular-nums;   /* no baila al refrescarse */
}
.efl-hero.neg .efl-hero-n { color: var(--shb-red-2); }
.efl-hero-sub {
    display: flex; align-items: center; gap: 7px;
    font-size: var(--shb-f2); color: var(--shb-fg-2);
}
.efl-hero-sub.avisa { color: var(--shb-warn); }

/*  LA CUENTA. Una superficie con hairlines adentro, no seis cards flotando. */
.efl-cuenta {
    margin: 12px 0; border: 1px solid var(--shb-line);
    border-radius: var(--shb-r-s); overflow: hidden;
}
.efl-fila {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 9px 13px; font-size: var(--shb-f3);
    border-bottom: 1px solid var(--shb-line);
}
.efl-fila:last-child { border-bottom: 0; }
.efl-fila span { color: var(--shb-fg-2); }
.efl-fila b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.efl-fila.pos b { color: var(--shb-ok); }
.efl-fila.neg b { color: var(--shb-red-2); }
.efl-fila.total {
    background: var(--shb-bg-2); font-size: var(--shb-f4);
    border-top: 1px solid var(--shb-line-2);
}
.efl-fila.total span { color: var(--shb-fg); font-weight: 700; }
.efl-fila.total b { font-weight: 900; }

.efl-pie {
    margin: 0 0 14px; font-size: var(--shb-f2); color: var(--shb-fg-3); line-height: 1.5;
}

.efl-det { border: 1px solid var(--shb-line); border-radius: var(--shb-r-s); overflow: hidden; }
.efl-det-r {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 8px 13px; font-size: var(--shb-f3);
    border-bottom: 1px solid var(--shb-line);
}
.efl-det-r:last-child { border-bottom: 0; }
.efl-det-r em { font-style: normal; color: var(--shb-fg-3); font-size: var(--shb-f1); }
.efl-det-r b { font-variant-numeric: tabular-nums; }
.efl-det-r b.pos { color: var(--shb-ok); }
.efl-det-r b.neg { color: var(--shb-red-2); }

.efl-acts { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 4px; }
.efl-acts .shb-btn { flex: 1 1 190px; }

/*  La consecuencia de lo que se está por hacer, ANTES de tocar el botón: cuánto
    queda en el local después del retiro, o si el pago baja o no el cajón. */
.efl-queda {
    margin: 12px 0 0; padding: 10px 12px;
    background: var(--shb-bg-3); border-radius: var(--shb-r-s);
    font-size: var(--shb-f2); color: var(--shb-fg-2); line-height: 1.5;
}
.efl-queda b { color: var(--shb-fg); font-variant-numeric: tabular-nums; }
