/* ═══════════════════════════════════════════════════════════════════════════
   VDH · Sistema No Compra — sistema de diseño compartido
   Lo usan todas las pantallas de la app (Carga, Panel, Estadísticas, Club,
   Beneficios, Configuración).

   El 30/09/2026 la app tomó la paleta del VDH CLUB, a pedido de Mauricio:
   una sola marca para la tienda (vdh.com.ar), el Club y el sistema interno.
   Los tonos de la app, exactos: fondo #F7F6F3, tarjetas blancas, carbón y
   la letra Poppins —la de vdh.com.ar—, y el verde de la app como único
   color. Se fue el rojo como color de marca: no era de la tienda, lo
   habíamos elegido para las apps internas (24/09 al 30/09/2026).

   Lo que se mantiene es la estructura: las esquinas redondas, el rail
   oscuro flotante, tres niveles de texto.

   ── Cada color tiene UN trabajo ──
     carbón   lo que se aprieta: botones, el chip elegido
     platino  lo que se mira: las tarjetas de números de los tableros
     verde    el color de la app: el campo elegido, el avance del objetivo,
              lo tuyo (vos en el equipo), los beneficios, lo que salió bien
     ámbar    lo que está esperando
     rojo     un error o una alerta. NADA más: así, cuando aparece, se ve.
     plata, oro y platino son SÓLO los niveles de un socio (sus pastillas y
     barras), como en la app. El dorado en la marca, el menú y el equipo se
     probó el mismo 30/09 y a Mauricio no lo convenció.

   La marca vive en los tokens de abajo: se cambia ahí y todas las pantallas
   siguen. Ningún archivo escribe un color de marca a mano.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── TOKENS ────────────────────────────────────────────────────────────────
   Arranca en CLARO, como el Club. El oscuro se pide a mano con el toggle y
   vive en html[data-theme="dark"], más abajo.

   Sobre el contraste: hay tres niveles de texto y cada uno tiene un trabajo.
     --txt    dato duro, lo que la persona vino a leer     (16:1)
     --txt-2  contexto que igual hay que poder leer         (9,9:1)
     --txt-3  etiquetas y apoyo, NUNCA un dato              (7:1)
   Ningún dato real usa --txt-3. El piso de 7:1 se respeta en los dos temas,
   y se mide contra la TARJETA, no contra el fondo: casi todas las etiquetas
   viven adentro de un panel.

   --acc es lo que se aprieta y va SIEMPRE con --acc-ink encima. En claro es
   carbón con blanco; en oscuro se invierte (claro con carbón), porque un
   botón carbón sobre una hoja carbón no existe. */
