/* ============================================================
   OPERACIÓN · MASTER STAFFING · las medidas

   Reescrito el 22/oct/2026 por decisión de Dirección: sólo tokens de
   `orvik-tokens.css`, como `operacion-vivo.css`. Cero tamaños, pesos,
   radios o colores sueltos.

   La barra de migas, el título y las pestañas NO se vuelven a definir
   aquí: viven una sola vez en `operacion-pase.css` (`.pase-barra`,
   `.pase-tit`, `.pase-tabs`, `.pase-tb`), y las dos pantallas son la
   misma tira. Copiarlas sería tener dos definiciones de la misma
   pestaña, que se separan solas el día que se agregue una tercera.

   ── LA TRADUCCIÓN DEL SEMÁFORO · criterio del director, 25-oct ──
   El mockup manda en estructura, estados y forma; `orvik-tokens.css`
   manda en color y medida. Ningún hex fuera de tokens, y un color = un
   significado en todo el sistema.

     estado                     token
     ─────────────────────────  ──────────────────────────────────
     trabaja (con persona)      aqua de marca suave / --marca-principal-texto
     descansa (cobertura de     --neutro-suave / --neutro-texto
       descanso: D, DX, DNG)
     sin asignar                --proceso-suave / --proceso-texto
                                + borde 1 px PUNTEADO --proceso
     domingo de 24 h cubierto   el estado que sea (trabaja o sin
                                asignar) + la marca «24». NUNCA «D»
     día sin cobertura          un punto de 8 px --linea-fuerte al 50 %
     hoy                        la COLUMNA en --marca-suave y el número
                                del día en un círculo --foco

   NO SE USA --exito PARA «TRABAJA». El verde de este sistema significa
   «se presentó», y eso lo dice el Pase de lista. Si el rol pintara de
   verde lo que sólo está PREVISTO, el mismo color diría dos cosas.

   Y EL ÁMBAR DEL MOCKUP NO EXISTE EN ORVIK: los cinco ámbar y naranja
   de `orvik-tokens.css` son del Orvik Score y sólo valen ahí. Un puesto
   sin asignar no es una alarma: es algo a medio hacer, que es lo que
   `--proceso` significa en el resto de la consola.

   ══ v1.1 · 25-oct-2026 · DOS PANTALLAS, NO UNA QUE SE ENCOGE ══

   Referencia: `docs/mockups-orvik/master-staffing-v1-1-aprobado.html`
   (commit 5d9afa6), que manda en GEOMETRÍA de 769 px hacia arriba.

   El archivo está partido en tres a propósito:

     1 · BASE ............ lo que comparten las dos maquetas
     2 · @min-width 769 .. la REJILLA: celda de nombre de 248 px, línea
                           de renglón continua, cabecera y columna
                           pegadas, columna de hoy, días pasados
     3 · @max-width 768 .. la TARJETA POR PUESTO, tal como se aprobó el
                           22-oct y como está hoy en producción

   Toda medida nueva del v1.1 vive dentro del bloque 2. Es la única
   forma de cumplir la orden al pie de la letra --«en celular (≤768) se
   queda EXACTAMENTE el diseño de tarjetas actual»--: si una regla
   nueva viviera en la base, el teléfono tendría que deshacerla una por
   una, y la que se olvidara se colaría sin que nadie la viera.
   ============================================================ */

/* ══════════════════════════════════════════════════════════════
   1 · BASE
   ══════════════════════════════════════════════════════════════ */

/* ── LA CABECERA DEL MES ──
   Dos botones y el rótulo. No es un selector de fechas: el Master
   Staffing se mira mes por mes, que es como está en el Excel.
   A la derecha, separados por el hueco elástico, los tres saltos de
   semana del v1.1 --que sólo existen donde hay desplazamiento
   horizontal, o sea de 769 px hacia arriba--. */
#app .rol-mes {
  display: flex; align-items: center; gap: var(--e-3);
  flex-wrap: wrap; margin: 0 0 var(--hueco-tarjetas);
}
#app .rol-mes b { font: var(--t-tarjeta); color: var(--texto); min-width: 170px }
#app .rol-sep { flex: 1 }
#app .rol-nav {
  /* 44 de alto y radio 12 · anexo del 27-oct. Era `--r-pildora`:
     «Mes anterior», «Mes siguiente», «‹ Semana», «Semana ›» y «Hoy»
     son navegación, y la navegación va en rectángulo. */
  min-height: var(--toque); min-width: var(--toque); padding: 0 var(--e-4);
  border-radius: var(--r-control);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--e-1);
  font: var(--t-sec); font-family: inherit; cursor: pointer;
  background: var(--control); border: 1px solid var(--linea);
  color: var(--texto-2);
  transition: background var(--dur-base) var(--curva);
}
#app .rol-nav:hover { background: var(--superficie-2) }
#app .rol-nav:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px }
#app .rol-nav[disabled] { opacity: .5; cursor: default }
#app .rol-nav.pri {
  background: var(--marca-principal); color: var(--marca-sobre-principal);
  border-color: transparent;
}
/* El botón «Hoy» no es otro botón: es el que te devuelve al día de
   trabajo. Va del color legible de la marca, como en el mockup. */
#app .rol-nav.hoy { color: var(--marca-principal-texto); font-weight: 600 }
#app .rol-ac { display: flex; gap: var(--e-2); margin-top: var(--e-1) }

/* ── LA LEYENDA ──
   Sin ella, las letras A/B/C no significan nada para quien abre la
   pantalla por primera vez. El contorno del cuadrito no es adorno: el
   de «descansa» va sobre el fondo de la página y sin borde desaparece. */
#app .rol-leg {
  display: flex; align-items: center; gap: var(--e-4); flex-wrap: wrap;
  font: var(--t-sec); color: var(--texto-2);
  margin: 0 0 var(--hueco-tarjetas);
}
#app .rol-leg span { display: inline-flex; align-items: center; gap: var(--e-2) }
#app .rol-sq {
  width: var(--e-3); height: var(--e-3); flex: none; display: inline-block;
  border-radius: var(--r-chico); border: 1px solid var(--linea);
}
#app .rol-sq.T { background: var(--marca-suave);
                 border-color: var(--marca-principal) }
