/* =========================================================================
   SISTEMA VISUAL — lo que comparten cotizador, técnicos y finanzas.
   Se enlaza desde los tres HTML ANTES de su <style>: lo particular de cada
   pantalla sigue adentro de cada archivo y, por venir después, le gana a esto.
   nota.html NO lo usa: se pinta en un iframe y lleva su CSS propio con los
   mismos tokens.

   Es el mismo sistema del landing (www.limpiolimpio.mx, «Sala en calma»):
   tinta y lino como base, el azul del logo solo como firma —acciones, pestaña
   activa, foco, cifras que importan—, Fraunces para los títulos y Onest para
   todo lo demás, sin degradados ni sombras bajo tarjetas. Las reglas completas
   están en README.md → Sistema visual.

   Regla: ningún color se escribe dos veces. Un tono que se use en más de un
   lugar vive aquí y en ningún otro lado; los que aparecen una sola vez se
   quedan literales en su pantalla, porque un color escrito una vez no se puede
   desincronizar. `#fff` también se queda literal: es la ausencia de color, no
   un tono de la marca.
   ========================================================================= */

/* --- Fuentes: las mismas del landing, autoalojadas (72 KB entre las dos, una
   sola vez). Fraunces es variable en peso y tamaño óptico con SOFT fijo en 60;
   Onest en peso 400–600. Los respaldos llevan `size-adjust` medido con
   fontTools para que el texto no cambie de líneas cuando carga la real. --- */
@font-face{ font-family:'Fraunces'; src:url('/assets/fonts/fraunces.woff2') format('woff2');
            font-weight:400 600; font-display:swap; }
@font-face{ font-family:'Onest'; src:url('/assets/fonts/onest.woff2') format('woff2');
            font-weight:400 600; font-display:swap; }
@font-face{ font-family:'Fraunces Respaldo'; src:local('Georgia'), local('Palatino Linotype'), local('Noto Serif'), local('Times New Roman');
            size-adjust:105.3%; ascent-override:92.9%; descent-override:24.2%; line-gap-override:0%; }
@font-face{ font-family:'Onest Respaldo'; src:local('Arial'), local('Roboto'), local('Helvetica Neue'), local('Segoe UI');
            size-adjust:104.9%; ascent-override:92.5%; descent-override:29.1%; line-gap-override:0%; }

