/* ============================================================
   PRINTIO.PE — modal.css
   Modal de pedido, formularios, resumen, confirmación y responsive
   ============================================================ */

/* ============================================================
   OVERLAY Y MODAL
   ============================================================ */
.overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay);   /* unificado con wizard via base.css */
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  z-index: 200;
  overflow-y: auto;
  backdrop-filter: blur(6px);
  /* Fade in del fondo y blur cuando se abre */
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
/* Culqi Checkout Custom EMBEBIDO (2026-08-27, reemplaza a Izipay/Culqi
   v4 pop-up — Frank: "usaremos solo Culqi como método de pago embebido").
   El widget arma su PROPIO iframe adentro de #culqi-embed con un alto
   chico por default y overflow:auto — eso es el scroll interno que se
   veía de más (Frank: "quítale el scroll"). #paso3 ya tiene su propio
   scroll a nivel de modal (.modal-body), así que acá adentro no hace
   falta ningún scroll propio — se le fuerza alto real (--culqi-alto,
   distinto por método — ver CULQI_ALTOS en render.js).
   Arranca CERRADO (max-height:0, opacity:0) — Frank: "que el formulario
   aparezca pequeño y que cuando le haga click recién aparezca, pero no de
   golpe sino con una animación de apertura". elegirMetodoPagoCulqi()
   agrega .abierto recién cuando el iframe ya está montado adentro, así la
   transición se ve como un acordeón abriéndose hacia el alto real, no un
   salto. overflow:hidden es necesario en el estado cerrado (para que
   max-height:0 realmente tape el contenido) — se libera a visible una vez
   abierto para que el iframe (ya con su alto forzado) no quede recortado
   por el propio max-height si algo no calzara exacto.
   2da vuelta (Frank: "mejora mucho la animación, la has hecho muy
   básica" + "cuando paso de tarjeta a qr también debería existir una
   animación") — se le suma movimiento real (no solo alto+opacidad):
   entra deslizándose un poco desde arriba y agrandándose levemente, con
   una curva "back-out" (leve rebote/overshoot al final, cubic-bezier con
   el 4to valor >1) en vez de una desaceleración plana — se siente más
   viva. elegirMetodoPagoCulqi() ahora espera a que term ine la transición
   de CIERRE (con un timeout que matchea la duración de acá) antes de
   reconstruir el contenido, para que cambiar de método SIEMPRE se vea
   como cierre completo → apertura completa, nunca un salto. */
#culqi-embed {
  max-height: 0;
  opacity: 0;
  transform: translateY(-10px) scale(0.97);
  transform-origin: top center;
  overflow: hidden;
  transition:
    max-height 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.32s ease,
    transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
#culqi-embed.abierto {
  max-height: var(--culqi-alto, 620px);
  opacity: 1;
  transform: translateY(0) scale(1);
  overflow: visible;
}
/* Tapa la propia pantalla de carga OSCURA de Culqi (Frank: "mira este
   parpadeo cuando el formulario carga" — un cuadro negro con su logo
   girando, imposible de re-estilizar por ser contenido de otro dominio).
   #culqi-cargando (spinner + texto con la paleta de Printio) se ve
   PRIMERO, apenas se abre la tarjeta — #culqi-mount (donde Culqi mete su
   iframe) nace en opacity:0 debajo, y recién se cruza a él cuando el
   formulario real ya está listo (timeout en elegirMetodoPagoCulqi). Así
   el cliente nunca ve el flash negro. */
#culqi-cargando {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: var(--culqi-alto, 620px);
  color: var(--texto-mid);
  font-size: 13px;
  transition: opacity 0.3s ease;
}
#culqi-cargando.oculto { display: none; }
#culqi-mount {
  opacity: 0;
  transition: opacity 0.35s ease;
}
#culqi-mount.listo { opacity: 1; }
#culqi-mount iframe {
  height: var(--culqi-alto, 620px) !important;
  min-height: var(--culqi-alto, 620px) !important;
  overflow: visible !important;
}
/* Selector "Pago con tarjeta" / "Pago con QR" (2026-08-27) — pasó por 2
   estilos (botones lado a lado con borde, después botones sólidos azules
   como .landing-opt-primary) hasta que Frank preguntó "¿usamos el
   deslizador de tarjeta y volante?" — se refería al toggle-sino que ya
   usa Entrega (Recojo/Delivery/Provincias) e Impresión (1/2 lados), no a
   los CTA grandes del landing. Tiene más sentido: elegir el método de
   pago es "1 de 2 opciones para lo mismo", no 2 botones a pantallas
   distintas — mismo patrón que el resto del checkout ya usa para eso.
   #culqi-metodo-toggle NO es hijo de .item-grupo-valor (ese selector
   scopeado es de items.css, pensado para el paso 1) — se redeclara el
   mismo tamaño/pastilla acá para no depender de ese contexto. La
   pastilla en sí (posición/ancho) la mueve _posicionarPillToggle()
   (items.js, ya compartida por Entrega/Impresión) desde
   elegirMetodoPagoCulqi(). */
#culqi-metodo-toggle {
  position: relative;
  display: flex;
  width: 100%;
  height: 44px;
  padding: 3px;
  margin-bottom: 12px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  gap: 3px;
}
#culqi-metodo-toggle .toggle-sino-btn {
  position: relative;
  z-index: 1;
  flex: 1;
  border: none;
  background: transparent;
  border-radius: calc(var(--radio-md) - 3px);
  font-family: 'DM Sans', sans-serif;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--texto-mid);
  cursor: pointer;
  transition: color 0.35s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
#culqi-metodo-toggle .toggle-sino-btn:hover:not(.activo) { color: var(--acento); }
#culqi-metodo-toggle .toggle-sino-btn.activo { color: #fff; font-weight: 700; transform: scale(1); }
#culqi-metodo-toggle .toggle-sino-btn:not(.activo) { transform: scale(0.98); }
/* Bug real 2026-08-27 (Frank: "aquí crece toda la página y aquí solo
   crece el pop up") — #modal-reclamaciones reusa la clase genérica .modal
   (la del wizard de checkout), que en desktop NO tiene max-height/scroll
   propio (a diferencia de .about-popup, que sí trae max-height:80vh +
   overflow-y:auto — ver arriba). Con un formulario tan largo, crecía sin
   límite y terminaba scrolleando la PÁGINA entera en vez de solo el
   popup. Fix acotado a este modal específico — no toca el .modal del
   checkout, que ya maneja su propio scroll en #paso1-4. */
#modal-reclamaciones {
  max-height: 85vh;
  overflow-y: auto;
}
/* Scrollbar personalizado (Frank: "es personalizable?", y después "está
   más feo" con la primera versión sólida/gruesa — así lo resuelven los
   sitios modernos: una línea delgada y semitransparente, casi invisible
   en reposo, que se marca más recién al pasar el mouse — no una barra
   sólida todo el tiempo). Reemplaza el intento anterior (mismo patrón que
   wizard.css .wz-modal, mismo grosor/color sólido — se veía pesado acá). */