#app .rol-sq.D { background: var(--neutro-suave) }
#app .rol-sq.V { background: var(--proceso-suave);
                 border: 1px dashed var(--proceso) }
/* El domingo de 24 h no es otro color: es el mismo estado con su marca.
   En el cuadrito la marca es la raya de abajo, como en la casilla.
   El mockup del v1.1 no lo dibuja --sus datos son de muestra y declara
   ser referencia de geometría-- pero el estado lo aprobó Dirección el
   25-oct, así que se queda. Anotado en el reporte. */
#app .rol-sq.H24 { background: var(--marca-suave);
                   border-color: var(--marca-principal);
                   box-shadow: inset 0 -2px 0 0 var(--marca-principal-texto) }
/* La casilla sin servicio también va en la leyenda: si no, «el día que
   no sale» parece un error de dibujo y no un dato. */
#app .rol-sq.X { background: transparent; border-style: dashed;
                 border-color: var(--linea-fuerte) }

/* ── LA TARJETA DEL CALENDARIO ──
   `position: relative` para el degradado del borde derecho, y
   `overflow: hidden` para que la tabla, que va a ras de la tarjeta, no
   se salga por las esquinas redondeadas. */
#app .rol-cal {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); padding: 0;
  position: relative; overflow: hidden; isolation: isolate;
}
/* `isolation: isolate` no se ve, y hace falta: los `z-index` de la
   cabecera pegada y de la columna de nombres son de ESTA tabla, y sin
   aislar compiten con los de la consola --la barra flotante y el
   lateral-- que usan los mismos tokens. Dentro de un contexto propio
   no pueden pasarse por encima. */

#app .rol-n { font: var(--t-cuerpo); color: var(--texto-2) }
#app .rol-n b { font: var(--t-cuerpo-f); color: var(--texto) }
#app .rol-n .rol-sin { color: var(--proceso-texto) }

/* La casilla que se puede tocar va dentro de un `td` sin relleno, para
   que el botón mida exactamente lo mismo que las casillas fijas. Con
   dos envoltorios distintos las tocables medían un píxel menos de alto
   y la cuadrícula se veía torcida. */
#app .rol-cal td.rol-c { padding: 0 }
#app .rol-d {
  width: var(--e-8); height: var(--e-8); min-width: var(--e-8);
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-chico); border: 1px solid transparent;
  font: var(--t-nota); font-family: inherit; padding: 0;
  cursor: default;
}
/* La letra de la casilla: 13/600. `--t-sec` es 13/500 y `--t-cuerpo-f`
   es 14/600; ninguno es 13/600, así que se compone con los dos tokens
   --tamaño y familia de `--t-sec`, peso de `--t-cuerpo-f`-- en vez de
   escribir un 13 y un 600 sueltos. */
#app .rol-d b { font: var(--t-sec); font-weight: 600 }

/* El borde de «trabaja» es el del mockup: el aqua de marca al 40 %.
   Sin él, sobre el tinte suave la casilla no tiene contorno y en claro
   se pierde contra la tarjeta. Es `color-mix` sobre un TOKEN --cero
   hex-- y no un color nuevo: es el mismo aqua, más transparente. */
#app .rol-d.T { background: var(--marca-suave);
                color: var(--marca-principal-texto);
                border-color: color-mix(in srgb,
                              var(--marca-principal) 40%, transparent) }
#app .rol-d.D { background: var(--neutro-suave);  color: var(--neutro-texto) }
#app .rol-d.V { background: var(--proceso-suave); color: var(--proceso-texto);
                border: 1px dashed var(--proceso) }
/* DÍA SIN COBERTURA · ni fondo ni letra. Ese puesto no existía ese día
   --el 1 al 19 de octubre de los siete que nacieron el 1-nov-- y
   pintarlo gris decía «descansó», que es falso: no había servicio que
   descansar. En la PC, además, lleva el punto del v1.1 (bloque 2). */
#app .rol-d.X { background: none; border-color: transparent }

/* EL DOMINGO DE 24 H · no es un estado más: es el mismo estado
   (trabaja o sin asignar) con una marca. La marca es la raya de abajo,
   del color fuerte de su estado, y el contenido es «24», nunca «D»
   --la letra «D» de este cuadro significa descanso y el domingo
   cubierto es justo lo contrario--.

   La raya va en `--marca-principal-texto` y NO en `--marca-principal`:
   medido en el banco, el aqua de marca sobre su propio tinte da 1.74:1
   en claro --invisible--. `--marca-principal-texto` es justo el token
   que existe para eso, «la variante legible sobre el fondo actual», y
   sube a 4.55:1. */
#app .rol-d.H24 { box-shadow: inset 0 -2px 0 0 var(--marca-principal-texto) }
#app .rol-d.H24.V { box-shadow: inset 0 -2px 0 0 var(--proceso-texto) }

#app button.rol-d { cursor: pointer; transition: outline-color var(--dur-rapida) var(--curva) }
#app button.rol-d:hover { outline: 2px solid var(--linea-fuerte) }
#app button.rol-d:focus-visible { outline: 2px solid var(--foco); outline-offset: 1px }
#app button.rol-d[disabled] { cursor: default; opacity: .7 }

/* El número del día sólo se enseña en el teléfono, donde no hay
   cabecera que lo diga. */
#app .rol-num { display: none }

#app .rol-nota,
#app .rol-cargando { font: var(--t-sec); color: var(--texto-3); margin-top: var(--e-3) }

#app .rol-vacio {
  display: flex; flex-direction: column; gap: var(--e-2);
  padding: var(--e-6);
  border-radius: var(--r-tarjeta);
  background: var(--superficie); border: 1px solid var(--linea);
}
#app .rol-vacio b { font: var(--t-tarjeta); color: var(--texto) }
#app .rol-vacio span { font: var(--t-cuerpo); color: var(--texto-2) }