:root{
  /* --- Los tokens del landing, tal cual --- */
  --tinta:#0B1F33; --tinta-2:#14304A; --tinta-suave:#4A5A6B;
  --lino:#ECEAE4; --lino-2:#E2DFD7; --gris-tela:#C9C6BF; --gris-sobre-tinta:#C8CED4;
  --azul:#0F75BC; --azul-oscuro:#0C6098; --azul-tinte:#E4EFF7; --azul-texto:#0B5A8E;
  /* Lo que una herramienta densa necesita y el landing no: un fondo de app
     (lino muy claro, para que las tarjetas blancas se lean como papel sobre
     tela) y un azul de borde para lo seleccionado. */
  --papel:#F6F5F1; --azul-borde:#B7D2E7;

  /* --- Alias: los nombres que las pantallas ya usaban, con los valores nuevos.
     Así cada regla de cada pantalla cambia de color sin reescribirse. --- */
  --azul-osc:var(--azul-oscuro); --azul-tinta:var(--azul-texto);
  --azul-bg:var(--azul-tinte); --azul-bg2:#EEF4F9; --azul-nube:#F4F8FB; --azul-niebla:#FAFCFD;
  --bg:var(--papel); --tinta2:var(--tinta-2); --negro:var(--tinta);
  --gris-osc:#3A4957; --gris:var(--tinta-suave); --gris-claro:#7E8892;
  --borde:var(--gris-tela); --linea:var(--lino-2); --linea2:#E9E7E1;
  --nube:var(--lino); --nube2:#F1F0EB; --nube3:#F8F7F4;

  /* Semánticos, cada uno con su par de fondo y de texto: nadie tiene que
     volver a escoger a mano un texto que se lea sobre un fondo de color.
     Van SOLO en chips, puntos y avisos; nunca como fondo de una tarjeta entera. */
  --verde:#1E8A4C; --verde-tinta:#175C36; --verde-claro:#A9DFC0;
  --verde-bg:#E3F4EA; --verde-wa:#25d366;

  --rojo:#C93B3B; --rojo-osc:#A83030; --rojo-tinta:#8C2626;
  --rojo-claro:#F0B4B4; --rojo-bg:#FBE9E9; --rojo-nube:#FDF4F4;

  --ambar:#A85F14; --ambar-osc:#8A4D0F; --ambar-tinta:#6E3D0B;
  --ambar-vivo:#E9A23B; --ambar-fuerte:#CF8A24;
  --ambar-borde:#F1CF8A; --ambar-medio:#F4DDAE;
  --ambar-bg:#FBF0DA; --ambar-nube:#FDF7EA; --ambar-niebla:#FEFBF3;

  --morado:#6B55B8; --morado-claro:#7A66C4; --morado-osc:#57429E;
  --morado-tinta:#493886; --morado-borde:#C9BEE8; --morado-linea:#E4DDF4;
  --morado-bg:#F3F0FA; --morado-nube:#F9F7FD; --morado-niebla:#FBF9FE;

  --teal:#187A6F; --teal-bg:#D6F1EC;

  /* Tipografía: Onest en toda la interfaz; Fraunces solo en títulos y montos
     grandes. Escala corta para una herramienta de trabajo. */
  --f-texto:'Onest','Onest Respaldo',system-ui,-apple-system,sans-serif;
  --f-display:'Fraunces','Fraunces Respaldo',Georgia,serif;
  --t-mini:13px; --t-small:14px; --t-base:15px; --t-3:20px; --t-2:26px; --t-1:34px;

  /* Forma y tiempo */
  --r-suave:24px; --r-media:14px; --r-campo:10px; --r-pill:999px; --dur:180ms;
}