#modal-reclamaciones,
.about-popup {
  scrollbar-width: thin;                                    /* Firefox */
  scrollbar-color: rgba(26, 122, 176, 0.25) transparent;    /* Firefox */
}
#modal-reclamaciones::-webkit-scrollbar,
.about-popup::-webkit-scrollbar {
  width: 6px;
}
#modal-reclamaciones::-webkit-scrollbar-track,
.about-popup::-webkit-scrollbar-track {
  background: transparent;
}
#modal-reclamaciones::-webkit-scrollbar-thumb,
.about-popup::-webkit-scrollbar-thumb {
  background: rgba(26, 122, 176, 0.25);
  border-radius: 8px;
  /* border transparente + background-clip "hunde" visualmente el thumb,
     separándolo del borde/esquina redondeada del modal en vez de tocarla. */
  border: 2px solid transparent;
  background-clip: padding-box;
}
#modal-reclamaciones:hover::-webkit-scrollbar-thumb,
.about-popup:hover::-webkit-scrollbar-thumb {
  background: rgba(26, 122, 176, 0.55);
  background-clip: padding-box;
}
#modal-reclamaciones::-webkit-scrollbar-thumb:hover,
.about-popup::-webkit-scrollbar-thumb:hover {
  background: var(--acento);
  background-clip: padding-box;
}

.overlay.open {
  display: flex;
  opacity: 1;
  animation: appFadeIn var(--dur-base) var(--ease-out);
}
/* El modal "hace pop" cuando se abre: scale+fade con resort suave. */
.overlay.open .modal {
  animation: appScaleIn var(--dur-base) var(--ease-out);
}
.overlay.is-leaving {
  display: flex;
  opacity: 0;
  animation: appFadeOut var(--dur-base) var(--ease-out);
}
.overlay.is-leaving .modal {
  animation: appScaleOut var(--dur-base) var(--ease-out);
}

/* Botón "Agregar otro producto" — en el espacio en blanco del paso 1,
   entre la card y el footer. */
.paso1-agregar-btn {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 14px auto 0;
  padding: 10px 22px;
  background: transparent;
  border: 1.5px solid var(--borde-mid, var(--borde-activo));
  border-radius: var(--radio-full);
  color: var(--acento);
  font-size: 14px;
  font-weight: 600;
  font-family: 'DM Sans', sans-serif;
  cursor: pointer;
  transition: all 0.15s;
  line-height: 1;
  white-space: nowrap;
}
.paso1-agregar-btn svg {
  display: inline-block;
  flex-shrink: 0;
  vertical-align: middle;
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.paso1-agregar-btn:hover {
  background: var(--acento-tenue);
  border-style: solid;
  border-color: var(--acento);
}
.paso1-agregar-btn:hover svg { transform: rotate(180deg) scale(1.15); }
.paso1-agregar-btn:active { transform: scale(0.98); }
/* Centrar horizontalmente dentro del paso1 */
#paso1 { display: flex; flex-direction: column; align-items: center; }
#paso1 .items-container { width: 100%; }
#paso1 .paso1-agregar-btn { align-self: center; }

/* Transición al avanzar/retroceder entre pasos (irPaso en navegacion.js).
   Frank: el slide horizontal "se ve mal, no tiene sentido" dentro de un
   modal angosto (choca contra los bordes) — un fade+lift vertical sutil
   es el patrón estándar para pasos dentro de un modal (mismo criterio que
   Stripe/Shopify), y no depende de calcular dirección adelante/atrás. */
#paso1, #paso2, #paso3, #paso4 {
  transition: opacity 0.2s ease, transform 0.2s ease;
}
#paso1.paso-saliendo, #paso2.paso-saliendo, #paso3.paso-saliendo, #paso4.paso-saliendo {
  opacity: 0;
  transform: translateY(-6px);
}
#paso1.paso-entrando, #paso2.paso-entrando, #paso3.paso-entrando, #paso4.paso-entrando {
  opacity: 0;
  transform: translateY(10px);
  transition: none;
}

.modal {
  background: var(--surface);
  border-radius: 20px;
  width: 100%;
  max-width: 560px;
  margin: auto;
  overflow: visible;
  box-shadow: 0 24px 64px rgba(10,25,50,0.2);
  display: flex;
  flex-direction: column;
}

.modal-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--borde);
}

.modal-hdr-titulo {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--acento);
  text-transform: uppercase;
  user-select: none;
}

/* Precio junto al título del modal */
.modal-hdr-right {
  display: flex;
  align-items: center;
  gap: 14px;
}
.modal-hdr-precio {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  color: var(--acento);
  font-weight: 800;
  font-size: 36px;
  letter-spacing: -0.03em;
  line-height: 1;
}
/* Live price update: cuando el total cambia (millares, acabado, boleado…)
   el span del número anima un breve pulse para confirmar visualmente que
   "tu acción se reflejó en el precio". Sin esto el cambio pasa
   desapercibido aunque el número ya esté actualizado.
   Inspirado en Vistaprint / Sticker Mule / Canva configurators. */
.modal-hdr-precio.precio-cambio,
.modal-hdr-precio .precio-cambio {
  /* No queremos animar el contenedor entero — solo el número */
}
@keyframes precioPulse {
  0%   { transform: scale(1);    color: var(--acento); }
  40%  { transform: scale(1.10); color: var(--exito); }
  100% { transform: scale(1);    color: var(--acento); }
}
#modal-footer-total-num.precio-cambio,
.item-card-precio-num.precio-cambio {
  display: inline-block;             /* sin esto, transform no se aplica */
  animation: precioPulse 320ms var(--ease-out);
  transform-origin: right center;
  will-change: transform, color;
}
@media (prefers-reduced-motion: reduce) {
  #modal-footer-total-num.precio-cambio,
  .item-card-precio-num.precio-cambio {
    animation: none;
  }
}

.modal-hdr-precio small {
  font-size: 17px;
  font-weight: 600;
  color: var(--texto-tenue);
}

.modal-close {
  background: var(--modal-bg);
  border: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-size: 17px;
  color: var(--texto-tenue);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
  line-height: 1;
}
.modal-close:hover { background: var(--borde); color: var(--texto); }

/* Barra de progreso */
.step-bar {
  display: flex;
  gap: 3px;
  padding: 0 1.25rem 0;
  background: var(--surface);
  border-bottom: 1px solid var(--borde);
  height: 3px;
  overflow: hidden;
}
.step-seg        { height: 3px; flex: 1; background: var(--borde); transition: background 0.4s; }
.step-seg.active { background: var(--acento); }
.step-seg.done   { background: var(--borde-activo); }

.modal-body {
  padding: 0.75rem 1rem 0.5rem;
  background: var(--surface);
}

.modal-footer {
  padding: 10px 20px 12px;
  background: var(--surface);
  border-top: 1.5px solid var(--borde);
  border-bottom-left-radius: 20px;
  border-bottom-right-radius: 20px;
  flex-shrink: 0;
}
#btn-siguiente {
  padding: 14px 28px;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 600;
}

/* ============================================================
   FORMULARIOS — paso datos
   ============================================================ */
.eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  display: block;
  text-align: center;
  margin-bottom: 0.35rem;
  user-select: none;
}

.modal-step-title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-bottom: 1.25rem;
  line-height: 1.15;
  text-align: center;
  color: var(--texto);
  user-select: none;
}

.form-group { margin-bottom: 1.1rem; }
.form-label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texto-mid);
  margin-bottom: 7px;
  /* Mismo motivo que .item-grupo-label (items.css): son etiquetas de UI
     ("MATERIAL", "TU NOMBRE", etc.), no contenido para seleccionar. */
  user-select: none;
}
/* En el modal de pedido, "Tus datos"/"Entrega" tienen que verse como la
   MISMA familia visual que "Producto"/"Tamaño" del paso 1 — mismo tamaño de
   label, mismo letter-spacing, mismo ritmo entre grupos. Antes diferían un
   poco (13px/0.06em/17.6px de separación acá vs. 12px/0.08em/10px allá) —
   suficiente para que un ojo atento notara que "no es el mismo sistema".
   Escopeado al modal de pedido para no tocar el form-label del portal de
   cliente (js/app/cliente.js), que es una pantalla distinta. */
