/* ============================================================
   Panel movil (M1) — Calendario de profesionales: barra del dia,
   fila de profesionales, rejilla, lista de «Todos» y hoja propia.
   REGLA DURA: todo dentro del @media (ver 01-carcasa.css).
   Spec: docs/superpowers/specs/2026-10-12-movil-m1-calendario-profesionales-design.md §4 y §7
   Prueba: scripts/test/e2e/movil/test_calendario_fixture.js (fixture-calendario.html
   lleva el marcado del contrato; si cambia una clase aqui, cambia alli).

   Las clases las pone Blazor, son estaticas. La rejilla va a escala (1 min = 1,2 px):
   el componente pone `top` y `height` en linea y este fichero no fija ninguna altura.
   Letra y objetivos tactiles en px: la raiz de Metronic en movil no son 16 px.
   ============================================================ */

@media (max-width: 991.98px) {
  /* --- Contenedor --------------------------------------------------------
     A todo el ancho de la pantalla: el margen negativo compensa el relleno lateral de
     #kt_app_content_container, que son 20 px (Metronic) y 12 px por debajo de 576
     (01-carcasa.css). Si ese relleno cambia, cambia aqui: lo vigila el fixture. */
  .vzt-cal {
    --vzt-cal-sangria: 20px;
    --vzt-cal-horas: 46px;
    --vzt-cal-sep: 4px;
    --vzt-cal-fondo: var(--bs-app-bg-color, var(--bs-body-bg));
    margin: 0 calc(-1 * var(--vzt-cal-sangria));
    background: var(--vzt-cal-fondo);
    color: var(--bs-gray-900);
    font-size: 13px;
    line-height: 17px;
  }

  @media (max-width: 575.98px) {
    .vzt-cal {
      --vzt-cal-sangria: 12px;
    }
  }

  /* --- Cabecera pegajosa -------------------------------------------------
     La barra del dia y la fila de profesionales, juntas: al desplazar la rejilla se sigue viendo
     que dia es, de quien es la agenda y el boton de filtros (spec §4.1). Se pega el contenedor y
     no cada pieza: la barra mide 56 px o 68 (titulo en dos lineas) y un `top` fijo para la fila
     la recortaria. Fondo opaco. z 5: por encima de todo lo de la rejilla (hasta 3), por debajo
     de la barra inferior (1039) y de las hojas (1056).
     La cabecera general NO es fija en movil (Metronic solo la fija con
     data-kt-app-header-fixed-mobile, que el panel no pone), asi que se pega a 0. Si un dia lo
     fuera, basta con dar --vzt-cal-dia-top en .vzt-cal. */
  .vzt-cal-cabecera {
    position: sticky;
    top: var(--vzt-cal-dia-top, 0px);
    z-index: 5;
    background: var(--bs-body-bg);
  }

  /* --- Barra del dia --- */
  .vzt-cal-dia {
    display: flex;
    align-items: center;
    gap: 2px;
    min-height: 56px;
    padding: 4px 6px;
    background: var(--bs-body-bg);
    box-shadow: 0 1px 0 var(--bs-border-color);
  }

  .vzt-cal-dia__flecha,
  .vzt-cal-dia__accion {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    min-width: 44px;
    height: 44px;
    margin: 0;
    padding: 0 6px;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--bs-primary);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    appearance: none;
  }

  .vzt-cal-dia__flecha {
    width: 44px;
    padding: 0;
  }

  .vzt-cal-dia__flecha i,
  .vzt-cal-dia__accion i {
    font-size: 15px;
    line-height: 1;
    color: inherit;
  }

  .vzt-cal-dia__accion:disabled {
    opacity: 0.45;
  }

  .vzt-cal-dia__acciones {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
  }

  /* Titulo y resumen. Es un <label>: tocarlo abre el selector de fecha nativo, porque el
     campo va superpuesto, transparente y a todo su tamano. */
  .vzt-cal-dia__centro {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 2px 0;
    text-align: center;
    cursor: pointer;
  }

  /* Un dia que no es hoy ni contiguo trae el mes y, a veces, el ano («Miercoles 30 de
     septiembre de 2025»): se parte en dos lineas antes que cortar una fecha. */
  .vzt-cal-dia__titulo {
    display: block;
    max-width: 100%;
    font-family: var(--vzt-font-titulo, inherit);
    font-size: 17px;
    font-weight: 800;
    line-height: 20px;
    letter-spacing: -0.01em;
    color: var(--bs-gray-900);
    text-wrap: balance;
  }

  .vzt-cal-dia__resumen {
    display: block;
    max-width: 100%;
    font-size: 12px;
    font-weight: 400;
    line-height: 16px;
    color: var(--bs-text-muted);
  }

  /* 16 px: por debajo, Safari de iPhone amplia la pagina al enfocar un campo. */
  .vzt-cal-dia__fecha {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    min-height: 44px;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    font-size: 16px;
    cursor: pointer;
  }

  /* En Chrome el selector solo se abre desde el icono del campo: se estira a todo el. */
  .vzt-cal-dia__fecha::-webkit-calendar-picker-indicator {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    cursor: pointer;
  }

  /* --- Fila de profesionales ---------------------------------------------
     La lista desplaza por dentro; el boton de filtros queda FUERA de ella, siempre a la
     vista. La lista llega hasta el borde izquierdo de la pantalla y se desvanece antes del
     boton, para que se note que hay mas nombres. */
  .vzt-cal-prof {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 12px 6px 0;
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color);
  }

  .vzt-cal-prof__lista {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 18px 4px 12px;
    overflow-x: auto;
    white-space: nowrap;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 18px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 18px), transparent);
  }

  .vzt-cal-prof__lista::-webkit-scrollbar {
    display: none;
  }

  /* Se ve de 36 px y se toca en 44: el ::after alarga el area de toque 4 px por arriba y por
     abajo, justo el relleno vertical de la lista (no asoma ni crea desplazamiento vertical).
     `inset` se mide desde el borde interior: -5px y -1px compensan el borde de 1 px. */
  .vzt-cal-prof__nombre {
    position: relative;
    flex: 0 0 auto;
    min-height: 36px;
    margin: 0;
    padding: 0 13px;
    border: 1px solid var(--bs-border-color);
    border-radius: 999px;
    background: var(--bs-body-bg);
    color: var(--bs-gray-700);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    appearance: none;
  }

  .vzt-cal-prof__nombre::after {
    content: "";
    position: absolute;
    inset: -5px -1px;
  }

  .vzt-cal-prof__nombre--activo {
    border-color: var(--bs-primary);
    background: var(--bs-primary);
    color: var(--bs-primary-inverse, #fff);
    font-weight: 600;
  }

  .vzt-cal-prof__filtros {
    position: relative;
    flex: 0 0 44px;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    background: var(--bs-body-bg);
    color: var(--bs-primary);
    font-size: 16px;
    line-height: 1;
    appearance: none;
  }

  .vzt-cal-prof__filtros i {
    font-size: 16px;
    line-height: 1;
    color: inherit;
  }

  /* Sobresale 5 px del boton: la fila reserva 6 arriba y 12 a la derecha, asi que se ve entera. */
  .vzt-cal-prof__cuenta {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--bs-primary);
    box-shadow: 0 0 0 2px var(--bs-body-bg);
    color: var(--bs-primary-inverse, #fff);
    font-size: 10px;
    font-weight: 600;
    line-height: 18px;
    text-align: center;
    pointer-events: none;
  }

  /* Mientras se carga un dia («Cargando el día…», el unico aviso con aria-busy) la vista conserva
     el alto de la pantalla: sin esto el documento encogia y la pagina saltaba arriba al cambiar de
     dia con la rejilla desplazada. */
  .vzt-cal:has(> .vzt-cal-aviso[aria-busy="true"]) {
    min-height: 100vh;
    min-height: 100dvh;
  }

  /* --- Avisos (dia sin horario, vacaciones, citas sin columna, lista vacia) --- */
  .vzt-cal-aviso {
    margin: 10px 12px 0;
    padding: 10px 12px;
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;
    background: var(--bs-body-bg);
    color: var(--bs-gray-700);
    font-size: 13px;
    line-height: 18px;
  }

  /* --- Rejilla -----------------------------------------------------------
     Los 46 px de la izquierda son la columna de horas: las cajas empiezan ahi. El aire de
     arriba y de abajo es para la etiqueta de la primera y de la ultima hora, que van a
     caballo de su linea. Orden de capas: horas, franjas y liberada tapada 0, huecos,
     bloqueos y citas 1, cita que libera hueco y «+N» 2, linea de ahora 3 (la cabecera, pegajosa, 5). */
  .vzt-cal-rejilla {
    position: relative;
    margin: 14px var(--vzt-cal-sep) 18px 0;
  }

  .vzt-cal-hora {
    position: absolute;
    left: 0;
    right: calc(-1 * var(--vzt-cal-sep));
    z-index: 0;
    height: 0;
    border-top: 1px solid var(--bs-border-color);
    pointer-events: none;
  }

  .vzt-cal-hora > small {
    position: absolute;
    top: -8px;
    left: 0;
    padding: 0 5px 0 10px;
    background: var(--vzt-cal-fondo);
    color: var(--bs-text-muted);
    font-size: 11px;
    font-weight: 400;
    line-height: 14px;
    font-variant-numeric: tabular-nums;
  }

  /* Citas, «+N», huecos y bloqueos son TARJETAS: la caja visible se dibuja con ::before y
     acaba 2 px antes que el elemento, para que dos seguidas (9:00-9:45 y 9:45-10:30) no
     queden pegadas. Asi el componente no tiene que restar nada al alto que calcula. Cada
     una lleva z-index numerico, que es lo que deja al ::before (z -1) detras de su texto y
     delante de lo que haya debajo. */
  .vzt-cal-cita,
  .vzt-cal-mas,
  .vzt-cal-hueco,
  .vzt-cal-bloqueo {
    position: absolute;
    box-sizing: border-box;
    margin: 0;
    border: 0;
    border-radius: 8px;
    background: none;
    overflow: hidden;
    font: inherit;
    text-align: left;
    appearance: none;
  }

  .vzt-cal-cita::before,
  .vzt-cal-mas::before,
  .vzt-cal-hueco::before,
  .vzt-cal-bloqueo::before {
    content: "";
    position: absolute;
    inset: 0 0 2px 0;
    z-index: -1;
    box-sizing: border-box;
    border-radius: 8px;
    pointer-events: none;
  }

  /* Franjas a todo el ancho util; acaban donde acaban las citas (que dejan 4 px a su derecha). */
  .vzt-cal-fuera,
  .vzt-cal-hueco,
  .vzt-cal-bloqueo {
    left: var(--vzt-cal-horas);
    right: var(--vzt-cal-sep);
  }

  /* Columnas: --col y --cols las pone el componente en linea. 4 px de separacion. */
  .vzt-cal-cita,
  .vzt-cal-mas {
    left: calc(var(--vzt-cal-horas) + (100% - var(--vzt-cal-horas)) * var(--col, 0) / var(--cols, 1));
    width: calc((100% - var(--vzt-cal-horas)) / var(--cols, 1) - var(--vzt-cal-sep));
  }

  /* --- Cita --------------------------------------------------------------
     Es un <button> con hijos planos: cliente, insignias (0 a 4) y servicio. Rejilla de una
     fila para cliente + insignias y otra para el servicio:
       - el cliente es la unica columna que encoge: con nombre largo se corta EL y las
         insignias quedan enteras y en su linea (en flex con salto de linea la insignia
         bajaba a la segunda linea y echaba el servicio fuera de la tarjeta);
       - la ultima columna (1fr) se queda con lo que sobre.
     container-type: size permite, mas abajo, saber si caben dos lineas. */
  .vzt-cal-cita {
    --vzt-cal-tono: var(--bs-gray-400);
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, auto) repeat(4, max-content) minmax(0, 1fr);
    grid-auto-rows: max-content;
    align-content: start;
    align-items: center;
    padding: 4px 8px 6px 11px;
    color: var(--bs-gray-900);
    font-size: 13px;
    line-height: 17px;
    cursor: pointer;
    container-type: size;
  }

  .vzt-cal-cita::before {
    border: 1px solid var(--bs-border-color);
    border-left: 4px solid var(--vzt-cal-tono);
    background: var(--bs-body-bg);
  }

  .vzt-cal-cita--success { --vzt-cal-tono: var(--bs-success); }
  .vzt-cal-cita--warning { --vzt-cal-tono: var(--bs-warning); }
  .vzt-cal-cita--danger { --vzt-cal-tono: var(--bs-danger); }
  .vzt-cal-cita--neutral { --vzt-cal-tono: var(--bs-gray-400); }

  .vzt-cal-cita__cliente {
    grid-row: 1;
    grid-column: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13px;
    font-weight: 600;
  }

  /* El servicio es, a su vez, un contenedor: su <span> interior se oculta cuando no le queda
     sitio para leerse (mas abajo). */
  .vzt-cal-cita__servicio {
    grid-row: 2;
    grid-column: 1 / -1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--bs-text-muted);
    font-size: 12px;
    font-weight: 400;
    line-height: 16px;
    container-type: inline-size;
  }

  /* NUNCA una astilla: con menos de 44 px (unos seis caracteres y los puntos suspensivos) el
     servicio no se pinta. Pasa en citas de 30 min, donde comparte linea con el cliente y las
     insignias y se queda con lo que sobre; con sitio para dos lineas ocupa la suya entera. */
  @container (max-width: 43.9px) {
    .vzt-cal-cita__servicio > span {
      display: none;
    }
  }

  .vzt-cal-cita > .vzt-cal-ins {
    grid-row: 1;
    margin-left: 5px;
  }

  /* Menos de 40 px de alto (citas de 25 a 30 min): no caben dos lineas y la segunda
     saldria cortada por la mitad. El servicio sube a la primera, detras del cliente y de
     las insignias, en la columna que sobra; y la linea se centra en la tarjeta.
     50cqh - 8.5px = lo que falta para centrar 17 px de linea en la caja visible. */
  @container (max-height: 39.9px) {
    .vzt-cal-cita__cliente,
    .vzt-cal-cita__servicio,
    .vzt-cal-cita > .vzt-cal-ins {
      margin-top: max(0px, calc(50cqh - 8.5px));
    }

    .vzt-cal-cita__servicio {
      grid-row: 1;
      grid-column: 6;
      margin-left: 7px;
    }
  }

  /* Corta (menos de 25 min): una sola linea, centrada, sin servicio. */
  .vzt-cal-cita--corta {
    align-content: center;
    padding-top: 0;
    padding-bottom: 2px;
    line-height: 16px;
  }

  .vzt-cal-cita--corta .vzt-cal-cita__cliente,
  .vzt-cal-cita--corta > .vzt-cal-ins {
    margin-top: 0;
  }

  .vzt-cal-cita--corta .vzt-cal-cita__servicio {
    display: none;
  }

  /* Cita que libera su hueco (cancelada, no asistio): sin color y tachada. Va por ENCIMA del
     hueco, pegada a la derecha y a media anchura de la zona de citas: la mitad derecha abre
     la cita y la izquierda sigue libre para reservar. Su texto va a la derecha: el hueco
     rotula a la izquierda y asi no se pisan. */
  .vzt-cal-cita.vzt-cal-cita--liberada {
    --vzt-cal-tono: var(--bs-border-color);
    left: calc(var(--vzt-cal-horas) + (100% - var(--vzt-cal-horas) - var(--vzt-cal-sep)) / 2);
    width: calc((100% - var(--vzt-cal-horas) - var(--vzt-cal-sep)) / 2);
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-top: 0;
    padding-bottom: 2px;
    opacity: 0.55;
  }

  .vzt-cal-cita--liberada .vzt-cal-cita__cliente {
    margin-top: 0;
    font-weight: 500;
    text-decoration: line-through;
  }

  .vzt-cal-cita--liberada > .vzt-cal-ins {
    flex: 0 0 auto;
    margin-top: 0;
  }

  /* Liberada cuya franja se ha vuelto a ocupar (la marca RejillaDiaMovil): con «Cancelada» visible
     tapaba media cita activa y tocar ahi abria la cancelada. Va por DEBAJO de las citas y no se
     lleva el toque; se sigue abriendo desde «Todos». */
  .vzt-cal-cita.vzt-cal-cita--liberada.vzt-cal-cita--tapada {
    z-index: 0;
    pointer-events: none;
  }

  /* --- «+N»: las citas que no caben lado a lado --- */
  .vzt-cal-mas {
    z-index: 2;
    display: grid;
    place-items: center;
    padding: 0 0 2px;
    color: var(--bs-primary);
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
  }

  .vzt-cal-mas::before {
    border: 1px solid rgba(var(--bs-primary-rgb), 0.25);
    background: linear-gradient(rgba(var(--bs-primary-rgb), 0.08), rgba(var(--bs-primary-rgb), 0.08)), var(--bs-body-bg);
  }

  /* --- Hueco libre -------------------------------------------------------
     Un <button> (o un <div> --pasivo si no se puede crear). */
  .vzt-cal-hueco {
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 9px 2px;
    color: var(--bs-text-muted);
    font-size: 12px;
    font-weight: 500;
    line-height: 16px;
    white-space: nowrap;
    cursor: pointer;
  }

  .vzt-cal-hueco::before {
    border: 1px dashed var(--bs-gray-400);
    background: transparent;
  }

  .vzt-cal-hueco:active::before {
    background: rgba(var(--bs-primary-rgb), 0.06);
  }

  .vzt-cal-hueco > i {
    font-size: 11px;
    line-height: 1;
    color: inherit;
  }

  /* OBLIGATORIA: la hora de la reserva sale de la posicion del toque DENTRO del hueco
     (offsetY). Si el toque cayera en el rotulo o en el «+», offsetY seria relativo a ellos. */
  .vzt-cal-hueco > * {
    pointer-events: none;
  }

  /* Un hueco que no se puede tocar no debe llevarse el toque. */
  .vzt-cal-hueco--pasivo {
    cursor: default;
    pointer-events: none;
  }

  .vzt-cal-hueco--pasivo:active::before {
    background: transparent;
  }

  /* --- Bloqueo --- */
  .vzt-cal-bloqueo {
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 9px 2px;
    color: var(--bs-danger);
    font-size: 11.5px;
    font-weight: 500;
    line-height: 16px;
  }

  .vzt-cal-bloqueo::before {
    border: 1px dashed rgba(var(--bs-danger-rgb), 0.4);
    background: linear-gradient(rgba(var(--bs-danger-rgb), 0.06), rgba(var(--bs-danger-rgb), 0.06)), var(--vzt-cal-fondo);
  }

  .vzt-cal-bloqueo > i {
    flex: 0 0 auto;
    font-size: 11px;
    line-height: 1;
    color: inherit;
  }

  .vzt-cal-bloqueo > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* --- Fuera de horario: una zona, no una tarjeta (no deja hueco debajo) --- */
  .vzt-cal-fuera {
    position: absolute;
    z-index: 0;
    box-sizing: border-box;
    border-radius: 6px;
    background: repeating-linear-gradient(135deg, var(--bs-gray-200) 0 6px, var(--bs-gray-100) 6px 12px);
    overflow: hidden;
  }

  .vzt-cal-fuera > span {
    display: inline-block;
    max-width: calc(100% - 16px);
    margin: 5px 0 0 8px;
    padding: 0 6px;
    border-radius: 6px;
    background: var(--bs-body-bg);
    color: var(--bs-text-muted);
    font-size: 11px;
    line-height: 16px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: top;
  }

  /* --- Linea de ahora: `top` es la hora; la linea se centra en el --- */
  .vzt-cal-ahora {
    position: absolute;
    left: calc(var(--vzt-cal-horas) - 6px);
    right: calc(-1 * var(--vzt-cal-sep));
    z-index: 3;
    height: 2px;
    margin-top: -1px;
    background: var(--bs-danger);
    pointer-events: none;
  }

  .vzt-cal-ahora::before {
    content: "";
    position: absolute;
    top: -3px;
    left: -4px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--bs-danger);
  }

  /* --- Insignias ---------------------------------------------------------
     Una linea, 16 px de alto, color propio. Selector doblado (0,2,0) a proposito: ninguna
     regla del tipo «.tarjeta span» puede pisarle el color ni estirarla (fallo de los
     mockups de M0, donde salian grises y altas). Tambien se usan en la hoja, fuera de
     .vzt-cal: por eso no cuelgan de ningun contenedor. */
  .vzt-cal-ins.vzt-cal-ins {
    display: inline-block;
    flex: 0 0 auto;
    box-sizing: border-box;
    height: 16px;
    padding: 0 5px;
    border-radius: 5px;
    background: var(--bs-gray-200);
    color: var(--bs-gray-700);
    font-family: var(--vzt-font-cuerpo, inherit);
    font-size: 10px;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: 0;
    text-decoration: none;
    white-space: nowrap;
    vertical-align: middle;
  }

  .vzt-cal-ins.vzt-cal-ins--urgente {
    background: rgba(var(--bs-danger-rgb), 0.13);
    color: var(--bs-danger);
  }

  .vzt-cal-ins.vzt-cal-ins--bono {
    background: rgba(var(--bs-success-rgb), 0.15);
    color: var(--success-text, #15803d);
  }

  .vzt-cal-ins.vzt-cal-ins--ob {
    background: rgba(var(--bs-warning-rgb), 0.15);
    color: var(--warning-text, #b45309);
  }

  .vzt-cal-ins.vzt-cal-ins--web {
    background: rgba(var(--bs-info-rgb), 0.12);
    color: var(--bs-info);
  }

  /* --- Insignias dentro de la tarjeta: el cliente manda ------------------
     La insignia de bono trae textos largos («quedan 4 de 5 sesiones») y las columnas de las
     insignias no encogen: sin tope dejaba al cliente (o al servicio) en una astilla. Los anchos
     se miden contra la propia tarjeta (cqw y @container: .vzt-cal-cita es contenedor), asi que
     valen igual en una, dos o tres columnas y en cualquier telefono.
     Con saldo la insignia trae DOS formas (TarjetaCitaMovil): la larga y la corta («Quedan 4/5»).
     Cortar la larga dejaria numeros a medias («quedan 1…» de 12), asi que donde no cabe se pinta
     la corta. Sin saldo solo hay un texto (el nombre del bono), que se acota con puntos
     suspensivos DENTRO de la insignia. Prioridad: Urgente, OB, bono, Web.
       - tarjeta ancha (una columna en un telefono): forma larga, como mucho el 55 % de la
         tarjeta; si la acompana otra insignia, forma corta (o el 35 % si no la hay);
       - tarjeta estrecha (dos columnas en un telefono): forma corta (o el 55 %); el bono no se
         pinta si hay «Urgente» u «OB», y «Web» tampoco si hay cualquiera de las otras tres;
       - tarjeta muy estrecha (tres columnas en un telefono): ni bono ni «Web».
     Lo que no se pinta aqui se lee en la hoja de la cita. Selectores con (0,3,0) o mas donde
     hay que ganar a `.vzt-cal-ins.vzt-cal-ins`. */
  .vzt-cal-cita > .vzt-cal-ins.vzt-cal-ins--bono {
    max-width: 55cqw;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .vzt-cal-ins__corto {
    display: none;
  }

  .vzt-cal-cita:has(> .vzt-cal-ins:not(.vzt-cal-ins--bono)) > .vzt-cal-ins.vzt-cal-ins--bono {
    max-width: 35cqw;
  }

  .vzt-cal-cita:has(> .vzt-cal-ins:not(.vzt-cal-ins--bono)) .vzt-cal-ins__largo {
    display: none;
  }

  .vzt-cal-cita:has(> .vzt-cal-ins:not(.vzt-cal-ins--bono)) .vzt-cal-ins__corto {
    display: inline;
  }

  @container (max-width: 199.9px) {
    /* Aqui el bono nunca va acompanado (cede o le ceden). Con forma corta: 60cqw del contenido,
       que son como mucho el 55 % de la tarjeta entera y dejan entera «Quedan 12/20». Sin ella
       (solo el nombre del bono, que se corta igual): 45cqw, para no quitarle sitio al cliente. */
    .vzt-cal-cita > .vzt-cal-ins.vzt-cal-ins--bono,
    .vzt-cal-cita:has(> .vzt-cal-ins:not(.vzt-cal-ins--bono)) > .vzt-cal-ins.vzt-cal-ins--bono {
      max-width: 45cqw;
    }

    .vzt-cal-cita > .vzt-cal-ins.vzt-cal-ins--bono:has(> .vzt-cal-ins__corto),
    .vzt-cal-cita:has(> .vzt-cal-ins:not(.vzt-cal-ins--bono)) > .vzt-cal-ins.vzt-cal-ins--bono:has(> .vzt-cal-ins__corto) {
      max-width: 60cqw;
    }

    .vzt-cal-ins__largo {
      display: none;
    }

    .vzt-cal-ins__corto {
      display: inline;
    }

    .vzt-cal-cita:has(> :is(.vzt-cal-ins--urgente, .vzt-cal-ins--ob)) > .vzt-cal-ins.vzt-cal-ins--bono,
    .vzt-cal-cita:has(> :is(.vzt-cal-ins--urgente, .vzt-cal-ins--ob, .vzt-cal-ins--bono)) > .vzt-cal-ins.vzt-cal-ins--web {
      display: none;
    }
  }

  @container (max-width: 119.9px) {
    .vzt-cal-cita > .vzt-cal-ins.vzt-cal-ins--bono,
    .vzt-cal-cita > .vzt-cal-ins.vzt-cal-ins--web {
      display: none;
    }
  }

  /* En una cita que libero su hueco (media anchura, atenuada) solo interesa de quien era. */
  .vzt-cal-cita.vzt-cal-cita--liberada > .vzt-cal-ins:is(.vzt-cal-ins--bono, .vzt-cal-ins--web) {
    display: none;
  }

  /* --- Pastilla de estado (lista y hoja) --- */
  .vzt-cal-estado.vzt-cal-estado {
    display: inline-block;
    flex: 0 0 auto;
    box-sizing: border-box;
    height: 20px;
    padding: 0 9px;
    border-radius: 999px;
    background: var(--bs-gray-200);
    color: var(--bs-gray-700);
    font-size: 11px;
    font-weight: 600;
    line-height: 20px;
    white-space: nowrap;
    vertical-align: middle;
  }

  .vzt-cal-estado.vzt-cal-estado--success {
    background: rgba(var(--bs-success-rgb), 0.15);
    color: var(--success-text, #15803d);
  }

  .vzt-cal-estado.vzt-cal-estado--warning {
    background: rgba(var(--bs-warning-rgb), 0.15);
    color: var(--warning-text, #b45309);
  }

  .vzt-cal-estado.vzt-cal-estado--danger {
    background: rgba(var(--bs-danger-rgb), 0.12);
    color: var(--bs-danger);
  }

  .vzt-cal-estado.vzt-cal-estado--neutral {
    background: var(--bs-gray-200);
    color: var(--bs-gray-700);
  }

  /* --- Lista del dia («Todos») --- */
  .vzt-cal-lista {
    padding: 2px 12px 4px;
  }

  .vzt-cal-lista__hora {
    margin: 12px 2px 6px;
    color: var(--bs-text-muted);
    font-family: var(--vzt-font-titulo, inherit);
    font-size: 12px;
    font-weight: 700;
    line-height: 16px;
    font-variant-numeric: tabular-nums;
  }

  /* La hora en curso: en primario y con el punto de la linea de ahora. */
  .vzt-cal-lista__hora[data-ahora="true"] {
    color: var(--bs-primary);
  }

  .vzt-cal-lista__hora[data-ahora="true"]::before {
    content: "";
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--bs-danger);
  }

  .vzt-cal-fila {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 48px;
    margin: 0 0 6px;
    padding: 7px 10px;
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;
    background: var(--bs-body-bg);
    color: var(--bs-gray-900);
    font: inherit;
    font-size: 13px;
    line-height: 17px;
    text-align: left;
    appearance: none;
    cursor: pointer;
  }

  .vzt-cal-fila__inic {
    flex: 0 0 28px;
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bs-primary);
    color: var(--bs-primary-inverse, #fff);
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1;
  }

  .vzt-cal-fila__texto {
    flex: 1 1 auto;
    display: block;
    min-width: 0;
  }

  .vzt-cal-fila__texto > b,
  .vzt-cal-fila__texto > span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .vzt-cal-fila__texto > b {
    font-size: 13px;
    font-weight: 600;
  }

  .vzt-cal-fila__texto > span {
    color: var(--bs-text-muted);
    font-size: 12px;
    font-weight: 400;
    line-height: 16px;
  }

  /* --- Hoja propia -------------------------------------------------------
     No es un modal de Bootstrap: la pinta Blazor solo mientras esta abierta. 1056: por
     encima de la barra inferior (1039) y de los modales (1055). OJO (Tarea 10): una ventana
     de accion abierta DESDE la hoja es un modal (1055) y quedaria debajo; si no se cierra
     antes la hoja, bajar esto a 1054. */
  .vzt-hoja {
    position: fixed;
    inset: 0;
    z-index: 1056;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }

  .vzt-hoja[hidden] {
    display: none;
  }

  /* Con una hoja abierta la pagina de debajo no desplaza. */
  body:has(.vzt-hoja:not([hidden])) {
    overflow: hidden;
  }

  .vzt-hoja__velo {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.5);
    animation: vzt-hoja-velo 0.18s ease-out both;
  }

  /* El panel no desplaza: desplaza su cuerpo, y la cabecera se queda en su sitio. Si el
     contenido va suelto (sin .vzt-hoja__cuerpo), desplaza el panel. */
  .vzt-hoja__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    width: 100%;
    max-height: 92vh;
    max-height: 92dvh;
    padding: 0 16px calc(16px + env(safe-area-inset-bottom, 0px));
    border-radius: 20px 20px 0 0;
    background: var(--bs-body-bg);
    box-shadow: 0 -8px 30px rgba(15, 23, 42, 0.18);
    color: var(--bs-gray-900);
    font-size: 13px;
    line-height: 18px;
    overflow-y: auto;
    overscroll-behavior: contain;
    animation: vzt-hoja-sube 0.2s ease-out both;
  }

  /* Tirador: 24 px de alto en total, con la barra de 38 x 4 en el centro. */
  .vzt-hoja__panel::before {
    content: "";
    flex: 0 0 auto;
    align-self: center;
    width: 38px;
    height: 4px;
    margin: 10px 0;
    border-radius: 2px;
    background: var(--bs-gray-400);
  }

  /* Zona de agarre opcional sobre el tirador dibujado (no pinta nada). */
  .vzt-hoja__tirador {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 24px;
  }

  .vzt-hoja__cabecera {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    margin-bottom: 2px;
  }

  .vzt-hoja__titulo {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    color: var(--bs-gray-900);
    font-family: var(--vzt-font-titulo, inherit);
    font-size: 17px;
    font-weight: 800;
    line-height: 22px;
    letter-spacing: -0.01em;
  }

  .vzt-hoja__cerrar {
    flex: 0 0 44px;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin: 0 -10px 0 auto;
    padding: 0;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--bs-text-muted);
    font-size: 17px;
    line-height: 1;
    appearance: none;
  }

  .vzt-hoja__cerrar i {
    font-size: 17px;
    line-height: 1;
    color: inherit;
  }

  .vzt-hoja__cuerpo {
    flex: 1 1 auto;
    min-height: 0;
    margin: 0 -16px;
    padding: 0 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .vzt-hoja__texto {
    margin: 0 0 10px;
    color: var(--bs-text-muted);
    font-size: 13px;
    line-height: 18px;
  }

  .vzt-hoja__datos {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 6px 14px;
    margin: 0 0 12px;
    padding: 10px 0;
    border-top: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color);
    font-size: 13px;
    line-height: 20px;
  }

  .vzt-hoja__datos > dt {
    color: var(--bs-text-muted);
    font-weight: 400;
  }

  .vzt-hoja__datos > dd {
    min-width: 0;
    margin: 0;
    color: var(--bs-gray-900);
    font-weight: 600;
    overflow-wrap: anywhere;
  }

  /* Llamar y WhatsApp: dos enlaces con aspecto de boton, lado a lado. */
  .vzt-hoja__contactar {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin: 0 0 12px;
  }

  /* Estados a elegir al pulsar «Cambiar estado»: se despliegan sobre las acciones. */
  .vzt-hoja__estados {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin: 0 0 12px;
  }

  .vzt-hoja__cargando {
    margin: 0 0 12px;
    color: var(--bs-text-muted);
    font-size: 13px;
    line-height: 18px;
  }

  /* --- Hoja de filtros: casillas de estado y origen, y filtros guardados --- */
  .vzt-hoja__rotulo {
    margin: 4px 0 8px;
    color: var(--bs-text-muted);
    font-size: 13px;
    font-weight: 600;
    line-height: 18px;
  }

  .vzt-hoja__casillas {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
  }

  .vzt-hoja__casilla {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 0;
    max-width: 100%;
    min-height: 44px;
    margin: 0;
    padding: 6px 14px;
    border: 1px solid var(--bs-border-color);
    border-radius: 20px;
    background: var(--bs-body-bg);
    color: var(--bs-gray-700);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    line-height: 16px;
    text-align: center;
    appearance: none;
  }

  .vzt-hoja__casilla--activa {
    border-color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.1);
    color: var(--bs-primary);
    font-weight: 600;
  }

  .vzt-hoja__guardado {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    margin: 0 0 8px;
  }

  .vzt-hoja__guardado-nombre {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--bs-gray-900);
    font-size: 13px;
    font-weight: 600;
    line-height: 18px;
    overflow-wrap: anywhere;
  }

  .vzt-hoja__guardado > .vzt-hoja__boton {
    flex: 0 0 auto;
    padding: 6px 16px;
  }

  .vzt-hoja__acciones {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin-bottom: 12px;
  }

  .vzt-hoja__boton {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    box-sizing: border-box;
    min-width: 0;
    min-height: 44px;
    margin: 0;
    padding: 6px 8px;
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;
    background: var(--bs-body-bg);
    color: var(--bs-gray-900);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    line-height: 16px;
    text-align: center;
    text-decoration: none;
    appearance: none;
  }

  .vzt-hoja__boton:disabled {
    opacity: 0.5;
  }

  /* Solo el primero (la accion principal de una hoja con varias) ocupa toda la fila; en una
     hoja de dos botones, «Cancelar | Eliminar», quedan lado a lado. */
  .vzt-hoja__boton--principal:first-child {
    grid-column: 1 / -1;
  }

  .vzt-hoja__boton--principal {
    border-color: var(--bs-primary);
    background: var(--bs-primary);
    color: var(--bs-primary-inverse, #fff);
  }

  .vzt-hoja__boton--peligro {
    border-color: rgba(var(--bs-danger-rgb), 0.25);
    color: var(--bs-danger);
  }

  /* Confirmar algo destructivo: principal Y de peligro. */
  .vzt-hoja__boton--principal.vzt-hoja__boton--peligro {
    border-color: var(--bs-danger);
    background: var(--bs-danger);
    color: var(--bs-danger-inverse, #fff);
  }

  /* --- Foco con teclado --- */
  .vzt-cal :is(button, a):focus-visible,
  .vzt-hoja :is(button, a):focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
  }

  .vzt-cal-dia__centro:has(:focus-visible) {
    outline: 2px solid var(--bs-primary);
    outline-offset: -2px;
    border-radius: 10px;
  }

  /* --- Cabecera general en esta pagina (spec D10) --------------------------
     En movil la pagina no pone titulo ni botones, pero el layout sigue pintando la fila del
     toolbar con el <h1> vacio y la miga «Inicio»: una linea suelta de 25 px encima del dia
     (visto en el panel real, 2026-10-12). La fila se retira mientras exista la vista movil. */
  body:has(.vzt-cal) #kt_app_header #kt_app_toolbar {
    display: none;
  }

  @keyframes vzt-hoja-sube {
    from { transform: translateY(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
  }

  @keyframes vzt-hoja-velo {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .vzt-cal *,
    .vzt-hoja * {
      animation: none !important;
      transition: none !important;
      scroll-behavior: auto !important;
    }
  }
}
