/* Plataforma de un solo diseño "liquid glass" oscuro, a proposito --
   NUNCA responde al modo claro/oscuro del sistema (antes si, por
   variables sobrantes de la plantilla base de Vite que nadie usaba:
   causaban que cualquier pantalla sin fondo propio, ej. .wizard-layout,
   se viera blanca en una PC con Windows en modo claro -- bug real
   reportado por Betza, invisible en pruebas automatizadas porque esas
   corren en modo oscuro por default). */
:root {
  font: 18px/145% var(--fuente-cuerpo);
  letter-spacing: 0.18px;
  color-scheme: dark;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  @media (max-width: 1024px) {
    font-size: 16px;
  }
}

body {
  margin: 0;
  /* Fondo oscuro fijo, SIN depender de si el sistema/navegador esta en
     modo claro u oscuro -- esta plataforma es un solo diseño "liquid
     glass" oscuro a proposito, nunca claro. Antes no tenia background
     propio: pantallas que no pintan su propio fondo (ej. .wizard-layout)
     caian al --bg claro (#fff) por default de la plantilla de Vite, y
     solo se veian oscuras si el sistema del usuario estaba en modo
     oscuro -- por eso el bug no aparecia en pruebas automatizadas
     (corren en oscuro) pero si en una PC en modo claro. */
  /* Oscurecido 2026-08-26 (Gerardo: "no se ve nada, hazlo mas oscuro" —
     con los grises originales el patron competia con el contenido de
     encima). Mismos tonos, mucho mas cerca de --page-bg (#080808):
     se nota como textura sutil, no como fondo ruidoso. */
  --patron-s: 200px;
  --patron-c1: #0a0a0a;
  --patron-c2: #161616;
  --patron-c3: #101010;
  /* Patron de triangulos/hexagonos isometricos, pedido explicito de
     Gerardo 2026-08-26 (referencia: componente React con
     styled-components) -- traducido a CSS plano con variables, mismo
     patron que ya usa el resto del proyecto (sin agregar la dependencia
     styled-components solo para esto). Va en <body> para que se vea
     detras de TODAS las pantallas; cada "shell" (admin-shell,
     portal-shell, wizard-layout, etc.) ya no pinta su propio fondo
     solido encima -- solo su acento naranja semitransparente, dejando
     ver este patron. background-attachment:fixed para que no se corte
     ni se repita raro en pantallas con scroll (ej. tablas largas).
     2026-08-27: se probo un reemplazo por reticula tecnica en el
     rediseño "orden de trabajo" -- Gerardo pidio regresar este patron
     de triangulos, se queda tal cual estaba. */
  background:
    repeating-conic-gradient(
        from 30deg,
        #0000 90deg 120deg,
        var(--patron-c3) 0deg 180deg
      )
      calc(0.5 * var(--patron-s)) calc(0.5 * var(--patron-s) * 0.577),
    repeating-conic-gradient(
      from 30deg,
      var(--patron-c1) 0deg 60deg,
      var(--patron-c2) 0deg 120deg,
      var(--patron-c3) 0deg 180deg
    );
  background-size: var(--patron-s) calc(var(--patron-s) * 0.577);
  background-attachment: fixed;
  color: var(--texto, #fff);
}

/* Sin limite de ancho: la interfaz abarca todo el navegador en
   cualquier dispositivo/resolucion. Cada pantalla decide su propio
   ancho maximo de lectura donde hace falta (ej. .portal-shell), esto
   solo es el contenedor raiz. */
#root {
  width: 100%;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

/* h1/h2 NO llevan tamaño/color global aqui a proposito: cada pantalla
   ya define su propio tamaño segun el contexto (.mr-panel h2,
   .paso-titulo, .conf-card h2, .portal-hero h1, etc.) -- el h1 gigante
   por default de la plantilla de Vite (56px) fue la causa de varios
   titulos encimados con su subtitulo, ya corregido caso por caso. Se
   quito de raiz para que no se repita en una pantalla nueva. */
p {
  margin: 0;
}

/* Destello naranja que sigue al cursor por toda la plataforma (pedido
   de Betza, 2026-08-31). El halo se retrasa un poco respecto al mouse
   gracias a la transition en transform, en vez de moverse pegado 1:1
   -- eso es lo que lo hace sentir "dinamico". Se posiciona con
   translate3d (actualizado desde JS via ref) y se centra con el
   margin negativo. Puramente decorativo. */
.cursor-destello {
  position: fixed;
  top: 0;
  left: 0;
  width: 340px;
  height: 340px;
  margin-left: -170px;
  margin-top: -170px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 9999;
  background: radial-gradient(circle, rgba(160, 120, 64, 0.16) 0%, rgba(160, 120, 64, 0.06) 40%, transparent 70%);
  opacity: 0;
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
  will-change: transform;
}
.cursor-destello.activo {
  opacity: 1;
}
@media (max-width: 800px), (hover: none) {
  /* En pantallas tactiles no hay cursor que seguir. */
  .cursor-destello {
    display: none;
  }
}
/* Plan react_glass (docs/plan_react_glass/), Fase 3.
   Tokens de marca migrados de app/static/styles.css (NO son colores
   nuevos, son los mismos de siempre) + variables nuevas para el
   sistema "liquid glass" (vidrio esmerilado con blur). Se importa UNA
   vez (en main.jsx) y todos los componentes lo reusan — nada de
   valores repetidos componente por componente. */

/* Reset global de box-sizing (causa raiz de varios "se sale de la
   tarjeta"/overflow horizontal reportados: sin esto, el padding y el
   borde de un elemento con width:100% se SUMAN al ancho en vez de
   contarse adentro — ej. .campo-vidrio de los formularios). Se pone
   aqui porque tokens.css se importa una sola vez, global, antes que
   cualquier otro estilo. */
*, *::before, *::after {
  box-sizing: border-box;
}

:root {
  /* Colores de marca (pedido de Betza, 2026-09-11: paleta "negro
     principal / oro acento / blanco texto" -- reemplaza el naranja GO
     oficial (#FB670B) que se habia decidido en Fase 0 sobre DESIGN_SYSTEM.md,
     por decision explicita de negocio de Betza, avisada y confirmada.
     --gold-strong y --gold-hot son variantes mas oscura/mas clara del
     mismo tono (antes eran variantes del naranja), para que gradientes
     y estados de hover seguian viendose bien sin perder contraste. */
  --gold: #A07840;
  --gold-strong: #8C6836;
  /* Mas claro que --gold, usado en el degradado de brillo del efecto
     "liquid glass" de los botones (ver .boton-primario en componentes.css). */
  --gold-hot: #B08A52;
  --page-bg: #080808;
  /* Semanas de alta demanda por exposiciones (pedido de Betza, 2026-10-05).
     Naranja Web de la paleta GO (DESIGN_SYSTEM.md), distinto del dorado de
     acento para que se distinga de un dia seleccionado. */
  --expo: #F97316;
  --error: #E53E3E;
  --amber: #F59E0B;
  --verde-ok: #00A36E;
  --texto: #ffffff;
  --texto-dim: rgba(255, 255, 255, 0.6);
  --texto-dimmer: rgba(255, 255, 255, 0.4);

  /* Tipografia (rediseño 2026-08-27): 3 roles, cargados de verdad via
     Google Fonts en index.html. Antes 'Oswald' se usaba en metricas.css
     sin cargarlo en ningun lado — caia siempre al fallback de sistema.
     --fuente-titulo: Archivo Narrow, para titulos/eyebrows/encabezados.
     --fuente-cuerpo: Archivo (misma familia, ancho normal), para todo
     el texto de UI — reemplaza el system-ui de index.css.
     --fuente-dato: Courier Prime, SOLO para folios/fechas/cifras de
     dato (concepto "orden de trabajo" — ver .ticket-folio en
     componentes.css). No usar para texto normal. */
  --fuente-titulo: 'Archivo Narrow', 'Segoe UI', sans-serif;
  --fuente-cuerpo: 'Archivo', 'Segoe UI', Roboto, sans-serif;
  --fuente-dato: 'Courier Prime', 'Consolas', monospace;

  /* Liquid glass: vidrio esmerilado sobre el fondo negro de marca.
     Blur subido de 20px a 48px (pedido 2026-08-26, referencia de
     Instagram/glassmorphism: el fondo detras del panel se ve borroso
     de verdad, como una foto fuera de foco — no el patron nitido
     encogido). Con el patron de triangulos del body, 20px no alcanzaba
     a diluir las lineas del patron; 48px las convierte en manchas de
     luz suaves, que es el look que se pidio.
     Tinte calido agregado en el rediseño 2026-08-27 (Gerardo: el
     rediseño anterior "no lo convencio" — el vidrio blanco-neutro es
     el look por default de cualquier glassmorphism generico). Mismo
     blur, mismo mecanismo, el "liquid glass" sigue intacto — solo
     ambar/papel en vez de blanco puro, para que se sienta como
     acrilico esmerilado propio y no como plantilla. */
  --vidrio-fondo: rgba(255, 233, 201, 0.055);
  --vidrio-fondo-fuerte: rgba(255, 233, 201, 0.10);
  --vidrio-fondo-campo: rgba(255, 233, 201, 0.085);
  --vidrio-borde: rgba(255, 230, 196, 0.16);
  --vidrio-blur: 48px;
  --vidrio-sombra: 0 20px 60px rgba(0, 0, 0, 0.45);
  --vidrio-radio: 16px;
  --vidrio-radio-chico: 10px;
  /* Borde brilloso del vidrio (pedido 2026-08-26, misma referencia de
     Instagram/glassmorphism: el canto del panel se ve como un filo de
     luz, no un borde plano). Luz arriba, sombra abajo, filo tenue
     alrededor — se combina con --vidrio-sombra via box-shadow (varias
     capas), sin tocar el blur del fondo. */
  --vidrio-brillo-borde:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06),
    inset 0 -1px 6px rgba(0, 0, 0, 0.2);
}
/* Plan react_glass, Fase 3 — estilos de los componentes base reutilizables.
   Todo centralizado aqui (un solo archivo), no repetido componente por
   componente. Contraste de texto revisado a proposito (ver nota en
   .glass-card): el bug de "texto ilegible sobre fondo claro/vidrio" ya
   paso una vez en la version HTML, aqui se evita desde el diseño. */

/* ---------- Tipografia base (rediseño 2026-08-27) ---------- */
/* Titulos con la fuente condensada en toda la app, un solo lugar --
   antes 'Oswald' se pedia solo en metricas.css y nunca cargaba (ver
   tokens.css). Solo tipografia, NUNCA tamaño (index.css deja el
   tamaño a cada pantalla a proposito, eso no cambia aqui). */
h1, h2, h3 {
  font-family: var(--fuente-titulo);
  font-weight: 700;
  /* Pedido de Betza (2026-10-06): ningun texto se sale de su caja. Los
     titulos suelen traer texto escrito por usuarios (titulo de la
     requisicion, nombres) que puede ser una palabra larguisima o una URL. */
  overflow-wrap: anywhere;
}

/* Envoltorio para cualquier tabla ancha (usuarios, clientes, mis
   requisiciones, etc.): en celular la tabla mantiene su ancho natural
   y se desliza con el dedo, en vez de encoger las columnas hasta
   volverse ilegibles o empujar toda la pagina a scroll horizontal.
   Mismo criterio que ya usaba .rpt-tbl-wrap en metricas.css, aqui
   generalizado para no repetirlo por pantalla (pedido de Betza,
   2026-08-31: que la plataforma se vea bien en pc y celular). */
.tabla-scroll {
  overflow-x: auto;
}

/* ---------- GlassCard ---------- */
.glass-card {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  box-shadow: var(--vidrio-sombra), var(--vidrio-brillo-borde);
  border-radius: var(--vidrio-radio);
  padding: 24px;
  color: var(--texto);
}

/* ---------- Marca (isotipo real + "GRUPO ORTIZ") ---------- */
/* Mismo isotipo que ahora usa el favicon (public/assets/isotipo-go-naranja.png),
   pedido por Gerardo para las pantallas de auth -- antes no habia ninguna
   marca visible antes de "Inicia sesion". */
.marca-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}
.marca-icono { flex-shrink: 0; display: block; height: auto; }
.marca-nombre {
  font-family: var(--fuente-titulo);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: #fff;
}

/* ---------- Boton ---------- */
/* Forma de pildora + sombra convexa, sin el brillo especular blanco
   (::before/::after) que traia antes -- Gerardo pidio quitarlo
   (2026-09-11), se veia mal. */