/* #modal-personalizado (impresión personalizada) comparte estas reglas a
   propósito — Frank 2026-08-22: "formulario en tamaño y colores
   completamente igual al formulario de diseño y producto". */
#modal-pedido .form-group, #modal-personalizado .form-group { margin-bottom: 10px; }
#modal-pedido .form-label, #modal-personalizado .form-label { font-size: 12px; letter-spacing: 0.08em; margin-bottom: 3px; }
.form-label-req {
  color: var(--error, #dc2626);
  font-weight: 700;
  margin-left: 2px;
}
.form-hint {
  font-size: 13px;
  color: var(--texto-tenue);
  margin-bottom: 6px;
  font-style: italic;
}

/* Label con info contextual: reemplaza los form-hint que antes estaban
   siempre visibles (ocupaban 2 líneas fijas por campo) por texto que
   aparece solo al pasar el mouse SOBRE EL LABEL MISMO (desktop) o al
   tocarlo (mobile, sin hover real — se autocierra solo) — sin ícono aparte
   (Frank 2026-08-21: "quita el signo de interrogación"). */
.form-info-wrap {
  position: relative;
  display: inline;
  cursor: help;
}
.form-info-popover {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  width: 280px;
  max-width: min(280px, 82vw);
  background: var(--surface);
  border: 1.5px solid var(--borde-activo);
  border-radius: var(--radio-md);
  box-shadow: 0 12px 32px rgba(15, 45, 94, 0.18);
  padding: 9px 12px;
  font-size: 11px;
  font-weight: 400;
  font-style: normal;
  line-height: 1.4;
  color: var(--texto);
  text-align: justify;
  z-index: 20;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s, visibility 0.15s;
  pointer-events: none;
}
.form-info-wrap:hover .form-info-popover,
.form-info-wrap.visible .form-info-popover {
  opacity: 1;
  visibility: visible;
}
.form-info-popover::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 8px;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--borde-activo);
}
.form-input {
  width: 100%;
  font-size: 16px;
  color: var(--texto);
  background: var(--surface);
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  padding: 11px 14px;
  transition: border-color 0.15s;
  outline: none;
}
.form-input:focus        { border-color: var(--acento); }
.form-input::placeholder { color: var(--texto-tenue); opacity: 0.6; }
.form-input.input-ok     { border-color: #86CEAB; }
.form-input.input-error  { border-color: #E8A0A0; }

.form-input-prefix {
  display: flex;
  align-items: center;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  overflow: hidden;
  transition: border-color 0.15s;
}
.form-input-prefix:focus-within { border-color: var(--acento); }
.form-prefix {
  background: var(--modal-bg);
  border-right: 1.5px solid var(--borde);
  padding: 11px 14px;
  font-size: 16px;
  color: var(--texto-mid);
  font-weight: 500;
  white-space: nowrap;
}
.form-input-prefix .form-input        { border: none; border-radius: 0; padding: 11px 14px; }
.form-input-prefix .form-input:focus  { border: none; }

/* ============================================================
   RESUMEN DE PEDIDO
   ============================================================ */
.resumen-card {
  background: var(--modal-bg);
  border: 1px solid var(--borde);
  border-radius: var(--radio-lg);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}
.resumen-row { display: flex; justify-content: space-between; font-size: 15px; padding: 4px 0; }
.resumen-row span:first-child { color: var(--texto-mid); }
.resumen-row span:last-child  { font-weight: 500; }
.resumen-divider { height: 1px; background: var(--borde); margin: 10px 0; }
.resumen-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 16px;
  font-weight: 700;
  padding-top: 4px;
}
.resumen-total-precio {
  font-size: 20px;
  font-weight: 700;
  color: var(--acento);
  letter-spacing: -0.03em;
}

/* ============================================================
   ENTREGA — paso 2
   ============================================================ */
.entrega-wrap { margin-bottom: 1.1rem; }

/* Separa visualmente las dos secciones de "Datos y envío": arriba lo que
   cambia según el tipo de entrega elegido, abajo "Tus datos" que es
   siempre lo mismo (nombre + WhatsApp) sin importar la opción — antes
   corría todo junto como un solo bloque sin quiebre (Frank 2026-08-21). */
/* El label ES la separación — no una línea arriba y el texto abajo, sino
   una sola línea partida por el texto centrado (Frank 2026-08-21: "que
   ella misma sea la separación"). */
.paso-seccion-divisor {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  color: var(--texto-tenue);
}
.paso-seccion-divisor::before,
.paso-seccion-divisor::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--borde);
}

/* Pista única de 3 segmentos — mismo patrón que el switch Producto del
   paso 1 (.item-toggle-sino/.toggle-sino-btn): un solo contenedor con
   borde, los 3 botones adentro SIN borde propio. Antes eran 3 píldoras
   sueltas con su propio borde cada una — otra inconsistencia visual entre
   pasos (Frank: "que sea un toggle de 3", no 3 botones separados). */
.entrega-toggle {
  position: relative;
  display: flex;
  width: 100%;
  padding: 3px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  gap: 3px;
  margin-top: 6px;
  margin-bottom: 10px;
}

/* Pastilla que se DESLIZA de una posición a otra (izq/centro/der) — un
   segmented control de verdad, no 3 botones que cambian de color cada uno
   en su lugar (Frank 2026-08-21: "que se sienta como un verdadero toggle
   de 3 opciones"). Se posiciona por JS con left/width en px, medidos del
   botón activo real (_actualizarPillEntrega en app/entrega.js) — más
   confiable que calcular tercios con CSS puro, porque "Provincias" es más
   angosto que "Recojo en tienda" y los anchos no son exactamente iguales. */
.entrega-toggle-pill {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: 0;
  background: var(--acento);
  border-radius: calc(var(--radio-md) - 3px);
  box-shadow: 0 2px 8px rgba(15,45,94,0.22);
  transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1), width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 0;
}
.entrega-toggle-pill.sin-transicion { transition: none; }

