/* MiratechSpA Store — shared chrome (header, footer, drawer, buttons)
   Built on the MiratechSpA design system tokens (styles.css). */

/* Alturas del header de 2 filas, reutilizadas por el cálculo de min-height del
   hero en landing.css (--util-bar-height + --header-height): declararlas una
   sola vez acá evita hardcodear el mismo número en dos archivos. */
:root {
  --util-bar-height: 32px;
  --header-height: 74px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  color: var(--text-body);
  background: var(--surface-page);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--text-strong); line-height: var(--lh-tight); letter-spacing: var(--ls-tight); }
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select { font-family: inherit; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 28px; }
.mono { font-family: var(--font-mono); }

.eyebrow {
  font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wider); text-transform: uppercase; color: var(--brand-steel);
  display: inline-flex; align-items: center; gap: 10px;
}
.eyebrow::before { content: ''; width: 22px; height: 1.5px; background: var(--brand-steel); }

/* ============ BUTTONS ============ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-weight: var(--fw-semibold); font-size: var(--fs-sm); letter-spacing: var(--ls-snug);
  padding: 13px 24px; border-radius: 10px;
  transition: transform 120ms cubic-bezier(.22,.61,.36,1), box-shadow 120ms, background 120ms, border-color 120ms, color 120ms;
}
.btn:active { transform: scale(0.99) translateY(0.5px); }
.btn .lucide, .btn i { width: 17px; height: 17px; }
.btn-primary { background: var(--action-bg); color: var(--action-fg); box-shadow: 0 4px 14px rgba(17,42,61,.18); }
.btn-primary:hover { background: var(--action-bg-hover); transform: translateY(-1px); box-shadow: 0 8px 22px rgba(17,42,61,.24); }
.btn-accent { background: var(--accent-bg); color: var(--accent-fg); box-shadow: 0 4px 14px rgba(76,139,162,.3); }
.btn-accent:hover { background: var(--accent-bg-hover); transform: translateY(-1px); }
.btn-outline { border: 1.5px solid var(--border-default); color: var(--text-strong); background: var(--surface-card); }
.btn-outline:hover { border-color: var(--brand-steel); color: var(--brand-steel); transform: translateY(-1px); }
/* Variante de aviso de "algo salió mal" (ej. plantillas de problema en el panel de
   pedido): mismo btn-outline con tinte ámbar, para distinguirla de un aviso de
   rutina sin tener que leer el texto del botón. */
.btn-outline-warn { border-color: var(--amber-500); color: var(--amber-600); background: var(--warning-soft); }
.btn-outline-warn:hover { border-color: var(--amber-600); color: var(--amber-600); }
/* Secundario sobre fondo oscuro. Con el borde al 28% y sin relleno se leía como un
   botón deshabilitado: ahora tiene cuerpo propio (vidrio esmerilado sobre el hero) y
   sigue por debajo del primario blanco, que es quien manda en la jerarquía. */