.boton {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 12px 26px;
  border-radius: 999px;
  cursor: pointer;
  border: 1px solid transparent;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -6px 10px rgba(0, 0, 0, 0.18),
    0 6px 18px rgba(0, 0, 0, 0.35);
  transition: background 0.15s, border-color 0.15s, opacity 0.15s, transform 0.15s;
}
.boton:active:not(:disabled) {
  transform: translateY(1px);
}
.boton:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.boton-primario {
  background: linear-gradient(180deg, var(--gold-hot) 0%, var(--gold-strong) 100%);
  color: #fff;
}
.boton-primario:hover:not(:disabled) {
  background: linear-gradient(180deg, var(--gold-hot) 0%, var(--gold) 100%);
}
.boton-secundario {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border-color: var(--vidrio-borde);
  color: #fff;
}
.boton-secundario:hover:not(:disabled) {
  background: var(--vidrio-fondo-fuerte);
}

/* ---------- Boton variante "brillo" ---------- */
/* Pedido explicito de Gerardo 2026-08-26, snippet de uiverse.io
   ("shadow__btn"): solido + resplandor que crece al pasar el mouse, SIN
   el vidrio convexo del resto de los botones -- se cancela el brillo
   especular (::before/::after) y la forma de pildora de .boton base
   para no mezclar dos estilos encima. Color cambiado de azul
   (rgb(0,140,255), el original) a naranja de marca -- esta plataforma
   no usa azul en ningun lado (ver DESIGN_SYSTEM.md). Letter-spacing
   bajado de 4px a 2px: el texto real ("Nueva requisición") es mucho
   mas largo que "UIVERSE", con 4px se hubiera visto forzado/dificil
   de leer. */
.boton-brillo {
  background: var(--gold);
  color: #fff;
  border-radius: 7px;
  text-transform: uppercase;
  letter-spacing: 2px;
  box-shadow: 0 0 25px rgba(160, 120, 64, 0.55);
  transition: box-shadow 0.5s;
}
.boton-brillo:hover:not(:disabled) {
  background: var(--gold);
  box-shadow:
    0 0 5px var(--gold),
    0 0 25px var(--gold),
    0 0 50px var(--gold),
    0 0 100px rgba(160, 120, 64, 0.45);
}

/* ---------- BotonFlecha (login "Entrar") ---------- */
/* Pedido explicito de Gerardo 2026-08-26, snippet de uiverse.io
   traducido a CSS plano. Color cambiado de "greenyellow" (el original)
   a naranja de marca -- esta plataforma no usa verde/amarillo neon en
   ningun lado (ver DESIGN_SYSTEM.md). justify-content:center agregado
   (el original asume un boton del tamaño de su contenido; aqui es
   ancho completo del formulario). */
.boton-flecha {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  padding: 12px 24px;
  border: 2px solid transparent;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  background: transparent;
  border-radius: 100px;
  color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold);
  cursor: pointer;
  overflow: hidden;
  transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}
.boton-flecha:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.boton-flecha svg {
  position: absolute;
  width: 18px;
  fill: var(--gold);
  z-index: 9;
  transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.boton-flecha-arr1 {
  right: 16px;
}
.boton-flecha-arr2 {
  left: -25%;
}
/* El circulo crece con transform:scale (no width/height) para que
   siempre tape el boton completo sin importar que tan ancho sea —
   con el tamaño fijo original (220px) se quedaba corto en un boton de
   ancho completo (~370px) y dejaba las orillas sin cubrir, bug real
   que reporto Gerardo 2026-08-26. */
.boton-flecha-circulo {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  background: var(--gold);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.boton-flecha-texto {
  position: relative;
  z-index: 1;
  transform: translateX(-12px);
  transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.boton-flecha:hover:not(:disabled) {
  box-shadow: 0 0 0 12px transparent;
  color: #212121;
  border-radius: 12px;
}
.boton-flecha:hover:not(:disabled) .boton-flecha-arr1 {
  right: -25%;
}
.boton-flecha:hover:not(:disabled) .boton-flecha-arr2 {
  left: 16px;
}
.boton-flecha:hover:not(:disabled) .boton-flecha-texto {
  transform: translateX(12px);
}
.boton-flecha:hover:not(:disabled) svg {
  fill: #212121;
}
.boton-flecha:active:not(:disabled) {
  scale: 0.95;
  box-shadow: 0 0 0 4px var(--gold);
}
.boton-flecha:hover:not(:disabled) .boton-flecha-circulo {
  /* 25x un circulo de 20px = 500px de diametro: cubre de sobra
     cualquier boton de este formulario (incluso el ancho completo del
     login, ~370px), tape esquina a esquina en cualquier tamaño de
     pantalla razonable. */
  transform: translate(-50%, -50%) scale(25);
}

/* ---------- Input / Select / Textarea ---------- */
/* Fondo de vidrio mas solido que las tarjetas (el usuario necesita ver
   bien donde puede escribir; demasiado transparente aqui confunde). */
.campo-grupo {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}
.campo-etiqueta {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--texto);
}
.campo-vidrio {
  background: var(--vidrio-fondo-campo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  padding: 11px 14px;
  font-size: 15px;
  font-family: inherit;
  color: #fff;
  width: 100%;
  box-shadow: var(--vidrio-brillo-borde);
}
.campo-vidrio::placeholder {
  color: rgba(255, 255, 255, 0.4);
}
.campo-vidrio:focus {
  outline: none;
  border-color: var(--gold);
}

/* Calendario propio de "Fecha de entrega requerida" (SelectorFechaEntrega.jsx,
   pedido de Betza 2026-09-02: limite de 3 requisiciones por dia). Un
   overlay invisible cierra el panel al hacer clic fuera. */
.calendario-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
}
.calendario-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 41;
  width: 280px;
  padding: 14px;
  /* SOLIDO a proposito (pedido de Betza, 2026-10-06): con el vidrio
     translucido de las tarjetas se transparentaban los avisos y campos
     de abajo y el calendario era dificil de leer. Es un menu flotante,
     no una tarjeta: necesita fondo opaco. */
  background: #1c1b19;
  border: 1px solid rgba(255, 230, 196, 0.28);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(0, 0, 0, 0.5);
}
.calendario-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  text-transform: capitalize;
  margin-bottom: 14px;
}
.calendario-cab button {
  background: transparent;
  border: 1px solid var(--vidrio-borde);
  color: #fff;
  border-radius: 6px;
  width: 24px;
  height: 24px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.calendario-cab button:hover {
  border-color: var(--gold);
  color: var(--gold);
}
.calendario-semana {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  color: var(--texto-dimmer);
  font-size: 11px;
  margin-bottom: 4px;
}
.calendario-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.calendario-dia {
  aspect-ratio: 1;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: #fff;
  font-size: 12.5px;
  cursor: pointer;
}
.calendario-dia:hover:not(:disabled) {
  border-color: var(--gold);
}
.calendario-dia.seleccionado {
  background: var(--gold);
  color: #1a0800;
  font-weight: 700;
}
.calendario-dia.lleno {
  color: var(--texto-dimmer);
  background: rgba(255, 255, 255, 0.04);
  text-decoration: line-through;
  cursor: not-allowed;
}
.calendario-nota {
  margin-top: 8px;
  color: var(--texto-dimmer);
  font-size: 11px;
  line-height: 1.4;
}
/* Semanas de alta demanda por exposiciones (pedido de Betza, 2026-10-05).
   Naranja (--expo), distinto del dorado de dia seleccionado. No bloquea:
   solo avisa. */
/* Hoy y dias anteriores: no se pueden elegir (pedido de Betza, 2026-10-06).
   Mas tenue que un dia lleno y SIN tachado, para que no se confundan. */
.calendario-dia.pasado {
  opacity: 0.35;
  cursor: not-allowed;
}
.calendario-dia.pasado.expo {
  background: transparent;
  border-color: transparent;
}
.calendario-cab button:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.calendario-cab button:disabled:hover {
  border-color: var(--vidrio-borde);
  color: #fff;
}
.calendario-dia.expo {
  background: rgba(249, 115, 22, 0.22);
  border-color: rgba(249, 115, 22, 0.55);
}
.calendario-dia.expo.seleccionado {
  background: var(--gold);
  box-shadow: 0 0 0 2px var(--expo);
}
.calendario-nota-expo {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  color: rgba(255, 255, 255, 0.75);
}
.calendario-punto-expo {
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  margin-top: 3px;
  border-radius: 3px;
  background: var(--expo);
}
/* Aviso debajo del campo cuando la fecha elegida cae en semana de expo. */
.aviso-expo {
  margin-top: 10px;
  padding: 12px 14px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(249, 115, 22, 0.1);
  border: 1px solid rgba(249, 115, 22, 0.35);
  color: rgba(255, 255, 255, 0.88);
  font-size: 13px;
  line-height: 1.5;
}
textarea.campo-vidrio {
  min-height: 90px;
  resize: vertical;
  line-height: 1.5;
}
select.campo-vidrio option {
  background: #171717;
  color: #fff;
}
.campo-password-wrap {
  position: relative;
  width: 100%;
}
.campo-password-wrap .campo-vidrio {
  padding-right: 42px;
}
.campo-password-ojo {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--texto-dimmer);
  cursor: pointer;
}
.campo-password-ojo:hover {
  color: var(--texto);
}

/* ---------- Badge (estados de requisicion) ---------- */
/* Mismos colores por estado que ya se decidieron para el tablero kanban
   (app/templates/admin_requisiciones.html) — no se inventan colores
   nuevos, se reusa esa decision para que el color de un estado
   signifique lo mismo en toda la plataforma. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid;
  white-space: nowrap;
}

/* ---------- Modal ---------- */
.modal-fondo {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}
.modal-panel {
  max-width: 480px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
}

/* ---------- Icono ---------- */
.icono {
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}

/* ---------- Layout compartido de pantallas de autenticacion (Fase 4) ---------- */
.pantalla-centrada {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* Sin acento naranja propio (quitado 2026-08-26, pedido de Gerardo):
     al estar fijo arriba del contenedor, con scroll se veia como que
     "se oscurece al bajar y se pone naranja al subir" — se deja solo
     el patron oscuro parejo del body en todas las pantallas. */
}
.pantalla-centrada h1 {
  color: var(--gold);
  /* Mismo motivo que .intro-content h1 (wizard.css): sin font-size
     propio hereda el tamaño gigante por default (sobrante de la
     plantilla base de Vite, ver index.css) — se ve bien solo por
     casualidad en titulos cortos de una linea. */
  font-size: 26px;
  line-height: 1.3;
  margin: 0 0 8px;
}
.pantalla-centrada a {
  color: var(--gold);
}
/* Antes cada pantalla de auth repetia
   style={{ maxWidth: 400|420|440, width: '100%' }} sobre su GlassCard
   con un numero ligeramente distinto cada vez -- un solo ancho, una
   clase (Login, Registro, Recuperar/Restablecer, ConfiguracionInicial,
   NoEncontrado). */
.auth-card {
  width: 100%;
  max-width: 420px;
}

/* ---------- Mensajes de error/exito ---------- */
/* Mismo criterio que ya se aprendio en la version HTML: nunca un color
   de texto que dependa de "adivinar" el fondo — aqui el fondo siempre es
   oscuro (.pantalla-centrada/.glass-card), asi que un texto de color
   solido (no un fondo claro con texto oscuro) siempre se lee bien. */
.mensaje-error {
  color: var(--error);
  font-size: 14px;
  line-height: 1.5;
}
.mensaje-exito {
  color: var(--verde-ok);
  font-size: 14px;
  line-height: 1.5;
}

/* ---------- Sistema "orden de trabajo" (rediseño 2026-08-27) ---------- */
/* Firma visual del rediseño: cada requisicion ES una orden de trabajo
   que una marca pide y que viaja por produccion hasta entregarse. 3
   piezas chicas, reusadas en TODA la app (kanban, metricas, detalle,
   wizard) en vez de un adorno distinto por pantalla. */

/* Estampa de prioridad: reemplaza toda pastilla plana de prioridad
   (antes .rpt-tag-alta/media/baja, .badge-prioridad) por un sello de
   tinta rotado, como el que lleva un formulario real. Uso:
   <span class="estampa-prioridad alta|media|baja">Alta</span> */