.entrega-btn {
  position: relative;
  z-index: 1;
  flex: 1;
  padding: 8px 10px;
  border: none;
  border-radius: calc(var(--radio-md) - 3px);
  background: transparent;
  font-size: 15px;
  font-weight: 600;
  color: var(--texto-mid);
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  transition: color 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.entrega-btn:hover:not(.active) { color: var(--acento); }
.entrega-btn.active { color: #fff; font-weight: 600; }
.entrega-btn-sub {
  display: block;
  font-size: 12px;
  font-weight: 400;
  opacity: 0.7;
  margin-top: 1px;
}

.entrega-sub { margin-top: 4px; }

.entrega-costo {
  font-size: 15px;
  color: var(--texto-mid);
  margin-top: -4px;
  margin-bottom: 1rem;
}
.entrega-costo strong { color: var(--acento); }

.inp-direccion-wrap {
  position: relative;
  width: 100%;
}

/* ── Autocompletado de ciudades ── */
.ciudad-dropdown {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  background: var(--surface);
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  box-shadow: var(--sombra-md);
  z-index: 9999;
  max-height: 200px;
  overflow-y: auto;
}
.ciudad-item {
  padding: 8px 12px;
  font-size: 15px;
  color: var(--texto-mid);
  cursor: pointer;
  border-bottom: 1px solid var(--borde);
}
.ciudad-item:last-child { border-bottom: none; }
.ciudad-item:hover { background: var(--acento-tenue); color: var(--acento); }
.ciudad-item strong { color: var(--acento); font-weight: 700; }

.places-dropdown {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  background: var(--surface);
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  box-shadow: var(--sombra-md);
  z-index: 9999;
  max-height: 200px;
  overflow-y: auto;
  /* Togglea con dropdown.style.display = 'block'/'none' directo (entrega.js
     filtrarCiudades, maps.js initAutocomplete/initAutocompleteAgencia) —
     no hace falta tocar ese JS: la animación en la regla base ya se dispara
     sola cada vez que el elemento pasa de display:none a block, mismo
     mecanismo que .prod-dd.abierto .prod-dd-list. No se re-dispara en cada
     tecla porque re-asignar el mismo valor 'block' no regenera la caja. */
  animation: appFadeInDown 0.18s ease-out;
}
.places-item {
  padding: 10px 14px;
  font-size: 15px;
  color: var(--texto-mid);
  cursor: pointer;
  border-top: 1px solid var(--borde);
}
.places-item:first-child { border-top: none; }
.places-item:hover { background: var(--acento-tenue); color: var(--texto); }

.entrega-costo-nd {
  font-size: 14px;
  color: var(--texto-tenue);
  margin-top: -4px;
  margin-bottom: 1rem;
}
.entrega-costo-error {
  font-size: 14px;
  color: var(--error);
  font-weight: 600;
  background: #FEF2F2;
  border: 1px solid #FCA5A5;
  border-radius: var(--radio-md);
  padding: 8px 12px;
  margin-top: 4px;
  margin-bottom: 1rem;
}
.entrega-fuera {
  background: #FEF2F2;
  border: 1px solid #FCA5A5;
  border-radius: var(--radio-md);
  padding: 12px 14px;
  margin-top: 6px;
  margin-bottom: 1rem;
}
.entrega-fuera-titulo {
  font-size: 15px;
  font-weight: 700;
  color: var(--error);
  margin-bottom: 4px;
}
.entrega-fuera-texto {
  font-size: 14px;
  color: var(--texto-mid);
  line-height: 1.5;
  margin-bottom: 10px;
}
.entrega-fuera-btn {
  display: block;
  width: 100%;
  background: var(--acento);
  color: #fff;
  border: none;
  border-radius: var(--radio-md);
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  transition: background 0.15s;
}
.entrega-fuera-btn:hover { background: var(--acento-hover); }

.tienda-info {
  background: var(--modal-bg);
  border: 1px solid var(--borde);
  border-radius: var(--radio-md);
  padding: 12px 14px;
  margin-top: 4px;
  text-align: center;
}
.tienda-info-dir {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 15px;
  color: var(--texto-mid);
  margin-bottom: 6px;
}
.tienda-info-mapa {
  background: none;
  border: none;
  padding: 0;
  font-family: 'DM Sans', sans-serif;
  font-size: 14px;
  color: var(--acento);
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}
.tienda-info-mapa:hover { text-decoration: underline; }

.link-mapa {
  background: none;
  border: none;
  padding: 0;
  margin-top: 6px;
  font-size: 14px;
  color: var(--texto-tenue);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  font-family: 'DM Sans', sans-serif;
  display: block;
}
.link-mapa:hover { color: var(--acento); }

/* Popup del mapa de Delivery — mismo patrón que .confirm-modal-overlay
   (usado también por el mapa de agencia en Provincias, abrirMapaAgencia):
   overlay fijo, card centrada. La diferencia es que ACÁ el mapa sigue
   siendo el SDK interactivo de Google Maps (el cliente clickea/arrastra el
   pin), no un iframe estático — por eso no se pudo reusar abrirMapaAgencia
   tal cual, solo su mismo lenguaje visual de popup. */
.mapa-picker-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 45, 94, 0.40);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 600;
  padding: 1rem;
}
.mapa-picker-overlay.hidden { display: none; }
.mapa-picker-popup {
  background: var(--surface);
  border-radius: var(--radio-xl);
  width: 100%;
  max-width: 480px;
  padding: 1rem;
  box-shadow: 0 20px 60px rgba(10,25,50,0.25);
}
.mapa-picker-popup-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.mapa-picker-popup-hdr strong { font-size: 15px; color: var(--texto); }
.mapa-picker-cerrar {
  background: none;
  border: none;
  font-size: 22px;
  color: var(--texto-tenue);
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.mapa-picker-cerrar:hover { color: var(--texto); }

#mapa-picker {
  width: 100%;
  height: 260px;
  border-radius: var(--radio-md);
  border: 1.5px solid var(--borde);
  margin-bottom: 6px;
  overflow: hidden;
}
.mapa-hint {
  font-size: 13px;
  color: var(--texto-tenue);
  text-align: center;
  margin-bottom: 0.75rem;
}


.form-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
/* Guardia necesaria desde que #pers-acabado-separado-wrap combina esta
   clase con el atributo [hidden]: display:grid de arriba es un selector
   de autor, así que le gana al [hidden]{display:none} nativo del User
   Agent aunque tengan la misma especificidad (los estilos de autor SIEMPRE
   ganan sobre los de UA) — sin esto, el atributo hidden queda ignorado y
   la fila se ve igual. Mismo bug ya visto varias veces este mismo día. */
.form-row-2[hidden] { display: none !important; }

/* Pastilla Sí/No para "Impresión" (1 lado / 2 lados) del formulario de
   "Impresión personalizada" — mismo componente visual que .item-toggle-sino
   de items.css (Tarjeta/Volante, Boleado), pero ESE está scoped con un
   selector de hijo directo (.item-grupo-valor > .item-toggle-sino) pensado
   para la tarjeta de ítem del pedido real. Acá el toggle vive directo
   dentro de un .form-group de este modal — copia desacoplada en vez de
   forzar el mismo selector frágil fuera de su contexto (ver el bug real ya
   documentado de envolver .item-toggle-sino y romper el pill). */
#pers-impresion-toggle {
  position: relative;
  display: flex;
  width: 100%;
  height: 38px;
  padding: 3px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  gap: 3px;
}
#pers-impresion-toggle .toggle-sino-btn {
  position: relative;
  z-index: 1;
  flex: 1;
  border: none;
  background: transparent;
  border-radius: calc(var(--radio-md) - 3px);
  font-family: 'DM Sans', sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--texto-mid);
  cursor: pointer;
  transition: color 0.35s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
#pers-impresion-toggle .toggle-sino-btn:hover:not(.activo) { color: var(--acento); }
#pers-impresion-toggle .toggle-sino-btn.activo { color: #fff; font-weight: 700; transform: scale(1); }
#pers-impresion-toggle .toggle-sino-btn:not(.activo) { transform: scale(0.98); }

/* Mismos 2 toggles (Tipo, Producto/Servicio) del Libro de Reclamaciones
   (2026-08-26) — copia desacoplada idéntica a #pers-impresion-toggle de
   arriba, mismo motivo exacto: viven sueltos dentro de un .form-group, no
   bajo .item-grupo-valor, así que el selector genérico de items.css
   (.item-grupo-valor > .item-toggle-sino) no los alcanza (Frank: "falta
   css" — se veían como checkboxes planos sin pastilla). */