/* ══════════════════════════════════════════════════════════════
   2 · LA REJILLA · 769 px o más
   Geometría del mockup aprobado 5d9afa6. Nada de esto llega al
   teléfono.
   ══════════════════════════════════════════════════════════════ */
@media (min-width: 769px) {

  /* ── EL MARCO QUE SE DESPLAZA ──
     Son dos cajas y cada una hace una cosa: `.rol-cal` es la tarjeta
     --borde, radio y el ancla del degradado-- y `.rol-scr` es la que
     se desplaza. Separadas porque el degradado tiene que quedarse
     quieto en el borde mientras los días pasan por debajo; si viviera
     dentro de la caja que se mueve, se iría con ellos.

     `max-height: 70vh` no es decoración: sin un alto que la limite, la
     tabla crece hasta lo que mida el mes y la que se desplaza es la
     PÁGINA. Y una cabecera pegada con `top: 0` se pega al borde de su
     propia caja de desplazamiento: si esa caja no se desplaza nunca,
     la cabecera nunca se pega. El alto es lo que hace que «pegada
     arriba» signifique algo. */
  #app .rol-scr {
    overflow: auto; max-height: 70vh; scroll-behavior: smooth;
  }
  #app .rol-cal table {
    border-collapse: separate; border-spacing: 0;
    width: max-content; min-width: 100%;
  }
  /* `min-width: 100%` para que la línea del renglón llegue de lado a
     lado también cuando el mes es más estrecho que la tarjeta --un
     monitor muy ancho-- y no se corte a media tarjeta. */
  #app .rol-cal th,
  #app .rol-cal td { padding: 0 }

  /* ── LA COLUMNA DE NOMBRES · celda de tabla, dos líneas ──
     Vuelve a ser una CELDA: sin `display: flex` en el `td`. Con flex
     el `td` deja de ser celda de tabla y su alto y su línea de abajo
     dejan de alinearse con los de la fila, que es justo lo que se
     medía torcido.

     Ancho fijo de 248 px --los tres, `width`, `min` y `max`-- para que
     la primera casilla de TODOS los renglones y la de la cabecera
     empiecen en la misma x. Con un ancho elástico cada renglón
     empezaba donde lo dejaba su nombre más largo. */
  #app .rol-cal td.rol-n,
  #app .rol-cal th.rol-n {
    position: sticky; left: 0; background: var(--superficie);
    width: 248px; min-width: 248px; max-width: 248px;
    padding: var(--e-2) var(--e-4) var(--e-2) var(--e-5) !important;
    border-bottom: 1px solid var(--linea);
    border-right: 1px solid var(--linea);
    text-align: left !important; vertical-align: middle;
    z-index: var(--z-contenido);
  }
  /* Dos líneas, y las dos se cortan con «…» por el final --nunca se
     parten en dos renglones, que descuadraría la fila--. Lo que el
     «…» se come está en el `title`. */
  #app .rol-l1, #app .rol-l2 {
    display: block; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap;
  }
  #app .rol-l1 { font: var(--t-cuerpo-f); color: var(--texto) }
  #app .rol-l2 { font: var(--t-nota); color: var(--texto-3) }
  #app .rol-l2 .rol-sin { color: var(--proceso-texto); font-weight: 600 }
  #app .rol-l2 .rol-per { color: var(--texto-2); font-weight: 600 }
  /* El cliente no cabe en 248 px junto al sitio, y es lo que se repite
     renglón tras renglón: va en el `title`, con todo lo demás. */
  #app .rol-cliente { display: none }

  /* La sombra del borde SÓLO cuando hay desplazamiento horizontal: con
     el mes al principio no hay nada tapado debajo y una sombra sin
     nada que tapar es una raya sucia. La clase la pone el JS al oír el
     desplazamiento.

     Va en `--linea-fuerte` y no en el negro del mockup: la consigna es
     cero color fuera de tokens, y el propio mockup lo dice --«en el
     panel, con token de sombra»--. Ninguna de las tres sombras de
     `orvik-tokens.css` es horizontal, así que la geometría es la del
     mockup y el color es el del token. */
  #app .rol-scr.desp td.rol-n,
  #app .rol-scr.desp th.rol-n {
    box-shadow: var(--e-2) 0 var(--e-3) calc(var(--e-2) * -1) var(--linea-fuerte);
  }

  /* ── LA CABECERA DE DÍAS, PEGADA ARRIBA ──
     `panel.css` pinta TODO `th` con fondo navy, mayúsculas, 800 y
     alineado a la izquierda. Aquí no es una cabecera de tabla de
     datos: es la regla de un calendario. Se anula para la fila
     entera, con `!important` donde `panel.css` gana por orden de
     cascada.

     ── EL ORDEN DE CAPAS, CORREGIDO RESPECTO AL MOCKUP ──
     El mockup deja la columna de nombres (z 2) por ENCIMA de la
     cabecera (z 1). Con eso, al bajar por un mes de 30 renglones los
     nombres se pintan sobre los días pegados arriba. El orden correcto
     es el contrario, y la esquina --el `th` que es las dos cosas-- va
     arriba de todo:

       esquina «PUESTO» ... --z-lateral   (20)
       cabecera de días ... --z-barra     (10)
       columna de nombres . --z-contenido (1)
       casillas ........... sin z

     Es el mismo diseño, bien apilado. Anotado en el reporte. */
  #app .rol-cal .rol-cab th {
    position: sticky; top: 0; z-index: var(--z-barra);
    background: var(--superficie) !important;
    border-bottom: 1px solid var(--linea-fuerte);
    border-radius: 0 !important;
    height: calc(var(--e-10) + var(--e-2));
    vertical-align: middle;
    text-transform: none !important;
    letter-spacing: normal !important;
    font: var(--t-sec) !important;
    color: var(--texto-3) !important;
    text-align: center !important;
    padding: 0 !important;
  }
  #app .rol-cal .rol-cab th.rol-n {
    z-index: var(--z-lateral);
    font: var(--t-etiqueta) !important;
    /* El 0.06em es el que el propio token documenta para las
       etiquetas en mayúsculas («MAYÚSCULAS, espaciado 0.06em»). */
    letter-spacing: .06em !important;
    text-transform: uppercase !important;
    color: var(--texto-3) !important;
  }
  #app .rol-cal .rol-cab th.rol-dia {
    width: calc(var(--e-8) + var(--e-2));
    min-width: calc(var(--e-8) + var(--e-2));
  }
  /* La letra del día arriba y el número abajo, cada uno en su token.
     En dos líneas porque en una sola «M 24» se partía por donde el
     navegador quería. */
  #app .rol-cab th.rol-dia small {
    display: block; font: var(--t-etiqueta); color: var(--texto-3);
  }
  #app .rol-cab th.rol-dia b {
    display: block; font: var(--t-sec); font-weight: 600; color: var(--texto-2);
  }
  /* El domingo va del mismo color que los demás días. El rojo de este
     sistema es el de la Alerta, y una cabecera no es una alerta. */
  #app .rol-cab th.rol-dia.rol-dom small,
  #app .rol-cab th.rol-dia.rol-dom b { color: var(--texto-3) }
  /* HOY · el número en un círculo de foco. Es el único redondel de la
     pantalla, y eso es lo que lo hace encontrable de un vistazo. */
  #app .rol-cab th.rol-dia.hoy b {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--e-6); height: var(--e-6);
    border-radius: var(--r-pildora);
    background: var(--foco); color: var(--superficie);
  }
  #app .rol-cab th.rol-dia.hoy small { color: var(--marca-principal-texto) }

  /* ── LA REJILLA ──
     La línea del renglón va en CADA casilla, no en la fila: un `tr` no
     admite borde cuando la tabla está en `border-collapse: separate`,
     y era la razón de que la línea se viera a trozos. Con
     `border-spacing: 0` y el borde en cada `td`, las líneas se tocan y
     la raya cruza de lado a lado. */
  #app .rol-cal td.rol-c {
    text-align: center; vertical-align: middle;
    border-bottom: 1px solid var(--linea);
    height: calc(var(--e-12) + var(--e-1));
  }
  #app .rol-cal .rol-d { margin: 0 auto }
  /* La raya vertical antes de cada lunes: parte el mes en semanas sin
     tener que contar días. */
  #app .rol-cal td.lun,
  #app .rol-cal th.lun { border-left: 1px solid var(--linea) }
  /* HOY · la columna entera, de la cabecera al último renglón. */
  #app .rol-cal td.hoy,
  #app .rol-cal th.rol-dia.hoy { background: var(--marca-suave) }
  /* El renglón bajo el ratón, completo --incluida la celda del nombre,
     que al estar pegada tiene fondo propio y si no se nombra se queda
     sin resaltar--. La columna de hoy conserva su tinte: es el dato,
     y el resalte es sólo de ayuda. */
  #app .rol-cal tbody tr:hover td { background: var(--superficie-2) }
  #app .rol-cal tbody tr:hover td.hoy { background: var(--marca-suave) }

  /* DÍA SIN SERVICIO · un punto, nunca una casilla en blanco. Una
     casilla vacía no dice nada: puede ser un dato que falta, un error
     de dibujo o un día que nadie generó. El punto dice «aquí se miró y
     no hay servicio». */
  #app .rol-d.X::after {
    content: ""; width: var(--e-2); height: var(--e-2);
    border-radius: var(--r-pildora);
    background: var(--linea-fuerte); opacity: .5;
  }

  /* LOS DÍAS PASADOS se ven, pero se ven apagados: ya no se cambian
     --eso es el pase de lista-- y el ojo tiene que irse solo a hoy y a
     lo que viene. El apagado va en la casilla, no en el `td`: el tinte
     de la columna de hoy y la línea del renglón son de la rejilla y no
     se apagan con ella. */
  #app .rol-cal td.rol-c.pas .rol-d { opacity: .55 }

  /* EL BORDE DERECHO QUE AVISA · un degradado hasta el color de la
     tarjeta. Sin él, la última columna visible parece el fin del mes.
     `pointer-events: none` o se tragaría el clic de las casillas que
     tiene debajo. */
  #app .rol-mas {
    position: absolute; top: 0; right: 0; bottom: 0;
    width: var(--e-8); pointer-events: none;
    background: linear-gradient(to right, transparent, var(--superficie));
  }
}