.btn-ghost-inverse {
  border: 1.5px solid rgba(255,255,255,.55); color: #fff;
  background: rgba(255,255,255,.12);
  backdrop-filter: saturate(140%) blur(6px);
  box-shadow: 0 4px 16px rgba(7,18,28,.22);
}
.btn-ghost-inverse:hover {
  border-color: #fff; background: rgba(255,255,255,.22);
  transform: translateY(-1px); box-shadow: 0 8px 22px rgba(7,18,28,.3);
}
.btn-ghost-inverse .lucide, .btn-ghost-inverse i { opacity: .9; }
.btn-secondary { background: var(--surface-brand-soft); color: var(--marine-700); }
.btn-secondary:hover { background: var(--marine-100); transform: translateY(-1px); }
.btn-danger { background: var(--danger-soft); color: var(--red-600); }
.btn-danger:hover { background: #F7DADA; transform: translateY(-1px); }
.btn-ghost { color: var(--text-muted); }
.btn-ghost:hover { color: var(--text-strong); background: var(--surface-sunken); }
.btn-sm { padding: 8px 14px; font-size: var(--fs-xs); border-radius: 8px; }
.btn-sm .lucide, .btn-sm i { width: 14px; height: 14px; }

/* ============ FILE INPUT (custom, reemplaza el <input type="file"> nativo) ============ */
/* left:0 y el !important en width: sin ellos, una regla de página más específica
   (ej. .quote-card .f-field input { width:100% }) estira este input oculto y, al ser
   absolute sin anclaje, desborda la página a la derecha. */
.file-drop-input {
  position: absolute; left: 0; width: 1px !important; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.file-drop {
  display: inline-flex; align-items: center; gap: 10px; width: 100%; padding: 12px 14px;
  border-radius: 10px; border: 1.5px dashed var(--border-default); background: var(--surface-card);
  color: var(--text-muted); font-size: var(--fs-sm); cursor: pointer;
  transition: border-color 120ms, background 120ms;
}
.file-drop:hover { border-color: var(--steel-500); background: var(--surface-accent-soft); }
.file-drop:has(.file-drop-input:focus-visible) {
  border-color: var(--focus-ring); box-shadow: 0 0 0 3px rgba(99,157,174,.18);
}
.file-drop .lucide, .file-drop i { width: 17px; height: 17px; flex: none; color: var(--steel-600); }
.file-drop.compact { width: auto; padding: 9px 14px; font-size: var(--fs-xs); border-radius: 8px; }
.file-drop.compact .lucide, .file-drop.compact i { width: 15px; height: 15px; }

/* e-RUT ya cargado: link al archivo + estado de revisión. Vive acá y no en cuenta.css
   porque lo usan la cuenta del cliente y /gestion/ (usuarios, card de documento). */
.erut-actual { display: flex; align-items: center; gap: 8px; margin: 2px 0 8px; font-size: var(--fs-xs); flex-wrap: wrap; }
.erut-actual .lucide, .erut-actual i { width: 15px; height: 15px; color: var(--green-600); }
.erut-actual a { color: var(--text-link); text-decoration: underline; }
.erut-ok, .erut-pend {
  padding: 2px 9px; border-radius: 999px; font-size: var(--fs-2xs); font-weight: var(--fw-semibold);
}
.erut-ok { background: var(--success-soft); color: var(--green-600); }
.erut-pend { background: var(--warning-soft); color: var(--amber-600); }
/* Acción de aprobar/revertir: va pegada a su badge, en la misma línea. Un .btn-sm
   (padding 8px) rompía la línea y se leía como acción suelta de la fila. */
.erut-accion {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: inherit; font-size: var(--fs-2xs); font-weight: var(--fw-semibold);
  color: var(--text-link); text-decoration: underline;
}
.erut-accion:hover { color: var(--brand-navy); }
.erut-actual form { display: inline-flex; }

/* Variante con fondo propio: úsala donde el e-RUT convive con otras filas de
   resumen (ej. junto a "Courier" en el panel de pedido) para que no se vea como
   texto suelto al lado de bloques con más peso visual. */
.erut-actual-destacada { background: var(--surface-sunken); border-radius: var(--radius-md); padding: 9px 12px; margin: 0 0 12px; }

/* ============ UTILITY BAR ============
   Fila institucional/secundaria sobre el navbar principal. position:static (no
   sticky) a propósito: desaparece con el primer scroll, solo el navbar principal
   (sticky) persiste — así no hay que recalcular el offset del hero al scrollear,
   solo en la carga inicial (ver --util-bar-height arriba y su uso en landing.css). */
.util-bar {
  /* Sticky con auto-hide/reveal (smart sticky header): se oculta al bajar,
     reaparece al subir sin importar cuánto se haya scrolleado antes — el JS en
     base.html decide cuándo (ver .util-bar--oculta), este archivo solo anima la
     transición. transform, no display/height: solo transform/opacity corren en
     GPU sin relayout (ver emil-design-eng). El navbar (.site-header, sticky
     top:0 más abajo) se coloca a var(--util-bar-height) del top para dejarle
     el espacio arriba; cuando la utility bar se oculta, el navbar NO sube solo
     (quedaría un hueco vacío entre header y contenido) — .util-bar--oculta
     también sube el top del navbar a 0 vía la misma clase en <body>, ver JS. */
  position: sticky; top: 0; z-index: 61;
  background: var(--marine-900);
  border-bottom: 1px solid rgba(255,255,255,.08);
  transform: translateY(0);
  /* linear, no ease-out: con ease-out la barra visualmente ya está fuera de
     vista bastante antes de que termine el tiempo nominal de la transición
     (la curva se acerca rápido al final y se enlentece solo en el último
     tramo) — el transition-delay del navbar (ver store.css .site-header,
     calculado para "esperar los 220ms completos de la utility bar") no
     alcanzaba a cubrir la ventana real en que ya no había nada tapando el
     hueco, y se veía una franja de fondo real de la página (confirmado con
     Playwright: gap de hasta 32px entre util-bar.bottom y site-header.top,
     solo al ocultar — Emmanuel reportó que al mostrar no pasaba nada, lo que
     cuadra: ahí no hay esta asimetría de curva). linear hace que "fuera de
     vista" y "tiempo nominal terminado" coincidan exactamente. */
  transition: transform 220ms linear;
}
.util-bar--oculta { transform: translateY(-100%); }
.util-bar-row {
  display: flex; align-items: center; gap: 20px;
  height: var(--util-bar-height); font-size: var(--fs-2xs);
}
.util-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--slate-300); transition: color var(--dur-fast);
}
.util-link:hover { color: #fff; }
.util-link .lucide, .util-link i { width: 13px; height: 13px; }
@media (max-width: 900px) { .util-bar { display: none; } }

/* ===== Fondo animado compartido (navbar + hero de la portada) =====
   Portado desde docs/source/proximamente-miratech.html (misma landing de
   "abrimos pronto", a pedido de Emmanuel: "toma la animación que tiene en el
   fondo para que el navbar fijo arriba con el primer banner tengan esa misma
   animación"). 5 capas, todas transform/opacity/background-position (GPU).

   UNA sola capa, fixed a pantalla completa, no una animación duplicada en el
   navbar y otra en el hero: --portada-degradado (ver landing.css) ya costó
   varias iteraciones para que esos dos elementos calzaran como una sola
   superficie — dos animaciones independientes con offsets calculados a mano
   se habrían desincronizado en la costura igual que pasó antes con el
   degradado diagonal. Con una única capa física detrás de ambos (el navbar
   se vuelve transparente+blur mientras no hay scroll, ver
   html.bg-animada-on .site-header.hd-dark en landing.css; el hero
   directamente transparente, ver .carrusel-slide--hero en landing.css),
   los dos "ven" literalmente la misma animación, sin sincronizar nada a mano.

   Vive acá (no en landing.css) aunque solo se vea en la portada: el <div>
   .bg-animada está en base.html (global), y store.css es la única hoja que
   TODAS las páginas cargan siempre — landing.css solo lo carga home.html. Sin
   esto, en /catalogo/ (que no carga landing.css) el <div> quedaba con el
   display:block por defecto de cualquier <div>, visible aunque nunca debía
   estarlo ahí (bug real, encontrado al verificar con Playwright).

   Solo se muestra cuando html lleva .bg-animada-on — activada por el mismo
   listener de scroll que ya alternaba .scrolled en el header (ver base.html),
   y solo si ese header es .hd-dark: en cuanto el navbar pasa a su estado
   opaco de scroll, o en cualquier página sin header oscuro, la capa se
   oculta por CSS para no seguir animando algo invisible. */
.bg-animada {
  /* opacity, no display:none/block: display es binario (no se puede
     transicionar) y el cambio de estado se veía como un corte instantáneo —
     toda la animación (retícula, auroras, partículas) desaparecía de golpe
     apenas se empezaba a scrollear, en vez de desvanecerse (reportado por
     Emmanuel: "el corte de la animación es raro"). opacity + visibility sí
     admite transición; visibility:hidden tras el fade (delay en la
     transición) saca la capa del árbol de accesibilidad/hit-testing una vez
     invisible, sin el salto de display.

     SOLO la SALIDA (desaparecer, disparada por scroll) tiene fundido de
     750ms — la ENTRADA es instantánea (ver html.bg-animada-on más abajo).
     Dos intentos de sincronizar duraciones (320ms, luego 750ms igualando la
     transición del carrusel) no bastaron: aunque ambas duraciones coincidan
     "en el papel", el toggle de clase en <html> (que dispara esta
     transición) y la escritura directa de cinta.style.transform (que mueve
     el carrusel) no arrancan garantizadamente en el mismo frame de pintado
     — cualquier desfase de incluso un frame deja una ventana real donde el
     hero (transparente, ver .portada-primera:has(...) en landing.css) no
     tiene nada opaco detrás y asoma el blanco de la página (reportado por
     Emmanuel: "se pone todo blanco y de a poco cambia al color original").
     Quitando el fundido de ENTRADA de la ecuación, no hay nada que
     sincronizar: la capa ya está a opacity:1 antes de que el track
     empiece a moverse. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 750ms ease, visibility 0s linear 750ms;
  /* Acotada a la altura real de .portada-primera (utility bar + navbar +
     banner/hero), no a toda la ventana: lo que viene después (categorías,
     destacados...) es "otro contenido" y no debe verse tocado por la
     animación. --bg-animada-alto la fija base.html (ResizeObserver sobre
     .portada-primera, ver ese archivo) — 100svh es solo el respaldo antes de
     que el JS corra en el primer frame. */
  position: fixed; top: 0; left: 0; right: 0;
  height: var(--bg-animada-alto, 100svh);
  z-index: 0; overflow: hidden;
  background: linear-gradient(115deg, #0A1B29 0%, var(--marine-800) 40%, var(--marine-600) 74%, var(--steel-600) 100%);
}
html.bg-animada-on .bg-animada {
  opacity: 1;
  visibility: visible;
  /* transition: none (no solo duración 0) — la entrada debe estar YA lista
     en el primer frame en que el navbar/hero la necesitan detrás, sin
     ningún fundido que sincronizar con el carrusel. */
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .bg-animada { transition: opacity 120ms ease, visibility 0s linear 120ms; }
  html.bg-animada-on .bg-animada { transition: opacity 120ms ease, visibility 0s linear 0s; }
}

.ba-aurora { position: absolute; border-radius: 50%; filter: blur(90px); will-change: transform; }
/* top:-15vw (el valor original, portado tal cual del "próximamente") dejaba
   el CENTRO de esta aurora bien arriba del viewport: a la altura del navbar
   (0-107px) solo asomaba un borde apenas visible, y esa franja se leía como
   color sólido comparada con el hero de abajo, donde sí pasan auroras
   (reportado por Emmanuel viendo el navbar plano en dos capturas seguidas).
   Subida a -6vw para que el cuerpo de la mancha SÍ cruce el navbar. */
.ba-aurora--1 {
  width: 48vw; height: 48vw; min-width: 340px; min-height: 340px; opacity: .55;
  background: radial-gradient(circle, var(--steel-500), transparent 68%);
  top: -6vw; right: -8vw; animation: baDeriva1 24s ease-in-out infinite;
}
.ba-aurora--2 {
  width: 40vw; height: 40vw; min-width: 280px; min-height: 280px; opacity: .5;
  background: radial-gradient(circle, var(--marine-700), transparent 70%);
  bottom: -14vw; left: -7vw; animation: baDeriva2 32s ease-in-out infinite;
}
.ba-aurora--3 {
  width: 34vw; height: 34vw; min-width: 240px; min-height: 240px; opacity: .32;
  background: radial-gradient(circle, var(--accent-cyan, #5cc4e4), transparent 72%);
  top: 38%; left: 44%; animation: baDeriva3 40s ease-in-out infinite;
}
@keyframes baDeriva1 { 50% { transform: translate3d(-5vw, 4vw, 0) scale(1.14); } }
@keyframes baDeriva2 { 50% { transform: translate3d(6vw, -4vw, 0) scale(1.1); } }
@keyframes baDeriva3 {
  33% { transform: translate3d(-8vw, 5vw, 0) scale(1.2); }
  66% { transform: translate3d(7vw, -6vw, 0) scale(.88); }
}

/* Retícula técnica que se desplaza en diagonal, muy lento. */
.ba-rejilla {
  position: absolute; inset: -70px;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 88% 70% at 50% 45%, #000 18%, transparent 76%);
  -webkit-mask-image: radial-gradient(ellipse 88% 70% at 50% 45%, #000 18%, transparent 76%);
  animation: baPan 26s linear infinite;
}
@keyframes baPan { to { background-position: 64px 64px; } }

/* Barrido de luz que cruza la pantalla cada tanto. */
.ba-barrido {
  position: absolute; top: 0; bottom: 0; width: 44vw; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(140, 215, 240, .07) 45%, transparent);
  transform: skewX(-14deg);
  animation: baBarrer 15s ease-in-out infinite;
}
@keyframes baBarrer {
  0%, 100% { transform: translateX(-60vw) skewX(-14deg); opacity: 0; }
  45% { opacity: 1; }
  55% { opacity: 1; }
  100% { transform: translateX(150vw) skewX(-14deg); }
}

/* Partículas que suben lentamente (generadas por JS, ver base.html). */
.ba-particulas { position: absolute; inset: 0; pointer-events: none; }
.ba-particulas i {
  position: absolute; bottom: -12px; display: block; border-radius: 50%;
  background: #bfe6f4; will-change: transform, opacity;
  animation: baSubir linear infinite;
}
@keyframes baSubir {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  12% { opacity: var(--op); }
  80% { opacity: var(--op); }
  100% { transform: translate3d(var(--dx), -102svh, 0); opacity: 0; }
}

/* Viñeta para concentrar la atención al centro. */
.ba-vineta {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 70% 60% at 50% 50%, transparent 35%, rgba(4, 14, 23, .5) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .ba-aurora, .ba-rejilla, .ba-barrido { animation: none; }
  .ba-particulas { display: none; }
}

/* ============ HEADER ============ */
.site-header {
  position: sticky; top: var(--util-bar-height); z-index: 60;
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--border-subtle);
  /* top se mueve EN SINCRONÍA con la utility bar (misma duración 220ms,
     mismo linear, sin delay) en las dos direcciones — subir el navbar solo
     DESPUÉS de que la utility bar termine de irse (delay, intentado antes)
     dejaba un hueco real: mientras la utility bar todavía se estaba
     trasladando hacia arriba, el navbar seguía esperando en top:32px sin
     cubrir nada, y por ahí se veía el fondo real de la página (confirmado
     con screenshot de Playwright a mitad de transición — franja gris/blanca
     visible entre ambos, justo el bug reportado por Emmanuel). Moviéndose
     al mismo ritmo, el navbar sube progresivamente mientras la utility bar
     sale, cubriendo el hueco en todo momento en vez de solo al final. */
  /* background/backdrop-filter transicionan (320ms) para que el paso de
     "glass sobre .bg-animada" a navy opaco al hacer scroll (.scrolled, ver
     landing.css) no se sienta como un corte instantáneo — reportado por
     Emmanuel viendo el cambio de golpe al bajar un poco. Más lento que el
     resto (180-220ms): background-color/backdrop-filter son más perceptibles
     que un cambio de sombra, un corte rápido igual se notaría. */
  transition: box-shadow 180ms, top 220ms linear, background 320ms ease, backdrop-filter 320ms ease;
}
body.util-bar-oculta .site-header { top: 0; }

/* Aplicada por static/js/modal-scroll.js (global, cargado abajo en este mismo
   archivo base) mientras haya un .adm-modal.open en cualquier página del sitio,
   no solo /gestion/: vivía solo en admin-shell.css, que el panel carga pero las
   páginas públicas no — un .adm-modal público (cotización en la home) marcaba la
   clase sin que nada la usara, y el fondo seguía scrolleando (reportado por
   Emmanuel). El padding-right que compensa el ancho de la scrollbar lo pone el
   propio JS (inline, es un valor calculado en runtime). */
body.modal-abierto { overflow: hidden; }
@media (max-width: 900px) {
  /* Bajo 900px la utility bar ya está oculta permanentemente (display:none
     arriba) — el navbar siempre en top:0, nunca reserva el espacio de arriba. */
  .site-header { top: 0; }
}
.site-header.scrolled { box-shadow: 0 4px 18px rgba(17,42,61,.08); }

/* La variante .hd-dark (header azul sólido de la landing) vive completa en
   landing.css — ahí está el fondo, el texto, los botones. Este bloque duplicaba
   ese mismo selector con reglas contrarias (transparente en vez de azul sólido,
   "recupera el header claro normal" al scrollear en vez de quedarse azul) y,
   por especificidad de :not(.scrolled), ganaba sobre landing.css sin que se
   notara al leer solo ese archivo — el bug real detrás de "el navbar se ve
   blanco arriba y azul solo al bajar". Una sola fuente de verdad ahora. */
.site-header .nav { display: flex; align-items: center; gap: 24px; height: 74px; }
.site-header .brand img { height: 36px; width: auto; }
.site-header nav.links { display: flex; align-items: center; gap: 20px; flex: none; }
.site-header nav.links a {
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-muted);
  position: relative; padding: 6px 0; transition: color 120ms;
  white-space: nowrap; flex: none;
}
.site-header nav.links a::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 2px; width: 0;
  background: var(--brand-steel); border-radius: 2px; transition: width 180ms cubic-bezier(.22,.61,.36,1);
}
.site-header nav.links a:hover { color: var(--text-strong); }
.site-header nav.links a:hover::after, .site-header nav.links a.active::after { width: 100%; }
.site-header nav.links a.active { color: var(--text-strong); font-weight: var(--fw-semibold); }

/* Enlace con ícono (Proveedores del Estado). */
.site-header nav.links a.con-icono { display: inline-flex; align-items: center; gap: 7px; }
.site-header nav.links a.con-icono i, .site-header nav.links a.con-icono .lucide {
  width: 16px; height: 16px; flex: none;
}

/* Tienda: es lo que vende, así que es lo único con forma de botón en el menú. */
.site-header nav.links a.nav-tienda {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 18px; border-radius: 999px;
  background: var(--brand-steel); color: #fff; font-weight: var(--fw-bold);
  box-shadow: 0 6px 18px rgba(76,139,162,.32);
  transition: background 120ms, transform 120ms, box-shadow 120ms;
}
.site-header nav.links a.nav-tienda:hover {
  background: var(--accent-bg-hover); color: #fff;
  transform: translateY(-1px); box-shadow: 0 8px 22px rgba(76,139,162,.42);
}
/* El subrayado del estado activo es para los enlaces de texto: en el botón sobra. */
.site-header nav.links a.nav-tienda::after { display: none; }
.site-header nav.links a.nav-tienda.active { color: #fff; }
.site-header nav.links a.nav-tienda i, .site-header nav.links a.nav-tienda .lucide {
  width: 17px; height: 17px; flex: none;
}

.nav-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* ---- Buscador del header ----
   Comparte la fila con el menú, así que se estira con el espacio que sobra pero
   puede encogerse: lo que no puede es empujar al carrito fuera de la barra. */
.hdr-search {
  display: flex; align-items: center;
  /* flex:1 ya lo deja crecer con el espacio sobrante entre nav.links (flex:none)
     y nav-actions (margin-left:auto) — el techo de 420px era el problema real
     (reportado por Emmanuel): en pantallas anchas el buscador quedaba angosto y
     desproporcionado pese a haber mucho más espacio libre. 720px es generoso sin
     que la caja de texto se vea absurda en monitores muy anchos. */
  flex: 1 1 220px; min-width: 150px; max-width: 720px;
  background: var(--surface-card); border: 1.5px solid var(--border-default);
  border-radius: 999px; transition: border-color 120ms, box-shadow 120ms;
}
.hdr-search:focus-within { border-color: var(--focus-ring); box-shadow: 0 0 0 3px rgba(99,157,174,.18); }
.hdr-search input {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  padding: 9px 4px 9px 16px; font-size: var(--fs-sm); color: var(--text-body);
}
.hdr-search input::placeholder { color: var(--text-subtle); }
.hdr-search button {
  flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; margin-right: 3px; border-radius: 50%;
  color: var(--steel-600); cursor: pointer; transition: background 120ms, color 120ms;
}
.hdr-search button:hover { background: var(--surface-accent-soft); color: var(--brand-navy); }
.hdr-search button i, .hdr-search button .lucide { width: 17px; height: 17px; }
/* Sobre el hero oscuro el header es transparente, pero el campo se queda blanco:
   es lo único que necesita leerse mientras se escribe. */
.site-header.hd-dark:not(.scrolled) .hdr-search { border-color: rgba(255,255,255,.32); }
.acct-btn {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  padding: 9px 16px; border-radius: 999px;
  border: 1.5px solid var(--border-default); color: var(--text-strong);
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  transition: border-color 120ms, color 120ms, transform 120ms, background 120ms;
}
.acct-btn:hover { border-color: var(--brand-steel); color: var(--brand-steel); transform: translateY(-1px); }
.acct-btn .lucide, .acct-btn i { width: 17px; height: 17px; }

.acct-menu { position: relative; }
.acct-btn.is-logged { padding: 6px 10px 6px 6px; gap: 9px; }
.acct-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--surface-accent-soft); color: var(--steel-600);
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: var(--fw-semibold);
}
.acct-chevron.lucide, .acct-chevron { width: 15px; height: 15px; color: var(--text-subtle); transition: transform 180ms; }
.acct-menu.open .acct-chevron { transform: rotate(180deg); }
.acct-panel {
  position: absolute; top: calc(100% + 10px); right: 0; min-width: 220px;
  background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: 14px;
  box-shadow: 0 18px 40px rgba(17,42,61,.16);
  padding: 8px; display: flex; flex-direction: column; gap: 2px;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity 160ms, transform 160ms, visibility 160ms;
  z-index: 70;
}
.acct-menu.open .acct-panel { opacity: 1; visibility: visible; transform: translateY(0); }
.acct-panel a {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 9px;
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-body);
  transition: background 120ms, color 120ms;
}
.acct-panel a:hover { background: var(--surface-sunken); color: var(--text-strong); }
.acct-panel a .lucide, .acct-panel a i { width: 16px; height: 16px; color: var(--text-subtle); flex: none; }
.acct-panel .acct-salir { color: var(--danger); }
.acct-panel .acct-salir .lucide, .acct-panel .acct-salir i { color: var(--danger); }
.acct-sep { height: 1px; background: var(--border-subtle); margin: 4px 6px; }
.acct-menu-label { display: block; padding: 4px 12px 2px; font-size: var(--fs-2xs); font-weight: var(--fw-semibold); text-transform: uppercase; letter-spacing: var(--ls-wide); color: var(--text-subtle); }
.acct-panel a.acct-panel-link { font-weight: var(--fw-semibold); color: var(--marine-700); }
.acct-panel a.acct-panel-link .lucide, .acct-panel a.acct-panel-link i { color: var(--marine-600); }