#rec-tipo-toggle, #rec-bien-toggle {
  position: relative;
  display: flex;
  width: 100%;
  height: 38px;
  padding: 3px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  gap: 3px;
}
#rec-tipo-toggle .toggle-sino-btn, #rec-bien-toggle .toggle-sino-btn {
  position: relative;
  z-index: 1;
  flex: 1;
  border: none;
  background: transparent;
  border-radius: calc(var(--radio-md) - 3px);
  font-family: 'DM Sans', sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--texto-mid);
  cursor: pointer;
  transition: color 0.35s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
#rec-tipo-toggle .toggle-sino-btn:hover:not(.activo), #rec-bien-toggle .toggle-sino-btn:hover:not(.activo) { color: var(--acento); }
#rec-tipo-toggle .toggle-sino-btn.activo, #rec-bien-toggle .toggle-sino-btn.activo { color: #fff; font-weight: 700; transform: scale(1); }
#rec-tipo-toggle .toggle-sino-btn:not(.activo), #rec-bien-toggle .toggle-sino-btn:not(.activo) { transform: scale(0.98); }

/* Precio en vivo del formulario "Impresión personalizada" — ver
   _actualizarPrecioPersonalizado/_renderTiersPersonalizado en
   app/popups.js. Vive en .modal-footer (flex-shrink:0, siempre visible)
   justo arriba del botón Continuar. Rediseño 2026-08-24 (2da vuelta, Frank:
   "le falta trabajar mucho a esa sección de presentación") — tarjeta
   blanca con sombra propia (se despega del formulario en vez de fundirse
   con el fondo azulado), badges de ahorro en verde para que "Mejores
   cotizaciones" tenga un motivo concreto y no solo números, input de
   cantidad exacta integrado como su propia fila con borde. */
.pers-precio-box {
  margin-bottom: 12px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-lg);
  box-shadow: 0 4px 14px rgba(15, 45, 94, 0.08);
}
.pers-precio-header-label {
  display: block;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--acento);
  margin-bottom: 10px;
}
.pers-tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: 8px;
}
.pers-tier {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 6px 9px;
  background: var(--acento-tenue);
  border: 1.5px solid transparent;
  border-radius: var(--radio-md);
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  transition: border-color 0.2s, background 0.2s, transform 0.15s, box-shadow 0.2s;
}
.pers-tier:hover {
  border-color: var(--borde-activo);
  transform: translateY(-2px);
  box-shadow: 0 3px 10px rgba(15, 45, 94, 0.12);
}
.pers-tier-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--texto-tenue);
  background: var(--surface);
  border-radius: 999px;
  padding: 2px 8px;
  margin-bottom: 2px;
}
.pers-tier-badge.pers-tier-badge-ahorro { color: #fff; background: var(--exito); }
.pers-tier-millares { font-size: 12px; font-weight: 600; color: var(--texto-mid); }
.pers-tier-precio { font-size: 15px; font-weight: 800; color: var(--texto); }
.pers-tier-precio small { font-size: 10px; font-weight: 600; opacity: 0.7; }
/* Score de aprovechamiento (2026-08-24) — cuánto del pliego usan
   realmente las piezas del cliente en ESTE escalón, inspirado en el
   feedback de "diseño para fabricación" de plataformas tipo Xometry: no
   solo dar el precio, mostrar por qué una medida rinde más o menos. */
.pers-tier-aprovechamiento {
  font-size: 10px;
  font-weight: 600;
  color: var(--texto-tenue);
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}
.pers-tier.pers-tier-activo {
  background: var(--acento);
  border-color: var(--acento);
  box-shadow: 0 3px 10px rgba(15, 45, 94, 0.2);
}
.pers-tier.pers-tier-activo .pers-tier-millares { color: rgba(255,255,255,0.75); }
.pers-tier.pers-tier-activo .pers-tier-precio { color: #fff; }
.pers-tier.pers-tier-activo .pers-tier-badge:not(.pers-tier-badge-ahorro) { background: rgba(255,255,255,0.2); color: #fff; }
.pers-tier.pers-tier-activo .pers-tier-badge-ahorro { background: #fff; color: var(--exito); }
.pers-tier.pers-tier-activo .pers-tier-aprovechamiento { color: rgba(255,255,255,0.7); }

/* Caja horizontal aparte (probado como tarjeta integrada en la grilla y
   revertido — Frank: "funcionaba mejor la anterior", 2026-08-24). Conserva
   el estado "activo" del experimento: se pinta azul, igual que un
   escalón elegido, cuando ES la selección actual — para que se sienta
   parte de la misma familia de controles aunque viva en su propia fila. */
.pers-precio-custom {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
  padding: 8px 12px;
  background: var(--acento-tenue);
  border: 1.5px dashed var(--borde);
  border-radius: var(--radio-md);
  transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
}
.pers-precio-custom:focus-within { border-color: var(--borde-activo); }
.pers-precio-custom label {
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-mid);
}
.pers-precio-custom input {
  width: 60px;
  padding: 6px 8px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-sm);
  background: var(--surface);
  color: var(--texto);
  font-family: 'DM Sans', sans-serif;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}
.pers-precio-custom input:focus { outline: none; border-color: var(--borde-activo); background: #fff; }
/* Activa (el cliente está usando ESTE valor, no un escalón preestablecido)
   — mismo tratamiento azul que .pers-tier-activo. */
.pers-precio-custom.pers-precio-custom-activo {
  background: var(--acento);
  border-color: var(--acento);
  border-style: solid;
  box-shadow: 0 3px 10px rgba(15, 45, 94, 0.15);
}
.pers-precio-custom.pers-precio-custom-activo label { color: rgba(255,255,255,0.8); }
.pers-precio-custom.pers-precio-custom-activo input {
  background: rgba(255,255,255,0.15);
  border-color: rgba(255,255,255,0.4);
  color: #fff;
}
/* Quita las flechitas nativas del <input type=number> — Frank 2026-08-24:
   "quitar esas flechas horribles". */
.pers-precio-custom input::-webkit-outer-spin-button,
.pers-precio-custom input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.pers-precio-custom input[type='number'] { -moz-appearance: textfield; }

.pers-precio-minimo-nota {
  margin: 8px 4px 0;
  padding: 6px 10px;
  background: var(--acento-tenue);
  border-radius: var(--radio-sm);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--texto-mid);
  text-align: center;
}

/* "¿Buscas otra cosa?" (Paso 1 de 4, personalizado) — 3ra vuelta,
   2026-08-27: bajo el botón Continuar, dentro de .modal-footer, así
   queda siempre visible como último recurso sin competir con el
   formulario ni el precio. */
.pers-otra-cosa-inline {
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--texto-tenue);
  text-align: center;
}
.pers-otra-cosa-inline a {
  color: var(--acento);
  font-weight: 600;
  text-decoration: underline;
}

.pers-precio-total {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--borde);
}
/* El precio por millar es el número protagonista (lo que de verdad cambia
   al mover la cantidad) — el Total queda como dato chico de referencia.
   Frank 2026-08-24: "cuando aumento el número me debe salir el precio por
   x millar que estoy pagando y el total más pequeño". */
.pers-precio-porUnidad {
  font-size: 22px;
  font-weight: 800;
  color: var(--texto);
}
.pers-precio-porUnidad small { font-size: 12px; font-weight: 600; color: var(--texto-tenue); }
.pers-precio-totalChico {
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-tenue);
}
.pers-precio-aprovechamiento {
  font-size: 11px;
  font-weight: 600;
  color: var(--texto-tenue);
  margin-top: 2px;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}