/* ══════════════════════════════════════════════════════════════
   3 · CELULAR · 768 o menos
   EN EL TELÉFONO NO HAY TABLA, HAY UNA TARJETA POR PUESTO.

   Una cuadrícula de 31 columnas en 375 px deja ver cuatro días, y el
   resto se busca arrastrando de lado con el pulgar mientras el nombre
   del puesto tapa media pantalla. Eso no es un calendario: es un
   calendario escondido.

   Aquí el renglón se abre: el nombre arriba, a todo el ancho, y el mes
   debajo en SIETE columnas. Como son siete, cada columna cae siempre
   en el mismo día de la semana y los domingos se alinean solos, sin
   rellenar el principio con casillas vacías. Y cada casilla mide el
   área táctil mínima de alto, con el número del día dentro, que es lo
   que sustituye a la cabecera.

   Es remaquetar, no encoger: ver [[orvik-no-es-recolorear-es-remaquetar]].
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  #app .rol-mes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e-2) }
  #app .rol-mes b { grid-column: 1 / -1; grid-row: 1; min-width: 0; text-align: center }
  #app .rol-nav { white-space: nowrap }
  /* Los saltos de semana y el hueco elástico no existen aquí: no hay
     desplazamiento horizontal que saltar --el mes va en siete
     columnas-- y tres botones más dejarían la cabecera en cuatro
     renglones. */
  #app .rol-sep, #app .rol-sem { display: none }

  #app .rol-cal { padding: 0; border: 0; border-radius: 0;
                  background: transparent; overflow: visible }
  #app .rol-scr { overflow: visible; max-height: none }
  #app .rol-mas { display: none }
  #app .rol-cal table,
  #app .rol-cal tbody { display: block; width: 100% }
  /* La cabecera de días no cabe y no hace falta: el número del día va
     dentro de cada casilla. */
  #app .rol-cal thead { display: none }
  /* `.rol-cal tr` pesa más que `.rol-cab` a secas, y la cabecera se
     quedaba pintada como una tarjeta suelta de números. */
  #app .rol-cal tr.rol-cab { display: none }

  #app .rol-cal tr {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--e-1);
    background: var(--superficie); border: 1px solid var(--linea);
    border-radius: var(--r-tarjeta);
    padding: var(--e-3) var(--e-2); margin-bottom: var(--e-3);
  }
  #app .rol-n {
    grid-column: 1 / -1; position: static; box-shadow: none;
    white-space: normal; min-width: 0; max-width: none;
    padding: 0 0 var(--e-1); font: var(--t-sec);
    display: block;
  }
  /* En el teléfono la tarjeta es de ancho completo y el rótulo se
     reparte en varias líneas: aquí no hay nada que acortar, y las dos
     líneas de la PC vuelven a ser un solo párrafo --el de hoy--. El
     separador lo pone el CSS porque en la PC no existe: allí cada
     línea va por su lado. */
  #app .rol-l1, #app .rol-l2 {
    display: inline; white-space: normal; overflow: visible;
    font: inherit; color: inherit;
  }
  #app .rol-l2::before { content: " · " }
  #app .rol-l2 .rol-per { color: inherit; font-weight: inherit }
  #app .rol-cliente { display: inline; max-width: none; overflow: visible;
                      white-space: normal }
  #app .rol-cal td.rol-c { display: block; border: 0; height: auto;
                           background: none }

  #app .rol-d {
    width: 100%; min-width: 0; height: var(--toque);
    flex-direction: column; justify-content: center; gap: 0;
    border-radius: var(--r-control); margin: 0;
  }
  /* HOY, en el teléfono, es el contorno de la casilla: no hay columna
     que teñir --cada tarjeta es un puesto y los días van en siete
     columnas-- ni cabecera donde poner el círculo. Es la marca
     aprobada el 22-oct y se queda tal cual. */
  #app .rol-d.hoy { outline: 2px solid var(--foco) }
  #app .rol-num { display: block; font: var(--t-etiqueta); opacity: .65 }
  /* El domingo NO va en rojo, ni en la cabecera de la PC ni aquí: el
     rojo de este sistema es el de la Alerta. Se distingue solo, porque
     en celular la rejilla es de siete columnas y el domingo es siempre
     la última. */
  #app .rol-d.dom .rol-num { opacity: 1 }
  #app .rol-d b { font: var(--t-sec); font-weight: 600 }
}

