/* ============================================================================
   Juicy — Dashboard Design System · UTILITIES
   ----------------------------------------------------------------------------
   Reemplazo de `bootstrap-utilities.min.css` (56 KB). F6b, quitar Bootstrap.

   Reproduce SOLO las clases de utilidad EN USO por algún consumidor del DS
   (censo sobre juicy-core + gw-fields + Hub): no las ~1500 de Bootstrap. Una
   utilidad que falte mañana es un `add` de una línea — pero no se generan a lo
   bruto: lo que no se usa, no entra (mismo criterio que mató los tokens muertos
   del DS). "Usado" = la UNIÓN de consumidores, no un repo: el Hub añadió
   `border`/`border-top`/`p-3`/`pt-3`/`py-2`/`align-items-end` que juicy-core no
   usa — reproducirlas aquí evita que el Hub se rompa al quitar Bootstrap (F-hub-1).

   ⚠️ LLEVAN `!important`, A PROPÓSITO. Las utilidades de Bootstrap son
   `!important`, y el producto se apoya en eso: una `.text-center` gana aunque un
   selector más específico diga otra cosa. Reproducirlas SIN `!important` sería un
   cambio de conducta silencioso (perderían ante `.foo .bar{…}`). Es deuda —
   `!important` en utilidades es un martillo— pero quitarlo es una decisión
   aparte, medible, no un efecto colateral de esta migración. Ver el plan §4.a.

   Valores = la escala de Bootstrap 5, al pie de la letra (0·.25·.5·1·1.5·3 rem),
   para no mover un pixel. NO se cablean a `--space-*` del DS: esa escala es otra
   (y hoy ningún componente la consume). Convergerlas es trabajo futuro y visible.
   ============================================================================ */

/* ---- Display -------------------------------------------------------------- */
.d-none         { display: none !important; }
.d-block        { display: block !important; }
.d-inline-block { display: inline-block !important; }
.d-flex         { display: flex !important; }
.d-inline-flex  { display: inline-flex !important; }

/* ---- Flexbox -------------------------------------------------------------- */
.flex-column   { flex-direction: column !important; }
.flex-wrap     { flex-wrap: wrap !important; }
.justify-content-center  { justify-content: center !important; }
.justify-content-end     { justify-content: flex-end !important; }
.justify-content-between { justify-content: space-between !important; }
.align-items-start   { align-items: flex-start !important; }
.align-items-center  { align-items: center !important; }
.align-items-end     { align-items: flex-end !important; }

/* ---- Gap (escala de Bootstrap) -------------------------------------------- */
.gap-1 { gap: 0.25rem !important; }
.gap-2 { gap: 0.5rem !important; }
.gap-3 { gap: 1rem !important; }

/* ---- Sizing --------------------------------------------------------------- */
.w-100 { width: 100% !important; }

/* ---- Position ------------------------------------------------------------- */
.position-relative { position: relative !important; }
.position-sticky   { position: sticky !important; }

/* ---- Texto ---------------------------------------------------------------- */
.text-start  { text-align: left !important; }
.text-end    { text-align: right !important; }
.text-center { text-align: center !important; }

/* Utilidades de COLOR — el censo halló SOLO estas dos (1 uso c/u): el subtítulo
   de fecha del home (`text-secondary`) y el guion de "sin dato" del archive de
   clientes (`text-muted`). Bootstrap las pintaba con grises ARBITRARIOS
   (`text-secondary`=#6c757d, `text-muted`=rgba(33,37,41,.75)); aquí se mapean al
   TOKEN del DS de la misma intención — es el nombre de la clase cumpliendo lo que
   dice. Cambia el tono un pelo (DS-nativo) y de paso el guion vacío queda más
   tenue, que es lo correcto para un placeholder. Documentado como corrección
   deliberada, no como fidelidad al pixel. (Estas dos NO estaban en el censo
   inicial: mi regex de `text-*` no cubría los colores de tema — hueco corregido.) */
.text-secondary { color: var(--text-secondary) !important; }
.text-muted     { color: var(--text-muted) !important; }