/* Diagrama "¿Cómo se aprovecha tu pedido?" — ver _abrirGeometriaPanol en
   app/popups.js (2026-08-24). Overlay/modal aparte, más angosto que el
   modal estándar (es solo un dibujo + 2 datos, no un formulario). */
.modal-geometria { max-width: 360px; }
.geometria-dibujo {
  display: flex;
  justify-content: center;
  padding: 14px 6px 4px;
}
.geometria-svg {
  width: 100%;
  max-width: 260px;
  height: auto;
}
.geometria-hoja { fill: var(--surface); }
.geometria-hoja-borde { fill: none; stroke: var(--borde-mid, var(--borde)); stroke-width: 0.6; }
.geometria-hatch-fondo { fill: var(--acento-tenue); }
.geometria-hatch-linea { stroke: var(--borde); }
.geometria-pieza { fill: var(--acento); }
/* Doble cara (2026-08-24) — 2 tonos del mismo azul para separar el grupo
   "Adelante" del "Atrás" (nunca las palabras internas "tira"/"retira",
   ver nota en popups.js). El tono de Atrás se aclaró 2026-08-26 (Frank:
   "la diferencia de colores fallan" — el #6E9BC7 anterior quedaba
   demasiado parecido al azul oscuro de Adelante a simple vista, sobre
   todo en piezas chicas). */
.geometria-pieza-a { fill: var(--acento); }
.geometria-pieza-b { fill: #9DBEDD; }
.geometria-etiqueta {
  fill: #fff;
  font-family: 'DM Sans', sans-serif;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: middle;
  pointer-events: none;
}

.geometria-leyenda {
  display: flex;
  justify-content: center;
  gap: 18px;
  margin-top: 6px;
}
.geometria-leyenda-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-mid);
}
.geometria-swatch {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  display: inline-block;
}
.geometria-swatch-usado { background: var(--acento); }
.geometria-swatch-adelante { background: var(--acento); }
.geometria-swatch-atras { background: #9DBEDD; }
.geometria-swatch-libre { background: var(--acento-tenue); border: 1px solid var(--borde); }

.geometria-stats {
  display: flex;
  justify-content: center;
  gap: 28px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--borde);
}
.geometria-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.geometria-stat-num {
  font-size: 20px;
  font-weight: 800;
  color: var(--texto);
}
.geometria-stat span:last-child {
  font-size: 11px;
  font-weight: 600;
  color: var(--texto-tenue);
  text-align: center;
}
.geometria-nota {
  margin: 10px 4px 2px;
  padding: 8px 10px;
  background: var(--acento-tenue);
  border-radius: var(--radio-sm);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--texto-mid);
  text-align: center;
}

/* "No cabe, pero prueba con esta medida" — ver _mostrarSugerenciaNoCabe
   en app/popups.js. Misma tarjeta blanca con sombra que .pers-precio-box
   (consistencia), con un ícono de aviso para que se lea como "esto tiene
   arreglo", no como un error duro. */
.pers-precio-nocabe {
  margin-bottom: 12px;
  padding: 16px;
  background: var(--surface);
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-lg);
  box-shadow: 0 4px 14px rgba(15, 45, 94, 0.08);
  text-align: center;
}
.pers-nocabe-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin: 0 auto 8px;
  border-radius: 50%;
  background: var(--acento-tenue);
  color: var(--acento);
}
.pers-nocabe-texto {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--texto-mid);
  margin-bottom: 12px;
}
.pers-nocabe-sugerencia {
  padding: 9px 18px;
  background: var(--acento);
  border: none;
  border-radius: var(--radio-md);
  color: #fff;
  font-family: 'DM Sans', sans-serif;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.2s, transform 0.15s;
}
.pers-nocabe-sugerencia:active { transform: scale(0.97); }
.pers-nocabe-sugerencia:hover { background: var(--acento-hover); }

/* ============================================================
   CONFIRMACIÓN
   ============================================================ */
.confirm-wrap { text-align: center; padding: 1.5rem 0 0.5rem; }
.confirm-icon {
  width: 64px;
  height: 64px;
  background: var(--acento-tenue);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1.25rem;
}
.confirm-titulo { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 4px; color: var(--texto); }
.confirm-codigo {
  font-size: 20px;
  font-weight: 700;
  color: var(--acento);
  letter-spacing: 0.03em;
  margin-bottom: 8px;
}
.confirm-sub { font-size: 15px; color: var(--texto-mid); line-height: 1.6; margin-bottom: 1.25rem; }
.confirm-acciones {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.confirm-accion-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 10px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  font-size: 15px;
  font-weight: 500;
  color: var(--texto-mid);
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  text-decoration: none;
  transition: all 0.15s;
}
.confirm-accion-btn:hover { border-color: var(--acento); color: var(--acento); }
.confirm-accion-wsp { background: #25D366; border-color: #25D366; color: #fff; font-weight: 600; }
.confirm-accion-wsp:hover { background: #1DA851; border-color: #1DA851; color: #fff; }

/* ============================================================
   UTILIDADES
   ============================================================ */
.hidden  { display: none !important; }
.w-full  { width: 100%; }
.mt-1    { margin-top: 0.5rem; }
.mt-2    { margin-top: 1rem; }
.mt-3    { margin-top: 1.5rem; }
.mb-1    { margin-bottom: 0.5rem; }
.mb-2    { margin-bottom: 1rem; }

.terminos-check {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 14px;
  color: var(--texto-mid);
  cursor: pointer;
  margin-bottom: 10px;
}
.terminos-link {
  color: var(--acento);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.terminos-link:hover { color: var(--acento-hover); }
.terminos-shake {
  animation: shake 0.5s ease;
  color: var(--error);
}
.terminos-shake .terminos-link { color: var(--error); }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

.terminos-popup {
  /* Más ancho que el .about-popup base (340px) — Frank 2026-08-23: "esto
     más ancho, cosa que nos evitamos la barra del costado". El texto legal
     es mucho más largo que "Sobre nosotros" (que sí le queda bien angosto
     y centrado); a 340px cada línea envolvía en 3-4 palabras, generando
     muchas más líneas de las necesarias y forzando el scroll vertical. */
  max-width: 520px;
  max-height: 80vh;
  overflow-y: auto;
}
.terminos-titulo {
  font-size: 20px;
  font-weight: 700;
  color: var(--texto);
  margin-bottom: 1rem;
}
.terminos-contenido p {
  font-size: 15px;
  color: var(--texto-mid);
  line-height: 1.6;
  margin-bottom: 0.75rem;
}
.terminos-contenido strong {
  color: var(--texto);
}

.cliente-switch {
  text-align: center;
  font-size: 14px;
  color: var(--texto-tenue);
  margin-top: 1rem;
}
.cliente-switch-btn {
  background: none;
  border: none;
  color: var(--acento);
  font-weight: 600;
  font-family: 'DM Sans', sans-serif;
  font-size: 14px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cliente-switch-btn:hover { color: var(--acento-hover); }
.verificacion-codigo {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--acento);
  background: var(--modal-bg);
  border: 2px solid var(--borde);
  border-radius: var(--radio-md);
  padding: 12px 24px;
  display: inline-block;
}

/* ── Acciones perfil ── */
.perfil-acciones {
  display: flex;
  gap: 6px;
  margin-bottom: 1.25rem;
}
.perfil-accion-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 6px;
  border: 1.5px solid var(--borde);
  border-radius: var(--radio-md);
  background: var(--surface);
  font-size: 13px;
  font-weight: 500;
  color: var(--texto-mid);
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  transition: all 0.15s;
  text-decoration: none;
}
.perfil-accion-btn:hover { border-color: var(--acento); color: var(--acento); }


/* ── Modal de confirmación (frontend, reemplaza confirm()) ── */
.confirm-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 45, 94, 0.40);   /* alineado con --overlay */
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 600;
  padding: 1rem;
  animation: appFadeIn var(--dur-base) var(--ease-out);
}
.confirm-modal-overlay.is-leaving {
  animation: appFadeOut var(--dur-base) var(--ease-out);
}
.confirm-modal {
  background: var(--surface);
  border-radius: var(--radio-xl);
  padding: 1.5rem;
  max-width: 340px;
  width: 100%;
  box-shadow: 0 20px 60px rgba(10,25,50,0.25);
  text-align: center;
  animation: appScaleIn var(--dur-base) var(--ease-out);
}
.confirm-modal-overlay.is-leaving .confirm-modal {
  animation: appScaleOut var(--dur-base) var(--ease-out);
}