.estampa-prioridad {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  font-family: var(--fuente-titulo);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 12px 4px;
  border-radius: 3px;
  /* Siempre derecho, en todas las pantallas (pedido de Betza, 2026-10-06).
     Antes iba inclinado -4deg como sello de tinta. */
  transform: none;
  border: 1.5px solid currentColor;
  box-shadow: 0 0 0 1px currentColor inset;
  /* Unica animacion nueva del rediseño: "golpe de sello" al aparecer. */
  animation: sello-golpe 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* Colores alineados al esquema semaforo que YA usaba el selector de
   prioridad del wizard (badge-prioridad: rojo/ambar/verde) -- antes
   metricas.css/kanban.css usaban un esquema distinto e inconsistente
   para lo mismo (Alta en blanco neutro, Baja en gris, Media en oro —
   la mas urgente terminaba con MENOS peso visual que la media). Un
   solo esquema de color para "prioridad" en toda la app. */
.estampa-prioridad.alta { color: var(--error); background: rgba(229, 62, 62, 0.10); }
.estampa-prioridad.media { color: var(--amber); background: rgba(245, 158, 11, 0.10); }
.estampa-prioridad.baja { color: var(--verde-ok); background: rgba(0, 163, 110, 0.10); }

/* Variante sin el marco/rectangulo del sello (pedido de Betza,
   2026-08-31): usada solo en el selector de prioridad del wizard, deja
   el resto de usos de .estampa-prioridad (admin, metricas, confirmacion)
   con su sello completo tal como lo diseño Gerardo. */
.estampa-prioridad.sin-marco {
  border: none;
  box-shadow: none;
  background: transparent;
  padding: 0 2px;
  /* Sin la inclinacion de "sello de tinta": aqui va suelta junto a un
     radio y un texto en la misma linea, la rotacion se veia chueca. */
  transform: none;
  animation: none;
  display: inline-flex;
  align-items: center;
}

/* Version recta (sin la inclinacion de "sello de tinta"), pero
   conservando el marco -- pedido de Betza (2026-08-31) para la estampa
   de prioridad de la linea de tiempo en Confirmacion.jsx, se veia
   ladeada. El resto de usos (admin, metricas) conservan la inclinacion
   completa tal como la diseño Gerardo. */
.estampa-prioridad.recto {
  transform: none;
}
@keyframes sello-golpe {
  0% { transform: scale(0.85); opacity: 0; }
  60% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .estampa-prioridad { animation: none; }
}

/* Folio de ticket: codigo corto tipo "GO-3F8329" (marca + prefijo del
   id, generado en el cliente -- ver util formatearFolio, sin cambios
   de backend). Junto al titulo en kanban/detalle/tablas. */
.ticket-folio {
  font-family: var(--fuente-dato);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--texto-dimmer);
  white-space: nowrap;
}

/* Perforacion de ticket: separa el "talon" (folio+prioridad+fecha) del
   cuerpo de una tarjeta, como el borde troquelado de un ticket real. */
.ticket-perforado {
  height: 1px;
  margin: 10px 0;
  background-image: radial-gradient(circle, var(--vidrio-borde) 1.4px, transparent 1.6px);
  background-size: 9px 1px;
  background-repeat: repeat-x;
  background-position: left center;
}

/* ---------- Utilidades ---------- */
/* Antes cada pantalla repetia style={{ textDecoration: 'none' }} al
   envolver un <Boton> en un <Link>/<a> (Clientes.jsx,
   RequisicionDetalle.jsx, RequisicionNueva.jsx...) -- una clase. */
.link-plano {
  text-decoration: none;
  display: inline-block;
}

/* ---------- Cargando (estado de carga compartido) ---------- */
.cargando {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  width: 100%;
  padding: 40px;
}
.cargando-barra {
  position: relative;
  overflow: hidden;
  width: 120px;
  height: 3px;
  border-radius: 999px;
  background: var(--vidrio-borde);
}
.cargando-barra::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  animation: cargando-barrido 1.1s ease-in-out infinite;
}
@keyframes cargando-barrido {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(340%); }
}
@media (prefers-reduced-motion: reduce) {
  .cargando-barra::after { animation: none; opacity: 0.6; }
}

/* Archivo adjunto con boton de quitar (ArchivoAdjunto.jsx, 2026-10-06). */
.archivo-adjunto-elegir {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  color: var(--texto-dim);
  cursor: pointer;
}
.archivo-adjunto-elegir:hover {
  border-color: var(--gold);
  color: #fff;
}
.archivo-adjunto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 8px 8px 12px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
  color: #fff;
  font-size: 13px;
}
.archivo-adjunto svg {
  flex-shrink: 0;
  color: var(--gold);
}
.archivo-adjunto-nombre {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.archivo-adjunto-peso {
  flex-shrink: 0;
  color: var(--texto-dimmer);
  font-size: 11.5px;
}
.archivo-adjunto.excede {
  border-color: var(--error);
}
.archivo-adjunto.excede .archivo-adjunto-peso {
  color: var(--error);
}
.archivo-adjunto button {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--vidrio-borde);
  background: transparent;
  color: rgba(255, 255, 255, 0.75);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.archivo-adjunto button:hover {
  color: #fff;
  border-color: var(--error);
  background: rgba(229, 62, 62, 0.15);
}
/* Plan react_glass, Fase 5 — estilos propios del wizard de requisicion
   (intro, pasos, tabs, opciones tipo tarjeta, sidebar/stepper, dropzone,
   pantalla de confirmacion con confeti). Usa los mismos tokens/clases
   base de la Fase 3 (glass-card, campo-vidrio, boton), esto es lo que
   falta encima. */

/* ---------- Intro (video + consentimiento) ---------- */
.intro-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* Sin acento naranja propio (quitado 2026-08-26): con scroll se veia
     como que oscurecia al bajar/se ponia naranja al subir. */
}
.intro-content {
  max-width: 700px;
  width: 100%;
}
.intro-content h1 {
  color: #fff;
  /* Sin font-size propio, heredaba el tamaño gigante por default del
     h1 (sobrante de la plantilla base de Vite, ver index.css) — con un
     titulo largo como este eso lo hacia envolver en 2 lineas casi
     pegadas al subtitulo de abajo. */
  font-size: 26px;
  line-height: 1.3;
  margin: 0 0 10px;
}
.intro-content .subt {
  color: var(--gold);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  margin-bottom: 14px;
}
.intro-content .brief-copy {
  color: rgba(255, 255, 255, 0.8);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 16px;
  text-align: justify;
}
.intro-content .brief-copy strong {
  color: var(--gold);
}
.intro-content .video-wrap img,
.intro-content .video-wrap video {
  max-width: 100%;
  max-height: 33vh;
  display: block;
  margin: 0 auto;
  border-radius: 10px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
}
/* El video necesita mas alto que la portada estatica para poder verse
   (pedido de Betza, 2026-10-05: ya es el video final, no una imagen). */
.intro-content .video-wrap video {
  max-height: 45vh;
  background: #000;
}
.intro-content .hint {
  color: rgba(255, 255, 255, 0.4);
  font-size: 12.5px;
  text-align: center;
  margin-top: 6px;
}
.intro-content .consent-box {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
  padding: 14px 16px;
}
.intro-content .consent-box label {
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
}

.req::after {
  content: ' *';
  color: var(--error);
}

/* ---------- Layout del wizard (sidebar + panel) ---------- */
.wizard-layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 24px;
  /* Sin max-width: la interfaz abarca todo el ancho disponible (mismo
     criterio que el panel de admin), tambien en monitores anchos. */
  padding: 32px 24px;
  min-height: 100vh;
  align-items: start;
}
@media (max-width: 800px) {
  .wizard-layout {
    grid-template-columns: 1fr;
  }
}

.sidebar {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.tiempo-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: 999px;
  padding: 6px 12px;
  width: fit-content;
}
.sidebar h1 {
  color: #fff;
  font-size: 20px;
  margin: 0;
}
.paso-contador {
  color: var(--texto-dim);
  font-size: 13px;
}
.progreso-barra {
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
.progreso-relleno {
  height: 100%;
  background: linear-gradient(90deg, var(--gold-strong), var(--gold));
  transition: width 0.25s ease;
}

.stepper-v {
  display: flex;
  flex-direction: column;
}
.paso-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  padding: 6px 0;
  cursor: default;
}
.paso-nav.clicable {
  cursor: pointer;
}
.circulo-v {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.08);
  border: 1.5px solid var(--vidrio-borde);
  color: var(--texto-dimmer);
}
.paso-nav.activo .circulo-v {
  background: var(--gold);
  border-color: var(--gold);
  color: #1a0800;
}
.paso-nav.completo .circulo-v {
  background: var(--verde-ok);
  border-color: var(--verde-ok);
  color: #fff;
}
.etiqueta-v {
  font-size: 13px;
  color: var(--texto-dimmer);
}
.paso-nav.activo .etiqueta-v {
  color: #fff;
  font-weight: 600;
}
.paso-nav.completo .etiqueta-v {
  color: rgba(255, 255, 255, 0.7);
}

.autosave-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--verde-ok);
}
.autosave-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--verde-ok);
}

/* ---------- Contenido del paso ---------- */
.paso-titulo {
  color: #fff;
  font-size: 20px;
  margin: 0 0 4px;
}
.paso-desc {
  color: var(--texto-dim);
  font-size: 13.5px;
  margin-bottom: 20px;
  line-height: 1.5;
}

.tabs-revisar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.tab-btn-revisar {
  background: transparent;
  border: 1px solid var(--vidrio-borde);
  color: var(--texto-dim);
  font-size: 13px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
}
.tab-btn-revisar.activo {
  background: var(--gold);
  border-color: var(--gold);
  color: #1a0800;
}
.tabs-revisar-flecha {
  color: var(--texto-dimmer);
}

.campo-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}
@media (max-width: 600px) {
  .campo-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Opciones tipo tarjeta (radio/checkbox) ---------- */
.opciones-filas {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}
.opciones-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 8px;
}
@media (max-width: 600px) {
  .opciones-grid-2 {
    grid-template-columns: 1fr;
  }
}
.opcion-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.opcion-fila:has(input:checked) {
  background: rgba(160, 120, 64, 0.12);
  border-color: var(--gold);
}

/* Selector de prioridad (pedido de Betza, 2026-08-31): al elegir una
   opcion, el resaltado toma el color de esa prioridad en vez del
   dorado por default -- Alta rojo, Media amarillo, Baja verde. */
.opcion-fila-alta:has(input:checked) {
  background: rgba(229, 62, 62, 0.12);
  border-color: var(--error);
}
.opcion-fila-media:has(input:checked) {
  background: rgba(245, 158, 11, 0.12);
  border-color: var(--amber);
}
.opcion-fila-baja:has(input:checked) {
  background: rgba(0, 163, 110, 0.12);
  border-color: var(--verde-ok);
}
.opcion-fila input {
  accent-color: var(--gold);
  flex-shrink: 0;
}
.opcion-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.opcion-cuerpo b {
  color: #fff;
  font-size: 14px;
}
.opcion-cuerpo span {
  color: var(--texto-dimmer);
  font-size: 12px;
}

/* Icono a un costado de cada tarjeta de "Tipo de contenido/material"
   (pedido de Betza, 2026-08-31, referencia de estilo enviada por ella:
   cuadro con brillo alrededor del icono elegido). Colores de marca GO
   (dorado/naranja), no el rojo de la referencia. */