.cart-btn {
  position: relative; display: flex; align-items: center; gap: 9px;
  background: var(--action-bg); color: var(--action-fg);
  padding: 10px 16px; border-radius: 999px;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  transition: background 120ms, transform 120ms;
}
.cart-btn:hover { background: var(--action-bg-hover); transform: translateY(-1px); }
.cart-btn .lucide, .cart-btn i { width: 18px; height: 18px; }
/* Solo ícono + contador: el texto ocupaba el ancho que ahora necesita el buscador. */
.cart-btn span:not(.cart-count) { display: none; }
.cart-btn { padding: 10px 13px; }
.cart-btn.shake { animation: cartShake .5s cubic-bezier(.36,.07,.19,.97); }
@keyframes cartShake {
  10%, 90% { transform: translateX(-1px) rotate(-2deg); }
  30%, 70% { transform: translateX(2px) rotate(2deg); }
  50% { transform: translateX(-2px) rotate(-1deg); }
}
.cart-count {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--brand-steel); color: #fff;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: var(--fw-semibold);
  display: grid; place-items: center;
}
.cart-count.bump { animation: bump .4s cubic-bezier(.22,.61,.36,1); }
@keyframes bump { 0%,100%{transform:scale(1)} 35%{transform:scale(1.4)} }

/* ===== Menú móvil: hamburguesa + drawer ===== */
/* Ocultos en desktop; se activan en el media query <880px (nav.links visible). */
.nav-burger, .nav-overlay, .nav-drawer { display: none; }
.nav-burger {
  align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: 50%; color: var(--text-strong); cursor: pointer;
}
.nav-burger:hover { background: var(--surface-sunken); }
.nav-burger i { width: 22px; height: 22px; }