:root {
  /* El fondo de la app del Club, exacto. Las tarjetas blancas se despegan
     por su canto (--line, el de la app) y la sombra: en pantallas que
     apagan el blanco —la notebook de Mauricio muestra #E1E1E1 donde hay
     #FFFFFF— el tono solo no alcanza. */
  /* 04/10/2026: un poco más cálido y más oscuro que el del Club, para que
     las tarjetas blancas se despeguen también en la notebook. */
  --bg:          #F1EFEA;
  --fondo-luz:   none;
  --surface:     #FFFFFF;
  --surface-2:   #F6F4F0;
  --surface-3:   #E9E6E0;
  --panel-fondo: #FFFFFF;
  /* El relleno de lo que se escribe: blanco. Beige, los campos parecían
     deshabilitados. */
  --campo:       #FFFFFF;

  /* ── Los dos bordes hacen trabajos distintos ──
     El de la TARJETA sólo separa (la separación la carga la sombra). El del
     CAMPO dice "acá se escribe": 3:1 contra su relleno como mínimo. */
  --line:       #E0DCD4;
  --line-alta:  #A39E94;
  --line-campo: #8A857C;   /* 3,6:1 contra el blanco del campo */

  --txt:   #1C1C1A;        /* 16,9:1 */
  --txt-2: #46433E;        /*  9,9:1 */
  --txt-3: #67635B;        /*  6:1 contra la tarjeta, 5,2:1 contra el fondo: la ayuda, más suave (04/10/2026) */

  /* ── Lo que se aprieta: carbón, como los botones del Club ── */
  --acc:      #1C1C1A;
  --acc-2:    #2E2D2A;
  --acc-ink:  #FFFFFF;
  --acc-txt:  #1C1C1A;
  --acc-soft: #EFEDE8;
  --acc-line: rgba(28, 28, 26, .30);

  /* El chip es un BOTÓN: blanco, canto fino y letra carbón. Elegido, se
     llena de carbón como el botón de guardar. */
  --chip:      #FFFFFF;
  --chip-line: #8A857C;

  /* ── Los estados ──
     Van apagados a propósito —no son colores de marca, son señales— y sólo
     aparecen en pastillas, cantos y números. El verde es el del Club. */
  --ok:        #1E5A3E;
  --ok-txt:    #1E5A3E;    /* 8,1:1 */
  --ok-soft:   #EAF3EE;
  --ok-ink:    #FFFFFF;    /* la letra del aviso verde: 8,1:1 */
  --warn:      #B7791F;
  --warn-txt:  #6B4403;    /* 7,6:1 contra su pastilla */
  --warn-soft: #FBF0DA;
  --bad:       #A00F1E;
  --bad-txt:   #A00F1E;    /* 8,1:1 */
  --bad-soft:  #FDF2F3;
  --bad-ink:   #FFFFFF;
  --info-txt:  #46433E;
  --info-soft: rgba(28, 28, 26, .06);
  --ok-borde:  #C4DCCD;

  /* El campo elegido: el verde de la app, no un halo gris (pedido de
     Mauricio, 30/09/2026). */
  /* El foco (04/10/2026): carbón, fino y nítido, sin halo. El verde
     queda para lo que significa algo: guardado, objetivo cumplido. */
  --foco:        #1C1C1A;
  --foco-anillo: transparent;

  /* ── Los materiales de los niveles del Club ──
     Los mismos degradados que la franja de la tarjeta del socio. Son para
     DETALLES que dicen algo (ver arriba), nunca para rellenar por rellenar.
     --oro-txt es el oro que se puede leer sobre blanco (5,6:1): el oro de
     verdad sobre blanco da 2:1 y no sirve para letra. */
  --oro:       linear-gradient(135deg, #EED79E 0%, #C99A3E 45%, #E0BC6C 100%);
  --oro-liso:  #D6AE55;
  --oro-ink:   #1A1406;
  --oro-txt:   #7A5A12;
  --oro-soft:  rgba(214, 174, 85, .20);
  --plata:     linear-gradient(135deg, #DDE0E4 0%, #A9AFB8 50%, #C9CDD3 100%);
  --plata-ink: #121417;
  --platino:   linear-gradient(135deg, #3A3935 0%, #1A1A18 55%, #46443F 100%);

  --sans:    'Poppins', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --display: var(--sans);

  --r:      18px;
  --r-sm:   12px;
  --r-pill: 999px;

  /* Sobre claro no hay luz de canto: la tarjeta la despega una sombra
     ancha y suave, no un borde marcado. */
  --sombra:      0 1px 2px rgba(20, 20, 18, .06), 0 18px 40px -22px rgba(20, 20, 18, .38);
  --sombra-alta: 0 16px 44px -16px rgba(28, 28, 26, .30);
  --glow:        0 8px 22px -12px rgba(28, 28, 26, .45);

  /* Curva de iOS: arranca rápido y frena suave. La misma para todo lo que se
     mueve, así la app "se siente" de una sola pieza. */
  --curva: cubic-bezier(.32, .72, 0, 1);

  --tope: 660px;

  /* El marco de navegación. En el celular el rail se acuesta abajo (--nav)
     y en pantalla grande se para a la izquierda: --rail-ancho es el panel en
     sí y --rail lo que le reserva al contenido (12 de aire + panel + 12).
     --cabeza es lo que mide la cabecera pegajosa: 36 del ícono + 12 y 12 de
     aire + 1 de borde. Está acá y no estimado en cada regla porque de ese
     número dependen el alto del rail y dónde se frena al scrollear. */
  --rail-ancho: 84px;
  --rail: 108px;
  --nav: 54px;
  --cabeza: 61px;

  /* El rail es oscuro en los DOS temas: en un tablero la columna de
     navegación es el marco y el contenido es lo que se mira. Carbón cálido,
     el mismo de los botones, y flotando (redondeado, con aire y sombra:
     a Mauricio le gusta así). La sección abierta se marca en blanco. Tiene sus propios tokens de texto porque los --txt de
     arriba están pensados contra --bg, no contra esto. */
  /* 04/10/2026: negro de verdad (era un carbón que tiraba a gris), con un
     canto de luz; las secciones casi blancas. */
  --rail-bg:    linear-gradient(180deg, #131312 0%, #050505 100%);
  --rail-borde: rgba(255, 255, 255, .12);
  --rail-acc:   #D6AE55;   /* la sección abierta, en oro: 7:1 contra el rail */
  --rail-txt:   #FFFFFF;
  --rail-txt-2: rgba(255, 255, 255, .76);   /* 13:1 contra el rail */
  --rail-line:  rgba(255, 255, 255, .10);
  --rail-campo: #1C1C1A;   /* el desplegable de quién carga, adentro del rail */
  /* Las tarjetas oscuras del tablero, del mismo negro que el panel. */
  --tablero-negro: linear-gradient(135deg, #1E1E1C 0%, #0A0A09 60%, #252522 100%);

  color-scheme: light;
}

html[data-theme="dark"] {
  /* ── Carbón, no negro azulado ──────────────────────────────────────────
     El mismo carbón cálido del Club, sin rojo. Para quien prefiera la
     pantalla oscura en el local. Todo lo que se aprieta se invierte: claro
     con letra carbón. */
  --bg:          #121211;
  --surface:     #1E1E1C;
  --surface-2:   #262624;
  --surface-3:   #302F2C;
  --panel-fondo: linear-gradient(180deg, #211F1D 0%, #171715 100%);
  --campo:       #262624;

  --line:       #3A3935;
  --line-alta:  #5C5A54;
  --line-campo: #7E7A71;   /* 3,4:1 contra el campo */

  --txt:   #F4F2EC;        /* 16:1 */
  --txt-2: #CFCAC0;        /* 11:1 */
  --txt-3: #B5AFA4;        /*  7,6:1 contra la tarjeta */

  --acc:      #F4F2EC;
  --acc-2:    #DAD5CB;
  --acc-ink:  #1C1C1A;
  --acc-txt:  #F4F2EC;
  --acc-soft: rgba(244, 242, 236, .10);
  --acc-line: rgba(244, 242, 236, .35);

  --chip:      #262624;
  --chip-line: #7E7A71;

  --ok:        #4FB07F;
  --ok-txt:    #8FD1AE;
  --ok-soft:   rgba(143, 209, 174, .14);
  --ok-ink:    #0B2A1C;    /* 5,4:1 sobre el verde */
  --warn:      #D9A441;
  --warn-txt:  #F0C66A;
  --warn-soft: rgba(240, 198, 106, .14);
  --bad:       #E06A72;
  --bad-txt:   #FF9AA0;
  --bad-soft:  rgba(255, 154, 160, .14);
  --bad-ink:   #2A0508;    /* 5,6:1 sobre el rojo */
  --info-txt:  #CFCAC0;
  --info-soft: rgba(255, 255, 255, .07);

  --oro-txt:   #E8C877;
  --oro-soft:  rgba(214, 174, 85, .18);
  --ok-borde:    rgba(143, 209, 174, .40);
  --foco:        #F1EEE7;
  --foco-anillo: transparent;

  --sombra:
    inset 0 1px 0 rgba(255, 255, 255, .05),
    0 1px 2px rgba(0, 0, 0, .5),
    0 12px 32px -14px rgba(0, 0, 0, .85);
  --sombra-alta:
    inset 0 1px 0 rgba(255, 255, 255, .06),
    0 16px 48px -14px rgba(0, 0, 0, .9);
  --glow: 0 8px 22px -12px rgba(0, 0, 0, .8);

  /* En oscuro el rail se despega del fondo con su canto, no con la sombra. */
  --rail-bg:    linear-gradient(180deg, #131312 0%, #050505 100%);
  --rail-borde: rgba(255, 255, 255, .12);

  color-scheme: dark;
}

/* ── BASE ──────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

/* El resplandor va en una capa fija propia y no en background-attachment:
   fixed, que en iOS directamente no funciona —y la app es una PWA que vive
   en iPhones—. Fija a la ventana, detrás de todo y sin capturar el dedo.
   Con --fondo-luz en none (tema claro) no dibuja nada. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--fondo-luz);
}

/* El fondo no es un color plano: lleva un resplandor rojo arriba, del
   lado donde están los números. Es lo que hace que una pantalla oscura se
   lea como un ambiente y no como una tapa negra, y de paso le da a la
   franja del tablero algo sobre qué apoyarse. En claro se apaga: ahí la
   luz ya la pone el papel. */
body {
  background: var(--bg);
  color: var(--txt);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  /* El fondo cambia con el tema: sin esto el cambio se ve como un parpadeo. */
  transition: background-color .25s ease, color .25s ease;
}

button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
button { cursor: pointer; border: none; background: none; touch-action: manipulation; }
a { color: var(--acc-txt); }

/* Todo lo que se puede tocar muestra dónde está el foco del teclado. Es lo que
   permite cargar el formulario entero con Tab desde la PC del local. */
:focus-visible {
  outline: 2px solid var(--foco);
  outline-offset: 2px;
  border-radius: 6px;
}

@keyframes aparecer { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
  }
}

/* ── CABECERA ──────────────────────────────────────────────────────────── */
.app-head {
  position: sticky;
  top: 0;
  z-index: 30;
  /* Opaco primero: en un navegador sin color-mix (o sin desenfoque) la barra
     tiene que quedar sólida, nunca transparente sobre el contenido. */
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .app-head {
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(18px) saturate(180%);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
  }
}
.app-head-in {
  max-width: var(--tope);
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 12px) 16px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.marca { display: flex; align-items: center; gap: 11px; min-width: 0; }
/* La marca: la bolsa en un CÍRCULO dorado (redondo como los botones de la
   app; el cuadrado se veía duro). El oro del nivel del Club. */
.marca-icono {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  background: var(--oro);
  color: var(--oro-ink);
  display: grid; place-items: center;
  box-shadow: 0 6px 16px -10px rgba(122, 90, 18, .7);
}
.marca-icono svg { width: 22px; height: 22px; }
.marca-txt { min-width: 0; }
.marca-txt h1 {
  font: 700 16px/1.15 var(--display);
  letter-spacing: -.2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.marca-txt span {
  display: block;
  font-size: 11px; font-weight: 500;
  color: var(--txt-3);
  letter-spacing: .4px; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.head-acciones { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* Control segmentado sol/luna — mismo componente que el ranking y el panel de
   gestión, para que el gesto sea el mismo en las tres apps. */
.tema {
  display: flex; gap: 3px; flex-shrink: 0;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 3px;
}
.tema-btn {
  width: 30px; height: 30px; border-radius: var(--r-pill);
  color: var(--txt-3);
  display: grid; place-items: center;
  transition: background .2s var(--curva), color .2s var(--curva);
}
.tema-btn svg { width: 15px; height: 15px; }
.tema-btn:hover { color: var(--txt); }
.tema-btn[aria-pressed="true"] {
  background: var(--acc); color: var(--acc-ink);
  box-shadow: var(--glow);
}

.btn-icono {
  width: 36px; height: 36px; border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--txt-2);
  display: grid; place-items: center;
  transition: transform .15s var(--curva), color .15s, border-color .15s;
}
.btn-icono svg { width: 16px; height: 16px; }
.btn-icono:hover { color: var(--txt); border-color: var(--line-alta); }
.btn-icono:active { transform: scale(.92); }
.btn-icono.girando svg { animation: girar .7s linear infinite; }
@keyframes girar { to { transform: rotate(360deg); } }

/* ── MARCO: la navegación de las tres pantallas ────────────────────────── */
/*
   Una sola navegación, en dos formas.

   En la PC del local es una columna a la izquierda, siempre a la vista: es la
   máquina donde la app queda abierta todo el día y donde el encargado entra a
   configuración. En el celular esa columna se acuesta abajo, al alcance del
   pulgar, porque en 380px de ancho un rail lateral le come el lugar a los
   campos — y los vendedores cargan parados en el local, desde el celular.

   Las dos formas son el MISMO marcado. Lo único que cambia es el CSS, así no
   hay dos navegaciones que mantener sincronizadas.
*/
.rail {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  /* Opaco primero, igual que la cabecera: sin color-mix la barra tiene que
     quedar sólida y nunca transparente sobre el contenido. */
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
/* La marca y la identidad son piezas del rail PARADO. En el celular la marca
   ya está en la cabecera y la identidad en su barra, así que acá no existen. */
.rail-marca, .rail-pie { display: none; }
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .rail {
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: blur(18px) saturate(180%);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
  }
}
.rail-in {
  display: flex;
  height: var(--nav);
  max-width: 460px;
  margin: 0 auto;
}
.rail-item {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  color: var(--txt-2);
  text-decoration: none;
  font: 600 10.5px/1 var(--sans);
  -webkit-tap-highlight-color: transparent;
  transition: color .15s var(--curva), background .15s var(--curva);
}
/* El ícono vive adentro de su propia cajita redondeada: es lo que permite
   marcar la sección abierta con un relleno y no sólo con color, que es como
   lo marcan los tableros. */
.rail-icono {
  display: grid; place-items: center;
  width: 34px; height: 26px;
  border-radius: 9px;
  transition: background .18s var(--curva), color .18s var(--curva);
}
.rail-item svg { width: 20px; height: 20px; }
/* Con siete secciones (12/10/2026, se sumó Gift Cards) cada botón ocupa lo
   que su palabra, sin partirla, y la letra baja medio punto. En partes
   iguales "Gift Cards" se partía en dos renglones (a 360 px) o quedaba
   pegado a "Estadísticas" (a 390): así queda la misma luz entre palabras
   que tenían las seis. Sólo en la barra de abajo: el rail parado tiene lo
   suyo más abajo. */
@media (max-width: 899px) {
  .rail-item { flex: 1 0 auto; white-space: nowrap; font-size: 10px; padding: 0 3px; }
  /* Con la letra grande del celular (accesibilidad) los siete no entran:
     antes que pisar o cortar las palabras, la barra se desliza de costado
     (comun.js la arranca mostrando la sección abierta). Cada botón deja
     3px de cada lado, así dos palabras nunca quedan pegadas. */
  .rail-in { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain; }
  .rail-in::-webkit-scrollbar { display: none; }
}
/* En los celulares más angostos (320 px) la letra baja medio punto más: así
   entran los siete sin deslizarse, con 6 px entre palabras. */
@media (max-width: 339px) {
  .rail-item { font-size: 9.5px; }
}
.rail-item:hover { color: var(--txt); }
.rail-item:active { transform: scale(.94); }
/* La sección abierta se marca con el color de acento como TEXTO, que para eso
   está --acc-txt; --acc es relleno y acá no hay tinta encima que lo acompañe. */
.rail-item[aria-current="page"] { color: var(--txt); }
.rail-item[aria-current="page"] .rail-icono { background: var(--oro-soft); color: var(--oro-txt); }

/* Lo que el rail acostado le tapa al contenido. El formulario suma lo suyo
   aparte en index.html, porque ahí abajo también está la barra de guardar. */
@media (max-width: 899px) {
  body { padding-bottom: calc(var(--nav) + env(safe-area-inset-bottom) + 14px); }
}

/* ── El rail parado ────────────────────────────────────────────────────────
   Un panel oscuro flotando contra el borde izquierdo, de arriba abajo de la
   ventana: adentro van la marca, las secciones y —en el formulario— quién
   está cargando. Es el marco de la app; la hoja clara del medio es el
   trabajo. Que esté SIEMPRE a la vista y no scrollee es la mitad de la
   gracia: la PC del local queda abierta todo el día en esta pantalla.

   El contenido no se corre con un grid sino con padding-left en el <body>,
   porque la cabecera pegajosa y la barra de guardar viven afuera del .marco
   y tienen que correrse igual. La clase la ponen las páginas: el panel de
   seguimiento no tiene rail hasta que alguien pasa el PIN. */
@media (min-width: 900px) {
  body.hay-rail { padding-left: var(--rail); }
  .marco { display: block; max-width: none; }

  .rail {
    position: fixed;
    top: 12px; bottom: 12px; left: 12px; right: auto;
    width: var(--rail-ancho);
    /* El rail es oscuro también con el tema claro, así que los controles que
       vivan adentro —el desplegable de vendedores— tienen que abrirse
       oscuros: si no, salta una lista blanca de una caja negra. */
    color-scheme: dark;
    display: flex; flex-direction: column;
    padding: 14px 10px;
    border-top: 0;
    border-radius: 24px;
    background: var(--rail-bg);
    /* Entre dos oscuros, lo que dibuja el canto es la línea, no la sombra:
       una sombra negra sobre un fondo casi negro no existe. */
    border: 1px solid var(--rail-borde);
    /* Flota sobre el fondo claro (04/10/2026): sombra más honda y un canto
       de luz arriba. */
    box-shadow: 0 26px 50px -20px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* La marca se muda acá: en un tablero el logo es parte del marco, no del
     encabezado. La cabecera se queda con el título de la pantalla. */
  .rail-marca {
    display: grid; place-items: center;
    margin-bottom: 16px;
  }
  .rail-marca-icono {
    width: 40px; height: 40px; border-radius: 50%;
    background: var(--oro);
    color: var(--oro-ink);
    display: grid; place-items: center;
    box-shadow: 0 8px 18px -10px rgba(0, 0, 0, .8);
  }
  .rail-marca-icono svg { width: 25px; height: 25px; }
  .rail-marca-txt { display: none; }

  .rail-in {
    flex-direction: column;
    height: auto;
    max-width: none;
    gap: 6px;
  }
  .rail-item {
    flex: 0 0 auto;
    padding: 9px 4px;
    border-radius: 14px;
    font-size: 11px;
    gap: 5px;
    color: var(--rail-txt-2);
  }
  .rail-item { position: relative; }
  .rail-item:hover { color: var(--rail-txt); background: rgba(255, 255, 255, .05); }
  .rail-item[aria-current="page"] { color: var(--rail-txt); background: rgba(255, 255, 255, .10); }
  /* La barra del canto. Va de 8 a 8 y no de punta a punta: pegada a los
     extremos se lee como el borde del rail y no como una marca. */
  .rail-item[aria-current="page"]::before {
    content: "";
    position: absolute;
    left: 0; top: 8px; bottom: 8px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--rail-acc);
  }
  .rail-icono { width: 38px; height: 34px; border-radius: 12px; }
  .rail-item[aria-current="page"] .rail-icono {
    background: rgba(214, 174, 85, .16);
    color: #E8C877;
  }

  /* Abajo de todo, separado por el aire que sobra: quién está cargando. Es la
     tarjeta que en los tableros lleva la foto del usuario.

     Aparece recién a 1200 —ver más abajo—: acá el rail mide 84px y el
     desplegable de vendedores no entra. Entre 900 y 1200 la identidad sigue
     en su barra, adentro del formulario. */
  .rail-pie {
    display: none;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--rail-line);
    text-align: center;
  }
  /* display:block y no el inline que trae un <span>: sin esto el ancho y el
     alto no se aplican, el punto mide cero y directamente no se ve. */
  /* ── El punto de estado ──
     Tiene que parecer una LUZ ENCENDIDA, no un círculo verde. La diferencia
     no es el color: es que una luz tira resplandor sobre lo que tiene
     alrededor. Son dos sombras —un aro cercano y apretado, y un halo abierto
     y difuso— y esa segunda es la que hace el truco.

     Y usa un verde propio, más vivo que el --ok de los estados. Ese está
     apagado a propósito para no competir con el rojo en pastillas y cantos,
     pero un indicador apagado parece pintado. Acá el punto mide ocho
     píxeles: no compite con nada. */
  .rail-punto {
    display: block;
    width: 8px; height: 8px; border-radius: 50%;
    margin: 0 auto 7px;
    background: #2FE38A;
    box-shadow:
      0 0 0 3px rgba(47, 227, 138, .16),
      0 0 12px 2px rgba(47, 227, 138, .55);
  }
  /* El nombre del local puede ocupar dos renglones: en el rail angosto
     "Rivadavia" ya no entra en uno, y "Lomas de Zamora" no entra nunca.
     Cortado con puntos suspensivos ("Lomas de…") no sirve para lo único que
     tiene que hacer, que es decir dónde estás parado. */
  .rail-local {
    display: block;
    font: 700 12.5px/1.2 var(--display);
    color: var(--rail-txt);
  }
  /* Cambiar de local es lo raro —una vez por dispositivo— así que es el
     botón chico y discreto de abajo. Lo de todos los días, que es cambiar de
     vendedor, está arriba y es un desplegable. */
  .rail-cambiar {
    width: 100%;
    margin-top: 8px;
    border: 1px solid var(--rail-line);
    background: rgba(255, 255, 255, .06);
    color: var(--rail-txt-2);
    border-radius: var(--r-pill);
    padding: 6px 4px;
    font-size: 11.5px; font-weight: 700;
    transition: background .15s var(--curva), color .15s;
  }
  .rail-cambiar:hover { background: rgba(255, 255, 255, .13); color: var(--rail-txt); }
  /* Sin identidad elegida late en rojo, como la barra del celular: es lo
     único que falta para poder cargar. */
  /* Va con valor fijo y no con --acc: el token cambia con el tema y acá el
     fondo es el rail, que es oscuro siempre. */
  .rail-pie.vacia .rail-punto {
    background: #FF3B49;
    box-shadow:
      0 0 0 3px rgba(255, 59, 73, .22),
      0 0 12px 2px rgba(255, 59, 73, .6);
    animation: latido-rail 2.4s ease-in-out infinite;
  }
  /* Sin identidad, el texto explica en vez de nombrar, así que puede ocupar
     dos renglones: cortarlo con puntos suspensivos dejaba "Todavía no dijiste
     quién …", que no dice nada. */
  .rail-pie.vacia .rail-local {
    font: 700 13px/1.25 var(--display);
    white-space: normal;
  }
  @keyframes latido-rail {
    0%, 100% { box-shadow: 0 0 0 3px rgba(255, 59, 73, .22), 0 0 12px 2px rgba(255, 59, 73, .6); }
    50%      { box-shadow: 0 0 0 7px transparent; }
  }
}

/* Pantalla ancha: el rail se ensancha y el ícono se pone al lado del texto,
   que es como se leen las secciones de un tablero de escritorio. */
@media (min-width: 1200px) {
  :root { --rail-ancho: 168px; --rail: 194px; }
  .rail { padding: 16px 12px; }
  .rail-marca {
    display: flex; align-items: center; gap: 9px;
    justify-content: flex-start;
    padding: 0 2px;
    margin-bottom: 22px;
  }
  /* 14px y no 15: con 15 "No Compra" no entra en el ancho del rail y se corta
     en "No Comp…", que es peor que un punto menos de letra. */
  .rail-marca-txt {
    display: block; min-width: 0;
    font: 700 14px/1.15 var(--display);
    color: var(--rail-txt);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* "SISTEMA" chico arriba y "No Compra" abajo: el nombre completo entra
     en el ancho del rail sin achicar la letra del nombre. */
  .rail-marca-txt small {
    display: block;
    font: 600 9.5px/1 var(--sans);
    letter-spacing: 2px; text-transform: uppercase;
    color: var(--rail-txt-2);
    margin-bottom: 3px;
  }
  .rail-item {
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    padding: 7px 10px 7px 10px;
    font-size: 13.5px; font-weight: 600;
    border-radius: 12px;
  }
  .rail-icono { width: 32px; height: 32px; border-radius: 10px; }
  .rail-item svg { width: 17px; height: 17px; }

  /* Acá sí entra la ficha de quién está cargando, con su desplegable. */
  .rail-pie { display: block; text-align: left; }
  .rail-punto { margin: 0 0 7px; }
  .rail .quien { margin-top: 9px; }
  /* background-color y no background: el atajo borraría la flechita del
     desplegable, que es una imagen de fondo. */
  /* El fondo va OPACO y no con un velo blanco encima del rail. Chrome pinta
     la lista desplegada con el color de fondo del propio select, y un rgba
     translúcido se compone contra el blanco del navegador: la lista se abría
     clara sobre el rail oscuro. Con un color sólido se abre oscura.
     Las opciones se pintan aparte porque en Windows no lo heredan. */
  /* En el rail la etiqueta se centra como todo lo de la ficha, y en 146px
     de ancho la palabra y el cartel no entran en un renglón: se apilan. Los
     colores se rehacen porque acá adentro los tokens de la hoja no valen —el
     rail es oscuro también con el tema claro—. */
  .rail .quien-lbl {
    justify-content: center;
    font-size: 11.5px;
    color: var(--rail-txt-2);
    gap: 5px;
    margin-bottom: 6px;
  }
  .rail .lbl-req {
    color: var(--rail-txt-2);
    background: rgba(255, 255, 255, .08);
    border-color: rgba(255, 255, 255, .16);
    padding: 3px 7px;
  }
  .rail .quien-sel, .rail .quien-txt {
    background-color: var(--rail-campo);
    border: 1px solid rgba(255, 255, 255, .18);
    color: var(--rail-txt);
    font-size: 12.5px;
    padding: 7px 9px;
    border-radius: 10px;
  }
  .rail .quien-sel option { background-color: var(--rail-campo); color: var(--rail-txt); }
  .rail .quien-sel { padding-right: 24px; background-position: right 8px center; }
  /* En 146px de ancho el campo y el botón no entran al lado: se apilan. */
  .rail .quien-nuevo { flex-direction: column; gap: 6px; margin-top: 6px; }
  .rail .quien-ok { width: 100%; min-height: 32px; padding: 0 8px; font-size: 12.5px; }
  .rail .quien-sel:focus, .rail .quien-txt:focus {
    background-color: #3E3D38;
    border-color: var(--rail-acc);
    box-shadow: none;
  }
}

/* Las PC de los locales (1366×768: al navegador le quedan ~658 px de alto)
   con ocho secciones (12/10/2026, se sumó el Asistente): el rail se aprieta
   de alto para que entren todas y, en Carga, también la ficha de quién
   carga con su botón de abajo. Sin esto, "Cambiar de local" quedaba debajo
   del borde de la pantalla. */
@media (min-width: 900px) and (max-height: 760px) {
  .rail { padding-top: 10px; padding-bottom: 10px; }
  .rail-marca { margin-bottom: 10px; }
  .rail-marca-icono { width: 34px; height: 34px; }
  .rail-in { gap: 2px; }
  .rail-item { padding-top: 5px; padding-bottom: 5px; gap: 3px; }
  .rail-icono { height: 28px; }
}
@media (min-width: 1200px) and (max-height: 760px) {
  .rail-marca { margin-bottom: 12px; }
  .rail-item { padding-top: 4px; padding-bottom: 4px; }
  .rail-icono { height: 30px; }
  .rail-pie { padding-top: 10px; }
}

/* ── ESTRUCTURA ────────────────────────────────────────────────────────── */
.hoja {
  max-width: var(--tope);
  margin: 0 auto;
  padding: 18px 16px 24px;
}
/* Con rail al costado, el contenido ya no se centra contra la ventana sino
   contra su columna, y pegarlo al borde del rail lo deja sin aire. */
@media (min-width: 900px) { .hoja { padding-left: 22px; padding-right: 22px; } }

/* ── TARJETAS DE NÚMEROS ───────────────────────────────────────────────── */
/*
   Las usan el formulario (los números del local) y el panel (los del
   seguimiento). Estaban sueltas adentro de panel.html; viven acá desde que
   son dos pantallas las que las muestran.

   Dos por fila en el celular y cuatro en pantalla ancha: con cuatro en 380px
   el número queda más chico que su propia etiqueta.
*/
.kpis {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-bottom: 16px;
}
@media (min-width: 620px) { .kpis { grid-template-columns: repeat(4, 1fr); } }
/*
   La tarjeta de números es de OTRO MATERIAL, no de otro color: grafito a
   negro en los dos temas, igual que el rail. La regla que queda es simple y
   se ve sin explicarla —lo que es tablero (la navegación y los números) es
   oscuro; la hoja donde se trabaja es clara—, y de paso no le roba el rojo
   lleno al botón de guardar, que es lo único que se toca.

   En claro eso alcanza: la tarjeta es lo único oscuro y se impone sola. En
   oscuro hay menos luz para repartir, y lo que la despega del fondo es el
   resplandor rojo de su canto derecho, que el fondo no tiene.

   Antes usaba el mismo --surface que los paneles del formulario y sólo se
   diferenciaba por el tamaño.

   Los tokens de texto se REDECLARAN acá adentro en vez de escribir colores
   sueltos en cada regla: los --txt de arriba están pensados contra --bg y
   acá el fondo es este. Así todo lo de adentro —etiquetas, pies, la barra y
   los números de colores— se acomoda solo y sigue habiendo un solo lugar
   donde se cambian. */
.kpi {
  --txt:   #F4F2EC;
  --txt-2: #D2CDC3;
  --txt-3: #B8B2A7;
  --line:      rgba(255, 255, 255, .10);
  /* El canto izquierdo de las tres tarjetas es la MISMA escala: la que no
     tiene nada especial que decir lo lleva apagado, y las que sí —objetivo
     y plata— lo llevan lleno. Tres intensidades de lo mismo, no dos pintadas
     y una sin pintar.

     Blanco y no rojo, por pedido de Mauricio: el rojo en esta franja ya lo
     pone el resplandor de la tarjeta, y un canto rojo al lado de ese
     resplandor no agrega un dato, agrega ruido. */
  /* Bajó de .26 a .12 cuando la tarjeta bajó a negro. No es capricho: un
     blanco al 26% sobre #2B2E33 era un canto; el MISMO blanco sobre #0E0F11
     es una chapa clara pegada al borde, y encima la esquina redondeada le
     dibuja un inglete que se ve como un error de recorte. Lo que cambió no
     es el canto: es cuánto contrasta, y eso se mide contra el fondo nuevo. */
  --canto: rgba(255, 255, 255, .12);
  /* La pista de la barra del objetivo. Ojo con este valor: a 0% no se ve el
     relleno, así que la pista SOLA es lo que queda, y cruza la tarjeta de
     lado a lado abajo de todo. Al 10% sobre el negro nuevo parecía un pie de
     tarjeta gris que no cargó —justo en la única tarjeta que lo tiene, así
     que se leía como que esa tarjeta estaba rota—. */
  --surface-2: rgba(255, 255, 255, .06);
  --ok-txt:   #8FD1AE;
  --warn-txt: #F0C66A;
  --bad-txt:  #FF9AA0;
  --acc-txt:  #F4F2EC;
  --info-txt: #D2CDC3;

  /* Dos capas, de adelante para atrás:
       1. el resplandor rojo, pegado al canto derecho. Ahí no hay texto
          nunca —el número y las etiquetas viven a la izquierda—, así que
          puede ser fuerte sin comerse el contraste de nada.
       2. la base, grafito arriba a negro abajo.
     Es el material del tablero, y es el mismo en los dos temas: lo que se
     mira es oscuro, la hoja donde se trabaja cambia.

     Había una tercera: una textura de rayas diagonales, al 2,8% de blanco,
     para que el negro no fuera una tapa plana. Mauricio la vio en la
     pantalla del local el 25/09/2026 y no le gustó. Y no hacía falta: el
     resplandor ya hace ese trabajo, y una textura que se NOTA dejó de ser
     textura. */
  /* 30/09/2026: el material del nivel Platino del Club, el mismo degradado
     que la franja de su tarjeta. Se fue el resplandor rojo del canto. */
  background: var(--tablero-negro, var(--platino));
  border: 1px solid var(--line);
  border-left: 3px solid var(--canto);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  color: var(--txt);
  position: relative;
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .07),
    0 14px 30px -14px rgba(0, 0, 0, .9);
  animation: aparecer .4s var(--curva) backwards;
}
.kpi-n { font: 700 27px/1.05 var(--display); letter-spacing: -.8px; }
.kpi-l { font-size: 12px; font-weight: 600; color: var(--txt-2); margin-top: 3px; }
.kpi-pie { font-size: 11.5px; color: var(--txt-3); margin-top: 1px; }
.kpi.es-pend { border-left-color: var(--warn); }
.kpi.es-pend .kpi-n { color: var(--warn-txt); }
.kpi.es-ok { border-left-color: var(--ok); }
.kpi.es-ok .kpi-n { color: var(--ok-txt); }
.kpi.es-plata { border-left-color: rgba(255, 255, 255, .32); }
.kpi.es-plata .kpi-n { color: var(--txt); }
/* Las tarjetas de plata llevan un importe, no un número corto: con 27px un
   "$ 1.234.567" se sale de la tarjeta en un celular. */
.kpi.es-ok .kpi-n, .kpi.es-plata .kpi-n { font-size: 21px; }

/* Objetivo: el único número que se compara contra otro, así que además del
   valor lleva la barra. El relleno sí usa --acc, que es para eso. */
.kpi.es-obj { border-left-color: rgba(255, 255, 255, .32); }
/* Objetivo cumplido: el verde de "esto ya está" es el mismo que usa el panel
   para lo cerrado, así el color quiere decir lo mismo en las dos pantallas. */
.kpi.es-obj.lleno { border-left-color: var(--oro-liso); }
.kpi.es-obj.lleno .kpi-n { color: #E8C877; }
.kpi.es-obj.lleno .kpi-barra i { background: var(--oro); }
/* La barra va pegada al BORDE de abajo y no en la fila del texto. Es la
   única tarjeta que la lleva: adentro del contenido, las otras dos quedaban
   con un hueco de casi medio centímetro abajo —mismo alto de grilla, un
   elemento menos— y eso se lee como algo que no cargó. Como parte del marco
   las tres terminan parejas, los números siguen en un solo renglón y la
   tarjeta se ahorra 14px de alto, que en la notebook del local valen. */
.kpi-barra {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 5px;
  background: var(--surface-2);
  border-top: 1px solid rgba(255, 255, 255, .05);
  overflow: hidden;
}
/* Con la pista apagada, el relleno queda solo contra el negro y puede ir a
   pleno: la barra pasó a decirse por lo que está HECHO y no por el hueco que
   falta, que es como se lee un objetivo. */
.kpi-barra i {
  display: block;
  height: 100%;
  /* El avance del objetivo, en oro: el logro del día. */
  background: var(--oro);
  transition: width .5s var(--curva);
}

.bloque {
  background: var(--panel-fondo);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 18px 16px;
  margin-bottom: 12px;
  box-shadow: var(--sombra);
  animation: aparecer .4s var(--curva) backwards;
}
.bloque-tit {
  font: 700 17px/1.25 var(--display);
  letter-spacing: -.2px;
  margin-bottom: 3px;
  display: flex; align-items: center; gap: 8px;
}
.bloque-sub {
  font-size: 13.5px;
  color: var(--txt-2);
  margin-bottom: 15px;
}
.bloque-tit + .campos, .bloque-tit + .chips { margin-top: 14px; }

/* "obligatorio" escrito, no un puntito de color.
   Antes era un punto al lado del título: sin leyenda en ninguna parte, quien
   abría la app por primera vez lo leía como adorno. La palabra ocupa unos
   pixeles más y no hay que explicarla. Es la única marca que queda en el
   formulario: los campos no anuncian que se pueden saltear, porque decirle a
   alguien que algo es opcional es darle permiso para no cargarlo.

   Y va en GRIS, no en rojo. El rojo está reservado para lo que se
   toca —los chips y el botón—; es la misma razón por la que el número del
   paso va hueco. Un cartel rojo al lado del título se ofrecía como si
   fuera un botón y competía con el único que hay que apretar. */
.lbl-req {
  font: 600 10.5px/1 var(--sans);
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--txt-3);
  background: var(--acc-soft);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  padding: 4px 8px;
  flex-shrink: 0;
}

/* ── CAMPOS ────────────────────────────────────────────────────────────── */
.campos { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.campo { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.campo.ancho { grid-column: 1 / -1; }

label, .campo-lbl {
  font-size: 13px;
  font-weight: 600;
  color: var(--txt-2);
  letter-spacing: .1px;
  display: flex; align-items: center; gap: 6px;
}
.lbl-opc { font-weight: 400; color: var(--txt-3); font-size: 12px; }

input[type=text], input[type=tel], input[type=email], input[type=number],
input[type=search], input[type=password], input[type=url], input[type=date], textarea, select {
  width: 100%;
  background: var(--campo);
  border: 1px solid var(--line-campo);
  border-radius: var(--r-sm);
  color: var(--txt);
  /* 16px exactos: con menos, iOS hace zoom solo al tocar el campo y descoloca
     toda la pantalla. Es la razón por la que ningún input baja de 16px. */
  font-size: 16px;
  /* Interlineado fijo (30/09/2026): el natural de Poppins es más alto que el
     de DM Sans, y cada campo crecía 3px. En la PC del local (1366×768) el
     alto es lo que manda: con esto Carga mide lo mismo que antes. */
  line-height: 1.3;
  padding: 13px 14px;
  outline: none;
  -webkit-appearance: none; appearance: none;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
input::placeholder, textarea::placeholder { color: var(--txt-3); opacity: 1; }
input:focus, textarea:focus, select:focus {
  border-color: var(--foco);
  /* Una línea más del mismo color, adentro del borde: 2 px nítidos en vez
     del borde de 1 más un halo de 4 que se veía difuso (04/10/2026). */
  box-shadow: 0 0 0 1px var(--foco);
  background: var(--campo);
}
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; }
textarea { resize: vertical; min-height: 84px; line-height: 1.55; }

/* El campo de número quedaba con el aspecto que le pone el navegador —caja
   gris, sin radio, otro alto— porque no estaba en la lista de arriba: se veía
   como un campo roto al lado de los demás. Las flechitas de subir y bajar se
   sacan: el único número que se carga acá es un objetivo de un dígito o dos y
   esas flechas se comen la mitad del ancho. */
input[type=number] { -moz-appearance: textfield; }
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 5L10 1' stroke='%238A857C' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}

/* Campo inválido: sólo después de intentar guardar (lo pone el JS), nunca
   mientras la persona todavía está escribiendo. */
.campo.mal input, .campo.mal textarea, .campo.mal select, .campo.mal .chips {
  border-color: var(--bad);
  box-shadow: 0 0 0 4px var(--bad-soft);
}
.campo-error {
  font-size: 12.5px; font-weight: 600; color: var(--bad-txt);
  display: flex; align-items: center; gap: 5px;
}

/* ── CHIPS (locales, talles, motivos, filtros) ─────────────────────────── */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  padding: 10px 14px;
  min-height: 42px;
  border: 1px solid var(--chip-line);
  border-radius: var(--r-pill);
  background: var(--chip);
  color: var(--txt);
  font-size: 14px; font-weight: 600; line-height: 1.2;
  text-decoration: none;
  display: inline-flex; align-items: center; gap: 7px;
  transition: transform .15s var(--curva), border-color .15s, background .15s, color .15s;
}
/* El hover ya no puede usar --line-alta: es el mismo color que el borde
   normal del chip. Un indicio rojo anticipa en qué se va a convertir. */
.chip:hover { border-color: var(--acc); color: var(--txt); }
.chip:active { transform: scale(.95); }
.chip.sel {
  background: var(--acc);
  border-color: var(--acc);
  color: var(--acc-ink);
  box-shadow: var(--glow);
}
.chip.sel:hover { color: var(--acc-ink); }

/* Grilla de locales: en el celular entran de a dos y el dedo no falla. */
.chips-local { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.chips-local .chip {
  justify-content: center;
  text-align: center;
  border-radius: var(--r-sm);
  padding: 13px 10px;
  min-height: 52px;
  font-size: 14.5px;
}
@media (min-width: 560px) { .chips-local { grid-template-columns: repeat(3, 1fr); } }

/* ── BOTONES ───────────────────────────────────────────────────────────── */
.btn {
  min-height: 50px;
  padding: 0 24px;
  border-radius: var(--r-sm);
  font: 700 16px var(--sans);
  letter-spacing: .1px;
  /* Varios .btn son <a> (WhatsApp, mail, ir al panel): sin esto se ven con el
     subrayado de enlace y dejan de parecer botones. */
  text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  transition: transform .15s var(--curva), box-shadow .2s, background .2s, opacity .2s;
}
.btn svg { width: 18px; height: 18px; }
.btn:active:not(:disabled) { transform: scale(.975); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-pri {
  background: linear-gradient(160deg, var(--acc) 0%, var(--acc-2) 100%);
  /* Blanco: sobre el rojo VDH da 6,8:1, y 9,4:1 en el extremo oscuro del
     degradado, que es el punto que manda. */
  color: var(--acc-ink);
  box-shadow: var(--glow);
}
.btn-sec {
  background: var(--surface-2);
  border: 1.5px solid var(--line);
  color: var(--txt);
}
.btn-sec:hover:not(:disabled) { border-color: var(--line-alta); }
.btn-ancho { width: 100%; }

.btn-chico {
  min-height: 38px; padding: 0 14px;
  font-size: 13.5px; font-weight: 600;
  border-radius: var(--r-pill);
}
.btn-chico svg { width: 15px; height: 15px; }

/* Verde de WhatsApp: es el color del producto, no del sistema. Se deja tal
   cual a propósito — es el único verde que queda en toda la app. */
.btn-wsp { background: #25D366; color: #06331A; font-weight: 700; }
.btn-wsp:hover:not(:disabled) { background: #1FBE5B; }

/* ── PÍLDORAS DE ESTADO ────────────────────────────────────────────────── */
.pill {
  font-size: 12px; font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: 5px;
  white-space: nowrap;
}
.pill-neutra { background: var(--surface-3); color: var(--txt-2); }
.pill-acc    { background: var(--acc-soft);  color: var(--acc-txt); }
.pill-ok     { background: var(--ok-soft);   color: var(--ok-txt); }
.pill-warn   { background: var(--warn-soft); color: var(--warn-txt); }
.pill-bad    { background: var(--bad-soft);  color: var(--bad-txt); }
.pill-info   { background: var(--info-soft); color: var(--info-txt); }
/* El nivel de un socio, con el color de su nivel (los mismos de la app). */
/* Los niveles del Club: Silver, Gold y Black (hasta el 07/10/2026, Plata,
   Oro y Platino; las clases viejas quedan para lo que todavía las usa). */
.pill-silver, .pill-plata  { background: #DADDE2; color: #2A2D31; }
.pill-gold, .pill-oro      { background: #F1D27A; color: #3A2A00; }
.pill-black, .pill-platino { background: #0B0C0E; color: #FFFFFF; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35); }

/* ── AVISO (cola offline, sin PIN, error de sincronización) ────────────── */
.aviso {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--warn);
  background: var(--warn-soft);
  color: var(--warn-txt);
  font-size: 13.5px; font-weight: 600;
  margin-bottom: 12px;
}
.aviso svg { width: 18px; height: 18px; flex-shrink: 0; }
.aviso-cuerpo { flex: 1; min-width: 0; }
.aviso button {
  flex-shrink: 0;
  border: 1.5px solid currentColor;
  border-radius: var(--r-pill);
  padding: 6px 12px;
  color: inherit;
  font: 700 12.5px var(--sans);
}
.aviso.aviso-bad { border-color: var(--bad); background: var(--bad-soft); color: var(--bad-txt); }

/* ── TOAST ─────────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom) + 96px);
  transform: translate(-50%, 20px);
  z-index: 130;  /* encima de las ventanitas (z 70) y del rail (96): un aviso tapado no avisa */
  max-width: calc(100vw - 32px);
  display: flex; align-items: center; gap: 9px;
  padding: 13px 18px;
  border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600;
  box-shadow: var(--sombra-alta);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s var(--curva), transform .25s var(--curva);
}
.toast.visible { opacity: 1; transform: translate(-50%, 0); }
.toast svg { width: 17px; height: 17px; flex-shrink: 0; }
.toast.ok  { background: var(--ok);  color: var(--ok-ink); }
.toast.err { background: var(--bad); color: var(--bad-ink); }
.toast.info { background: var(--surface-3); color: var(--txt); border: 1px solid var(--line-alta); }

/* ── VACÍO / CARGANDO ──────────────────────────────────────────────────── */
.vacio {
  text-align: center;
  padding: 56px 24px;
  color: var(--txt-2);
}
.vacio-icono {
  width: 52px; height: 52px; margin: 0 auto 14px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  color: var(--txt-3);
}
.vacio-icono svg { width: 22px; height: 22px; }
.vacio b { display: block; font: 700 16px var(--display); color: var(--txt); margin-bottom: 4px; }
.vacio span { font-size: 13.5px; }

/* Esqueleto de carga: evita el salto de "Cargando..." a la lista. */
.skel {
  height: 108px;
  border-radius: var(--r);
  background: linear-gradient(100deg, var(--surface) 30%, var(--surface-2) 50%, var(--surface) 70%);
  background-size: 300% 100%;
  animation: brillo 1.4s ease infinite;
  margin-bottom: 12px;
  border: 1px solid var(--line);
}
@keyframes brillo { from { background-position: 150% 0; } to { background-position: -50% 0; } }

/* ── PIE ───────────────────────────────────────────────────────────────── */
.pie {
  text-align: center;
  font-size: 12px;
  color: var(--txt-3);
  padding: 8px 16px calc(env(safe-area-inset-bottom) + 16px);
}
.pie a { color: var(--txt-3); text-decoration: underline; text-underline-offset: 3px; }
.pie a:hover { color: var(--acc-txt); }

/* Un pulso corto al elegir un chip: confirma el toque sin hacer esperar a
   nadie. 280ms es lo que tarda en leerse como respuesta y no como demora. */
.chip.sel { animation: pulso .28s var(--curva); }
@keyframes pulso {
  0%   { transform: scale(.93); }
  55%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}


/* ── PANTALLA GRANDE ───────────────────────────────────────────────────────
   Arriba de 1600px el problema deja de ser el ancho y pasa a ser la ESCALA.
   Hasta acá un monitor de 27" recibía exactamente el mismo layout que una
   notebook de 1280 —la misma letra de 16px, el mismo padding de 16px, los
   mismos números de 24px— y lo único que crecía eran los márgenes. Por eso
   se veía chico y apretado en el medio en vez de angosto.

   Lo que sube es el cuerpo de lo que se lee, NO el ancho de las columnas:
   estirar un campo de texto a 700px empeora la lectura —el ojo viaja de más
   entre la etiqueta y el campo— y eso ya estaba dicho en index.html. Los
   topes de cada pantalla crecen aparte, y con moderación.

   El alto no entra en la cuenta: un monitor de 27" tiene alto de sobra. Las
   reglas por altura que achican todo para las notebooks viven en index.html,
   son más específicas por venir después y siguen mandando sobre esto.

   Los inputs no bajan de 16px nunca (iOS hace zoom solo); acá sólo suben. */
@media (min-width: 1600px) {
  .kpi-l { font-size: 14px; }
  .kpi-pie { font-size: 12.5px; }

  .bloque { padding: 20px 22px; }
  .bloque-tit { font-size: 18.5px; }
  .bloque-sub { font-size: 14.5px; }

  .campos { gap: 14px; }
  label, .campo-lbl { font-size: 13.5px; }
  input[type=text], input[type=tel], input[type=email], input[type=number],
  input[type=search], input[type=password], input[type=url], input[type=date], textarea, select {
    font-size: 16.5px;
    padding: 14px 15px;
  }

  .chip { font-size: 14.5px; min-height: 44px; padding: 10px 16px; }
  .btn { font-size: 16.5px; min-height: 52px; }
  .btn-chico { font-size: 14px; }
}


/* ── Las pastillas de una sección con varias caras ───────────────────────
   El Club tiene cuatro: Cobrar (la caja), Socios, Movimientos y
   Estadísticas (30/09/2026). Se ven como una sola sección con una pastilla
   arriba para pasar de una a otra. La elegida se ve apretada, no sólo de
   otro color. */
.pestanas {
  display: inline-flex; gap: 4px; padding: 4px; margin-bottom: 16px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 99px;
}
.pestana {
  padding: 9px 20px; border-radius: 99px; text-decoration: none;
  font: 700 14.5px/1 var(--sans); color: var(--txt-2);
  transition: background .15s var(--curva), color .15s var(--curva);
}
.pestana:hover { color: var(--txt); }
.pestana:focus-visible { outline: 2px solid var(--txt); outline-offset: 2px; }
.pestana[aria-current="page"] { background: var(--surface); color: var(--txt); box-shadow: var(--sombra); }
/* En el celular las cuatro no entran con su aire: ocupan el ancho y se
   reparten el lugar. */
@media (max-width: 520px) {
  .pestanas { display: flex; width: 100%; }
  .pestana { flex: 1 1 auto; text-align: center; padding: 9px 6px; font-size: 13.5px; }
}

/* ── La foto de una promo: pegarla, arrastrarla o elegirla (02/10/2026) ──
   Al lado del enlace, no en vez de él: las dos formas quedan. */
.foto-zona {
  margin-top: 8px; padding: 12px 14px;
  border: 1.5px dashed var(--line); border-radius: 10px;
  background: var(--surface-2); color: var(--txt-2);
  font-size: 13.5px; line-height: 1.45;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.foto-zona.encima { border-color: var(--foco); background: var(--ok-soft); }
.foto-zona.subiendo { opacity: .7; pointer-events: none; }
.foto-zona b { color: var(--txt); }
.foto-zona .btn { flex: none; }

/* La zona a la que va lo que se pega (la portada o la colección). */
.foto-zona.activa { border-style: solid; border-color: var(--foco); }

/* ── La colección de una promo (SQL 43, 03/10/2026) ──
   Las fotos en orden, como van a salir en la revista: la 1, la 4, la 7…
   a lo ancho; las otras de a dos. */
.col-admin { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; margin-top: 12px; }
.col-admin:empty { display: none; }
.col-item { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--surface); }
.col-item-foto { position: relative; aspect-ratio: 2 / 3; background: var(--surface-2) center / cover no-repeat; }
.col-item-n {
  position: absolute; top: 6px; left: 6px; min-width: 24px; height: 24px; padding: 0 7px; border-radius: 12px;
  background: rgba(0, 0, 0, .7); color: #fff; font: 700 12px/24px var(--sans); text-align: center;
}
.col-item-ancho {
  position: absolute; bottom: 6px; left: 6px; padding: 2px 8px; border-radius: 10px;
  background: rgba(255, 255, 255, .92); color: #16181B; font: 600 11px/18px var(--sans);
}
.col-item-barra { display: flex; gap: 4px; padding: 6px; }
.col-item-barra button {
  flex: 1; min-height: 32px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
  color: var(--txt); font: 700 15px var(--sans); cursor: pointer;
}
.col-item-barra button:disabled { opacity: .35; cursor: default; }
.col-item select { width: calc(100% - 12px); margin: 0 6px 6px; font-size: 12.5px; min-height: 32px; }

/* ── QUIÉN ENTRÓ (persona.js, 13/10/2026) ─────────────────────────────────
   Cada persona entra con su usuario y la barra muestra lo que usa su rol.
   persona.js pone el rol en <html> ANTES de pintar, así lo que no va nunca
   llega a verse. Sin usuario no hay rol y se ve todo, como siempre. */
html[data-nc-rol="vendedor"] .rail-item[href="panel.html"],
html[data-nc-rol="vendedor"] .rail-item[href^="club-numeros.html"],
html[data-nc-rol="vendedor"] .rail-item[href="config.html"],
html[data-nc-rol="supervisor"] .rail-item[href="panel.html"],
html[data-nc-rol="supervisor"] .rail-item[href^="club-numeros.html"],
html[data-nc-rol="atencion"] .rail-item[data-impecable],
html[data-nc-rol="atencion"] .rail-item[href="impecable-admin.html"] { display: none; }

/* El botón de quién entró es el último de la barra. Es un <button> y no un
   enlace: se le saca lo que el navegador le pone a los botones. */
button.rail-item { border: 0; background: none; cursor: pointer; }
.rail-yo.adentro .rail-icono { background: var(--ok-soft); color: var(--ok-txt); }
.rail-yo.espera .rail-icono { background: var(--warn-soft); color: var(--warn-txt); }
@media (min-width: 900px) {
  /* En el rail oscuro: el mismo verde de la luz de "conectado". */
  .rail-yo.adentro .rail-icono { background: rgba(47, 227, 138, .14); color: #7EEBB5; }
  .rail-yo.espera .rail-icono { background: rgba(232, 200, 119, .16); color: #E8C877; }
  button.rail-item:hover { background: rgba(255, 255, 255, .05); }
}

/* En la Carga, en la PC ancha, el rail ya va justo de alto con su pie (quién
   carga y cambiar de local): una sección más lo hacía salirse por abajo en la
   PC del local (1366×658). Ahí quien entró es un botón redondo en el mismo
   renglón que "Cambiar de local", sin sumar alto; en las otras pantallas, y
   entre 900 y 1200 (donde el pie no se muestra), sigue siendo el último de la
   barra. La clase con-pie la pone persona.js. */
.rail-fila { display: flex; align-items: center; gap: 5px; margin-top: 8px; }
/* En un renglón y sin partirse: partido, el pie crecía 17 px y la barra se
   volvía a salir por abajo. */
.rail-fila .rail-cambiar { margin-top: 0; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-left: 4px; padding-right: 4px; font-size: 11px; }
.rail-yo-mini { display: none; }
@media (min-width: 1200px) {
  .rail.con-pie .rail-in .rail-yo { display: none; }
  .rail-yo-mini {
    display: grid; place-items: center; flex: 0 0 auto;
    width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
    border: 1px solid var(--rail-line); background: rgba(255, 255, 255, .06); color: var(--rail-txt-2);
  }
  .rail-yo-mini svg { width: 16px; height: 16px; }
  .rail-yo-mini:hover { background: rgba(255, 255, 255, .13); color: var(--rail-txt); }
  .rail-yo-mini.adentro { background: rgba(47, 227, 138, .14); border-color: rgba(47, 227, 138, .35); color: #7EEBB5; }
  .rail-yo-mini.espera { background: rgba(232, 200, 119, .16); border-color: rgba(232, 200, 119, .4); color: #E8C877; }
}

/* La ventana para entrar (local → nombre → PIN), la de quién entró y la de
   esperar el OK. Encima de todo menos de los avisos (130). */
.ncp-velo {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  padding: 16px; overflow-y: auto;
  background: rgba(20, 20, 18, .5);
}
.ncp-caja {
  position: relative;
  width: min(460px, 100%);
  background: var(--surface); color: var(--txt);
  border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .45);
  padding: 22px 20px 20px;
}
.ncp-caja h2 { font: 700 20px/1.25 var(--display); margin: 0 40px 4px 0; }
.ncp-caja:focus { outline: none; }
.ncp-bajada { font-size: 14px; color: var(--txt-2); margin: 0 0 14px; }
.ncp-x {
  position: absolute; top: 12px; right: 12px;
  width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: var(--surface-2); color: var(--txt-2);
  font: 400 22px/1 var(--sans); cursor: pointer;
}
.ncp-x:hover { color: var(--txt); background: var(--surface-3); }
.ncp-volver {
  border: 0; background: none; padding: 0 0 10px; cursor: pointer;
  color: var(--txt-2); font: 600 13.5px var(--sans);
}
.ncp-volver:hover { color: var(--txt); }
.ncp-lista { max-height: min(52vh, 420px); overflow-y: auto; padding: 2px; }
.ncp-nuevo { margin-top: 12px; }
.ncp-vacio, .ncp-cargando { color: var(--txt-2); font-size: 14px; padding: 8px 0; margin: 0; }
.ncp-campos { display: grid; gap: 12px; }
.ncp-aviso { min-height: 20px; margin: 10px 0 0; font-size: 13.5px; font-weight: 600; color: var(--txt-2); text-align: center; }
.ncp-aviso.mal { color: var(--bad-txt); }
.ncp-pie { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; margin-top: 16px; }
.ncp-nota { font-size: 13.5px; color: var(--txt-2); background: var(--surface-2); border-radius: var(--r-sm); padding: 10px 12px; margin: 0; }
.ncp-puntos { display: flex; justify-content: center; gap: 14px; margin: 8px 0 2px; }
.ncp-puntos i { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line-alta); transition: background .15s, border-color .15s; }
.ncp-puntos i.lleno { background: var(--txt); border-color: var(--txt); }
.ncp-puntos.esperando i { animation: ncp-latir 1s ease-in-out infinite; }
.ncp-puntos.mal { animation: ncp-temblar .35s; }
.ncp-teclado { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: 300px; margin: 12px auto 0; }
.ncp-teclado button {
  height: 56px; border-radius: 16px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt);
  font: 600 22px var(--sans);
}
.ncp-teclado button:hover:not(:disabled) { border-color: var(--line-alta); }
.ncp-teclado button:active:not(:disabled) { transform: scale(.95); background: var(--surface-3); }
.ncp-teclado button:disabled { opacity: .45; cursor: not-allowed; }
@keyframes ncp-temblar { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-8px); } 75% { transform: translateX(8px); } }
@keyframes ncp-latir { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) {
  .ncp-puntos.mal, .ncp-puntos.esperando i { animation: none; }
}

/* Config → Usuarios (usuarios.js). En la PC, la lista a la izquierda y lo
   que se hace (aprobar, crear) a la derecha. */
.us-grilla { display: grid; gap: 12px; align-items: start; }
@media (min-width: 1100px) { .us-grilla { grid-template-columns: minmax(0, 1fr) 400px; } }
.us-col > .bloque:last-child { margin-bottom: 0; }
.us-filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 12px; }
.us-filtros select { width: auto; min-width: 220px; max-width: 100%; }
.us-check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--txt-2); cursor: pointer; }
.us-check input { width: 18px; height: 18px; accent-color: var(--acc); }
.us-lista { display: grid; gap: 8px; }
.us-grupo { font: 700 12px/1 var(--sans); letter-spacing: .6px; text-transform: uppercase; color: var(--txt-3); margin: 10px 2px 0; }
.us-grupo:first-child { margin-top: 0; }
.us-fila {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface);
}
.us-fila.apagada { background: var(--surface-2); }
.us-fila.apagada .us-quien b { color: var(--txt-2); }
.us-pend { border-color: var(--warn); background: var(--warn-soft); }
.us-quien { flex: 1 1 180px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.us-quien b { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.us-quien b small { font-weight: 500; color: var(--txt-3); font-size: 12.5px; }
.us-quien span { font-size: 13px; color: var(--txt-2); }
.us-acciones, .us-editor { display: flex; flex-wrap: wrap; gap: 6px; }
.us-acciones { flex: 0 1 auto; }
.us-editor { flex: 1 1 100%; }
.us-editor select { width: auto; flex: 1 1 160px; min-height: 40px; padding-top: 8px; padding-bottom: 8px; }
.us-editor select[hidden] { display: none; }
.us-vacio { font-size: 14px; color: var(--txt-2); margin: 0; }
.us-nota { font-size: 13px; color: var(--txt-3); margin: 14px 0 0; }
.us-fijo { font-size: 15px; font-weight: 600; padding: 4px 0; }
#usCampoLocal[hidden] { display: none; }

/* El portón de lo que antes pedía el PIN compartido (persona.porton). */
.porton-usuario { width: 100%; }
.porton-usuario:empty { display: none; }
.ncp-porton-txt { font-size: 14px; color: var(--txt-2); margin: 0 0 12px; }
.ncp-porton-txt b { color: var(--txt); }

/* Llegó con la dirección a una pantalla que no es de su rol: la tapa entera,
   con la salida a mano. */
.ncp-sinacceso {
  position: fixed; inset: 0; z-index: 95;
  display: grid; place-items: center; padding: 16px;
  background: var(--bg);
}

/* ══ INTERFAZ COMÚN (interfaz.js, 15/10/2026) ═══════════════════════════════
   Pedido de Mauricio: "que todo funcione de la misma manera". Eligió en la
   maqueta la barra como Supabase, el mismo botón para achicar los paneles y
   un solo selector de período. Va al final para mandar sobre lo de arriba. */

/* ── La barra negra, angosta ─────────────────────────────────────────────
   En la compu: sólo los íconos; al pasar el mouse se abre con los nombres por
   ENCIMA (la pantalla no se mueve) y "Dejarla abierta" la fija (ahí sí corre la
   pantalla). El nombre de cada sección sigue en el marcado: angosta, mide 0.
   En el celular sigue siendo la barra de abajo, sin cambios. */
.rail-fijar { display: none; }
@media (min-width: 900px) {
  :root { --rail-ancho: 64px; --rail: 88px; --rail-abierta: 196px; }
  :root.rail-fija { --rail-ancho: 196px; --rail: 220px; }
  html.rail-lista body.hay-rail { transition: padding-left .2s var(--curva); }
  .rail {
    width: var(--rail-ancho);
    overflow: hidden;
    padding: 14px 10px;
    transition: width .18s var(--curva), box-shadow .18s var(--curva);
  }
  /* Abierta va por encima de la pantalla (la cabecera es 30) pero por debajo de las ventanas (60 en adelante):
     angosta se queda en 45, como siempre, para que el fondo oscuro de una ventana la tape. */
  .rail.abierta {
    z-index: 58;
    width: var(--rail-abierta);
    box-shadow: 0 30px 70px -18px rgba(0, 0, 0, .72), inset 0 1px 0 rgba(255, 255, 255, .06);
  }
  .rail-marca { display: flex; align-items: center; justify-content: flex-start; gap: 9px; padding: 0 1px; margin-bottom: 16px; }
  .rail-marca-icono { flex: none; }
  .rail-marca-txt {
    display: block; min-width: 0;
    font: 700 14px/1.15 var(--display);
    color: var(--rail-txt);
    white-space: nowrap; overflow: hidden;
    opacity: 0; transition: opacity .12s;
  }
  .rail-marca-txt small {
    display: block;
    font: 600 9.5px/1 var(--sans);
    letter-spacing: 2px; text-transform: uppercase;
    color: var(--rail-txt-2);
    margin-bottom: 3px;
  }
  .rail-in { gap: 4px; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: none; }
  .rail-in::-webkit-scrollbar { display: none; }
  .rail-item {
    flex: 0 0 auto;
    flex-direction: row; justify-content: flex-start;
    gap: 10px;
    padding: 5px;
    border-radius: 12px;
    font-size: 0; font-weight: 600;
    white-space: nowrap;
  }
  .rail-icono { width: 34px; height: 32px; border-radius: 10px; flex: none; }
  .rail-item svg { width: 18px; height: 18px; }
  .rail.abierta .rail-item, :root.rail-fija .rail-item { font-size: 13.5px; }
  .rail.abierta .rail-marca-txt, :root.rail-fija .rail-marca-txt { opacity: 1; }
  /* Abajo de todo: "Dejarla abierta" / "Achicar la barra". */
  .rail-fijar { display: flex; margin-top: auto; color: var(--rail-txt-2); }
  .rail-fijar .rail-icono { background: none; }
  .rail-fijar:hover { color: var(--rail-txt); }
}
/* La Carga (index.html, <html class="rail-ficha">) tiene abajo de la barra la
   ficha de quién carga: en la PC ancha la barra queda abierta siempre, como
   estaba, porque esa ficha no entra angosta. Entre 900 y 1200 la ficha vive en
   la barra de identidad del formulario y la barra es la angosta, como en todas. */
@media (min-width: 1200px) {
  :root.rail-ficha { --rail-ancho: 168px; --rail: 194px; }
  :root.rail-ficha .rail-item { font-size: 13.5px; }
  :root.rail-ficha .rail-marca-txt { opacity: 1; }
  :root.rail-ficha .rail-fijar { display: none; }
  :root:not(.rail-ficha):not(.rail-fija) .rail-pie { display: none; }
}
@media (min-width: 900px) and (max-height: 760px) {
  .rail-marca { margin-bottom: 10px; }
  .rail-in { gap: 2px; }
  .rail-item { padding-top: 3px; padding-bottom: 3px; }
  .rail-icono { height: 28px; }
}

/* ── El panel de cada sección (CRM, Equipo VDH, Asistente) ────────────────
   El mismo botón, arriba a la derecha del panel, para achicarlo a íconos. */
:root { --panel-ancho: 240px; --panel-chico: 60px; }
.plegar-panel {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; border-radius: 10px;
  background: none;
  color: var(--txt-3);
  cursor: pointer;
  transition: background .15s, color .15s;
}
.plegar-panel:hover { background: var(--surface-3); color: var(--txt); }
.plegar-panel:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }
.plegar-panel svg { width: 19px; height: 19px; }

/* ── El selector de período ───────────────────────────────────────────────
   Un botón que dice el período, con ‹ › al costado. Al tocarlo: los atajos a la
   izquierda y el calendario a la derecha (un día, otro día y "Aplicar"). */
.per {
  position: relative;
  display: inline-flex; align-items: stretch;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(20, 20, 18, .06);
}
.per-flecha, .per-boton {
  border: 0; background: none; color: var(--txt); cursor: pointer;
  transition: background .15s, color .15s;
}
.per-flecha { width: 40px; display: grid; place-items: center; color: var(--txt-3); }
.per-flecha:first-child { border-right: 1px solid var(--line); border-radius: var(--r-sm) 0 0 var(--r-sm); }
.per-flecha[data-mover="1"] { border-left: 1px solid var(--line); border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.per-flecha:hover, .per-boton:hover { background: var(--surface-2); color: var(--txt); }
.per-flecha:disabled { opacity: .35; cursor: default; }
.per-flecha:disabled:hover { background: none; color: var(--txt-3); }
.per-flecha svg, .per-boton svg { width: 18px; height: 18px; flex: none; }
.per-boton {
  display: flex; align-items: center; gap: 9px;
  min-width: 0; min-height: 42px;
  padding: 8px 14px;
  font: 600 14px/1.2 var(--sans);
  white-space: nowrap;
}
.per-boton > svg:first-child { color: var(--txt-3); }
.per-txt { overflow: hidden; text-overflow: ellipsis; }
.per button:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; }
.per-pop {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 90;
  display: grid; grid-template-columns: 172px 300px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--sombra-alta);
  overflow: hidden;
  color: var(--txt);
  text-align: left;
}
.per-pop.a-la-izq { left: auto; right: 0; }
.per-pop.arriba { top: auto; bottom: calc(100% + 8px); }
.per-pop[hidden] { display: none; }
.per-atajos { display: flex; flex-direction: column; gap: 2px; padding: 10px; background: var(--surface-2); border-right: 1px solid var(--line); }
.per-atajos button {
  border: 0; background: none; cursor: pointer;
  text-align: left; padding: 8px 10px; border-radius: 10px;
  font: 500 13.5px/1.25 var(--sans); color: var(--txt);
}
.per-atajos button:hover { background: var(--surface-3); }
.per-atajos button[aria-pressed="true"] { background: var(--acc); color: var(--acc-ink); font-weight: 600; }
.per-cal { padding: 12px 14px 10px; }
.per-cal-cab { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.per-cal-cab b { font: 700 14px/1 var(--display); }
.per-cal-cab button {
  border: 0; background: none; cursor: pointer;
  width: 32px; height: 32px; border-radius: 9px;
  display: grid; place-items: center; color: var(--txt-3);
}
.per-cal-cab button:hover { background: var(--surface-2); color: var(--txt); }
.per-cal-cab svg { width: 18px; height: 18px; }
.per-grilla { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: 2px; }
.per-dsem { font: 600 10.5px/1 var(--sans); letter-spacing: .06em; color: var(--txt-3); text-align: center; padding: 6px 0; }
.per-dia {
  border: 0; background: none; cursor: pointer;
  padding: 0; min-width: 0; height: 36px;
  font: 500 13px/1 var(--sans); font-variant-numeric: tabular-nums; color: var(--txt);
}
.per-dia span { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; }
.per-dia:hover span { background: var(--surface-2); }
.per-dia:disabled { opacity: .3; cursor: default; }
.per-dia:disabled:hover span { background: none; }
.per-dia.otro-mes { color: var(--txt-3); opacity: .65; }
.per-dia.en-rango { background: var(--surface-3); }
.per-dia.inicio { background: linear-gradient(90deg, transparent 50%, var(--surface-3) 50%); }
.per-dia.fin { background: linear-gradient(90deg, var(--surface-3) 50%, transparent 50%); }
.per-dia.inicio.fin { background: none; }
.per-dia.inicio span, .per-dia.fin span { background: var(--acc); color: var(--acc-ink); font-weight: 700; }
.per-dia.hoy span { box-shadow: inset 0 0 0 1.5px var(--oro-liso); }
.per-pie {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}
.per-pie small { color: var(--txt-3); font-size: 12.5px; }
.per-botones { display: flex; gap: 8px; margin-left: auto; }
.per-btn {
  border: 1px solid var(--line); background: var(--surface); color: var(--txt); cursor: pointer;
  border-radius: 11px; padding: 8px 16px;
  font: 600 13px/1 var(--sans);
}
.per-btn.oscuro { background: var(--acc); border-color: var(--acc); color: var(--acc-ink); }
.per-btn:disabled { opacity: .45; cursor: default; }
/* En el celular se abre como una hoja abajo, arriba de la barra de secciones. */
@media (max-width: 640px) {
  .per-pop {
    position: fixed; left: 12px; right: 12px; top: auto;
    bottom: calc(var(--nav) + 12px + env(safe-area-inset-bottom));
    grid-template-columns: 1fr;
    max-height: calc(100dvh - 120px); overflow-y: auto;
  }
  .per-pop.a-la-izq { right: 12px; }
  .per-atajos { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--line); }
}
@media (prefers-reduced-motion: reduce) {
  .rail, body.hay-rail, .rail-marca-txt { transition: none; }
}