.opcion-icono {
  margin-left: auto;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
  color: var(--texto-dimmer);
  transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.opcion-fila:has(input:checked) .opcion-icono {
  background: rgba(160, 120, 64, 0.18);
  border-color: var(--gold);
  color: var(--gold);
  box-shadow: 0 0 12px rgba(160, 120, 64, 0.55);
}
.opcion-chica {
  font-size: 13.5px;
  color: #fff;
  padding: 10px 12px;
}
.opcion-texto {
  color: var(--texto-dim);
  font-size: 13px;
}

.otro-input {
  margin-top: -8px;
  margin-bottom: 16px;
}

.hint {
  color: var(--texto-dimmer);
  font-size: 12.5px;
  line-height: 1.5;
}

/* ---------- Dropzone de referencias ---------- */
.dropzone {
  border: 1.5px dashed var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  padding: 16px;
  text-align: center;
  color: var(--texto-dim);
  font-size: 13.5px;
  margin-bottom: 6px;
  transition: border-color 0.15s, background 0.15s;
}
.dropzone.sobre {
  border-color: var(--gold);
  background: rgba(160, 120, 64, 0.08);
}
.dropzone a {
  color: var(--gold);
}
.dropzone-valor {
  margin-top: 6px;
  color: #fff;
  font-size: 12.5px;
  word-break: break-all;
}
/* Lista de referencias agregadas (pedido de Betza, 2026-10-06): varias, y
   cada una se puede quitar con la x. */
.referencias-lista {
  list-style: none;
  margin: 10px 0 6px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.referencias-lista li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 8px 8px 12px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
  color: #fff;
  font-size: 13px;
}
.referencias-lista li svg {
  flex-shrink: 0;
  color: var(--gold);
}
.referencias-texto {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.referencias-lista button {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--vidrio-borde);
  background: transparent;
  color: rgba(255, 255, 255, 0.75);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.referencias-lista button:hover {
  color: #fff;
  border-color: var(--error);
  background: rgba(229, 62, 62, 0.15);
}

/* ---------- Resumen (paso Revisar) ---------- */
.resumen-seccion {
  margin-bottom: 20px;
}
.resumen-seccion-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.seccion-eyebrow {
  color: var(--gold);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.editar-link {
  color: var(--texto-dim);
  font-size: 12.5px;
  text-decoration: none;
  cursor: pointer;
}
.editar-link:hover {
  color: var(--gold);
}
.resumen-item {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 13.5px;
}
.resumen-item .k {
  color: var(--texto-dimmer);
  flex: 0 0 40%;
  min-width: 0;
}
/* min-width:0 + overflow-wrap (pedido de Betza, 2026-10-06): un correo o
   un nombre largo sin espacios (ej. betzafuentesramos@gmail.com) no se
   puede partir solo, y como el valor es un hijo flex con min-width:auto,
   empujaba el texto fuera de la tarjeta. Asi se parte donde haga falta. */
.resumen-item .v {
  color: #fff;
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
}
.resumen-item.apilado {
  flex-direction: column;
  gap: 4px;
}
.resumen-item.apilado .v {
  text-align: left;
  overflow-wrap: anywhere;
  /* Respeta los renglones (ej. una referencia por renglon). */
  white-space: pre-line;
}

/* Version compacta del paso Revisar (pedido de Betza, 2026-08-31): que
   el resumen completo quepa en pantalla sin tener que hacer scroll. */
.resumen-compacto .paso-titulo {
  font-size: 18px;
  margin-bottom: 2px;
}
.resumen-compacto .paso-desc {
  margin-bottom: 10px;
  font-size: 12.5px;
}
.resumen-compacto .resumen-seccion {
  margin-bottom: 8px;
}
.resumen-compacto .resumen-seccion-cab {
  margin-bottom: 2px;
}
.resumen-compacto .resumen-item {
  padding: 4px 0;
  font-size: 12.5px;
}
.resumen-compacto .resumen-item.apilado {
  gap: 2px;
}

/* ---------- Agendar (Meet embebido) ---------- */
/* Nota de merge (2026-08-31): Betza probo un enlace de sala fija
   (.meet-sala) en su rama mientras se decidia el enfoque -- Gerardo
   decidio seguir con Calendar API real (freebusy + evento dinamico,
   ver BACKLOG.md #6), delegado a Betza. Se restaura el iframe de
   calendario aqui como placeholder hasta que ese endpoint exista. */
.meet-caja-clara {
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
  height: 420px;
}
.meet-embed iframe {
  width: 133.34%;
  height: 560px;
  border: 0;
  display: block;
  transform: scale(0.75);
  transform-origin: top left;
}
.meet-embed .fallback {
  margin-top: 10px;
  font-size: 13px;
  color: var(--texto-dim);
}
.meet-embed .fallback a {
  color: var(--gold);
  font-weight: 700;
  text-decoration: none;
}

.err-box {
  background: rgba(229, 62, 62, 0.12);
  border-left: 4px solid var(--error);
  color: #fff;
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 13.5px;
  margin-top: 16px;
  margin-bottom: 16px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.nav-botones {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 28px;
}

/* ---------- Pantalla de confirmacion (confeti + timeline) ---------- */
.exito-shell {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  padding: 40px 16px;
  /* Sin acento naranja propio (quitado 2026-08-26): con scroll se veia
     como que oscurecia al bajar/se ponia naranja al subir. */
}
.conf-wrap {
  /* Sin max-width: abarca todo el ancho disponible (mismo criterio que
     el resto de la plataforma), tambien en monitores anchos. */
  width: 100%;
  position: relative;
}
.conf-confetti {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 340px;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}
.conf-confetti span {
  position: absolute;
  top: -20px;
  width: 6px;
  height: 14px;
  border-radius: 2px;
  opacity: 0;
  animation: conf-fall 1.8s ease-in forwards;
}
@keyframes conf-fall {
  0% { opacity: 0; transform: translateY(0) rotate(0deg); }
  8% { opacity: 1; }
  100% { opacity: 0; transform: translateY(360px) rotate(340deg); }
}
.conf-hero {
  text-align: center;
  padding: 44px 30px 36px;
  position: relative;
  z-index: 1;
}
.conf-check-wrap {
  width: 76px;
  height: 76px;
  margin: 0 auto 20px;
  position: relative;
}
.conf-check-ring {
  width: 76px;
  height: 76px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--gold), #ff8a4c);
  display: flex;
  align-items: center;
  justify-content: center;
}
.conf-check-ring svg {
  width: 32px;
  height: 32px;
  stroke: #1a0800;
  stroke-width: 4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.conf-pulse-ring {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 2px solid var(--gold);
  opacity: 0;
  animation: conf-pulse-out 1.6s ease-out 0.4s infinite;
}
@keyframes conf-pulse-out {
  0% { transform: scale(0.85); opacity: 0.6; }
  100% { transform: scale(1.6); opacity: 0; }
}
.conf-eyebrow {
  color: var(--gold);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  margin-bottom: 8px;
}
.conf-hero h1 {
  color: #fff;
  font-size: 28px;
  margin: 0 0 8px;
}
.conf-hero h1 span {
  color: var(--gold);
}
.conf-subtitle {
  color: var(--texto-dim);
  font-size: 14px;
  line-height: 1.5;
  max-width: 440px;
  margin: 0 auto 16px;
}
.conf-id-chip {
  max-width: 100%;
  overflow-wrap: anywhere;
  display: inline-block;
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.8);
}
.conf-id-chip b {
  color: var(--gold);
}

/* Aviso de carga de trabajo (pedido de Betza, 2026-08-31): se muestra
   solo cuando el backend detecta 3+ requisiciones activas con fecha de
   entrega cercana a la que se acaba de crear. */
.conf-aviso-carga {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(160, 120, 64, 0.1);
  border: 1px solid rgba(160, 120, 64, 0.3);
  color: rgba(255, 255, 255, 0.85);
  font-size: 13px;
  line-height: 1.5;
  text-align: left;
}
.conf-aviso-carga svg {
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--gold);
}

.conf-card {
  margin-top: 22px;
  padding: 32px;
}
.conf-card h2 {
  color: #fff;
  font-size: 18px;
  margin: 0 0 4px;
}
.conf-timeline {
  margin: 24px 0 8px;
}
.conf-tl-row {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 0 0 24px;
  position: relative;
  opacity: 0;
  animation: conf-tl-drop 0.4s ease-out forwards;
}
.conf-tl-row:last-child {
  padding-bottom: 0;
}
.conf-tl-row::before {
  content: '';
  position: absolute;
  left: 13px;
  top: 28px;
  bottom: 0;
  width: 2px;
  background: var(--vidrio-borde);
  transform: scaleY(0);
  transform-origin: top;
  animation: conf-tl-linea 0.3s ease-out forwards;
}
.conf-tl-row:last-child::before {
  display: none;
}
.conf-tl-row:nth-child(1) { animation-delay: 0.1s; }
.conf-tl-row:nth-child(1)::before { animation-delay: 0.45s; }
.conf-tl-row:nth-child(2) { animation-delay: 0.45s; }
.conf-tl-row:nth-child(2)::before { animation-delay: 0.8s; }
.conf-tl-row:nth-child(3) { animation-delay: 0.8s; }
.conf-tl-row:nth-child(3)::before { animation-delay: 1.15s; }
.conf-tl-row:nth-child(4) { animation-delay: 1.15s; }
@keyframes conf-tl-drop {
  from { opacity: 0; transform: translateY(-14px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes conf-tl-linea {
  to { transform: scaleY(1); }
}
.conf-tl-dot {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
  background: rgba(255, 255, 255, 0.06);
  border: 1.5px solid var(--vidrio-borde);
  color: var(--texto-dimmer);
}
.conf-tl-row.hecho .conf-tl-dot {
  background: var(--gold);
  border-color: var(--gold);
  color: #1a0800;
}
.conf-tl-dot svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  stroke-width: 3;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.conf-tl-body b {
  display: block;
  font-size: 14px;
  margin-bottom: 2px;
  color: #fff;
}
.conf-tl-row.pendiente .conf-tl-body b {
  color: rgba(255, 255, 255, 0.6);
}
.conf-tl-body {
  min-width: 0;
  overflow-wrap: anywhere;
}
.conf-tl-body span {
  font-size: 12px;
  color: var(--texto-dimmer);
}

.conf-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 8px;
}
@media (max-width: 600px) {
  .conf-info-grid {
    grid-template-columns: 1fr;
  }
}
.conf-info-box {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  padding: 14px 16px;
}
.conf-info-box .k {
  font-size: 11px;
  color: var(--texto-dimmer);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.conf-info-box .v {
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  /* Pedido de Betza (2026-10-06): ningun texto se sale de su caja. El
     titulo del material es texto libre del cliente. */
  overflow-wrap: anywhere;
}
.conf-info-grid > * {
  min-width: 0;
}
.conf-info-box .v.naranja {
  color: var(--gold);
}
.conf-actions {
  margin-top: 24px;
  text-align: center;
}
/* Plan react_glass, Fase 6 — portal de cliente ("Mis requisiciones") y
 * pantalla de cambiar mi contraseña. Reusa los tokens/componentes base
 * de la Fase 3 (GlassCard, Badge, Boton), esto es solo el layout propio
 * de estas pantallas. */
.portal-shell {
  min-height: 100vh;
  padding: 32px 24px;
  /* Sin max-width: la interfaz abarca todo el ancho disponible (mismo
     criterio que el panel de admin), tambien en monitores anchos.
     Sin acento naranja propio (quitado 2026-08-26): con scroll se veia
     como que oscurecia al bajar/se ponia naranja al subir. */
}
/* Version sin chrome de pagina (sin min-height/padding/fondo propio):
   usada dentro de PanelCliente.jsx, que ya pone el fondo y el padding a
   nivel de layout (.admin-main). .portal-shell se deja intacta por si
   alguna pantalla la sigue usando standalone. */
.portal-contenido {
  min-width: 0;
}
.portal-hero {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.portal-hero h1 {
  color: #fff;
  margin: 0 0 8px;
  font-size: 22px;
  line-height: 1.3;
}
.portal-sub {
  color: var(--texto-dim);
  font-size: 13.5px;
  line-height: 1.6;
}
.portal-sub a {
  color: var(--gold);
  text-decoration: none;
}
.portal-sub a:hover {
  text-decoration: underline;
}
.portal-panel {
  margin-bottom: 20px;
}
.portal-panel h2 {
  color: #fff;
  font-size: 16px;
  margin: 0 0 12px;
}
.portal-tabla {
  width: 100%;
  border-collapse: collapse;
}
.portal-tabla th {
  text-align: left;
  color: var(--texto-dimmer);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 8px 10px;
  border-bottom: 1px solid var(--vidrio-borde);
}
.portal-tabla td {
  padding: 12px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  color: #fff;
  font-size: 13.5px;
}
.portal-tabla tr:last-child td {
  border-bottom: none;
}
.portal-vacio {
  color: var(--texto-dimmer);
  font-size: 13.5px;
  text-align: center;
  padding: 20px 6px;
}
.portal-vacio-grande {
  text-align: center;
  padding: 30px 20px;
}
.portal-vacio-grande p {
  color: rgba(255, 255, 255, 0.7);
  margin: 12px 0 18px;
}

/* Apartado "Tus proximas citas de Meet" (pedido de Betza, 2026-08-31,
   opcion B: un lugar dedicado en vez de tener que abrir cada
   requisicion para encontrar el enlace de su sesion). */
.citas-lista {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cita-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border-radius: var(--vidrio-radio-chico);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--vidrio-borde);
}
/* min-width:0 + overflow-wrap (pedido de Betza, 2026-10-06: que ningun texto
   se salga de su caja): el titulo de la requisicion y el dia/hora de la
   cita son texto libre y pueden traer palabras larguisimas o URLs. */
.cita-info {
  min-width: 0;
  max-width: 100%;
  flex: 1 1 220px;
}
.cita-titulo {
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 3px;
  overflow-wrap: anywhere;
}
.cita-cuando {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  color: var(--texto-dim);
  font-size: 12.5px;
  overflow-wrap: anywhere;
}
.cita-cuando svg {
  flex-shrink: 0;
  margin-top: 2px;
}

/* Progreso de cada requisicion en el portal del cliente (pedido de Betza,
   2026-10-05): etiqueta + barra de 5 etapas. El estado interno lo cambia
   el admin, ver utilidades/progreso.js. Colores por "tono": neutro =
   recibida, activo = en proceso (dorado de marca), atencion = le toca al
   cliente (aprobar/retroalimentar, ambar para que lo note), ok = aprobada
   o entregada, error = rechazada. */
.portal-etapas {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
  font-size: 12px;
  color: var(--texto-dimmer);
}
.portal-etapas-sep {
  margin: 0 6px;
  opacity: 0.6;
}
.progreso-req {
  --tono: var(--texto-dim);
  min-width: 150px;
}
.progreso-req.tono-activo { --tono: var(--gold); }
.progreso-req.tono-atencion { --tono: var(--amber); }
.progreso-req.tono-ok { --tono: var(--verde-ok); }
.progreso-req.tono-error { --tono: var(--error); }
.progreso-req-etiqueta {
  color: var(--tono);
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 6px;
}
.progreso-req-barra {
  display: flex;
  gap: 3px;
}
.progreso-req-seg {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
}
.progreso-req-seg.lleno {
  background: var(--tono);
}
.progreso-req-seg.actual {
  box-shadow: 0 0 8px var(--tono);
}
.progreso-req-paso {
  margin-top: 5px;
  font-size: 11px;
  color: var(--texto-dimmer);
}
/* Plan react_glass, Fase 7 — layout del panel de administracion
   (sidebar + contenido). Mismo look & feel que el resto de la
   plataforma, con vidrio esmerilado. */
.admin-shell {
  display: flex;
  min-height: 100vh;
  gap: 20px;
  padding: 20px;
  /* Sin acento naranja propio (quitado 2026-08-26): se veia como que
     oscurecia al bajar/se ponia naranja al subir por quedar fijo
     arriba del contenedor con scroll. Solo el patron del body. */
}
/* Sidebar flotante estilo "liquid glass": separada del borde de la
   pantalla, esquinas redondas, sombra propia — ya no pegada de canto a
   canto como una barra fija. */
.admin-sidebar {
  width: 240px;
  flex-shrink: 0;
  padding: 24px 18px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), var(--vidrio-brillo-borde);
  position: sticky;
  top: 20px;
  height: calc(100vh - 40px);
  /* Rediseño 2026-09-05 (referencia figma_sidebar_navigation, SOLO el
     diseño/interaccion de colapsar/expandir — sin framer-motion, la
     misma transicion se logra con CSS plano, sin dependencia nueva). */
  transition: width 0.24s ease, padding 0.24s ease;
}
.admin-sidebar.colapsado {
  width: 84px;
  padding: 24px 12px;
}

/* Encabezado: avatar con iniciales + nombre + rol (antes decia solo
   "GRUPO ORTIZ"). El boton de colapsar queda fuera del flujo (absolute)
   para no romper el layout cuando el sidebar esta angosto — mismo
   truco que la referencia de Figma (su boton tambien vive "afuera" del
   header en modo colapsado). */
.admin-colapsar-btn {
  position: absolute;
  top: 18px;
  right: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--vidrio-fondo-fuerte);
  border: 1px solid var(--vidrio-borde);
  color: var(--texto-dim);
  cursor: pointer;
  z-index: 5;
  transition: right 0.24s ease, color 0.15s, background 0.15s;
}
.admin-colapsar-btn:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}
.admin-sidebar.colapsado .admin-colapsar-btn {
  right: -12px;
  background: var(--vidrio-fondo-fuerte);
  box-shadow: var(--vidrio-sombra), var(--vidrio-brillo-borde);
}
.admin-sidebar-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-right: 20px;
  /* min-width:0 + max-width (pedido de Betza, 2026-10-06: que ningun texto
     se salga): en celular el menu pasa a ser una fila que envuelve y,
     sin esto, el encabezado no podia encogerse por debajo del ancho del
     nombre (nowrap), asi que un nombre largo de admin ensanchaba toda
     la pagina (680px en una pantalla de 390). Con esto el nombre se
     recorta con "..." como ya estaba pensado. */
  min-width: 0;
  max-width: 100%;
}
.admin-sidebar.colapsado .admin-sidebar-header {
  flex-direction: column;
  gap: 10px;
  padding-right: 0;
}
.admin-avatar {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--fuente-titulo);
  font-weight: 700;
  font-size: 14px;
  color: #fff;
  background: linear-gradient(180deg, var(--gold-hot) 0%, var(--gold-strong) 100%);
}
.admin-header-texto {
  min-width: 0;
  flex: 1;
}
.admin-header-eyebrow {
  color: var(--texto-dimmer);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-header-nombre {
  color: #fff;
  font-weight: 700;
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-header-acciones {
  flex-shrink: 0;
}
.admin-sidebar-linea {
  height: 1px;
  background: var(--vidrio-borde);
  opacity: 0.7;
  margin: 0 -4px;
}
.admin-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-nav-label {
  color: var(--texto-dimmer);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0 14px 4px;
}
.admin-nav-link {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 999px;
  color: var(--texto-dim);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
}
.admin-sidebar.colapsado .admin-nav-link {
  justify-content: center;
  padding: 10px;
}
.admin-sidebar.colapsado .admin-nav-link span {
  display: none;
}
.admin-nav-link:hover {
  background: rgba(255, 255, 255, 0.05);
}
.admin-nav-link.activo {
  background: linear-gradient(180deg, rgba(160, 120, 64, 0.28) 0%, rgba(160, 120, 64, 0.14) 100%);
  color: var(--gold);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    inset 0 -4px 8px rgba(0, 0, 0, 0.12);
}
/* Tarjeta de CTA "Nueva requisición", pegada al fondo del sidebar
   (mismo lugar/idea que la tarjeta "Add New Task" de la referencia de
   Figma) — accion real que ya existia (/admin/requisiciones/nueva), no
   una inventada para parecerse al diseño. */
.admin-cta-card {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 14px;
  border-radius: var(--vidrio-radio);
  background: var(--vidrio-fondo-fuerte);
  border: 1px solid var(--vidrio-borde);
  text-decoration: none;
}
.admin-cta-titulo {
  color: #fff;
  font-weight: 700;
  font-size: 14px;
}
.admin-cta-sub {
  color: var(--texto-dim);
  font-size: 11.5px;
  line-height: 1.4;
}
.admin-cta-boton {
  margin-top: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px;
  border-radius: var(--vidrio-radio-chico);
  background: linear-gradient(180deg, var(--gold-hot) 0%, var(--gold-strong) 100%);
  color: #fff;
  font-weight: 700;
  font-size: 12.5px;
}
.admin-cta-colapsado {
  margin-top: auto;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 14px;
  background: linear-gradient(180deg, var(--gold-hot) 0%, var(--gold-strong) 100%);
  box-shadow: 0 4px 14px rgba(160, 120, 64, 0.35);
  text-decoration: none;
}
/* El footer solo empuja abajo por su propia cuenta cuando NO hay una
   tarjeta de CTA justo antes (portal de cliente, sin CTA) -- si ya la
   hay (panel de admin), es la CTA la que empuja, el footer solo la
   sigue pegado (dos margin-top:auto en la misma columna se repartirian
   el espacio y separarian ambos bloques). */
.admin-sidebar-footer {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--vidrio-borde);
  font-size: 12.5px;
}
.admin-cta-card + .admin-sidebar-footer,
.admin-cta-colapsado + .admin-sidebar-footer {
  margin-top: 0;
}
.admin-sidebar-correo {
  color: var(--texto-dimmer);
  font-size: 11.5px;
  margin-bottom: 8px;
  word-break: break-all;
}
.admin-sidebar-footer a {
  display: block;
  color: var(--texto-dim);
  text-decoration: none;
  padding: 3px 0;
  cursor: pointer;
}
.admin-sidebar-footer a:hover {
  color: var(--gold);
}
.admin-sidebar.colapsado .admin-sidebar-footer {
  display: flex;
  justify-content: center;
  padding-top: 0;
  border-top: none;
}
.admin-sidebar.colapsado .admin-sidebar-footer a {
  padding: 6px;
}

.admin-main {
  flex: 1;
  /* plan_diseno_fixes/fase_3: causa raiz del overflow horizontal en
     Metricas/Kanban/Detalle. Un hijo de flex container por default tiene
     min-width:auto — no se encoge mas alla del ancho natural de su
     contenido (ej. una tabla ancha), aunque tenga flex:1. min-width:0
     le permite encogerse de verdad al espacio disponible. */
  min-width: 0;
  padding: 28px 32px;
  /* Sin max-width: la interfaz abarca todo el ancho disponible (pedido
     explicito), tambien en monitores anchos. */
}
@media (max-width: 800px) {
  .admin-shell {
    flex-direction: column;
    padding: 12px;
    gap: 12px;
  }
  .admin-sidebar {
    width: auto;
    height: auto;
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    border-radius: 16px;
  }
  /* El sidebar ya se acomoda solo (fila, envuelve) en pantallas
     chicas -- colapsar no aporta nada ahi, se oculta el boton y se
     ignora el ancho angosto si alguien lo dejo colapsado en desktop. */
  .admin-colapsar-btn {
    display: none;
  }
  .admin-sidebar.colapsado {
    width: auto;
    padding: 24px 18px;
  }
  .admin-main {
    padding: 20px 18px;
  }
}

/* Campana de requisiciones por vencer, visible en todo el panel (antes
   era el banner fijo "admin-alerta" de arriba, ahora es un icono con
   contador que abre un modal — pedido de Gerardo 2026-08-27). Forma de
   campana con un solo div + pseudo-elementos, traducido del snippet
   Uiverse.io que paso Gerardo (styled-components -> CSS plano, mismo
   criterio que los demas botones custom de esta sesion). */
.campana {
  background: transparent;
  border: none;
  padding: 9px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 200ms;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--texto);
  flex-shrink: 0;
}
.campana:hover {
  background: rgba(255, 255, 255, 0.06);
}
.campana:hover .campana-bell-container {
  animation: campana-anillo 650ms ease-out 0s 1 normal both;
}
.campana-bell-container {
  display: block;
}
.campana-bell {
  display: block;
  position: relative;
  top: -2px;
  width: 12px;
  height: 14px;
  border: 2px solid currentColor;
  border-radius: 8px 8px 0 0;
  background: transparent;
}
.campana-bell::before,
.campana-bell::after {
  content: '';
  display: block;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  background: currentColor;
  height: 2px;
}
.campana-bell::before {
  top: 100%;
  width: 17px;
}
.campana-bell::after {
  top: calc(100% + 4px);
  width: 6px;
}
.campana-badge {
  position: absolute;
  top: 3px;
  right: 3px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--error);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