/* `.text-red` — VINO DE `main.css` (0.9.157), donde estaba bajo "TEXTS COLORS" desde siempre.
   Es una utilidad de color como las dos de arriba, así que su sitio es esta hoja; que viviera en
   la legacy significaba que **el mismo marcado salía de dos colores**, porque el front nuevo no
   importa `main.css` a propósito. Medido con el espejo en Ajustes › Registradoras: el aviso de
   contraste del logo (`.juicy-logo-preview-warn`, que PHP emite con esta clase) daba
   `rgb(240,68,56)` en PHP y `rgb(62,67,73)` —el gris heredado— en React.

   ⚠ CON `--red-500` Y NO CON `--error-500`, que es lo que decía la regla original. Ese segundo es
   un ALIAS que define `main.css` (`--error-500: var(--red-500)`), o sea que en el front no existe
   y la declaración entera se cae sin decir nada. Es la trampa que ya está contada en
   `ds/bubble.css` a cuenta de esta misma clase, y por la que allí `.remove-filters-link` tuvo que
   declararse su propio color. El valor es el mismo #F04438, así que en PHP no se mueve un pixel —
   verificado con `foto-estilos.mjs` en dos pantallas, 0 diferencias.

   LA USAN 14 sitios del producto: los enlaces "Quitar Filtros" de ocho archives, los contadores de
   error de los tres importadores, los importes reembolsados del historial, el arqueo negativo de
   la caja y el aviso del logo de Ajustes. */
.text-red       { color: var(--red-500) !important; }

/* ---- Bordes (solo las usa el Hub: `.border`, `.border-top`) ----------------
   Bootstrap las pinta con `var(--bs-border-color)` = #dee2e6, definido en el
   `:root` de bootstrap-grid. Al quitar Bootstrap ese token desaparece; se
   reproduce el valor literal (fiel al pixel, como toda esta hoja). Tokenizarlo a
   un borde del DS es convergencia futura (F-hub-2/3), no un efecto colateral. */
.border     { border: 1px solid #dee2e6 !important; }
.border-top { border-top: 1px solid #dee2e6 !important; }

/* ---- Spacing (margin/padding, escala 0·.25·.5·1·1.5·3 rem) ----------------
   Solo los lados/pasos EN USO. mx-auto centra en horizontal. */
.m-0  { margin: 0 !important; }
.mt-1 { margin-top: 0.25rem !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
.mt-5 { margin-top: 3rem !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-1 { margin-bottom: 0.25rem !important; }
.mb-2 { margin-bottom: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1.5rem !important; }
.my-4 { margin-top: 1.5rem !important; margin-bottom: 1.5rem !important; }
.mx-auto { margin-right: auto !important; margin-left: auto !important; }

.p-0  { padding: 0 !important; }
.p-3  { padding: 1rem !important; }
.p-4  { padding: 1.5rem !important; }
.pe-1 { padding-right: 0.25rem !important; }
.pt-3 { padding-top: 1rem !important; }
.py-2 { padding-top: 0.5rem !important; padding-bottom: 0.5rem !important; }
.py-3 { padding-top: 1rem !important; padding-bottom: 1rem !important; }
.py-4 { padding-top: 1.5rem !important; padding-bottom: 1.5rem !important; }
.py-5 { padding-top: 3rem !important; padding-bottom: 3rem !important; }

/* ---- Responsivo (los únicos en uso: md/lg) -------------------------------- */
@media (min-width: 992px) {
  .d-lg-flex { display: flex !important; }
}

/* ---- Scroll horizontal SIN barra (`data-hscroll`) -------------------------
   Para barras que se desbordan a lo ancho: las categorías de la caja y los tabs
   de comensales. La barra de scroll estorba a la vista, y esconderla obliga a
   dar otra forma de moverse — de eso se encarga el JS (main.js): rueda del
   ratón (vertical → horizontal) y arrastre. En táctil el arrastre ya es nativo
   y no se toca.

   SIN `!important`, aunque el resto del archivo lo lleve: esto no es una
   utilidad de layout que deba ganarle a un componente, es un comportamiento.
   Un componente que necesite otro `overflow` tiene que poder pedirlo.
   ------------------------------------------------------------------------- */
[data-hscroll] {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* Edge legacy */
  overscroll-behavior-x: contain; /* llegar al borde no dispara el "atrás" */
}

/* Chrome/Safari ignoran `scrollbar-width`: ésta es la que de verdad la esconde
   ahí, y es la que faltaba (la barra de categorías ya traía la de Firefox). */
[data-hscroll]::-webkit-scrollbar {
  display: none;
}

/* Arrastrando: el cursor lo dice y el texto de los tabs no se selecciona
   (arrastrar sobre texto lo pinta de azul y se ve como un error). */
[data-hscroll].is-hdragging {
  cursor: grabbing;
  user-select: none;
}