/* En un teléfono estrecho (iPhone SE, 320 px) siete casillas no caben
   con el relleno normal: se recorta el relleno, no la casilla. El área
   táctil mínima no se toca. */
@media (max-width: 360px) {
  #app .rol-cal tr { gap: var(--e-1); padding: var(--e-2) var(--e-1) }
  #app .rol-n { font: var(--t-nota) }
}

/* ═══════════════════════════════════════════════════════════════════════
   MASTER STAFFING COMO TERMINAL AÉREA · 27/oct/2026

   Del mockup aprobado el 26-oct. Medidas de `08-SISTEMA-VISUAL-v2.md`:
   tarjeta radio 16, botón píldora de 56, pastilla de 28, letra en
   13/15/17/24, márgenes 16 y 24, toque de 44.

   ── EL ÁMBAR VIVE AQUÍ, Y SÓLO AQUÍ ──

   El juego de tokens de Orvik tiene éxito, peligro, proceso y neutro;
   **no tiene ámbar**, porque hasta hoy ninguna pantalla lo necesitaba.
   Esta sí: es la tercera excepción de color del `08` §10, aprobada el
   26-oct para Master Staffing y sólo para Master Staffing.

   Se define aquí, en el archivo de esta pantalla, en vez de agregarlo
   al juego general: un token en `orvik-tokens.css` sería una
   invitación a usarlo en otra pantalla, y la excepción no es para
   otras. Los valores son los del mockup.

   Y ojo con la trampa A.1 de `docs/65-ERRORES-COMUNES.md`: una
   variable que no existe no falla, **desaparece**. Por eso todo lo
   demás usa nombres que ya están en `orvik-tokens.css`, comprobados
   uno por uno. */
.rol-ms, #ms-reloj, #ms-kpis, .ms-cuerpo {
  --ms-am-bg: rgba(242,181,13,.16); --ms-am: #F5C451;
  --ms-amf-bg: #F5C451; --ms-amf: #2A1C00;
}
:root[data-tema="claro"] .rol-ms,
:root[data-tema="claro"] #ms-reloj,
:root[data-tema="claro"] #ms-kpis,
:root[data-tema="claro"] .ms-cuerpo {
  --ms-am-bg: #FFF3DC; --ms-am: #8A5A00;
  --ms-amf-bg: #8A5A00; --ms-amf: #FFFFFF;
}
@media (prefers-color-scheme: light) {
  :root:not([data-tema="oscuro"]) .rol-ms,
  :root:not([data-tema="oscuro"]) #ms-reloj,
  :root:not([data-tema="oscuro"]) #ms-kpis,
  :root:not([data-tema="oscuro"]) .ms-cuerpo {
    --ms-am-bg: #FFF3DC; --ms-am: #8A5A00;
    --ms-amf-bg: #8A5A00; --ms-amf: #FFFFFF;
  }
}