@keyframes campana-anillo {
  0%, 100% {
    transform: rotate(0deg);
  }
  20% {
    transform: rotate(15deg);
  }
  40% {
    transform: rotate(-15deg) scale(1.1);
  }
  60% {
    transform: rotate(10deg) scale(1.1);
  }
  80% {
    transform: rotate(-10deg);
  }
}

/* Modal de la campana: lista de requisiciones por entregar pronto */
.campana-lista {
  display: flex;
  flex-direction: column;
  max-height: 50vh;
  overflow-y: auto;
  margin-top: 4px;
}
.campana-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--vidrio-borde);
}
.campana-item:first-child {
  border-top: none;
}
.campana-item-titulo {
  color: #fff;
  font-weight: 600;
  font-size: 13.5px;
}
.campana-item-meta {
  color: var(--texto-dimmer);
  font-size: 12px;
  margin-top: 2px;
}
.campana-item a {
  color: var(--gold);
  text-decoration: none;
  flex-shrink: 0;
  font-weight: 600;
  font-size: 12.5px;
}

/* Cabecera comun de pantallas de admin */
.mr-hero {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.mr-hero > div {
  min-width: 0;
  max-width: 100%;
}
.mr-hero h1 {
  color: #fff;
  margin: 0 0 4px;
  font-size: 22px;
  /* Un titulo largo sin espacios (o una URL) se parte donde haga falta en
     vez de salirse de la pantalla. */
  overflow-wrap: anywhere;
}
.mr-sub {
  color: var(--texto-dim);
  font-size: 13.5px;
}
.mr-sub a {
  color: var(--gold);
  text-decoration: none;
}
/* Hallazgo del rediseño 2026-08-27: .mr-panel era un <div> sin fondo/
   borde/radio propio (solo el margen) en Usuarios, Clientes,
   ClienteEditar/Nuevo, UsuarioEditar, RequisicionEditar/Nueva,
   CambiarPasswordAdmin -- "liquid glass es de ley" y estas pantallas no
   tenian NINGUN vidrio. Se le da la misma receta que .glass-card
   directamente aqui (sin tocar cada JSX uno por uno). */
.mr-panel {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio);
  box-shadow: var(--vidrio-sombra), var(--vidrio-brillo-borde);
  padding: 24px;
  margin-bottom: 20px;
}
.mr-panel h2 {
  color: #fff;
  font-size: 16px;
  margin: 0 0 12px;
}
/* Antes RequisicionEditar/Nueva.jsx repetian
   <h2 style={{ color:'#fff', fontSize:15, margin:'24px 0 8px' }}> como
   sub-encabezado de seccion, ~5 veces por archivo -- una clase. */