*{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html{ color-scheme:light; -webkit-text-size-adjust:100%; }
body{ margin:0; font-family:var(--f-texto); font-size:var(--t-base); line-height:1.5;
      background:var(--bg); color:var(--tinta); -webkit-font-smoothing:antialiased; }
::selection{ background:var(--azul); color:#fff; }
:focus-visible{ outline:3px solid var(--azul); outline-offset:2px; border-radius:6px; }
button, input, select, textarea{ font:inherit; color:inherit; }
button{ cursor:pointer; }
a{ color:var(--azul-texto); }
.num{ font-variant-numeric:tabular-nums; }
/* Fraunces: para el título de una pantalla y los montos grandes. Peso 500 y
   tamaño óptico 32: suave, no de alto contraste, para que hable con el
   wordmark redondeado sin imitarlo. */
.display{ font-family:var(--f-display); font-weight:500; letter-spacing:-.012em;
          font-variation-settings:'SOFT' 60, 'opsz' 32; }

/* El icono en línea (SVG de trazo, `ICONOS`/`ic()` en cada script). Hereda
   color y se alinea con la caja de texto, que es justo lo que un emoji no hace. */
.ic{ vertical-align:-2px; flex:none; }
/* Dos tallas y nada más: la de texto y la del acuse. */
.ic.grande{ width:44px; height:44px; vertical-align:0; }
/* Iconos por CSS, para lo que no pasa por `ic()`: una máscara de un trazo de
   2 px que toma el color del texto. `<i class="ico ico-buscar"></i>`. */
.ico{ display:inline-block; width:18px; height:18px; vertical-align:-4px; flex:none; background:currentColor;
      -webkit-mask:var(--m) center / contain no-repeat; mask:var(--m) center / contain no-repeat; }
.ico-buscar{   --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E"); }
.ico-cerrar{   --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E"); }
.ico-mas{      --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E"); }
.ico-flecha{   --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6'/%3E%3C/svg%3E"); }
.ico-volver{   --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H6M11 6l-6 6 6 6'/%3E%3C/svg%3E"); }
.ico-pin{      --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s7-6.3 7-11a7 7 0 1 0-14 0c0 4.7 7 11 7 11z'/%3E%3Ccircle cx='12' cy='10' r='2.5'/%3E%3C/svg%3E"); }
.ico-whatsapp{ --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a8 8 0 0 1-11.6 7.1L3 21l1.9-6.4A8 8 0 1 1 21 12z'/%3E%3Cpath d='M9 9.5c0 3 2.5 5.5 5.5 5.5l1-1.5-2-1-1 1a4 4 0 0 1-2-2l1-1-1-2z'/%3E%3C/svg%3E"); }
.ico-estrella{ --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M12 2.5l2.9 6.1 6.6.8-4.9 4.6 1.3 6.6L12 17.4l-5.9 3.2 1.3-6.6L2.5 9.4l6.6-.8z'/%3E%3C/svg%3E"); }
.ico-ajustes{  --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3Cpath d='M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z'/%3E%3C/svg%3E"); }
.ico-compartir{--m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12M7 8l5-5 5 5'/%3E%3Cpath d='M5 14v5a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-5'/%3E%3C/svg%3E"); }
.ico-imprimir{ --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9V3h12v6'/%3E%3Crect x='3' y='9' width='18' height='8' rx='2'/%3E%3Cpath d='M6 14h12v7H6z'/%3E%3C/svg%3E"); }
.ico-check{    --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E"); }
.ico-alerta{   --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4l9 16H3z'/%3E%3Cpath d='M12 10v4M12 17.5v.5'/%3E%3C/svg%3E"); }
.ico-calendario{--m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E"); }
.ico-nota{     --m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3h9l5 5v13H6z'/%3E%3Cpath d='M15 3v5h5M9 13h7M9 17h5'/%3E%3C/svg%3E"); }

/* --- Cabecera: el logo es un lockup (ya trae el nombre), así que al lado va
   solo el subtítulo de la pantalla y el botón de salir. --- */
.top{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:14px; }
.logout-btn{ background:#fff; border:1.5px solid var(--gris-tela); color:var(--tinta); font-size:var(--t-mini);
             font-weight:500; cursor:pointer; padding:7px 13px; border-radius:var(--r-pill); min-height:36px;
             white-space:nowrap; font-family:inherit; transition:background var(--dur); }
.logout-btn:hover{ background:var(--lino); }

/* --- Tarjeta: borde, no sombra. --- */
.card{ background:#fff; border:1px solid var(--linea); border-radius:var(--r-media); padding:16px; margin-bottom:12px; }
.row{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; }

/* --- Botones. Píldora azul con brillo al pasar el cursor (el mismo del
   landing); fantasma con borde gris-tela; el rojo solo como fantasma. 44 px
   de alto, 52 en los cierres (`.bloque` en técnicos, `.btn-login`). --- */
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px; padding:0 20px;
      border-radius:var(--r-pill); border:0; background:var(--azul); color:#fff; font:inherit; font-weight:600;
      font-size:var(--t-base); text-decoration:none; cursor:pointer; position:relative; overflow:hidden;
      transition:background var(--dur) ease, transform var(--dur) ease; }
.btn:hover{ background:var(--azul-oscuro); }
.btn:active{ transform:translateY(1px); }
.btn:disabled{ opacity:.55; cursor:default; }
.btn::after{ content:""; position:absolute; inset:0; pointer-events:none;
             background:linear-gradient(115deg, transparent 42%, rgba(255,255,255,.26) 50%, transparent 58%);
             transform:translateX(-130%); }
.btn:hover::after{ transition:transform 650ms ease; transform:translateX(130%); }
.btn.ghost, .btn.sec{ background:#fff; color:var(--tinta); box-shadow:inset 0 0 0 1.5px var(--gris-tela); }
.btn.ghost:hover, .btn.sec:hover{ background:var(--lino); }
.btn.ghost::after, .btn.sec::after, .btn.gris::after{ display:none; }
.btn.ok, .btn.verde{ background:var(--verde); }
.btn.ok:hover, .btn.verde:hover{ background:var(--verde-tinta); }
.btn.gris{ background:var(--lino); color:var(--tinta); }
.btn.gris:hover{ background:var(--lino-2); }
.btn.mal{ background:#fff; color:var(--rojo); box-shadow:inset 0 0 0 1.5px var(--rojo-claro); }
.btn.mal:hover{ background:var(--rojo-nube); }
.btn.chico{ min-height:36px; padding:0 14px; font-size:var(--t-small); }
.btn.bloque{ display:flex; width:100%; min-height:52px; }
.btn .ic, .btn .ico{ vertical-align:0; }

/* --- Campos: 44 px, borde gris-tela, foco azul. --- */
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]), select, textarea{
  width:100%; min-height:44px; padding:9px 12px; border:1.5px solid var(--gris-tela); border-radius:var(--r-campo);
  background:#fff; color:var(--tinta); font:inherit; font-size:var(--t-base); }
select{ appearance:none; -webkit-appearance:none; padding-right:34px; background-repeat:no-repeat; background-position:right 12px center;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A5A6B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
        background-size:18px; }
textarea{ min-height:96px; resize:vertical; line-height:1.5; }
input:focus, select:focus, textarea:focus{ outline:none; border-color:var(--azul); box-shadow:0 0 0 3px rgba(15,117,188,.16); }
input::placeholder, textarea::placeholder{ color:#9AA3AC; }
input[type=checkbox], input[type=radio]{ width:18px; height:18px; accent-color:var(--azul); margin:0 6px 0 0; vertical-align:-3px; }
input[type=range]{ accent-color:var(--azul); }
.lbl{ font-size:var(--t-mini); color:var(--tinta-suave); font-weight:500; }

/* --- Pastillas y navegación. Lo seleccionado se dice con el azul: borde y
   tinte, texto azul oscuro; nunca texto negro sobre color. --- */
.pill{ min-height:38px; padding:7px 14px; border-radius:var(--r-pill); border:1.5px solid var(--gris-tela); background:#fff;
       color:var(--tinta-suave); font-weight:500; font-size:var(--t-small); cursor:pointer; flex:1; text-align:center;
       min-width:82px; font-family:inherit; white-space:nowrap;
       transition:background var(--dur), border-color var(--dur), color var(--dur); }
.pill:hover{ background:var(--nube3); }
.pill.on{ border-color:var(--azul); background:var(--azul-tinte); color:var(--azul-texto); font-weight:600; }

/* NAVEGACIÓN DE DOS NIVELES (cotizador y finanzas; la función `navHTML()` es
   idéntica en los dos scripts).
   Nivel 1: cinco palabras cortas que SIEMPRE caben en un renglón. En 332 px
   útiles son ~66 px cada una.
   Nivel 2: las pastillas del grupo. NO se envuelve — se desliza. Envolver
   mueve todo lo de abajo y es justo lo que pasa con diez pastillas en una
   fila; deslizar deja la altura fija y la pantalla quieta. */
.nav1{ display:flex; gap:4px; margin-bottom:8px; background:var(--lino); border-radius:var(--r-pill); padding:3px; }
/* 13.5 px y 4 px de padding: cinco palabras («Vender», «Operar», «Ajustes») tienen
   que caber sin cortarse en 320 px, que son ~58 px por botón. */
.nav1 button{ flex:1 1 0; min-width:0; border:none; background:none; font:inherit; font-size:13.5px;
              font-weight:500; color:var(--tinta-suave); padding:9px 4px; border-radius:var(--r-pill); cursor:pointer;
              position:relative; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
              transition:background var(--dur), color var(--dur); }
.nav1 button.on{ background:#fff; color:var(--tinta); font-weight:600; box-shadow:inset 0 0 0 1px var(--gris-tela); }
/* El punto sube al nivel 1 cuando el grupo NO está abierto: dice que hay algo
   ahí sin obligar a entrar. Adentro, el contador vuelve a su pastilla. */
.nav1 button .pt{ position:absolute; top:7px; right:9px; width:7px; height:7px; border-radius:50%; background:var(--rojo); }
.nav2{ display:flex; gap:8px; margin-bottom:12px; overflow-x:auto; flex-wrap:nowrap; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
.nav2::-webkit-scrollbar{ display:none; }
.nav2 .pill{ flex:none; }

/* --- Piezas menores compartidas --- */
.pcard{ border:1px solid var(--linea); border-radius:12px; padding:12px; background:var(--nube3); margin-bottom:10px; }
.rev{ display:flex; align-items:center; gap:7px; font-size:var(--t-mini); color:var(--gris-osc); cursor:pointer; }
.pdetail{ font-size:12px; color:var(--tinta-suave); }
.sec2{ font-weight:600; color:var(--tinta); margin-bottom:9px; }

/* Avisos en línea. Un aviso que se ve igual que un dato neutro no es un aviso. */
.hint{ background:var(--azul-tinte); border-radius:10px; padding:9px 12px; font-size:var(--t-mini);
       color:var(--azul-texto); margin-top:8px; line-height:1.45; }
.hint.warn{ background:var(--ambar-bg); color:var(--ambar-tinta); }
.hint.mal{ background:var(--rojo-bg); color:var(--rojo-tinta); }
.hint.ok{ background:var(--verde-bg); color:var(--verde-tinta); }

/* El índice único de Ajustes (cotizador y finanzas). */
.ajidx .ajgrupo{ display:flex; gap:10px; align-items:baseline; padding:8px 0; border-top:1px solid var(--linea); flex-wrap:wrap; }
.ajidx .ajgrupo:first-of-type{ border-top:none; }
.ajidx .ajtit{ flex:0 0 132px; font-size:11.5px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--gris-claro); }
.ajidx .ajls{ flex:1 1 200px; min-width:0; font-size:var(--t-small); line-height:1.7; }
.ajidx .ajls a{ color:var(--azul-texto); text-decoration:none; font-weight:600; }
.ajidx .sep{ color:var(--gris-claro); margin:0 7px; }

/* EL CALENDARIO DEL MES (cotizador y técnicos: es el mismo calendario y tiene
   que verse igual).
   ⚠ ESTAS CLASES EXISTEN PARA QUE EL `@media` DE ABAJO PUEDA GANARLES. Estaban
     escritas en `style="…"` en línea, y una regla de hoja de estilos no le
     gana a un atributo `style` sin `!important`.

   EL PROBLEMA, con el número: en un iPhone de 390 px, menos `.wrap` (14×2),
   menos `.card` (14×2 + borde), menos 6 separaciones de 3 px, quedan 44.9 px
   por casilla. Adentro, restando padding y borde del botón, ~36 px; y la
   pastilla tiene su propio padding, así que al texto le quedan ~30 px.
   Lo que se le metía era `soloHora()`, que en es-MX con `hour:"2-digit"`
   devuelve «12:00 p. m.» — unos 50 px. Cada pastilla se cortaba TODOS LOS
   DÍAS. No era un caso raro: era el comportamiento normal. */
.calGrid{ display:grid; grid-template-columns:repeat(7,1fr); gap:3px; }
.calCab{ text-align:center; font-size:10.5px; font-weight:600; color:var(--gris-claro); }
.calDia{ display:flex; flex-direction:column; gap:2px; align-items:stretch; min-height:52px; padding:4px 3px;
         border-radius:10px; cursor:pointer; text-align:left; border:1.5px solid var(--linea); background:#fff; }
.calDia.hoy{ border-color:var(--azul-borde); }
.calDia.sel{ border-color:var(--azul); background:var(--azul-tinte); }
.calDia .n{ font-size:11px; font-weight:500; color:var(--gris-claro); }
.calDia.hoy .n{ font-weight:600; color:var(--azul-texto); }
.calVacio{ background:transparent; }
/* EN CELULAR, LA CASILLA NO LLEVA TEXTO: un punto por servicio y ya. A ~7 px
   por punto, cuatro puntos y el `+N` caben de sobra en 36 px. Los colores ya
   existen y ya significan estado, así que la rejilla del mes sirve para VER
   DÓNDE HAY CARGA — para los detalles está la franja del día, que no cambia. */
.calPuntos{ display:flex; flex-wrap:wrap; gap:3px; align-items:center; padding:1px 0; }
.calPunto{ width:7px; height:7px; border-radius:50%; flex:none; }
.calMas{ font-size:9px; font-weight:600; color:var(--gris); line-height:1; }
.calHora{ display:none; }
/* Las horas vuelven a partir de 520 px, donde 7 columnas dan ~70 px y sí
   caben. Clases con nombre, y el punto de corte justificado con la cuenta de
   píxeles, no a ojo. */
@media (min-width: 520px){
  .calPuntos{ display:none; }
  .calHora{ display:block; font-size:9.5px; line-height:1.25; color:#fff; border-radius:4px; padding:1px 4px;
            overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .calDia{ min-height:62px; }
}

/* LOGIN (cotizador y finanzas; técnicos tiene el suyo, más ancho, en su archivo).
   En el login el logo manda: es lo único que hay en pantalla antes de entrar,
   y es donde la marca puede respirar. `width:100%` con `max-width` para que en
   un teléfono chico se encoja en vez de empujar la tarjeta. */
.login-wrap{ min-height:80vh; display:flex; align-items:center; justify-content:center; }
.login-card{ background:#fff; border:1px solid var(--linea); border-radius:var(--r-suave); padding:34px 28px;
             width:100%; max-width:360px; margin:0 auto; }
.login-title{ font-family:var(--f-display); font-weight:500; font-size:24px; letter-spacing:-.012em;
              font-variation-settings:'SOFT' 60, 'opsz' 32; color:var(--tinta); margin-bottom:4px; line-height:1.15; }
.login-sub{ font-size:var(--t-small); color:var(--tinta-suave); margin-bottom:22px; }
.login-logo{ display:block; width:100%; max-width:196px; height:auto; margin:0 auto 16px; }
.login-logo.sm{ max-width:128px; margin-bottom:14px; }   /* pantallas de aviso */
.login-field{ margin-bottom:14px; }
.login-field .lbl{ display:block; margin-bottom:5px; }
.login-err{ color:var(--rojo); font-size:var(--t-mini); margin-top:10px; min-height:18px; }
.btn-login{ display:flex; align-items:center; justify-content:center; width:100%; min-height:52px; padding:0 20px;
            border-radius:var(--r-pill); border:none; background:var(--azul); color:#fff; font-weight:600; font-size:16px;
            cursor:pointer; margin-top:8px; font-family:inherit; position:relative; overflow:hidden;
            transition:background var(--dur) ease; }
.btn-login:hover{ background:var(--azul-oscuro); }
.btn-login::after{ content:""; position:absolute; inset:0; pointer-events:none;
                   background:linear-gradient(115deg, transparent 42%, rgba(255,255,255,.26) 50%, transparent 58%);
                   transform:translateX(-130%); }
.btn-login:hover::after{ transition:transform 650ms ease; transform:translateX(130%); }
.btn-login:disabled{ opacity:.6; cursor:default; }

@media (prefers-reduced-motion:reduce){
  *, *::before, *::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
}