/* ── EL RELOJ Y LA REGLA DIBUJADA ── */
#ms-reloj:empty, #ms-kpis:empty { display: none }
.ms-reloj {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); padding: var(--e-3) var(--e-4);
  display: grid; grid-template-columns: auto 1fr; gap: var(--e-1) var(--e-5);
  align-items: center; margin-bottom: var(--e-3);
}
.ms-ahora {
  font: 700 17px/22px var(--fuente); font-variant-numeric: tabular-nums;
  min-width: 170px;
}
.ms-ahora small {
  display: block; font: 500 13px/18px var(--fuente); color: var(--texto-3);
}
.ms-vivo {
  display: inline-flex; align-items: center; gap: var(--e-1);
  font: 500 13px/18px var(--fuente); color: var(--texto-3); margin-top: 2px;
}
.ms-vivo i {
  width: 8px; height: 8px; border-radius: var(--r-pildora);
  background: var(--exito); flex: none;
}
.ms-barra { position: relative; height: 28px }
.ms-pista, .ms-lleno {
  position: absolute; left: 0; top: 12px; height: 4px;
  border-radius: var(--r-pildora);
}
.ms-pista { right: 0; background: var(--superficie-2) }
.ms-lleno { background: var(--marca-principal) }
.ms-hito { position: absolute; top: 0; transform: translateX(-50%) }
.ms-hito i { display: block; width: 2px; height: 28px; background: var(--linea) }
/* ── LAS DOS LÍNEAS DE ETIQUETAS · anexo del inspector §2 ──
   Arriba, sola, la hora de entrada, centrada en su marca. Abajo, los
   otros tres, en tres columnas: izquierda, centro y derecha. En tres
   columnas no se pueden encimar aunque la hora de entrada se mueva,
   que es justo lo que rompía la línea única de antes. */
.ms-hitos {
  font: 500 13px/18px var(--fuente); color: var(--texto-3);
}
.ms-hitos-arriba { position: relative; height: 18px; margin-bottom: 2px }
.ms-hitos-arriba span {
  position: absolute; transform: translateX(-50%); white-space: nowrap;
}
.ms-hitos-abajo {
  display: grid; grid-template-columns: auto auto auto;
  justify-content: space-between; gap: var(--e-3);
}
.ms-hitos-abajo span { white-space: nowrap }
.ms-hitos-abajo span:nth-child(2) { text-align: center }
.ms-hitos-abajo span:nth-child(3) { text-align: right }
.ms-hitos b { color: var(--texto); font-weight: 600 }
/* La marca de la hora de entrada se ve, porque es la que tiene
   etiqueta propia arriba. */
.ms-hito-h i { background: var(--texto-3) }

/* ── LOS CINCO NÚMEROS · cada uno filtra ── */
.ms-kpis {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--e-2);
  margin-bottom: var(--e-3);
}
.ms-k {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); padding: var(--e-3) var(--e-4);
  min-height: 64px; display: grid; grid-template-columns: 1fr auto;
  align-items: end; text-align: left; cursor: pointer;
  font: inherit; color: var(--texto);
}
.ms-k small {
  grid-column: 1 / -1; font: 500 13px/18px var(--fuente); color: var(--texto-3);
}
.ms-k b { font: 700 17px/22px var(--fuente); font-variant-numeric: tabular-nums }
.ms-k em { font: 600 13px/18px var(--fuente); font-style: normal; color: var(--marca-principal-texto) }
.ms-k.on { box-shadow: inset 0 0 0 2px var(--marca-principal) }
.ms-k-ve b { color: var(--exito-texto) }
.ms-k-am b, .ms-k-amf b { color: var(--ms-am) }
.ms-k-ro b { color: var(--peligro-texto) }
.ms-k-ac b { color: var(--marca-principal-texto) }

/* ── LAS PASTILLAS DE ESTADO · 28 de alto, 13/600 (08 §4) ── */
.ms-ch {
  display: inline-flex; align-items: center; gap: var(--e-1);
  height: 28px; padding: 0 12px; border-radius: var(--r-pildora);
  font: 600 13px/16px var(--fuente); white-space: nowrap;
}
.ms-ch i {
  width: 8px; height: 8px; border-radius: var(--r-pildora);
  background: currentColor; flex: none;
}
.ms-ne  { background: var(--neutro-suave);  color: var(--neutro-texto) }
.ms-ve  { background: var(--exito-suave);   color: var(--exito-texto) }
.ms-ro  { background: var(--peligro-suave); color: var(--peligro-texto) }
.ms-mo  { background: var(--proceso-suave); color: var(--proceso-texto) }
.ms-ac  { background: var(--marca-suave);   color: var(--marca-principal-texto) }
.ms-am  { background: var(--ms-am-bg);      color: var(--ms-am) }
.ms-amf { background: var(--ms-amf-bg);     color: var(--ms-amf) }

/* ── EL CUERPO · la rejilla o la lista, y el detalle al lado ──

   ── `1fr` NO ES «LO QUE QUEDE» ──

   Esto decía `1fr 392px` y sacaba la página entera de la pantalla.
   `1fr` es `minmax(auto, 1fr)`, y ese `auto` quiere decir «al menos lo
   que mida su contenido». La tabla del mes es `width: max-content`:
   mide treinta y un días. Así que la columna no se encogía a lo que
   quedaba, se estiraba a lo que medía el mes, y lo que terminaba
   deslizándose de lado era **toda la consola**.

   Con `minmax(0, 1fr)` la columna puede encogerse hasta cero, y
   entonces el que se desplaza es quien debe: la tarjeta del mes, que
   para eso tiene su propia caja con `overflow: auto`.

   El `min-width: 0` de los hijos es la otra mitad de la misma regla, y
   hace falta aunque la de arriba esté: un hijo de grid tiene
   `min-width: auto` y vuelve a plantarse en su tamaño mínimo por su
   cuenta. Las dos juntas, o no sirve ninguna. */