.form-seccion-titulo {
  color: #fff;
  font-size: 15px;
  margin: 24px 0 8px;
}
.form-seccion-titulo:first-child {
  margin-top: 0;
}
.mr-tabla {
  width: 100%;
  border-collapse: collapse;
}
.mr-tabla th {
  text-align: left;
  color: var(--texto-dimmer);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 8px 10px;
  border-bottom: 1px solid var(--vidrio-borde);
}
.mr-tabla td {
  padding: 12px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  color: #fff;
  font-size: 13.5px;
  /* plan_diseno_fixes/fase_6: sin esto, las celdas heredaban
     text-align:center de #root (index.css, sobrante de la plantilla de
     Vite) — rompia el escaneo vertical de nombre/correo. Columnas
     numericas/cortas que SI deben quedar centradas usan .centro. */
  text-align: left;
}
.mr-tabla td.centro {
  text-align: center;
}
.mr-tabla tr:last-child td {
  border-bottom: none;
}
.mr-tabla a {
  color: var(--gold);
  text-decoration: none;
}

/* plan_diseno_fixes/fase_6: "Editar"/"Resetear contraseña" eran texto
   suelto sin affordance. Ahora son botones pequeños, separados con
   claridad, para una tabla de cuentas (accion sensible). */
.mr-acciones {
  display: flex;
  gap: 8px;
  align-items: center;
}
.mr-accion-btn {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--vidrio-borde);
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  color: var(--texto-dim);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.mr-accion-btn:hover {
  background: var(--vidrio-fondo-fuerte);
  color: #fff;
}
.mr-accion-btn.peligro {
  color: var(--amber);
  border-color: rgba(245, 158, 11, 0.3);
}
.mr-accion-btn.peligro:hover {
  background: rgba(245, 158, 11, 0.12);
  color: var(--amber);
}
.mr-vacio {
  color: var(--texto-dimmer);
  font-size: 13.5px;
  text-align: center;
  padding: 20px 6px;
}
.mr-vacio-grande {
  text-align: center;
  padding: 30px 20px;
}
.mr-vacio-grande p {
  color: rgba(255, 255, 255, 0.7);
  margin: 12px 0 18px;
}

.btn-confirmar-2clics {
  background: transparent;
  color: var(--gold);
  padding: 0;
  font-weight: 600;
  font-size: inherit;
  border: none;
  text-decoration: underline;
  cursor: pointer;
}

.password-temporal {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #fff;
  font-family: monospace;
  text-align: center;
  padding: 16px 0;
}

.toggle-password {
  background: transparent;
  border: none;
  color: var(--texto-dim);
  cursor: pointer;
  padding: 4px;
}
.campo-password {
  position: relative;
  display: flex;
  align-items: center;
}
.campo-password input {
  flex: 1;
  padding-right: 40px;
}
.campo-password .toggle-password {
  position: absolute;
  right: 6px;
}