/* ── Panel cliente ── */
.cliente-header { margin-bottom: 0.75rem; }
.cliente-pedido-card {
  background: var(--modal-bg);
  border: 1px solid var(--borde);
  border-radius: var(--radio-md);
  padding: 12px 14px;
  margin-bottom: 8px;
}
.cliente-pedido-hdr {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.cliente-pedido-codigo {
  font-size: 15px;
  font-weight: 700;
  color: var(--texto);
}
.cliente-pedido-estado {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  border-radius: var(--radio-full);
}
.estado-pendiente   { background: #FEF3C7; color: #92400E; }
.estado-produccion  { background: #DBEAFE; color: #1E40AF; }
.estado-listo       { background: #D1FAE5; color: #065F46; }
.estado-entregado   { background: #E5E7EB; color: #374151; }
.cliente-pedido-detalle {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: var(--texto-mid);
}
.cliente-pedido-precio { font-weight: 600; color: var(--texto); }
.cliente-pedido-entrega {
  font-size: 13px;
  color: var(--texto-tenue);
  margin-top: 2px;
}
.cliente-pedido-fecha {
  font-size: 13px;
  color: var(--texto-tenue);
  margin-top: 4px;
}

/* ── Perfil ── */
.perfil-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 1.25rem;
}
.perfil-avatar {
  width: 48px;
  height: 48px;
  background: var(--acento);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 700;
  flex-shrink: 0;
}
.perfil-nombre { font-size: 17px; font-weight: 700; color: var(--texto); }
.perfil-wsp { font-size: 14px; color: var(--texto-tenue); }
.perfil-stats {
  display: flex;
  gap: 0;
  margin-bottom: 1.25rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio-md);
  overflow: hidden;
}
.perfil-stat {
  flex: 1;
  text-align: center;
  padding: 10px 8px;
  border-right: 1px solid var(--borde);
}
.perfil-stat:last-child { border-right: none; }
.perfil-stat-num { display: block; font-size: 17px; font-weight: 700; color: var(--texto); }
.perfil-stat-label { font-size: 12px; color: var(--texto-tenue); text-transform: uppercase; letter-spacing: 0.05em; }

/* ── Timeline consulta ── */
.consulta-timeline {
  display: flex;
  justify-content: space-between;
  padding: 0 8px;
}
.consulta-paso {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--texto-tenue);
  position: relative;
  flex: 1;
}
.consulta-paso-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--borde);
  border: 2px solid var(--surface);
  z-index: 1;
}
.consulta-paso-done .consulta-paso-dot { background: var(--exito); }
.consulta-paso-done { color: var(--texto); font-weight: 600; }
.consulta-paso:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 5px;
  left: 50%;
  right: -50%;
  height: 2px;
  background: var(--borde);
  z-index: 0;
}
.consulta-paso-done:not(:last-child)::after { background: var(--exito); }

.error-msg {
  background: #FEF2F2;
  color: var(--error);
  font-size: 14px;
  padding: 8px 12px;
  border-radius: var(--radio-md);
  margin-bottom: 1rem;
  display: none;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 768px) {
  .overlay {
    align-items: flex-end;
    padding: 0;
    overflow: hidden;
  }
  .modal {
    margin: 0;
    max-width: 100%;
    width: 100%;
    border-radius: 0;
    max-height: 100dvh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
  }
  .modal::before { display: none; }
  .modal-hdr    { flex-shrink: 0; }
  .modal-body   { overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: center; }
  /* paso1 (producto y diseño), paso2 (entrega) y paso3 (datos) son
     formularios largos, no un mensaje corto — centrarlos verticalmente deja
     un hueco vacío arriba cuando el contenido no llena la pantalla, y da la
     sensación de una pantalla rota/a medio cargar (Frank: "se ve bien mal"
     en celular). paso4 (confirmación, contenido corto) sí queda centrado,
     que es donde tiene sentido. */
  #paso1.modal-body, #paso2.modal-body, #paso3.modal-body { justify-content: flex-start; }
  /* body + clase (más específico que el ".toast-error" solo de la regla base
     de más abajo en el archivo) — si no, el "top:20px" de esa regla base
     gana por venir después en el CSS, sin importar el @media. */
  body .toast-error { top: calc(env(safe-area-inset-top, 0px) + 68px); }
  .modal-footer { flex-shrink: 0; }
}

@media (max-width: 480px) {
  .form-input { font-size: 17px; }

  /* ── Modal ── */
  .modal-hdr { padding: 0.75rem 1rem; }
  .modal-hdr-titulo { font-size: 14px; }
  .modal-body { padding: 1rem; }
  .modal-footer { padding: 0.75rem 1rem 1rem; }
  .modal-step-title { font-size: 20px; margin-bottom: 1rem; }

  /* ── Resumen ── */
  .resumen-card { padding: 0.75rem; }
  .resumen-row { font-size: 14px; }
  .resumen-total { font-size: 15px; }
  .resumen-total-precio { font-size: 20px; }

  /* ── Entrega ── */
  .entrega-toggle { gap: 4px; }
  .entrega-btn { font-size: 15px; padding: 8px 8px; }
  .entrega-btn-sub { font-size: 12px; }
  .form-row-2 { gap: 6px; }
  .tienda-info { padding: 10px 12px; }

  /* ── Confirmación ── */
  .confirm-wrap { padding: 1rem 0 0.25rem; }
  .confirm-icon { width: 52px; height: 52px; margin-bottom: 1rem; }
  .confirm-titulo { font-size: 20px; }
  .confirm-codigo { font-size: 17px; }
  .confirm-sub { font-size: 14px; }
  .confirm-accion-btn { font-size: 14px; padding: 9px; }

  /* ── Perfil cliente ── */
  .perfil-avatar { width: 40px; height: 40px; font-size: 20px; }
  .perfil-nombre { font-size: 16px; }
  .perfil-stat-num { font-size: 16px; }
  .perfil-stat-label { font-size: 12px; }
  .perfil-acciones { gap: 4px; }
  .perfil-accion-btn { font-size: 12px; padding: 8px 4px; }
  .cliente-pedido-card { padding: 10px 12px; }

  /* ── Pago ── */
  .verificacion-codigo { font-size: 28px; padding: 10px 18px; }

  /* ── Mapa ── */
  #mapa-picker { height: 180px; }

  /* ── Términos ── */
  .terminos-check { font-size: 13px; }
  .terminos-popup { max-width: 92vw; }
}