/* Fly-to-cart dot */
.fly-dot {
  position: fixed; z-index: 200; width: 14px; height: 14px; border-radius: 50%;
  background: var(--brand-steel); box-shadow: 0 0 0 4px rgba(76,139,162,.25), 0 4px 10px rgba(17,42,61,.3);
  pointer-events: none;
  transition: transform .55s cubic-bezier(.5,-0.1,.75,.4), opacity .55s;
}

/* ============ CART DRAWER ============ */
.cart-overlay {
  position: fixed; inset: 0; background: rgba(17,42,61,.45); backdrop-filter: blur(3px);
  opacity: 0; visibility: hidden; transition: opacity 250ms; z-index: 90;
}
.cart-overlay.open { opacity: 1; visibility: visible; }
.cart-drawer {
  position: fixed; top: 0; right: 0; height: 100%; width: 430px; max-width: 92vw;
  background: var(--surface-card); z-index: 100; display: flex; flex-direction: column;
  transform: translateX(105%);
  /* visibility oculta el drawer cerrado: desplazado solo con transform seguía
     contando para el área de scroll y desbordaba la página a la derecha. */
  visibility: hidden;
  transition: transform 380ms cubic-bezier(.22,.61,.36,1), visibility 380ms;
  box-shadow: -16px 0 50px rgba(17,42,61,.2);
}
.cart-drawer.open { transform: translateX(0); visibility: visible; }
.cart-drawer .dr-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 26px; border-bottom: 1px solid var(--border-subtle);
}
.cart-drawer .dr-head h3 { font-size: var(--fs-md); display: flex; align-items: center; gap: 10px; }
.cart-drawer .dr-pill {
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: var(--fw-semibold);
  background: var(--surface-accent-soft); color: var(--steel-600); padding: 3px 10px; border-radius: 999px;
}
.dr-close { width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; color: var(--text-muted); transition: background 120ms, color 120ms; }
.dr-close:hover { background: var(--surface-sunken); color: var(--text-strong); }
.dr-close .lucide, .dr-close i { width: 19px; height: 19px; }
.cart-drawer .dr-body { flex: 1; overflow-y: auto; padding: 6px 26px; }
.cart-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: 14px; text-align: center; padding: 40px; color: var(--text-muted); }
.cart-empty .ce-ico { width: 74px; height: 74px; border-radius: 50%; background: var(--surface-sunken); display: grid; place-items: center; color: var(--text-subtle); }
.cart-empty .ce-ico .lucide, .cart-empty .ce-ico i { width: 32px; height: 32px; }
.cart-empty h4 { font-size: var(--fs-base); }
.cart-empty .btn { margin-top: 6px; }