/* ---------- Detalle de requisicion: resumen + notas (Fase 7, 3/4) ---------- */
.resumen-item { display: flex; justify-content: space-between; gap: 16px; padding: 11px 0; border-bottom: 1px solid var(--vidrio-borde); font-size: 14px; }
.resumen-item .k { color: var(--texto-dimmer); flex: 0 0 42%; }
.resumen-item .v { color: #fff; text-align: right; }
.resumen-item.apilado { flex-direction: column; gap: 4px; }
.resumen-item.apilado .v { text-align: left; overflow-wrap: anywhere; word-break: break-word; }

.notas-lista { display: flex; flex-direction: column; gap: 12px; }
.nota-item {
  background: var(--vidrio-fondo-fuerte);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: 8px;
  padding: 12px 14px;
}
.nota-meta { font-size: 12px; color: var(--texto-dimmer); margin-bottom: 6px; overflow-wrap: anywhere; }
.nota-meta strong { color: var(--gold); }
.nota-texto { font-size: 14px; white-space: pre-wrap; color: #fff; overflow-wrap: anywhere; }
.nota-archivo { margin-top: 8px; font-size: 13px; overflow-wrap: anywhere; }
.nota-archivo a { color: var(--gold); }

/* plan_diseno_fixes/fase_8: el detalle de requisicion era una lista
   vertical larga label-valor (".mr-panel" no tenia fondo/borde propio,
   solo un margen) — se reemplaza por tarjetas de vidrio (GlassCard)
   agrupadas por tema, en cuadricula que se ajusta sola al ancho
   disponible (2-3 columnas en pantalla ancha, 1 columna angosta). */
.rq-detalle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-bottom: 20px;
  align-items: start;
}
.rq-detalle-grid h2 {
  color: #fff;
  font-size: 16px;
  margin: 0 0 12px;
}

/* Pantalla "Exposiciones" del admin (pedido de Betza, 2026-10-05). Reusa
   las clases .calendario-* de componentes.css para los dias; aqui solo
   el contenedor en linea (no flotante), el interruptor y las etiquetas
   de semanas marcadas. */
.expo-interruptor {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
}
.expo-interruptor input {
  margin-top: 4px;
  accent-color: var(--expo);
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.expo-interruptor b {
  display: block;
  color: #fff;
  font-size: 15px;
}
.expo-interruptor small {
  display: block;
  margin-top: 2px;
  color: var(--texto-dim);
  font-size: 12.5px;
}
.expo-layout {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.calendario-inline {
  width: 100%;
  max-width: 320px;
  padding: 14px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
}
.expo-lista {
  flex: 1;
  min-width: 240px;
}
.expo-lista-titulo {
  color: var(--texto-dim);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 10px;
}
.expo-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.expo-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 6px 12px;
  border-radius: 999px;
  background: rgba(249, 115, 22, 0.14);
  border: 1px solid rgba(249, 115, 22, 0.45);
  color: #fff;
  font-size: 12.5px;
}
.expo-chip button {
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0 4px;
}
.expo-chip button:hover {
  color: #fff;
}

/* Responsable en Marketing (pedido de Betza, 2026-10-06): franja arriba del
   detalle de la requisicion y linea en cada tarjeta del tablero. */
.kb-card-resp {
  margin: 2px 0 6px;
  font-size: 11.5px;
  color: var(--gold-hot);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kb-card-resp.sin {
  color: var(--texto-dimmer);
  font-style: italic;
}

/* Responsables en Marketing, una o varias personas (pedido de Betza,
   2026-10-06): pastillas que se activan con un clic, campo para sumar a
   alguien que no este en la lista y boton de guardar. */
.responsable-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}
.responsable-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--vidrio-borde);
  background: rgba(255, 255, 255, 0.04);
  color: var(--texto-dim);
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.responsable-pill:hover {
  border-color: var(--gold);
  color: #fff;
}
.responsable-pill.activo {
  background: rgba(160, 120, 64, 0.28);
  border-color: var(--gold);
  color: #fff;
  font-weight: 600;
}
.responsable-pill svg {
  flex-shrink: 0;
  color: var(--gold-hot);
}
.responsable-agregar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 16px;
}
.responsable-agregar .campo-vidrio {
  flex: 1;
  min-width: 240px;
}
.responsable-pie {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
/* Reporte de metricas — rediseño liquid glass (pedido explicito de
   Gerardo, 2026-08-27). Antes este archivo era una copia tal cual de
   app/static/styles.css (formato aprobado por Betza en su momento,
   deliberadamente "no se rediseña" — ver commits de la fase 7 del plan
   react_glass) y se habia quedado con el look plano original
   (--dark-card/--dark-border solidos, sin blur) mientras el resto de la
   plataforma ya migro al vidrio esmerilado. Ahora usa el mismo fondo/
   blur/borde brilloso que .glass-card (componentes.css) y los mismos 3
   colores semanticos que ya usan las etiquetas de estado de esta misma
   pantalla (rpt-tag-entregado = verde, rpt-tag-rechazada = rojo) —
   antes las graficas usaban una escala de grises sin relacion con esos
   semaforos (ver graficas.jsx). Prefijo rpt- se conserva tal cual. */
.rpt-main { max-width: 1360px; margin: 0 auto; padding: 0; }
.rpt-section { margin-bottom: 32px; }
.rpt-sec { font-family: var(--fuente-titulo); font-size: 11.5px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: #fff; margin-bottom: 14px; display: flex; align-items: center; gap: 10px; }
.rpt-sec::before { content: ''; width: 24px; height: 3px; background: var(--gold); border-radius: 2px; flex-shrink: 0; }
.rpt-sec::after { content: ''; flex: 1; height: 1px; background: var(--vidrio-borde); }

.rpt-kpi-grid5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.rpt-kpi-grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.rpt-kpi-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }

.rpt-kpi {
  position: relative;
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-left: 3px solid var(--gold);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: var(--vidrio-brillo-borde);
  padding: 16px 16px 14px;
  transition: background 150ms;
}
.rpt-kpi:hover { background: var(--vidrio-fondo-fuerte); }
.rpt-kpi.light { border-left-color: rgba(255, 255, 255, 0.28); }
.rpt-kpi.gray { border-left-color: rgba(255, 255, 255, 0.28); }
.rpt-kpi.amber { border-left-color: var(--amber); }
/* Nuevas variantes semanticas (antes "Fuera de Plazo"/"A Tiempo" no
   tenian color propio, quedaban con el mismo gris que cualquier KPI
   secundario — ahora coinciden con el rojo/verde de las graficas). */
.rpt-kpi.success { border-left-color: var(--verde-ok); }
.rpt-kpi.danger { border-left-color: var(--error); }

.rpt-kpi-icono { position: absolute; top: 14px; right: 14px; opacity: 0.4; }
.rpt-kpi-lbl { font-family: var(--fuente-titulo); font-size: 9.5px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: rgba(255,255,255,0.45); margin-bottom: 8px; padding-right: 22px; }
.rpt-kpi-lbl-conHint { margin-bottom: 1px; }
.rpt-kpi-hint { font-size: 9px; letter-spacing: .3px; color: rgba(255,255,255,0.35); margin-bottom: 8px; }
.rpt-ch-vacio { height: 220px; display: flex; align-items: center; justify-content: center; text-align: center; color: rgba(255,255,255,0.35); font-size: 12.5px; padding: 0 20px; }
.rpt-kpi-val { font-family: var(--fuente-dato); font-size: 26px; font-weight: 700; line-height: 1; margin-bottom: 8px; color: #fff; }
.rpt-kpi-val.o { color: var(--gold); }
.rpt-kpi-val.a { color: var(--amber); }
.rpt-kpi-val.g { color: var(--verde-ok); }
.rpt-kpi-val.r { color: var(--error); }
.rpt-kpi-sub { font-size: 10.5px; color: rgba(255,255,255,0.45); }
.rpt-kpi-rows { display: flex; flex-direction: column; gap: 4px; }
.rpt-kr { display: flex; align-items: center; justify-content: space-between; font-size: 10.5px; }
.rpt-kr-l { display: flex; align-items: center; gap: 5px; color: rgba(255,255,255,0.5); }
.rpt-kr-v { font-weight: 600; color: rgba(255,255,255,0.8); }
.rpt-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; display: inline-block; background: var(--gold); }

.rpt-ch-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.rpt-ch-card {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: var(--vidrio-brillo-borde);
  padding: 20px 20px 16px;
}
.rpt-ch-title { font-family: var(--fuente-titulo); font-size: 12px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase; color: #fff; margin-bottom: 3px; }
.rpt-ch-sub { font-size: 10.5px; color: rgba(255,255,255,0.45); margin-bottom: 14px; }
.rpt-ch-leg { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 12px; }
.rpt-li { display: flex; align-items: center; gap: 5px; font-size: 10.5px; color: rgba(255,255,255,0.5); }
.rpt-lr { width: 10px; height: 3px; border-radius: 2px; }

.rpt-tbl-wrap { overflow-x: auto; }
.rpt-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.rpt-table thead th { background: rgba(255,255,255,0.04); color: rgba(255,255,255,0.45); text-align: left; padding: 9px 10px; font-family: var(--fuente-titulo); font-weight: 600; font-size: 9.5px; letter-spacing: 1.2px; text-transform: uppercase; border-bottom: 1px solid var(--vidrio-borde); white-space: nowrap; }
.rpt-table tbody tr { border-bottom: 1px solid rgba(255,255,255,0.06); transition: background 120ms; }
.rpt-table tbody tr:hover { background: rgba(255,255,255,0.05); }
.rpt-table tbody td { padding: 8px 10px; vertical-align: middle; color: rgba(255,255,255,0.85); }
.rpt-tag { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 9.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; }
.rpt-tag-entregado { background: rgba(74,222,128,0.12); color: var(--verde-ok); border: 1px solid rgba(74,222,128,0.25); }
.rpt-tag-pendiente { background: rgba(197,197,197,0.08); color: rgba(255,255,255,0.7); border: 1px solid rgba(197,197,197,0.15); }
.rpt-tag-rechazada { background: rgba(229,62,62,0.1); color: var(--error); border: 1px solid rgba(229,62,62,0.25); }
.rpt-tag-atencion { background: rgba(245,158,11,0.1); color: var(--amber); border: 1px solid rgba(245,158,11,0.25); }
.rpt-early { color: var(--gold); font-weight: 600; }
/* Bug encontrado en la revision (2026-08-27): "Fuera de Plazo" (entrega
   tardia) se pintaba con --text-dimmer, el MISMO gris apagado que
   "Sin completar/sin fecha" — una entrega tarde es justo lo que este
   reporte deberia resaltar, no diluir. Ahora usa --error, igual que
   rpt-tag-rechazada y las graficas. */
.rpt-late { color: var(--error); font-weight: 600; }
.rpt-ontime { color: rgba(255,255,255,0.8); font-weight: 600; }
.rpt-anomaly { color: rgba(255,255,255,0.35); font-size: 10px; }
.rpt-ins-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.rpt-ins {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-left: 3px solid var(--gold);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: var(--vidrio-brillo-borde);
  padding: 20px 18px 18px;
}
.rpt-ins.light { border-left-color: rgba(255, 255, 255, 0.28); }
.rpt-ins.gray { border-left-color: rgba(255, 255, 255, 0.28); }
.rpt-ins.amber { border-left-color: var(--amber); }
.rpt-ins-n { font-family: var(--fuente-dato); font-size: 34px; font-weight: 700; color: var(--gold); line-height: 1; margin-bottom: 8px; opacity: .25; }
.rpt-ins-t { font-family: var(--fuente-titulo); font-size: 12px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; color: #fff; margin-bottom: 6px; }
.rpt-ins-p { font-size: 11.5px; color: rgba(255,255,255,0.55); line-height: 1.6; }
.rpt-hl { color: var(--gold); font-weight: 600; }
.rpt-hl-l { color: rgba(255,255,255,0.85); font-weight: 600; }
.rpt-banner { margin: 0 0 20px; }
.rpt-banner-box {
  padding: 12px 16px;
  background: rgba(245,158,11,0.10);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid rgba(245,158,11,0.32);
  border-radius: var(--vidrio-radio-chico);
  font-size: 12px;
  color: rgba(255,255,255,0.8);
  line-height: 1.6;
}
@media (max-width: 900px) {
  .rpt-kpi-grid5, .rpt-kpi-grid4, .rpt-kpi-grid3 { grid-template-columns: repeat(2, 1fr); }
  .rpt-ch-grid2, .rpt-ins-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .rpt-kpi-grid5, .rpt-kpi-grid4, .rpt-kpi-grid3 { grid-template-columns: 1fr; }
}

/* ---------- Selector de periodo ---------- */
.periodo-selector {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  align-items: center;
}
.periodo-btn {
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  box-shadow: var(--vidrio-brillo-borde);
  color: var(--texto-dim);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  transition: background 150ms, color 150ms;
}
.periodo-btn:hover:not(.activo) {
  background: var(--vidrio-fondo-fuerte);
  color: var(--texto);
}
.periodo-btn.activo {
  background: var(--gold);
  border-color: var(--gold);
  color: #1a0800;
  box-shadow: none;
}
/* Plan react_glass, Fase 7 (3/4) — tablero kanban de requisiciones.
   Rediseño 2026-08-27: vidrio real en vez de --dark-card/--dark-border
   planos (unico rezago del sistema de vidrio en el panel de admin,
   junto con .mr-panel), talon con folio + estampa de prioridad
   troquelado del cuerpo de la tarjeta (concepto "orden de trabajo",
   ver componentes.css) -- cada tarjeta es literalmente eso: una orden
   de trabajo con folio y prioridad, viajando de columna en columna. */
/* plan_diseno_fixes/fase_7: el tablero SI necesita su propio scroll
   horizontal (8 columnas no caben en una pantalla estandar) — eso es
   intencional (ver fase_3.md, "no se toca"). Lo que faltaba era una
   señal visual de que hay mas columnas fuera de la vista. */
.kb-board-wrap { position: relative; }
.kb-board { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 12px; margin-top: 22px; }
.kb-board-fade {
  position: absolute;
  top: 0;
  bottom: 12px;
  width: 56px;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 1;
}
.kb-board-fade-izq { left: 0; background: linear-gradient(to right, var(--page-bg), transparent); }
.kb-board-fade-der { right: 0; background: linear-gradient(to left, var(--page-bg), transparent); }
/* min-width:0 -- mismo motivo que .admin-main en fase_3.md: sin esto,
   un titulo largo sin espacios (white-space:nowrap) empuja a la columna
   a crecer mas alla de sus 260px fijos, ignorando flex-shrink:0, porque
   el min-width:auto por default de un hijo flex gana sobre flex-basis. */
.kb-col {
  flex: 0 0 260px;
  min-width: 0;
  background: var(--vidrio-fondo);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: var(--vidrio-brillo-borde);
  display: flex;
  flex-direction: column;
  max-height: 78vh;
}
.kb-col-header { padding: 12px 14px; border-bottom: 1px solid var(--vidrio-borde); display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* plan_diseno_fixes/fase_7: titulos largos se cortaban abruptamente
   contra el borde, sin "..." ni forma de ver el texto completo. */
.kb-col-titulo { font-family: var(--fuente-titulo); font-size: 13px; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.kb-col-count { font-family: var(--fuente-dato); font-size: 11px; color: var(--texto-dimmer); background: rgba(255,255,255,0.08); border-radius: 999px; padding: 2px 9px; flex-shrink: 0; }
.kb-col-body { padding: 10px; overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 10px; min-height: 70px; transition: background .15s; }
.kb-col-body.kb-col-hover { background: rgba(255,255,255,0.04); }
.kb-col-vacio { font-size: 12px; color: var(--texto-dimmer); text-align: center; padding: 18px 6px; }
.kb-card {
  background: var(--vidrio-fondo-fuerte);
  backdrop-filter: blur(var(--vidrio-blur));
  -webkit-backdrop-filter: blur(var(--vidrio-blur));
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--vidrio-radio-chico);
  box-shadow: var(--vidrio-brillo-borde);
  padding: 10px 12px 12px;
  cursor: grab;
  min-width: 0;
}
.kb-card:active { cursor: grabbing; }
.kb-card.arrastrando { opacity: 0.35; }
.kb-card-talon { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.kb-card-titulo { font-size: 13px; font-weight: 600; color: #fff; margin-bottom: 4px; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-card-meta { font-size: 11px; color: var(--texto-dimmer); margin-bottom: 8px; }
.kb-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.kb-card-fecha { font-family: var(--fuente-dato); font-size: 11px; color: var(--texto-dimmer); }
.kb-card-link { font-size: 11px; color: var(--gold); text-decoration: none; }
.kb-card-link:hover { text-decoration: underline; }
.kb-buscador { max-width: 360px; margin: 16px 0 0; }
.kb-card.kb-oculta { display: none; }
.kb-card.kb-card-atrasada { border-color: var(--error); }
.kb-tag-atrasada { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--error); background: rgba(229,62,62,0.12); border: 1px solid rgba(229,62,62,0.35); border-radius: 4px; padding: 2px 7px; margin-bottom: 6px; }
/* Plan react_glass, Fase 2: solo el minimo para que la pantalla de
   prueba se vea legible. El sistema de diseno real (liquid glass) se
   construye en la Fase 3. */
.app-esqueleto {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: #080808;
  color: #fff;
  font-family: 'Segoe UI', Arial, sans-serif;
  text-align: center;
  padding: 24px;
}

.app-esqueleto h1 {
  color: #A07840;
  margin: 0;
}
/* Capa de movimiento y materiales (pedido de Gerardo, 2026-10-07:
   "dale un buen diseño y animaciones" con la skill apple-design).

   Se importa AL FINAL de App.jsx, despues de todas las pantallas, para
   que gane la cascada sobre componentes.css/panelAdmin.css/etc. sin
   tener que reescribir esos archivos. NO cambia colores, patron de
   fondo ni la identidad "liquid glass" (decision de Gerardo/Betza):
   solo agrega la fisica y el pulido encima.

   Reglas que sigue (Apple, "Designing Fluid Interfaces"):
   - Respuesta: el feedback al presionar es instantaneo (pointer-down),
     nunca espera al soltar.
   - Resortes, no curvas: la entrada/salida usa resorte critico (sin
     rebote, amortiguamiento 1.0) y solo el feedback de "soltar" un
     boton lleva un poco de rebote (damping ~0.6), porque ese si viene
     de una accion fisica del usuario.
   - Simetria espacial: lo que entra por un lado sale por ese mismo lado
     (pasos del wizard, modal).
   - Materiales: vidrio con saturacion, canto de luz; pesado en lo
     estructural (sidebar), ligero en lo interactivo.
   - Reduce motion / transparency / contrast: ver el final del archivo. */

/* ---------- Fisica: resortes como curvas CSS ---------- */
/* Fallback con cubic-bezier para navegadores sin linear(); abajo, en
   @supports, se reemplazan por la curva real de resorte (muestreada de
   la ecuacion de un oscilador amortiguado). */
:root {
  --mov-suave: cubic-bezier(0.22, 1, 0.36, 1); /* resorte critico, sin rebote */
  --mov-rebote: cubic-bezier(0.34, 1.56, 0.64, 1); /* resorte con rebote leve */
  --t-presionar: 90ms;
  --t-media: 420ms;
  --t-lenta: 620ms;
  --mov-anim-entrada: mov-aparece;
}
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    /* damping 1.0, response 0.4s */
    --mov-suave: linear(0, 0.18, 0.454, 0.67, 0.811, 0.896, 0.944, 0.97, 0.985, 0.992, 0.996, 0.998, 1);
    /* damping 0.62, response 0.4s: rebota ~8% y se asienta */
    --mov-rebote: linear(0, 0.15, 0.444, 0.727, 0.929, 1.041, 1.081, 1.078, 1.056, 1.031, 1.011, 0.999, 0.994, 0.993, 0.995, 0.997, 0.999, 1);
  }
}

/* ---------- Respuesta: sin retraso de toque, sin destello gris ---------- */
:where(a, button, [role='button'], label, input, select, summary) {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* ---------- Feedback al presionar (pointer-down, instantaneo) ----------
   Se usa la propiedad individual `scale` (no `transform`) para no pisar
   los transform que cada componente ya trae (rotaciones, translate).
   Al soltar, regresa con resorte con rebote; al presionar baja rapido. */
.boton,
.boton-brillo,
.periodo-btn,
.admin-colapsar-btn,
.admin-cta-card,
.admin-cta-colapsado,
.admin-nav-link,
.calendario-dia,
.opcion-fila,
.mr-accion-btn,
.kb-card {
  transition-property: background, background-color, border-color, color, opacity, box-shadow, transform, scale, translate;
  transition-duration: 0.15s, 0.15s, 0.15s, 0.15s, 0.15s, 0.4s, 0.15s, var(--t-media), var(--t-media);
  transition-timing-function: ease, ease, ease, ease, ease, ease, ease, var(--mov-rebote), var(--mov-suave);
}
.boton-brillo {
  /* conserva su resplandor que crece (0.5s) */
  transition-duration: 0.15s, 0.15s, 0.15s, 0.15s, 0.15s, 0.5s, 0.15s, var(--t-media), var(--t-media);
}
.boton:active:not(:disabled),
.boton-brillo:active:not(:disabled),
.boton-flecha:active:not(:disabled),
.periodo-btn:active,
.admin-colapsar-btn:active,
.admin-cta-card:active,
.admin-cta-colapsado:active,
.admin-nav-link:active,
.mr-accion-btn:active {
  scale: 0.965;
  transform: none;
  transition-duration: var(--t-presionar);
  transition-timing-function: var(--mov-suave);
}
.calendario-dia:active:not(:disabled),
.opcion-fila:active {
  scale: 0.97;
  transition-duration: var(--t-presionar);
  transition-timing-function: var(--mov-suave);
}
@media (hover: hover) {
  .boton:hover:not(:disabled),
  .boton-brillo:hover:not(:disabled) {
    translate: 0 -1px;
  }
  .calendario-dia:hover:not(:disabled):not(.lleno):not(.pasado) {
    scale: 1.08;
  }
}

/* ---------- Kanban: la tarjeta se "levanta" al tomarla ---------- */
.kb-card {
  cursor: grab;
}
@media (hover: hover) {
  .kb-card:hover {
    translate: 0 -2px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4), var(--vidrio-brillo-borde);
  }
}
.kb-card:active {
  cursor: grabbing;
  scale: 1.025;
  translate: 0 -3px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5), var(--vidrio-brillo-borde);
  transition-duration: var(--t-presionar);
}
/* Al caer en una columna nueva (la tarjeta se vuelve a montar ahi) llega
   con un asentamiento suave, no aparece de golpe. */
.kb-card {
  animation: mov-asienta var(--t-media) var(--mov-rebote) backwards;
}

/* ---------- Entradas: aparecen con resorte, escalonadas ---------- */
@keyframes mov-aparece {
  from {
    opacity: 0;
    translate: 0 14px;
    scale: 0.985;
  }
  to {
    opacity: 1;
    translate: 0 0;
    scale: 1;
  }
}
@keyframes mov-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes mov-asienta {
  from {
    opacity: 0;
    scale: 0.94;
    translate: 0 -8px;
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}
@keyframes mov-pop {
  from {
    opacity: 0;
    scale: 0.92;
    translate: 0 10px;
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}
/* `backwards` (no `both`): al terminar se quita todo — un `transform`
   o `scale` que se quedara puesto crearia un contexto de apilamiento y
   rompe position:fixed de los hijos (modales). */
.admin-main > *,
.intro-content > *,
.portal-hero,
.conf-card,
.mr-panel,
.rpt-kpi,
.rpt-ch-card,
.rpt-ins,
.kb-col {
  animation: var(--mov-anim-entrada) var(--t-lenta) var(--mov-suave) backwards;
  animation-delay: calc(var(--mov-i, 0) * 55ms);
}
.admin-main > *:nth-child(1) { --mov-i: 0; }
.admin-main > *:nth-child(2) { --mov-i: 1; }
.admin-main > *:nth-child(3) { --mov-i: 2; }
.admin-main > *:nth-child(4) { --mov-i: 3; }
.admin-main > *:nth-child(5) { --mov-i: 4; }
.admin-main > *:nth-child(6) { --mov-i: 5; }
.admin-main > *:nth-child(n + 7) { --mov-i: 6; }
.rpt-kpi:nth-child(1), .kb-col:nth-child(1) { --mov-i: 1; }
.rpt-kpi:nth-child(2), .kb-col:nth-child(2) { --mov-i: 2; }
.rpt-kpi:nth-child(3), .kb-col:nth-child(3) { --mov-i: 3; }
.rpt-kpi:nth-child(4), .kb-col:nth-child(4) { --mov-i: 4; }
.rpt-kpi:nth-child(5), .kb-col:nth-child(5) { --mov-i: 5; }
.kb-col:nth-child(n + 6) { --mov-i: 6; }
.rpt-ch-card:nth-child(2n), .rpt-ins:nth-child(2n) { --mov-i: 2; }
.rpt-ch-card:nth-child(2n + 1), .rpt-ins:nth-child(2n + 1) { --mov-i: 1; }

/* Tarjetas de acceso: llegan con un poco de rebote (es lo primero que
   ve la persona y no viene de un gesto, asi que el rebote es leve). */
.auth-card {
  animation: mov-pop var(--t-lenta) var(--mov-rebote) backwards;
}
.main-panel {
  animation: var(--mov-anim-entrada) var(--t-lenta) var(--mov-suave) backwards;
}
.err-box {
  animation: mov-pop var(--t-media) var(--mov-rebote) backwards;
}

/* ---------- Wizard: los pasos entran por el lado de donde vienen ---------- */
@keyframes mov-paso-adelante {
  from { opacity: 0; translate: 28px 0; }
  to { opacity: 1; translate: 0 0; }
}
@keyframes mov-paso-atras {
  from { opacity: 0; translate: -28px 0; }
  to { opacity: 1; translate: 0 0; }
}
.paso-anim {
  animation: var(--mov-paso, mov-paso-adelante) var(--t-lenta) var(--mov-suave) backwards;
}
.paso-anim.paso-atras {
  --mov-paso: mov-paso-atras;
}

/* ---------- Barra de progreso del cliente: se llena con resorte ---------- */
@keyframes mov-llena {
  from { scale: 0 1; opacity: 0.4; }
  to { scale: 1 1; opacity: 1; }
}
.progreso-req-seg.lleno {
  transform-origin: left center;
  animation: mov-llena var(--t-lenta) var(--mov-suave) backwards;
}
.progreso-req-seg.lleno:nth-child(2) { animation-delay: 90ms; }
.progreso-req-seg.lleno:nth-child(3) { animation-delay: 180ms; }
.progreso-req-seg.lleno:nth-child(4) { animation-delay: 270ms; }
.progreso-req-seg.lleno:nth-child(5) { animation-delay: 360ms; }
@keyframes mov-latido {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.62; }
}
.progreso-req-seg.actual {
  animation: mov-llena var(--t-lenta) var(--mov-suave) backwards, mov-latido 2.8s ease-in-out 1s infinite;
}

/* ---------- Sidebar: se pliega con resorte, el texto se desvanece ---------- */
.admin-sidebar {
  transition: width var(--t-lenta) var(--mov-suave), padding var(--t-lenta) var(--mov-suave);
}
.admin-colapsar-btn {
  transition-property: right, color, background, scale;
  transition-duration: var(--t-lenta), 0.15s, 0.15s, var(--t-media);
  transition-timing-function: var(--mov-suave), ease, ease, var(--mov-rebote);
}
.admin-colapsar-btn .icono {
  transition: transform var(--t-lenta) var(--mov-rebote);
}
.admin-nav-link span {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  max-width: 180px;
  transition: opacity var(--t-media) var(--mov-suave), max-width var(--t-lenta) var(--mov-suave);
}
.admin-sidebar.colapsado .admin-nav-link span {
  display: inline-block; /* anula el display:none de panelAdmin.css para poder animarlo */
  opacity: 0;
  max-width: 0;
}
.admin-sidebar.colapsado .admin-nav-link {
  gap: 0;
}
.admin-header-texto,
.admin-nav-label,
.admin-sidebar-correo,
.admin-cta-card,
.admin-cta-colapsado {
  animation: mov-fade var(--t-media) var(--mov-suave) backwards;
}
/* La pill activa "se asienta" cuando cambias de seccion. */
@keyframes mov-pill {
  from { opacity: 0.4; scale: 0.94; }
  to { opacity: 1; scale: 1; }
}
.admin-nav-link.activo {
  animation: mov-pill var(--t-media) var(--mov-rebote);
}
.admin-nav-link:hover:not(.activo) {
  color: #fff;
}

/* ---------- Modal: el vidrio "llega" y se va por el mismo camino ---------- */
@keyframes mov-modal-entra {
  from { opacity: 0; scale: 0.93; translate: 0 12px; }
  to { opacity: 1; scale: 1; translate: 0 0; }
}
@keyframes mov-modal-sale {
  from { opacity: 1; scale: 1; translate: 0 0; }
  to { opacity: 0; scale: 0.93; translate: 0 12px; }
}
@keyframes mov-velo-entra {
  from { opacity: 0; backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
  to { opacity: 1; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
}
@keyframes mov-velo-sale {
  from { opacity: 1; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
  to { opacity: 0; backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
}
.modal-fondo {
  animation: mov-velo-entra var(--t-media) var(--mov-suave) backwards;
}
.modal-fondo .modal-panel {
  animation: mov-modal-entra var(--t-media) var(--mov-suave) backwards;
}
.modal-fondo.cerrando {
  animation: mov-velo-sale 220ms ease-in forwards;
  pointer-events: none;
}
.modal-fondo.cerrando .modal-panel {
  animation: mov-modal-sale 220ms ease-in forwards;
}

/* ---------- Materiales: vidrio con saturacion y canto de luz ----------
   Las superficies grandes se sienten mas gruesas (blur + saturacion);
   las chicas e interactivas quedan como estaban (un blur de 48px + mas
   saturacion en cada pill seria caro y ensucia el contraste). */
.glass-card,
.admin-sidebar,
.mr-panel,
.kb-col,
.rpt-kpi,
.rpt-ch-card,
.rpt-ins {
  backdrop-filter: blur(var(--vidrio-blur)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--vidrio-blur)) saturate(160%);
}
@media (hover: hover) {
  .rpt-kpi,
  .rpt-ch-card {
    transition: translate var(--t-media) var(--mov-suave), box-shadow var(--t-media) var(--mov-suave), background 150ms;
  }
  .rpt-kpi:hover,
  .rpt-ch-card:hover {
    translate: 0 -2px;
    box-shadow: 0 14px 36px rgba(0, 0, 0, 0.42), var(--vidrio-brillo-borde);
  }
}

/* ---------- Tipografia: tracking por tamaño, cifras alineadas ---------- */
h1, h2, h3 {
  text-wrap: balance;
}
:where(.portal-hero h1, .intro-content h1, .auth-card h1, .paso-titulo, .conf-card h2, .mr-panel h2, .admin-main > h1) {
  letter-spacing: -0.012em; /* grande = un poco mas junto, como en SF */
  line-height: 1.12;
}
.rpt-kpi-val,
.rpt-table td,
.kb-card-fecha,
.ticket-folio,
.progreso-req-paso {
  font-variant-numeric: tabular-nums;
}

/* ---------- Foco visible (teclado), con la misma fisica ---------- */
:where(a, button, [role='button'], summary):focus-visible {
  outline: 2px solid var(--gold-hot);
  outline-offset: 3px;
  border-radius: inherit;
}

/* ---------- Accesibilidad ---------- */
@media (prefers-reduced-motion: reduce) {
  /* No es "sin feedback": es una version tranquila. Las entradas pasan a
     un cross-fade corto; nada se desliza, rebota ni escala. */
  :root {
    --mov-anim-entrada: mov-fade;
    --mov-paso: mov-fade;
    --t-lenta: 220ms;
    --t-media: 180ms;
  }
  .paso-anim,
  .paso-anim.paso-atras {
    animation-name: mov-fade;
  }
  .auth-card,
  .err-box,
  .kb-card,
  .admin-nav-link.activo {
    animation-name: mov-fade;
  }
  .progreso-req-seg.lleno,
  .progreso-req-seg.actual {
    animation: none;
  }
  .modal-fondo .modal-panel,
  .modal-fondo.cerrando .modal-panel {
    animation-name: mov-fade;
  }
  .boton:active:not(:disabled),
  .boton-brillo:active:not(:disabled),
  .boton-flecha:active:not(:disabled),
  .periodo-btn:active,
  .admin-colapsar-btn:active,
  .admin-cta-card:active,
  .admin-cta-colapsado:active,
  .admin-nav-link:active,
  .mr-accion-btn:active,
  .calendario-dia:active:not(:disabled),
  .opcion-fila:active,
  .kb-card:active,
  .calendario-dia:hover:not(:disabled) {
    scale: 1;
  }
  .boton:hover:not(:disabled),
  .boton-brillo:hover:not(:disabled),
  .kb-card:hover,
  .kb-card:active,
  .rpt-kpi:hover,
  .rpt-ch-card:hover {
    translate: 0 0;
  }
  .cursor-destello {
    display: none;
  }
}
@media (prefers-reduced-transparency: reduce) {
  .glass-card,
  .admin-sidebar,
  .mr-panel,
  .kb-col,
  .rpt-kpi,
  .rpt-ch-card,
  .rpt-ins,
  .modal-fondo {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background-color: rgba(24, 22, 19, 0.96);
  }
}
@media (prefers-contrast: more) {
  .glass-card,
  .admin-sidebar,
  .mr-panel,
  .kb-col,
  .rpt-kpi,
  .rpt-ch-card,
  .rpt-ins,
  .kb-card {
    background-color: rgba(18, 16, 14, 0.98);
    border-color: rgba(255, 255, 255, 0.55);
  }
}