/* ── EL DETALLE ES UN INSPECTOR · anexo del 27-oct ──

   CERRADO, EL PANEL NO EXISTE. Antes la columna de 392 px estaba
   siempre, con la frase «Toca un turno…» dentro: en 1440 se comía casi
   la mitad del mes y sólo se veían cinco o seis días. Ahora, cerrado,
   `.ms-cuerpo` es UNA columna y la rejilla usa todo el ancho --en 1440
   se ven unos dieciséis días-- y la frase se fue al final de la
   leyenda, que es donde se lee sin quitarle sitio a nada.

   ABIERTO, DEPENDE DEL ANCHO:
     · de 1280 para arriba, el panel entra por la derecha y la rejilla
       se encoge;
     · por debajo de 1280 el panel se pone ENCIMA de la rejilla, con su
       velo, porque encoger una rejilla que ya iba justa no deja ver ni
       el mes ni el detalle;
     · en celular no cambia nada: el detalle sigue debajo, como está.

   El ancho sólo cambia como respuesta a un toque, nunca solo. */
.ms-cuerpo {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--e-3); align-items: start; position: relative;
}
.ms-cuerpo > * { min-width: 0 }
#ms-det:empty { display: none }

@media (min-width: 1280px) {
  .ms-cuerpo { transition: grid-template-columns 250ms ease-out }
  .ms-cuerpo.abierto { grid-template-columns: minmax(0, 1fr) 392px }
}
@media (prefers-reduced-motion: reduce) {
  .ms-cuerpo { transition: none }
}

/* De 769 a 1279: encima, anclado a la derecha de la tarjeta, con velo.
   `--z-hoja` existe en `orvik-tokens.css` y es justo esta capa: una
   hoja sobre el contenido, por debajo de los diálogos. */
@media (min-width: 769px) and (max-width: 1279px) {
  .ms-cuerpo.abierto #ms-det {
    position: absolute; z-index: var(--z-hoja);
    top: 0; right: 0; width: 392px; max-width: calc(100% - var(--e-6));
  }
  .ms-cuerpo.abierto .ms-velo {
    display: block; position: absolute; inset: 0;
    background: rgba(15, 23, 42, 0.38);
    border: 0; padding: 0; cursor: pointer;
    z-index: calc(var(--z-hoja) - 1);
    border-radius: var(--r-tarjeta);
  }
}
.ms-velo { display: none }

/* La frase que antes vivía dentro del panel vacío. Va al final de la
   línea de la leyenda, alineada a la derecha, y se esconde en cuanto
   hay un turno abierto: ya no hay nada que invitar. */
#app .rol-leg-toca {
  margin-left: auto; color: var(--texto); font-weight: 600;
}
#app .ms-cuerpo.abierto .rol-leg-toca { display: none }

/* ── LA LISTA DE HOY ── */
.ms-filas { display: flex; flex-direction: column; gap: var(--e-2) }
.ms-fl {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); padding: var(--e-3) var(--e-4);
  min-height: 64px; display: grid; grid-template-columns: 56px 1fr auto;
  gap: var(--e-1) var(--e-3); align-items: center; text-align: left;
  cursor: pointer; font: inherit; color: var(--texto); width: 100%;
}
.ms-fl.sel { box-shadow: inset 0 0 0 2px var(--marca-principal) }
.ms-hr { font: 700 17px/22px var(--fuente); font-variant-numeric: tabular-nums }
.ms-n b { display: block; font: 600 15px/21px var(--fuente) }
.ms-n small { display: block; font: 500 13px/18px var(--fuente); color: var(--texto-3) }
@media (max-width: 560px) {
  .ms-fl { grid-template-columns: 56px 1fr }
  .ms-fl .ms-ch { grid-column: 2 }
}
.ms-vacio {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); padding: var(--e-5);
  font: 500 15px/21px var(--fuente); color: var(--texto-2); text-align: center;
}

/* ── LA COLUMNA DE HOY, EN LA REJILLA DEL MES ──
   Más ancha que las demás porque lleva una frase, no una letra. Ancho
   FIJO: el contador en vivo cambia de texto cada minuto y una celda
   elástica empujaría la fila entera («pantalla que brinca sola»). */
.rol-tdhoy { min-width: 196px }
.rol-hoyb {
  width: 188px; background: none; border: 0; padding: var(--e-1);
  cursor: pointer; font: inherit; display: flex; justify-content: center;
}
.rol-hoyb.sel .ms-ch { box-shadow: 0 0 0 2px var(--marca-principal) }
.rol-leg-hoy { color: var(--texto-3) }