.cart-item { display: flex; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--border-subtle); animation: itemIn .35s cubic-bezier(.22,.61,.36,1) both; }
@keyframes itemIn { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: translateX(0); } }
.cart-item.removing { animation: itemOut .28s ease both; }
@keyframes itemOut { to { opacity: 0; transform: translateX(30px); } }
.ci-thumb {
  width: 60px; height: 60px; flex: none; border-radius: 12px; overflow: hidden;
  background: var(--surface-accent-soft); border: 1px solid var(--border-subtle);
  display: grid; place-items: center; color: var(--steel-600);
}
.ci-thumb .lucide, .ci-thumb i { width: 26px; height: 26px; }
.ci-main { flex: 1; min-width: 0; }
.ci-name { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--text-strong); line-height: var(--lh-snug); }
.ci-sku { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-subtle); margin-top: 2px; }
.ci-price { font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--brand-navy); margin-top: 4px; }
.ci-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 9px; }

/* ===== Selector de cantidad (tarjeta de la tienda y ficha de producto) =====
   Un solo control para todo el sitio: la tarjeta de la tienda, la ficha de producto,
   el drawer y la página del carrito. Reemplazó a .qty, el stepper viejo del carrito
   (28px y radio de 8px escritos a mano, con el número en un <span> no editable).
   Sigue el lenguaje de los campos del design system, porque esto ES un campo que el
   cliente completa: borde de 1,5px, radio --radius-md y el mismo anillo de foco steel
   que usan el buscador, el filtro de precio y el select de orden de la tienda.
   El anillo lo pinta el contenedor con :focus-within, así se ve como un campo único
   y no como un input suelto entre dos botones. La lógica está en cantidad.js. */
.cantidad {
  display: inline-flex; align-items: stretch; flex: none;
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  overflow: hidden;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
  /* Alto propio: al lado de un botón (tienda, ficha) se estira solo, pero en el
     carrito va suelto en una fila centrada y sin esto colapsaba al alto del input
     —unos 22px—, con lo que el radio de 10px lo dejaba con forma de pastilla. */
  min-height: 34px;
}
.cantidad:focus-within { border-color: var(--focus-ring); box-shadow: 0 0 0 3px rgba(99,157,174,.18); }
.cantidad button {
  flex: none; width: 32px; display: grid; place-items: center; color: var(--text-muted);
  transition: background var(--dur-fast), color var(--dur-fast), transform var(--dur-fast) var(--ease-out);
}
.cantidad button:hover:not(:disabled) { background: var(--surface-sunken); color: var(--brand-navy); }
.cantidad button:active:not(:disabled) { transform: scale(.9); }
/* En el mínimo y en el tope el botón se apaga, en vez de dejar clics que no hacen nada. */
.cantidad button:disabled { opacity: .3; cursor: not-allowed; }
.cantidad button .lucide, .cantidad button i { width: 14px; height: 14px; }
.cantidad input {
  width: 38px; padding: 0; border: 0; background: transparent; text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  color: var(--brand-navy);
  /* Se ocultan las flechitas nativas: los botones − y + hacen ese trabajo. */
  appearance: textfield; -moz-appearance: textfield;
}
.cantidad input::-webkit-outer-spin-button,
.cantidad input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cantidad input:focus { outline: none; }

/* Talla grande: la ficha de producto, donde va junto a un botón de 16px de padding. */
.cantidad--lg { min-height: 48px; }
.cantidad--lg button { width: 44px; }
.cantidad--lg button .lucide, .cantidad--lg button i { width: 17px; height: 17px; }
.cantidad--lg input { width: 50px; font-size: var(--fs-md); }
.ci-remove { font-size: var(--fs-xs); color: var(--text-subtle); display: inline-flex; align-items: center; gap: 5px; transition: color 120ms; }
.ci-remove:hover { color: var(--danger); }
.ci-remove .lucide, .ci-remove i { width: 14px; height: 14px; }

.cart-drawer .dr-foot { padding: 20px 26px calc(20px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border-subtle); background: var(--surface-page); }
/* Los grises del resumen del pedido se subieron el 28 ago 2026: medidos contra el
   blanco del card, --text-subtle daba 2,50:1 y --text-muted 4,36:1, los dos por
   debajo del mínimo legible de 4,5:1, y encima a 11px. Acá se usa --slate-600 (6,79)
   para las etiquetas y --text-body (10,15) para lo que el cliente tiene que leer sí
   o sí. La jerarquía se mantiene con el peso y el tamaño, no bajando el contraste. */
.sum-row { display: flex; justify-content: space-between; font-size: var(--fs-sm); color: var(--slate-600); margin-bottom: 8px; }
.sum-row strong { font-family: var(--font-mono); font-weight: var(--fw-semibold); color: var(--text-body); }
.sum-row.total { font-size: var(--fs-md); color: var(--text-strong); font-weight: var(--fw-bold); margin: 12px 0 16px; }
.sum-row.total strong { font-family: var(--font-mono); color: var(--brand-navy); font-weight: var(--fw-semibold); font-size: var(--fs-lg); }
.sum-iva-note { font-size: var(--fs-xs); color: var(--slate-600); margin: -10px 0 14px; }
.checkout-btn { width: 100%; padding: 15px; font-size: var(--fs-base); }
.checkout-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; }
.free-ship { display: flex; align-items: center; justify-content: center; gap: 7px; font-size: var(--fs-xs); color: var(--text-muted); margin-top: 12px; }

/* ---- Página de carrito: layout 2 columnas ---- */
.cart-resumen-top { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-bottom: 20px; }
.cart-resumen-top p { font-size: var(--fs-sm); color: var(--text-muted); }
.cart-seguir { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-muted); transition: color var(--dur-fast); }
.cart-seguir:hover { color: var(--brand-navy); }
.cart-seguir:hover .lucide, .cart-seguir:hover i { transform: translateX(-2px); }
.cart-seguir .lucide, .cart-seguir i { width: 15px; height: 15px; transition: transform var(--dur-fast) var(--ease-out); }