/* ============================================================
   Puente en el modal de pedido → wizard de IA
   Aparece debajo de "Agregar otro producto" en el paso 1.
   ============================================================ */
.pedido-puente-ia {
  /* Ya no hay estado "default" (se sacó el CTA "Te lo diseñamos con IA" —
     esa decisión se confirma un paso antes, en el fork). El único contenido
     posible ahora es "Volver a editarlo", así que el puente entero arranca
     oculto y solo aparece cuando ESE hijo deja de estar hidden (ver la regla
     :has() más abajo, que es la que pone display:flex).
     OJO: no declarar acá otro `display` — un `display:flex` en ESTE bloque
     le ganaba SIEMPRE al `display:none` de arriba (misma especificidad,
     gana el que está después en la cascada), así que el puente quedaba
     visible aunque no tuviera nada adentro: una caja azul vacía con el
     badge "NUEVO" flotando (bug real, Frank 2026-08-20: "quita el botón de
     nuevo en color amarillo que quedó abajo"). */
  display: none;
  margin: 16px 1.25rem 8px;
  padding: 16px 18px;
  animation: appFadeInUp 0.5s var(--ease-out) 0.15s both;
  background: var(--acento, #0F2D5E);
  border: 1.5px solid var(--acento, #0F2D5E);
  border-radius: 12px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.85);
  text-align: center;
  box-shadow: 0 4px 14px rgba(15, 45, 94, 0.18);
  position: relative;
}
/* Badge "Nuevo" naranja arriba a la derecha del puente con pulse continuo
   muy sutil — 2.4s por ciclo, scale 1 → 1.04 → 1. Suficiente para que el
   ojo lo capte sin molestar. */
.pedido-puente-ia::before {
  content: 'NUEVO';
  position: absolute;
  top: -8px;
  right: 14px;
  background: #F5A623;
  color: #fff;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 1px;
  padding: 3px 10px;
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(245, 166, 35, 0.4);
  animation: appPulseSoft 2.4s var(--ease-in-out) infinite;
  transform-origin: center;
}
.pedido-puente-default {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}
/* El atributo `hidden` del HTML debe ganarle al display:flex de arriba. Sin
   este !important, ambos hijos se ven a la vez aunque el JS marque hidden. */
.pedido-puente-default[hidden],
.pedido-puente-volver[hidden] {
  display: none !important;
}
/* El puente decide en cada renderItems() cuál de los dos mostrar (ver
   elVolver.hidden en render.js) — sin esto el swap era un corte seco. */
.pedido-puente-default:not([hidden]),
.pedido-puente-volver:not([hidden]) {
  animation: appFadeIn 0.2s var(--ease-out);
}
.pedido-puente-default > span {
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
}
.pedido-puente-ia .pedido-puente-default button {
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  padding: 8px 16px;
  border-radius: 8px;
  font-family: inherit;
  transition: all 0.15s;
  backdrop-filter: blur(4px);
}
.pedido-puente-ia .pedido-puente-default button:hover {
  background: rgba(255, 255, 255, 0.22);
  transform: translateY(-1px);
}
.pedido-puente-ia .pedido-puente-default button:active {
  transform: translateY(0);
}
/* Cuando el puente está en modo "volver a editarlo" (secundario), atenuamos
   el resaltado para que no compita visualmente con el de "Nuevo". */
.pedido-puente-ia:has(.pedido-puente-volver:not([hidden])) {
  display: flex;
  background: rgba(15, 45, 94, 0.04);
  border: 1px dashed rgba(15, 45, 94, 0.22);
  box-shadow: none;
}
.pedido-puente-ia:has(.pedido-puente-volver:not([hidden]))::before {
  display: none;
}

/* Variante "Volver al diseñador con IA" del puente — se muestra cuando ya
   hay un diseño de IA cargado en el pedido. Estilo diferenciado para que
   se entienda que es una salida atrás, no una alternativa. */
.pedido-puente-volver {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--texto-mid, #475569);
  text-align: center;
}
.pedido-puente-volver > span {
  font-weight: 500;
}
/* Botón secundario "Volver a editarlo": sobre-escribe el botón resaltado
   del puente para que cuando está en modo "volver" sea más sutil (no compite
   con la novedad de la versión inicial). */
.pedido-puente-volver button {
  background: transparent;
  border: none;
  color: var(--acento, #0F2D5E);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  font-family: inherit;
  transition: all 0.15s;
  box-shadow: none;
}
.pedido-puente-volver button:hover {
  background: rgba(15, 45, 94, 0.08);
  text-decoration: underline;
  transform: translateX(-2px);
  filter: none;
  box-shadow: none;
}

/* Link secundario "diseñar otro con IA", debajo de "+ Agregar otro
   producto" — mismo criterio visual sutil que .pedido-puente-volver
   (no compite con el botón principal, que sigue siendo subir tu archivo). */
.paso1-agregar-ia-link[hidden] { display: none !important; }
.paso1-agregar-ia-link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 6px auto 0;
  background: transparent;
  border: none;
  color: var(--acento, #0F2D5E);
  font-size: 12.5px;
  font-weight: 600;
  font-family: 'DM Sans', sans-serif;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background 0.15s;
}
.paso1-agregar-ia-link i { font-size: 11px; }
.paso1-agregar-ia-link:hover {
  background: var(--acento-tenue);
  text-decoration: underline;
}

/* ============================================================
   Validación: toast flotante + resaltado de campos
   - .toast-error: pop-up rojo flotante arriba a la derecha
   - .input-error: borde rojo + sombra rojiza en el campo
   - .input-shake: animación de "tambaleo" breve al fallar
   ============================================================ */

/* Toast flotante */
.toast-error {
  position: fixed;
  top: 20px;
  left: 50%;
  /* top se sobreescribe en mobile (ver @media abajo) — ahí el modal ocupa
     toda la pantalla y "20px desde arriba" caía encima del propio header
     del modal (tapaba "TU PEDIDO" y el precio). */
  transform: translate(-50%, -30px);
  background: linear-gradient(135deg, #E53E3E, #C53030);
  color: #fff;
  padding: 12px 18px 12px 14px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 10px 30px rgba(229, 62, 62, 0.35), 0 2px 6px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 10000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease, transform 0.32s cubic-bezier(0.16, 1, 0.3, 1);
  max-width: 90vw;
}
.toast-error.visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
  animation: toastBounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes toastBounce {
  0%   { transform: translate(-50%, -30px); }
  70%  { transform: translate(-50%, 6px); }
  100% { transform: translate(-50%, 0); }
}
.toast-error-icono {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 13px;
  flex-shrink: 0;
}
.toast-error-texto {
  line-height: 1.4;
}

/* Resaltado del campo problemático: borde rojo fuerte + glow.
   Funciona en inputs, selects, textareas, botones de upload, etc. */
.input-error {
  border-color: #E53E3E !important;
  box-shadow: 0 0 0 3px rgba(229, 62, 62, 0.18) !important;
  background: rgba(229, 62, 62, 0.04) !important;
}

/* Animación de tambaleo cuando un campo falla */
.input-shake {
  animation: inputShake 0.55s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}
@keyframes inputShake {
  10%, 90%  { transform: translateX(-1px); }
  20%, 80%  { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60%  { transform: translateX(4px); }
}