/* ── EL DETALLE DEL TURNO ── */
.ms-det {
  background: var(--superficie); border: 1px solid var(--linea);
  border-radius: var(--r-tarjeta); display: flex; flex-direction: column;
  overflow: hidden; position: sticky; top: var(--e-3);
}
.ms-det-vacio { padding: var(--e-5); color: var(--texto-3) }
.ms-det-vacio p { margin: 0; font: 500 15px/21px var(--fuente) }
.ms-det-c {
  padding: var(--e-4); border-bottom: 1px solid var(--linea);
  display: flex; flex-direction: column; gap: var(--e-2);
}
.ms-det-top { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--e-3) }
.ms-lug { font: 600 17px/22px var(--fuente) }
.ms-d { font: 500 13px/18px var(--fuente); color: var(--texto-3) }
.ms-cerrar {
  /* 44, el área táctil mínima de `08`; el radio baja de píldora a 12
     por el anexo del 27-oct: un botón de ícono es 44 × 44, radio 12. */
  width: var(--toque); height: var(--toque); border-radius: var(--r-control);
  border: 1px solid var(--linea); background: var(--superficie);
  color: var(--texto-2); cursor: pointer; flex: none; font-size: 15px;
}
.ms-per { display: flex; align-items: center; gap: var(--e-3) }
.ms-per b { display: block; font: 600 15px/21px var(--fuente) }
.ms-per .ms-ch { margin-left: auto }
.ms-foto {
  width: 44px; height: 44px; border-radius: var(--r-pildora);
  background: var(--superficie-2); flex: none;
}
.ms-frase { font: 600 15px/21px var(--fuente) }
.ms-cuenta {
  background: var(--ms-am-bg); color: var(--ms-am);
  border-radius: var(--r-chico); padding: var(--e-2) var(--e-3);
  font: 600 13px/18px var(--fuente);
}
.ms-linea {
  padding: var(--e-3) var(--e-4); display: flex; flex-direction: column;
  max-height: 260px; overflow: auto;
}
.ms-rotl {
  font: 600 13px/16px var(--fuente); letter-spacing: .06em;
  text-transform: uppercase; color: var(--texto-3); margin-bottom: var(--e-2);
}
.ms-ev { display: grid; grid-template-columns: 48px 14px 1fr; gap: var(--e-2); align-items: start; padding-bottom: 10px }
.ms-ev .h { font: 600 13px/18px var(--fuente); color: var(--texto-3); font-variant-numeric: tabular-nums; text-align: right }
.ms-ev .pu {
  width: 10px; height: 10px; border-radius: var(--r-pildora); margin-top: 4px;
  background: var(--linea); box-shadow: 0 0 0 3px var(--superficie);
}
.ms-ev .pu.am { background: var(--ms-am) }
.ms-ev .pu.ac { background: var(--marca-principal) }
.ms-ev .pu.ro { background: var(--peligro) }
.ms-ev .pu.ne { background: var(--texto-3) }
.ms-ev .t { font: 400 13px/18px var(--fuente); color: var(--texto-2) }
.ms-ev .t b { color: var(--texto); font-weight: 600 }

/* ── LAS ACCIONES ──
   Dos columnas, y «Confirmar falta» separado por un hueco: una acción
   que destruye no va pegada a la principal. */
.ms-acc {
  padding: var(--e-3) var(--e-4) var(--e-4); border-top: 1px solid var(--linea);
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--e-2);
}
.ms-sep { grid-column: span 2; height: var(--e-2) }
.ms-bt {
  /* Radio 12 · anexo del 27-oct. Era `--r-pildora`. */
  min-height: 44px; border-radius: var(--r-control); padding: 0 var(--e-3);
  display: flex; align-items: center; justify-content: center; text-align: center;
  font: 600 15px/21px var(--fuente); cursor: pointer; border: 1px solid transparent;
}
.ms-bt.pri { grid-column: span 2; background: var(--marca-principal); color: var(--marca-sobre-principal) }
.ms-bt.sec { background: transparent; border-color: var(--linea); color: var(--texto) }
.ms-bt.mal { grid-column: span 2; background: transparent; border-color: var(--peligro); color: var(--peligro-texto) }
#ms-msg:not(:empty) { padding: 0 var(--e-4) var(--e-4) }

/* ── EN PANTALLA ANGOSTA, LA REGLA SE LEE EN RENGLONES ──

   Los cuatro hitos del reloj van colocados a lo ancho de la barra con
   un `left` en por ciento: a 1440 se leen de un vistazo y a 390 se
   encima uno sobre otro hasta volverse una mancha. Medido: a 390 las
   tres etiquetas caen en el mismo tramo de 358 px.

   No se achica la letra --nada baja de 13-- y no se quita ninguna: se
   dejan de colocar y se leen como lo que son, los pasos de la regla en
   orden. La barra se queda, porque lo que dibuja --cuánto falta-- sí
   cabe. */
@media (max-width: 900px) {
  .ms-reloj { grid-template-columns: 1fr; gap: var(--e-3) }
  .ms-ahora { min-width: 0 }
  /* En pantalla angosta las tres de abajo tampoco caben de lado: las
     dos líneas se vuelven una lista, una debajo de otra. */
  .ms-hitos, .ms-hitos-arriba, .ms-hitos-abajo {
    height: auto; display: flex; flex-direction: column; gap: 2px;
    margin-bottom: 0;
  }
  .ms-hitos span {
    position: static !important; transform: none !important;
    white-space: normal; left: auto !important; text-align: left !important;
  }
  /* Cinco cajas de 70 px no son cinco números: son cinco rendijas.
     De dos en dos cada una tiene 170 y su frase cabe entera. */
  .ms-kpis { grid-template-columns: repeat(2, 1fr) }
}
@media (max-width: 420px) {
  .ms-kpis { grid-template-columns: 1fr }
  .ms-k { min-height: 56px }
}

/* ── «HOY» NO ENSEÑA LOS MANDOS DEL MES ──

   El atributo `hidden` del HTML sólo vale mientras nadie le ponga un
   `display` encima, y estas dos cajas lo tienen: `.rol-mes` es `flex`
   y `.rol-leg` también. El resultado era que en «Hoy» seguían a la
   vista el navegador de meses, los saltos de semana y la leyenda de
   las letras, que ahí no significan nada.

   Es la misma trampa de siempre con `hidden`: no es una regla fuerte,
   es la más débil de todas. */
.rol-mes[hidden], .rol-leg[hidden] { display: none }

/* ── EL PIE DE LA TARJETA DEL MES ──
   Las dos frases del lienzo aprobado, dentro del mismo borde que la
   tabla: dicen qué se queda quieto al desplazarse y que hay mes a la
   derecha. En celular la segunda sobra --ahí no se desliza de lado,
   la tabla se dibuja de otra forma-- y se esconde. */
#app .rol-pie {
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--e-3); padding: var(--e-2) var(--e-4);
  border-top: 1px solid var(--linea);
  font: var(--t-sec); color: var(--texto-3);
}
#app .rol-pie b { color: var(--texto); font-weight: 600 }
/* La leyenda, ya dentro de la tarjeta: separada de la tabla por su
   propia raya, con el mismo relleno que el pie. */
#app .rol-cal > .rol-leg {
  margin: 0; padding: var(--e-3) var(--e-4);
  border-bottom: 1px solid var(--linea);
}
@media (max-width: 768px) {
  #app .rol-pie span:last-child { display: none }
}