.cart-page-grid { display: grid; grid-template-columns: 1fr 360px; gap: 28px; align-items: start; }
.cart-page-items { display: flex; flex-direction: column; gap: 12px; }
.cart-page-items .cart-item {
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  border-bottom: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-xs);
  align-items: flex-start;
  gap: 18px;
  transition: box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.cart-page-items .cart-item:hover { box-shadow: var(--shadow-md); border-color: var(--border-default); }
.cart-page-items .ci-thumb { width: 92px; height: 92px; border-radius: var(--radius-md); }

/* Fila superior del item: datos a la izquierda, subtotal anclado a la derecha */
.ci-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ci-head { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cart-page-items .ci-name { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--text-strong); line-height: var(--lh-snug); }
.ci-marca { font-size: var(--fs-2xs); color: var(--text-subtle); text-transform: uppercase; letter-spacing: var(--ls-wide); font-weight: var(--fw-medium); margin-top: 1px; }
.cart-page-items .ci-sku { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-subtle); }
.cart-page-items .ci-price { font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-muted); margin-top: 8px; }
.cart-page-items .ci-price .ci-unit { font-size: var(--fs-2xs); color: var(--text-subtle); }

.cart-page-items .ci-foot { margin-top: 14px; gap: 12px; justify-content: space-between; }
/* En la página del carrito el control va más grande que en el drawer. */
.cart-page-items .cantidad { min-height: 40px; }
.cart-page-items .cantidad button { width: 36px; }
.cart-page-items .cantidad button .lucide, .cart-page-items .cantidad button i { width: 16px; height: 16px; }
.cart-page-items .cantidad input { width: 46px; }

.cart-page-items .ci-remove {
  width: 34px; height: 34px; border-radius: var(--radius-md);
  display: inline-grid; place-items: center; gap: 0; position: relative;
  color: var(--text-subtle); background: transparent;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.cart-page-items .ci-remove:hover { background: var(--danger-soft); color: var(--danger); }
.cart-page-items .ci-remove .lucide, .cart-page-items .ci-remove i { width: 16px; height: 16px; }
.ci-remove-txt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.ci-subtotal { flex: none; text-align: right; }
.ci-subtotal-val { font-family: var(--font-mono); font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--brand-navy); line-height: var(--lh-snug); white-space: nowrap; animation: valorIn 260ms var(--ease-out) both; }

.cart-summary-sticky { position: sticky; top: 90px; max-height: calc(100vh - 110px); overflow-y: auto; }
.cart-summary { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: 24px; }
.cart-summary h3 { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--text-strong); margin-bottom: 16px; }

.cart-summary .sum-row { margin-bottom: 4px; }
.cart-summary .sum-iva-note { margin: 0; }

.cart-total-row {
  display: flex; justify-content: space-between; align-items: baseline;
  border-top: 1px solid var(--border-subtle); padding-top: 16px; margin-top: 16px;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--text-strong);
}
.cart-total-row strong { font-family: var(--font-mono); font-size: var(--fs-xl); font-weight: var(--fw-extra); color: var(--brand-navy); animation: valorIn 260ms var(--ease-out) both; }
.cart-total-nota {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-body);
  line-height: var(--lh-normal);
  margin-top: 8px; margin-bottom: 16px;
}

.cart-summary .checkout-btn { width: 100%; }
.cart-summary .checkout-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.cart-summary .checkout-btn:active { transform: translateY(0); }
.cart-summary .checkout-btn:hover i[data-lucide="arrow-right"] { transform: translateX(3px); }
.cart-summary .checkout-btn i[data-lucide="arrow-right"] { transition: transform var(--dur-fast) var(--ease-out); }
.cart-summary .checkout-btn:disabled { background: var(--slate-300); color: var(--slate-600); opacity: 1; cursor: not-allowed; }

@keyframes valorIn { from { opacity: .35; } to { opacity: 1; } }

@media (max-width: 880px) {
  .cart-page-grid { grid-template-columns: 1fr; }
  .cart-summary-sticky { position: static; max-height: none; overflow: visible; }
}

/* En pantallas angostas el subtotal baja bajo el nombre en vez de competir por el ancho */
@media (max-width: 640px) {
  .ci-top { flex-direction: column; gap: 8px; }
  .cart-page-items .ci-subtotal { text-align: left; }
}

@media (max-width: 560px) {
  .cart-page-items .ci-thumb { width: 72px; height: 72px; }
  .cart-page-items .cart-item { padding: 14px; }
  .cart-page-items .ci-name { font-size: var(--fs-sm); }
  .cart-page-items .ci-price { font-size: var(--fs-xs); }
  .ci-subtotal-val { font-size: var(--fs-sm); }
}

@media (prefers-reduced-motion: reduce) {
  .cart-seguir .lucide, .cart-seguir i,
  .cart-page-items .cantidad button,
  .cart-page-items .ci-remove,
  .ci-subtotal-val,
  .cart-total-row strong,
  .cart-summary .checkout-btn,
  .cart-summary .checkout-btn i[data-lucide="arrow-right"] {
    transition: none;
    animation: none;
  }
}
.free-ship .lucide, .free-ship i { width: 14px; height: 14px; color: var(--success); }
.ship-progress { height: 4px; border-radius: 2px; background: var(--slate-200); margin-top: 10px; overflow: hidden; }
.ship-progress > div { height: 100%; border-radius: 2px; background: linear-gradient(90deg, var(--steel-500), var(--marine-500)); transition: width .4s cubic-bezier(.22,.61,.36,1); }

/* ============ TOAST ============ */
.toast {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%) translateY(120px);
  background: var(--surface-inverse); color: #fff; padding: 13px 22px; border-radius: 12px;
  font-size: var(--fs-sm); font-weight: var(--fw-medium); z-index: 120;
  display: flex; align-items: center; gap: 10px;
  box-shadow: 0 18px 40px rgba(17,42,61,.35);
  transition: transform 350ms cubic-bezier(.22,.61,.36,1);
}
.toast.show { transform: translateX(-50%) translateY(0); }
.toast .lucide, .toast i { width: 17px; height: 17px; color: var(--steel-300); }

/* ============ FOOTER ============ */
.site-footer { background: var(--surface-inverse); color: var(--slate-300); padding: 60px 0 30px; }
.site-footer .foot-top { display: flex; justify-content: space-between; gap: 44px; flex-wrap: wrap; padding-bottom: 36px; border-bottom: 1px solid rgba(255,255,255,.1); }
.site-footer .foot-brand img { height: 34px; width: auto; filter: brightness(0) invert(1); opacity: .95; }
.site-footer .foot-loc { display: flex; align-items: center; gap: 9px; margin-top: 16px; font-size: var(--fs-sm); color: var(--slate-400); }
.site-footer .foot-loc .lucide, .site-footer .foot-loc i { width: 16px; height: 16px; color: var(--steel-400); }
.site-footer .foot-links { display: flex; gap: 56px; flex-wrap: wrap; }
.site-footer .foot-col h4 { color: #fff; font-size: var(--fs-xs); letter-spacing: var(--ls-wider); text-transform: uppercase; font-family: var(--font-mono); font-weight: var(--fw-medium); margin-bottom: 16px; }
.site-footer .foot-col a { display: block; font-size: var(--fs-sm); margin-bottom: 11px; color: var(--slate-400); transition: color 120ms; }
.site-footer .foot-col a:hover { color: var(--steel-300); }
.site-footer .foot-bottom { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; padding-top: 26px; font-size: var(--fs-xs); color: var(--slate-500); }
.site-footer .tagline { font-family: var(--font-mono); letter-spacing: var(--ls-wide); color: var(--slate-400); }
.site-footer .tagline span { color: var(--steel-400); }
/* Crédito de agencia: discreto a propósito, no debe competir con la marca de
   Miratech. margin-left:auto lo ancla a la derecha aunque el tagline (elemento
   central del flex) se envuelva antes en pantallas angostas. */
.site-footer .foot-credito { margin-left: auto; color: var(--slate-600); transition: color 120ms; }
.site-footer .foot-credito:hover { color: var(--slate-400); }

/* ============ BANNER DE COOKIES ============
   Fixed al pie, por encima de todo (z-index alto: debe ganarle al header
   sticky y a cualquier drawer). Oculto por defecto vía [hidden] — lo revela
   static/js/cookies.js si no hay decisión guardada en localStorage.
   .cookie-banner[hidden] explícito con !important: [hidden] a secas tiene la
   MISMA especificidad (0,1,0) que .cookie-banner, y por orden de cascada
   (la regla de autor va después del UA stylesheet) display:flex ganaba pese
   al atributo — el banner quedaba siempre visible y hidden=true desde JS no
   se notaba en pantalla. */
.cookie-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  flex-wrap: wrap;
  padding: 18px max(20px, calc(50vw - 600px));
  background: var(--surface-inverse); color: var(--slate-300);
  border-top: 1px solid rgba(255,255,255,.1);
  box-shadow: 0 -8px 24px rgba(7,18,28,.18);
}
.cookie-banner[hidden] { display: none !important; }
/* Blanco sólido, no .btn-primary (marine-700): sobre el navy del banner un
   azul oscuro se pierde casi tanto como el fondo — mismo criterio que ya usa
   el hero para "primario sobre fondo oscuro" (ver .btn-ghost-inverse arriba),
   así Aceptar manda claramente sobre Rechazar. */
.btn-cookie-aceptar { background: #fff; color: var(--marine-900); box-shadow: 0 4px 14px rgba(7,18,28,.28); }
.btn-cookie-aceptar:hover { background: var(--slate-100); transform: translateY(-1px); }
.cookie-banner-texto p { margin: 0; font-size: var(--fs-sm); max-width: 640px; }
.cookie-banner-texto a { color: var(--steel-300); text-decoration: underline; }
.cookie-banner-acciones { display: flex; gap: 10px; flex: none; }
@media (max-width: 560px) {
  .cookie-banner { flex-direction: column; align-items: stretch; }
  .cookie-banner-acciones { justify-content: flex-end; }
}

/* ============ RESPONSIVE CHROME ============ */
/* Tablet: se oculta el texto de los botones; quedan como pastillas con icono.
   1200px y no 1040: en tablets tipo Chromebook (~1024) el menú horizontal todavía
   está visible (colapsa a 880), así que "Mi cuenta" y "Carrito" con texto empujaban
   el header hasta desbordar la página. Colapsan antes que la hamburguesa a propósito. */
@media (max-width: 1200px) {
  /* Ocultamos el texto pero NO el avatar (.acct-avatar también es un span): antes
     'span' genérico borraba las iniciales y el botón quedaba invisible. */
  .acct-name, .acct-btn:not(.is-logged) span { display: none; }
  .acct-btn:not(.is-logged) { padding: 9px 12px; }
  .acct-btn.is-logged { padding: 5px; }
  .acct-chevron { display: none; }
  .cart-btn { padding: 10px 12px; }
  /* El menú aún ocupa ~670px a este ancho: apretar el espacio entre enlaces y el
     de la barra evita que el header quede al filo de desbordar. */
  .site-header .nav { gap: 16px; }
  .site-header nav.links { gap: 16px; }
}
/* 900px: con solo tres enlaces (Tienda, Proveedores del Estado, Contacto) el menú
   aguanta más que los seis de antes, que obligaban a colapsar ya en 980. Los botones
   de cuenta/carrito siguen compactándose antes (1200px). */
@media (max-width: 900px) {
  .site-header nav.links { display: none; }
  .wrap { padding: 0 20px; }

  /* Header móvil: logo más contenido + acciones como dos círculos iguales,
     alineados y del mismo tamaño (antes el avatar quedaba diminuto y descuadrado). */
  .site-header .nav { height: 62px; gap: 12px; }
  .site-header .brand img { height: 30px; }
  /* Con nav.links oculto, nada empuja las acciones a la derecha: lo hacemos aquí. */
  .nav-actions { gap: 8px; margin-left: auto; }

  /* Hamburguesa visible, al extremo derecho (order:9); cuenta y carrito antes. */
  .nav-burger { display: inline-flex; order: 9; }

  /* Overlay + drawer de navegación desde la derecha. */
  .nav-overlay {
    display: block; position: fixed; inset: 0; z-index: 80;
    background: rgba(17, 42, 61, 0.45); opacity: 0; visibility: hidden;
    transition: opacity var(--dur-base, 180ms) ease, visibility var(--dur-base, 180ms);
  }
  body.nav-abierto .nav-overlay { opacity: 1; visibility: visible; }
  body.nav-abierto { overflow: hidden; }

  .nav-drawer {
    display: flex; flex-direction: column; gap: 4px;
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 81;
    width: min(82vw, 320px); padding: 14px;
    background: var(--surface-card); box-shadow: -4px 0 30px rgba(17, 42, 61, 0.18);
    transform: translateX(100%);
    /* visibility oculta el drawer cerrado: desplazado solo con transform seguía
       contando para el área de scroll y desbordaba la página a la derecha. */
    visibility: hidden;
    transition: transform var(--dur-base, 200ms) ease, visibility var(--dur-base, 200ms);
    overflow-y: auto;
  }
  body.nav-abierto .nav-drawer { transform: none; visibility: visible; }

  .nav-drawer-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 4px 4px 12px; margin-bottom: 6px; border-bottom: 1px solid var(--border-subtle);
  }
  .nav-drawer-title { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--text-strong); }
  .nav-drawer-close {
    display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px;
    color: var(--text-muted); cursor: pointer;
  }
  .nav-drawer-close:hover { background: var(--surface-sunken); }
  .nav-drawer-close i { width: 19px; height: 19px; }

  .nav-drawer-link {
    display: flex; align-items: center; gap: 12px; padding: 13px 12px; border-radius: 10px;
    font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--text-body);
    transition: background 120ms, color 120ms;
  }
  .nav-drawer-link:hover { background: var(--surface-sunken); color: var(--text-strong); }
  .nav-drawer-link.active { background: var(--surface-accent-soft); color: var(--brand-navy); font-weight: var(--fw-semibold); }
  .nav-drawer-link i { width: 19px; height: 19px; color: var(--text-subtle); flex: none; }
  .nav-drawer-link.active i { color: var(--steel-600); }
  /* Tienda encabeza el drawer con el mismo peso que tiene en la barra. */
  .nav-drawer-link.destacado {
    background: var(--brand-steel); color: #fff; font-weight: var(--fw-bold);
    margin-bottom: 6px;
  }
  .nav-drawer-link.destacado:hover { background: var(--accent-bg-hover); color: #fff; }
  .nav-drawer-link.destacado i, .nav-drawer-link.destacado.active i { color: #fff; }

  /* Cuenta: solo el avatar, como círculo de 40px sin borde de pastilla. */
  .acct-btn.is-logged { padding: 0; border: none; gap: 0; }
  .acct-btn.is-logged:hover { transform: none; }
  .acct-avatar { width: 40px; height: 40px; font-size: var(--fs-xs); }
  /* Cuenta (invitado): círculo con borde e icono en color de marca, bien visible
     sobre el header claro (el fondo accent-soft solo casi no se distingue del blanco). */
  .acct-btn:not(.is-logged) {
    width: 40px; height: 40px; padding: 0; gap: 0; justify-content: center; border-radius: 50%;
    border: 1.5px solid var(--border-default); background: var(--surface-card); color: var(--steel-600);
  }
  .acct-btn:not(.is-logged):hover { transform: none; border-color: var(--steel-400); background: var(--surface-accent-soft); }
  .acct-btn:not(.is-logged) .lucide, .acct-btn:not(.is-logged) i { width: 20px; height: 20px; color: inherit; }

  /* Carrito: círculo del mismo tamaño, con el contador encima. */
  .cart-btn { width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: 50%; }
  .cart-btn .lucide, .cart-btn i { width: 19px; height: 19px; }
  .cart-count {
    position: absolute; top: -3px; right: -3px;
    min-width: 18px; height: 18px; font-size: 10.5px;
    border: 2px solid var(--surface-card);
  }
}
@media (max-width: 560px) {
  .site-header .brand img { height: 27px; }
  .acct-panel { right: -8px; min-width: 200px; }
}
/* Bajo 720px el buscador no cabe en la línea con un ancho útil: pasa a la suya, a lo
   ancho, en vez de encogerse hasta no dejar leer lo que se escribe. */
@media (max-width: 720px) {
  .site-header .nav { flex-wrap: wrap; height: auto; padding-top: 10px; padding-bottom: 10px; row-gap: 10px; }
  .hdr-search { order: 3; flex-basis: 100%; max-width: none; }
}

/* Campo marcado como inválido por form-guard.js (validación reactiva). */
.is-invalid,
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 3px var(--danger-soft) !important;
}
.fg-error {
  display: flex; align-items: center; gap: 5px;
  margin-top: 6px; font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--danger);
}
.fg-error::before {
  content: ""; flex: none; width: 14px; height: 14px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ============ SEGUIMIENTO DEL PEDIDO (cliente) ============ */
/* Línea de tiempo: pagado → en preparación → enviado. Termina ahí porque el estado
   posterior lo tiene el courier y su seguimiento sigue en la web del courier.
   Vive acá y no en pago.css porque lo usan las dos vistas del pedido: el seguimiento
   público por token y el detalle dentro de la cuenta (que carga cuenta.css). */
.seg-pasos { display: flex; align-items: center; margin: 22px 0 4px; }
.seg-paso { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: none; }
.seg-dot {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  background: var(--surface-sunken); color: var(--text-muted);
  border: 1.5px solid var(--border-default);
}
.seg-paso.done .seg-dot { background: var(--green-600); border-color: var(--green-600); color: #fff; }
.seg-paso.current .seg-dot { background: var(--brand-navy); border-color: var(--brand-navy); color: #fff; }
.seg-lbl { font-size: var(--fs-2xs); color: var(--text-muted); text-align: center; }
.seg-paso.current .seg-lbl { color: var(--text-strong); font-weight: var(--fw-semibold); }
.seg-linea { flex: 1; height: 2px; background: var(--border-default); margin: 0 6px 22px; }
.seg-linea.done { background: var(--green-600); }

/* Sin pagar: reemplaza el stepper (no hay nada que avanzar todavía). Un solo bloque
   de acción (no un aviso + botón sueltos) para que se lea como algo urgente, no como
   un dato informativo más. */
.pago-pendiente {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 22px 0 4px; padding: 20px 22px; border-radius: 14px;
  background: var(--warning-soft); border: 1px solid var(--amber-500);
}
.pago-pendiente-ico {
  flex: none; align-self: flex-start; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center; background: rgba(168, 113, 26, .16); color: var(--amber-600);
}
.pago-pendiente-ico .lucide, .pago-pendiente-ico i { width: 19px; height: 19px; }
.pago-pendiente-texto { flex: 1 1 320px; }
.pago-pendiente-texto strong { display: block; font-size: var(--fs-md); color: var(--text-strong); margin-bottom: 4px; }
.pago-pendiente-texto p { margin: 0; font-size: var(--fs-sm); color: var(--text-body); line-height: var(--lh-snug); max-width: 48ch; }
.pago-pendiente .btn { flex: none; margin-left: auto; }

/* Envío bloqueado: mismo card que el despacho real, atenuado, para que la columna
   derecha no quede vacía sin explicación mientras el pago está pendiente. */
.seg-envio-locked { opacity: .55; }
.seg-envio-locked .seg-nota { display: flex; align-items: center; gap: 7px; }
.seg-envio-locked .seg-nota .lucide, .seg-envio-locked .seg-nota i { width: 13px; height: 13px; flex: none; }

/* Productos dentro del card de resumen: el total cierra la lista y se separa de los
   datos secundarios (fecha, documento) que van debajo. */
.seg-item span { color: var(--text-body); }
.seg-total { border-top: 1px solid var(--border-subtle); margin-top: 6px; padding-top: 12px; }
.seg-total strong { font-size: var(--fs-md); color: var(--text-strong); font-weight: var(--fw-extra); }

/* Resumen + despacho lado a lado en pantallas anchas. align-items:start para que la
   card corta no se estire al alto de la otra. */
.seg-cols { display: grid; grid-template-columns: 1fr; gap: 18px; margin-top: 22px; align-items: start; }
@media (min-width: 900px) { .seg-cols { grid-template-columns: 1fr 1fr; } }

.seg-envio {
  padding: 18px; border-radius: 14px;
  background: var(--surface-card); border: 1px solid var(--border-subtle);
}
.seg-envio-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-size: var(--fs-sm); color: var(--text-strong); }
.seg-envio-head .lucide, .seg-envio-head i { width: 18px; height: 18px; color: var(--steel-600); }
.seg-nota { margin: 8px 0 0; font-size: var(--fs-sm); color: var(--text-body); line-height: 1.5; }

/* Novedades: los mensajes que el admin marcó como visibles para el cliente.
   Lo más reciente primero. En pantallas anchas van en dos columnas: en una sola fila
   vertical el bloque quedaba altísimo con pocas novedades largas. */
/* Una sola línea de tiempo, de arriba (lo más reciente) hacia abajo. En dos columnas
   los hitos se repartían por columna y el orden se leía en zigzag, con una línea
   vertical suelta por lado. El alto se controla acotando el ancho del texto, no
   partiendo la secuencia. */
.seg-eventos { display: flex; flex-direction: column; }
.seg-ev {
  position: relative; padding: 0 0 20px 26px; border-left: 2px solid var(--border-default);
}
.seg-ev:last-child { border-left-color: transparent; padding-bottom: 0; }
.seg-ev::before {
  content: ''; position: absolute; left: -6px; top: 4px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--surface-card); border: 2px solid var(--border-default);
}
/* El primero es lo último que pasó: es el hito que el cliente viene a ver. */
.seg-ev:first-child::before { background: var(--brand-navy); border-color: var(--brand-navy); }
.seg-ev:first-child .seg-ev-head strong { color: var(--brand-navy); }
.seg-ev-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.seg-ev-head strong { font-size: var(--fs-sm); color: var(--text-strong); }
.seg-ev-fecha { font-size: var(--fs-2xs); color: var(--text-subtle); font-family: var(--font-mono); }
/* Sin white-space: pre-line — el texto ya pasa por |linebreaksbr y los saltos se
   duplicarían. max-width: una línea de ~70 caracteres se lee mejor que una que cruza
   toda la pantalla, y de paso el bloque no se estira a lo ancho en desktop. */
.seg-ev-texto {
  margin: 5px 0 0; font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.65;
  max-width: 68ch;
}
