/* =========================================================
   INNOBANC — Sistema de diseño
   Identidad "banca premium": Negro Premium + Gris Carbón de fondo, Blanco
   Marfil como texto principal, y Oro Metálico / Oro Champagne como acento
   de marca (logo, botones principales, títulos destacados). Los ESTADOS
   (activo/pendiente/suspendido, cargos/abonos) siguen su propio semáforo
   verde/ámbar/rojo — es información, no decoración, y no se toca aunque
   el ámbar y el oro sean parientes cercanos.
   Tipografía: Playfair Display (serif, marca/títulos) + Montserrat (texto
   de interfaz), cargadas en cada plantilla vía Google Fonts.
   ========================================================= */

:root {
  --ib-bg: #000000;              /* Negro Premium */
  --ib-bg-elev: #0d0d0c;
  --ib-surface: #1a1a1a;         /* Gris Carbón */
  --ib-surface-2: #262523;
  --ib-border: rgba(248, 246, 240, 0.08);
  --ib-border-strong: rgba(248, 246, 240, 0.16);

  --ib-silver: #d9d6c9;
  --ib-silver-strong: #f8f6f0;   /* Blanco Marfil */
  --ib-silver-dim: #9c9788;

  --ib-text: #f8f6f0;            /* Blanco Marfil */
  --ib-text-dim: #b8b3a4;
  --ib-text-faint: #7a7568;

  --ib-accent: #d4af37;          /* Oro Metálico */
  --ib-accent-strong: #f3d9a7;   /* Oro Champagne */
  --ib-accent-dim: rgba(212, 175, 55, 0.14);

  /* Color con propósito: solo para estados (activo/pendiente/suspendido) y cargos/abonos */
  --ib-verde: #34d399;
  --ib-verde-dim: rgba(52, 211, 153, 0.16);
  --ib-ambar: #fbbf24;
  --ib-ambar-dim: rgba(251, 191, 36, 0.16);
  --ib-rojo: #f87171;
  --ib-rojo-dim: rgba(248, 113, 113, 0.16);

  --ib-font-marca: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --ib-font-texto: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  --ib-radius-sm: 12px;
  --ib-radius: 20px;
  --ib-radius-lg: 28px;
  --ib-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
  --ib-shadow-soft: 0 1px 0 rgba(248, 246, 240, 0.05) inset, 0 14px 34px rgba(0, 0, 0, 0.45);
  --ib-shadow-elevated: 0 1px 0 rgba(248, 246, 240, 0.06) inset, 0 20px 46px rgba(0, 0, 0, 0.55);
  --ib-glass-top: linear-gradient(180deg, rgba(248, 246, 240, 0.05), rgba(248, 246, 240, 0) 40%);
  --ib-max-width: 480px;

  color-scheme: dark;
}

/* La textura de grano (html::before, position:fixed + mix-blend-mode) se quitó: en pantallas
   angostas/gama media hacía que la app se "pasmara" al deslizar, porque el navegador tiene que
   recomponer esa mezcla contra TODO lo que hay debajo en cada cuadro de scroll, en todas las
   pantallas (cliente y admin, era una regla global). No vale la pena el costo por un detalle tan
   sutil — ver Ampliación 29 en innobanc.md. */

/* Panel administrativo: mismo sistema; solo cambia el ancho del layout */
body.ib-admin {
  --ib-max-width: 1100px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--ib-bg);
  color: var(--ib-text);
  font-family: var(--ib-font-texto);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: contain;
  overflow-x: hidden; /* salvaguarda: nada debe generar scroll horizontal */
  max-width: 100vw;
}

.ib-field input,
.ib-field select,
.ib-field textarea { min-width: 0; } /* evita que un input empuje su fila fuera del contenedor flex */

body {
  min-height: 100dvh;
  padding-bottom: env(safe-area-inset-bottom);
}

a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 {
  margin: 0 0 4px;
  font-family: var(--ib-font-marca);
  font-weight: 500;
  letter-spacing: 0.01em;
}
p { margin: 0 0 8px; color: var(--ib-text-dim); }

/* Lockup de marca "INNOBANC" cuando aparece como texto (no como imagen) */
.ib-wordmark {
  font-family: var(--ib-font-marca);
  font-weight: 500;
  letter-spacing: 0.22em;
  color: var(--ib-accent);
}
.ib-tagline {
  font-family: var(--ib-font-texto);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ib-text-dim);
}

img { max-width: 100%; display: block; }
/* Sin esto, "display:block" (arriba) le gana al [hidden] nativo del navegador — mismo efecto
   colateral que ya se corrigió una vez para .ib-dots — así que cualquier <img hidden> quedaba
   visible (como ícono de imagen rota) en vez de oculto. */
img[hidden] { display: none; }

/* ---------- Accesibilidad: foco visible ----------
   Solo se muestra al navegar con teclado (:focus-visible), para no ensuciar
   el tap táctil normal; anillo dorado consistente con la marca. */
a:focus-visible,
button:focus-visible,
.ib-btn:focus-visible,
.ib-bottomnav__item:focus-visible,
.ib-admin-side a:focus-visible,
.ib-quickgrid a:focus-visible,
.ib-linkcard:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--ib-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ---------- Transición de entrada suave (sensación de app nativa) ---------- */
/* OJO: sin "both"/"forwards" a propósito. Mientras animation-fill-mode sostiene el fotograma
   final, los navegadores lo materializan como una matriz (aunque el keyframe diga "none"), y
   cualquier transform que no sea el literal "none" convierte a este elemento en el marco de
   referencia de sus descendientes position:fixed — eso "pegaba" a .ib-bottomnav respecto a esta
   caja en vez de respecto a la ventana, y dejaba de quedarse fijo al hacer scroll. Sin fill-mode,
   en cuanto la animación termina el elemento vuelve a su estado normal (sin transform), que ya es
   exactamente el que queríamos como destino — mismo resultado visual, sin el efecto colateral. */
@keyframes ibFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.ib-shell, .ib-admin-shell { animation: ibFadeIn .28s ease; }

/* ---------- Layout ---------- */

.ib-shell {
  max-width: var(--ib-max-width);
  margin: 0 auto;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1; /* por encima de .ib-ambient (fondo fijo con montañas/estrellas muy sutiles) */
  background: transparent;
}

.ib-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  padding-top: calc(16px + env(safe-area-inset-top));
  /* Sin backdrop-filter a propósito: en un elemento sticky forzaba a recomponer el desenfoque
     contra todo lo que pasa debajo en cada cuadro de scroll — la causa más probable de que la
     app se sintiera "pasmada" al deslizar. Se sube la opacidad para compensar visualmente. */
  background: rgba(0, 0, 0, 0.92);
  border-bottom: 1px solid var(--ib-border);
}
.ib-topbar::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, #bf953f 35%, #fcf6ba 45%, #b38728 50%, #fbf5b7 55%, #aa771c 65%, transparent);
  opacity: .55;
}

.ib-topbar__logo { width: 30px; height: 30px; object-fit: contain; }

.ib-topbar h1 {
  font-size: 17px;
  flex: 1;
  min-width: 0;
  color: var(--ib-silver-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Nombre del admin junto al título: en pantallas angostas ya no cabe cómodo junto al botón de
   menú + el título, así que se oculta ahí (sigue visible en el sidebar/perfil). */
.ib-topbar__admin-name { font-size: 12px; color: var(--ib-text-faint); flex-shrink: 0; }
@media (max-width: 480px) {
  .ib-topbar__admin-name { display: none; }
}

.ib-topbar__action {
  position: relative;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border);
  color: var(--ib-text-dim);
}

.ib-main {
  flex: 1;
  padding: 16px 16px 108px;
}

.ib-main--noNav { padding-bottom: 32px; }

/* ---------- Bottom nav: isla flotante (look & feel de app móvil moderna) ---------- */

.ib-bottomnav {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom));
  width: calc(100% - 28px);
  max-width: calc(var(--ib-max-width) - 28px);
  display: flex;
  justify-content: space-around;
  /* Mismo motivo que en .ib-topbar: sin backdrop-filter en un elemento fixed, compensando con
     más opacidad de fondo. */
  background: rgba(10, 10, 10, 0.95);
  border: 1px solid var(--ib-border-strong);
  border-radius: 24px;
  padding: 8px 6px;
  box-shadow: var(--ib-shadow-elevated);
  z-index: 30;
}

.ib-bottomnav__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 7px 4px;
  border-radius: 14px;
  color: var(--ib-text-faint);
  font-size: 9.5px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  text-align: center;
  transition: color .15s ease, background .15s ease;
}

.ib-bottomnav__item svg { width: 19px; height: 19px; transition: transform .2s cubic-bezier(.34,1.56,.64,1); }

.ib-bottomnav__item.is-active {
  color: #d4af37;
  background: var(--ib-accent-dim);
}
.ib-bottomnav__item.is-active svg { transform: translateY(-1px); stroke: url(#ibGoldGrad); }

/* Envoltura del ícono para poder anclar el badge de "pendientes" */
.ib-icon-wrap { position: relative; display: inline-flex; }

/* Badge de avisos sin leer: rojo, siempre visible sobre gris/blanco */
.ib-badge-dot {
  position: absolute;
  top: -5px;
  right: -7px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--ib-rojo);
  color: #1a0505;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 15px;
  text-align: center;
  border: 1.5px solid var(--ib-bg);
}

/* ---------- Tarjetas / superficies ---------- */

.ib-card {
  position: relative;
  background:
    linear-gradient(180deg, rgba(248, 246, 240, 0.035), rgba(248, 246, 240, 0) 46%),
    var(--ib-surface);
  border: 1px solid var(--ib-border);
  border-radius: var(--ib-radius);
  padding: 20px;
  margin-bottom: 14px;
  box-shadow: var(--ib-shadow-soft);
}

.ib-card--flat { box-shadow: none; }

.ib-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ib-text-faint);
  margin: 26px 2px 12px;
  font-weight: 700;
}
.ib-section-title::before {
  content: "";
  width: 3px;
  height: 13px;
  border-radius: 3px;
  background: linear-gradient(180deg, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c);
  flex-shrink: 0;
}

/* ---------- Botones ---------- */

.ib-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 14px 18px;
  border-radius: 16px;
  border: 1px solid transparent;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  transition: transform .12s ease, opacity .12s ease;
}
.ib-btn:active { transform: scale(0.98); }
.ib-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Oro metálico "de joyería": degradado de 5 tonos con recorrido animado al tocar/pasar el
   cursor, como una lámina de oro que refleja la luz. */
.ib-btn--primary {
  position: relative;
  overflow: hidden;
  border-radius: 999px;
  background: linear-gradient(to right, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c);
  background-size: 200% 200%;
  background-position: left center;
  color: rgb(121, 103, 3);
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: 5px 5px 10px rgba(0, 0, 0, .144);
  transition: transform .25s ease, background-position .8s ease;
}

@keyframes ibGoldShimmer {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

.ib-btn--primary:active {
  transform: scale(0.95);
  background-position: right center;
  animation: ibGoldShimmer 5s ease infinite;
}
@media (hover: hover) {
  .ib-btn--primary:hover {
    transform: scale(0.97);
    background-position: right center;
    animation: ibGoldShimmer 5s ease infinite;
  }
}

.ib-btn--primary:disabled {
  animation: none;
  opacity: .65;
  color: #7e7e7e;
  background: #dcdcdc;
  box-shadow: none;
}

.ib-btn--secondary {
  background: var(--ib-surface-2);
  border-color: var(--ib-border-strong);
  color: var(--ib-silver-strong);
}

.ib-btn--ghost {
  background: transparent;
  color: var(--ib-text-dim);
}

/* Acciones que desactivan/cierran algo: acento rojo para contraste */
.ib-btn--danger {
  background: var(--ib-rojo-dim);
  color: var(--ib-rojo);
  border: 1.5px solid rgba(248, 113, 113, .35);
  font-weight: 800;
  letter-spacing: .02em;
}
.ib-btn--danger:active { background: rgba(248, 113, 113, .24); }

/* Semáforo: activar/aprobar = verde, dejar pendiente = ámbar */
.ib-btn--verde {
  background: var(--ib-verde-dim);
  color: var(--ib-verde);
  border: 1.5px solid rgba(52, 211, 153, .35);
  font-weight: 800;
}
.ib-btn--verde:active { background: rgba(52, 211, 153, .24); }

.ib-btn--ambar {
  background: var(--ib-ambar-dim);
  color: var(--ib-ambar);
  border: 1.5px solid rgba(251, 191, 36, .35);
  font-weight: 800;
}
.ib-btn--ambar:active { background: rgba(251, 191, 36, .24); }

.ib-btn--sm { padding: 9px 14px; font-size: 13px; width: auto; border-radius: 10px; }

/* ---------- Formularios ---------- */

.ib-field { margin-bottom: 16px; }

.ib-field label {
  display: block;
  font-size: 12.5px;
  color: var(--ib-text-dim);
  margin-bottom: 6px;
  font-weight: 600;
}

.ib-field input,
.ib-field select,
.ib-field textarea {
  width: 100%;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border-strong);
  border-radius: 14px;
  padding: 13px 14px;
  color: var(--ib-text);
  /* 16px, no 15px: por debajo de 16px, Safari en iPhone hace zoom automático al tocar el campo
     (no se puede desactivar con meta viewport) — se sentía como que la app "se traba"/se comporta
     raro al usar cualquier formulario desde un iPhone. Ver Ampliación 35. */
  font-size: 16px;
  font-family: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.ib-field input:focus,
.ib-field select:focus,
.ib-field textarea:focus {
  outline: none;
  border-color: var(--ib-accent);
  box-shadow: 0 0 0 3px var(--ib-accent-dim);
}

.ib-field small { display: block; margin-top: 6px; color: var(--ib-text-faint); font-size: 11.5px; }
.ib-field.has-error input { border-color: var(--ib-silver-strong); border-width: 1.5px; }
.ib-field.has-error small.error { color: var(--ib-silver-strong); font-weight: 700; }

/* flex-wrap + una base mínima: en pantallas muy angostas (o con letra grande de accesibilidad)
   dos campos lado a lado (ej. dos fechas) ya no se aprietan sin límite — se apilan solos. */
.ib-row { display: flex; gap: 12px; flex-wrap: wrap; }
.ib-row > * { flex: 1 1 140px; }

/* ---------- Chips de estado ----------
   Sin matices: se distinguen por relleno/borde y un glifo, no por color. */

.ib-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  border: 1px solid transparent;
}
.ib-chip::before { font-size: 8px; line-height: 1; }

/* activo */
.chip-verde { background: var(--ib-verde-dim); color: var(--ib-verde); border-color: rgba(52,211,153,.3); }
.chip-verde::before { content: "●"; }

/* pendiente / revisión */
.chip-ambar { background: var(--ib-ambar-dim); color: var(--ib-ambar); border-style: dashed; border-color: rgba(251,191,36,.4); }
.chip-ambar::before { content: "◐"; }

/* suspendido */
.chip-rojo { background: var(--ib-rojo-dim); color: var(--ib-rojo); border-color: rgba(248,113,113,.3); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.chip-rojo::before { content: "■"; text-decoration: none; }

/* neutral / sin etapa */
.chip-gris { background: rgba(255,255,255,.04); color: var(--ib-text-faint); border-color: var(--ib-border); }
.chip-gris::before { content: "○"; }

/* ---------- Tarjeta bancaria (front/back flip) ---------- */

.ib-cardflip {
  perspective: 1200px;
  margin: 6px 0 4px;
}
.ib-cardflip__inner {
  position: relative;
  width: 100%;
  aspect-ratio: 1.586;
  transform-style: preserve-3d;
  transition: transform .55s cubic-bezier(.4,.2,.2,1);
}
.ib-cardflip.is-flipped .ib-cardflip__inner { transform: rotateY(180deg); }

.ib-cardflip__face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 20px;
  backface-visibility: hidden;
  padding: 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background:
    radial-gradient(circle at 15% 15%, rgba(255,255,255,.10), transparent 45%),
    linear-gradient(135deg, #242424, #0c0c0c 65%);
  border: 1px solid var(--ib-border-strong);
  color: var(--ib-silver-strong);
  box-shadow: var(--ib-shadow-elevated);
  /* variables que las variantes gold/platino sobreescriben */
  --ib-cf-fg: var(--ib-silver-strong);
  --ib-cf-fg-dim: var(--ib-text-faint);
  --ib-cf-fg-mid: var(--ib-text-dim);
}
.ib-cardflip__face--back { transform: rotateY(180deg); }

/* Brillo tipo "foil" holográfico — antes se movía sin parar (animation: infinite) en cada
   tarjeta visible; ahora es un brillo fijo (mismo look de reflejo de luz, sin animar) para no
   mantener el hilo de composición ocupado todo el tiempo en la pantalla de más tráfico de la
   app. Ver Ampliación 34. */
.ib-cardflip__face::after {
  content: "";
  position: absolute;
  inset: -40%;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,.16) 50%, transparent 58%);
  transform: translateX(-8%);
  pointer-events: none;
}

.ib-cardflip__top { display: flex; justify-content: space-between; align-items: flex-start; }
.ib-cardflip__tipo { font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--ib-cf-fg-mid); }
.ib-cardflip__logo { width: 46px; opacity: .9; }

/* Chip EMV simulado (sin imagen): un rectángulo dorado con líneas grabadas, como en una tarjeta real */
.ib-cardflip__chip {
  width: 38px;
  height: 28px;
  border-radius: 6px;
  margin: 10px 0 2px;
  background: linear-gradient(135deg, #f3d9a7, #d4af37 55%, #a9821f);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.5), inset 0 -1px 1px rgba(0,0,0,.35);
  position: relative;
  opacity: .92;
}
.ib-cardflip__chip::before {
  content: "";
  position: absolute;
  inset: 5px 4px;
  border: 1px solid rgba(0,0,0,.28);
  border-radius: 3px;
  background:
    linear-gradient(rgba(0,0,0,.28) 1px, transparent 1px) 0 33% / 100% 34%,
    linear-gradient(90deg, rgba(0,0,0,.28) 1px, transparent 1px) 50% 0 / 50% 100%;
}
.ib-cardflip--platino .ib-cardflip__chip { background: linear-gradient(135deg, #f4f6f7, #c9ced2 55%, #9aa1a7); }

.ib-cardflip__numero { position: relative; font-size: 19px; letter-spacing: .12em; font-weight: 600; margin: 8px 0; font-variant-numeric: tabular-nums; }
.ib-cardflip__bottom { position: relative; display: flex; justify-content: space-between; align-items: flex-end; font-size: 11px; color: var(--ib-cf-fg-mid); }
.ib-cardflip__bottom strong { display: block; color: var(--ib-cf-fg); font-size: 13px; font-weight: 600; }
.ib-cardflip__banda { height: 40px; background: #0a0a0a; margin: 6px -20px; }
.ib-cardflip__cvv { align-self: flex-end; background: #fff; color: #111; font-weight: 700; padding: 6px 12px; border-radius: 4px; font-size: 13px; letter-spacing: .1em; }

/* Tarjeta Gold: dorada, texto oscuro para contraste (como una tarjeta física dorada real) */
.ib-cardflip--gold .ib-cardflip__face {
  background:
    radial-gradient(circle at 15% 15%, rgba(255,255,255,.3), transparent 45%),
    linear-gradient(135deg, var(--ib-accent-strong), var(--ib-accent) 60%, #b8892a 100%);
  border-color: rgba(243, 217, 167, .5);
  --ib-cf-fg: #2a1d05;
  --ib-cf-fg-dim: rgba(42, 29, 5, .58);
  --ib-cf-fg-mid: rgba(42, 29, 5, .72);
}
.ib-cardflip--gold .ib-cardflip__face--back { background: linear-gradient(135deg, #b8892a, #7a5a1e 70%); }

/* Tarjeta Platino: plateada/metálica clara */
.ib-cardflip--platino .ib-cardflip__face {
  background:
    radial-gradient(circle at 15% 15%, rgba(255,255,255,.7), transparent 50%),
    linear-gradient(135deg, #eef0f2, #aab0b6 55%, #82898f 100%);
  border-color: rgba(255,255,255,.6);
  --ib-cf-fg: #1c2024;
  --ib-cf-fg-dim: rgba(28, 32, 36, .55);
  --ib-cf-fg-mid: rgba(28, 32, 36, .7);
}
.ib-cardflip--platino .ib-cardflip__face--back { background: linear-gradient(135deg, #c3c8cc, #8b9298 70%); }
.ib-cardflip--platino .ib-cardflip__banda { background: #1c2024; }

/* ---------- Copiar dato ---------- */

.ib-copytile {
  display: flex; align-items: center; justify-content: space-between;
  border: 1px solid var(--ib-border); border-radius: 12px; padding: 9px 12px; margin-bottom: 8px;
}
.ib-copytile__label { font-size: 10.5px; color: var(--ib-text-faint); display: block; }
.ib-copytile__value { font-size: 13px; font-weight: 600; color: var(--ib-text); }
.ib-copytile button {
  background: var(--ib-surface-2); border: 1px solid var(--ib-border-strong); color: var(--ib-text-dim);
  border-radius: 8px; padding: 6px 8px; cursor: pointer;
}

/* ---------- Quick actions (home) ---------- */

.ib-quickgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 14px 0 6px; }
.ib-quickgrid--3 { grid-template-columns: repeat(3, 1fr); }
.ib-quickgrid a {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 14px 4px 12px; border-radius: 16px; background: var(--ib-surface);
  border: 1px solid var(--ib-border); font-size: 10.5px; font-weight: 600; color: var(--ib-text-dim);
}
.ib-quickgrid__icon {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 12px;
  background: linear-gradient(150deg, var(--ib-accent-dim), rgba(212,175,55,.05));
  border: 1px solid rgba(212,175,55,.18);
}
.ib-quickgrid svg { width: 20px; height: 20px; stroke: url(#ibGoldGrad); color: #d4af37; }
.ib-quickgrid a { transition: transform .12s ease, background .15s ease, border-color .15s ease; }
.ib-quickgrid a:active { transform: scale(0.95); background: var(--ib-surface-2); }
@media (hover: hover) {
  .ib-quickgrid a:hover { border-color: var(--ib-border-strong); background: var(--ib-surface-2); }
}

/* ---------- Indicadores de carrusel (tarjetas en el home) ---------- */

.ib-dots { display: flex; justify-content: center; gap: 6px; margin: 2px 0 16px; }
.ib-dots[hidden] { display: none; }
.ib-dots__dot {
  width: 6px; height: 6px; border-radius: 999px; background: var(--ib-border-strong);
  border: none; padding: 0; cursor: pointer; transition: all .2s ease;
}
.ib-dots__dot.is-active { width: 18px; background: linear-gradient(90deg, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c); }

/* ---------- Toast / flash ---------- */

@keyframes ibFlashIn { from { opacity: 0; transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); } }

.ib-flash {
  position: fixed;
  /* Antes quedaba en top:12px, encima de la topbar — ahí tapaba el botón de menú/hamburguesa
     (y el de regresar) mientras el aviso estaba visible: un toque en esa zona le pegaba al
     aviso, no al botón, y parecía que el menú "no respondía". Se baja para que quede siempre
     debajo de la topbar (altura de la topbar + margen), nunca encima de sus botones. */
  top: calc(78px + env(safe-area-inset-top));
  left: 50%; transform: translateX(-50%);
  max-width: calc(var(--ib-max-width) - 24px); width: calc(100% - 24px);
  z-index: 40; padding: 13px 16px; border-radius: 14px; font-size: 13.5px; font-weight: 600;
  box-shadow: var(--ib-shadow); border: 1px solid var(--ib-border-strong);
  display: flex; align-items: center; gap: 10px;
  animation: ibFlashIn .25s ease both;
}
.ib-flash::before {
  flex-shrink: 0;
  font-size: 15px; font-weight: 800;
}
.ib-flash__msg { flex: 1; }
.ib-flash__close {
  flex-shrink: 0; background: transparent; border: none; color: inherit; opacity: .6;
  cursor: pointer; padding: 2px; display: flex; line-height: 0;
}
.ib-flash__close:active { opacity: 1; }
/* éxito: verde, marca de verificación */
.ib-flash--ok { background: #0f2a22; color: var(--ib-verde); border-color: rgba(52,211,153,.35); }
.ib-flash--ok::before { content: "✓"; }
/* error: rojo, símbolo de alerta */
.ib-flash--error { background: #2a1414; color: var(--ib-rojo); border-color: rgba(248,113,113,.4); border-width: 1.5px; }
.ib-flash--error::before { content: "!"; border: 1.5px solid currentColor; border-radius: 999px; width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; }
/* informativo: superficie neutra (gris) */
.ib-flash--info { background: var(--ib-surface-2); color: var(--ib-text); }
.ib-flash--info::before { content: "i"; font-style: italic; }

/* Variante "de flujo": para errores de validación de un formulario (login, transferencia, alta de
   cliente, etc.) que se muestran arriba del formulario en vez de como toast flotante. Antes estas
   pantallas ponían `style="position:static; width:100%"` en línea sobre `.ib-flash`, pero eso NO
   pisaba `left:50%` ni `transform:translateX(-50%)` de la clase base (pensados para el toast
   flotante) — en un elemento `position:static` el `left` no hace nada, pero el `transform` sí
   sigue aplicando, así que el aviso terminaba desplazado la mitad de su propio ancho hacia la
   izquierda, cortado fuera de la pantalla en móvil. Esta clase resetea eso — y también anula la
   animación `ibFlashIn` de la clase base, cuyos keyframes vuelven a fijar ese mismo
   `translate(-50%, ...)`: una animación en curso le gana al `transform` de aquí abajo aunque
   tenga más especificidad/orden, así que sin este `animation: none` el corrimiento reaparecía de
   todas formas apenas cargaba la página. */
.ib-flash--static {
  position: static; left: auto; transform: none; animation: none;
  width: 100%; max-width: none; margin-bottom: 14px;
}

/* ---------- Modal ---------- */

.ib-modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.55); backdrop-filter: blur(2px);
  display: flex; align-items: flex-end; justify-content: center; z-index: 90;
}
.ib-modal {
  background: var(--ib-surface); border: 1px solid var(--ib-border-strong);
  border-radius: 22px 22px 0 0; padding: 22px; width: 100%; max-width: var(--ib-max-width);
  max-height: 85dvh; overflow-y: auto;
}
@media (min-width: 560px) {
  .ib-modal-backdrop { align-items: center; }
  .ib-modal { border-radius: 22px; }
}
.ib-modal__row { display: flex; justify-content: space-between; padding: 9px 0; border-bottom: 1px dashed var(--ib-border); font-size: 13.5px; }
.ib-modal__row span:first-child { color: var(--ib-text-dim); }
.ib-modal__row span:last-child { font-weight: 600; }

/* ---------- Auth screens (login / registro) ---------- */

.ib-auth {
  position: relative;
  z-index: 1; /* por encima de .ib-scene (montañas + estrellas de fondo) */
  min-height: 100dvh; display: flex; flex-direction: column; align-items: center;
  justify-content: center; padding: 32px 22px; max-width: var(--ib-max-width); margin: 0 auto;
}
.ib-auth__logo {
  width: 150px;
  margin-bottom: 22px;
  filter: drop-shadow(0 0 26px rgba(212, 175, 55, 0.28));
  animation: ibLogoIn .6s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes ibLogoIn { from { opacity: 0; transform: translateY(-8px) scale(.96); } to { opacity: 1; transform: none; } }
.ib-auth .ib-card { width: 100%; }
.ib-auth__footer { margin-top: 22px; text-align: center; font-size: 12px; color: var(--ib-text-faint); }
.ib-auth__link { color: var(--ib-accent-strong); font-weight: 600; }

/* ---------- Stepper de registro ---------- */

.ib-steps { display: flex; gap: 6px; margin-bottom: 18px; }
.ib-steps__dot { flex: 1; height: 4px; border-radius: 4px; background: var(--ib-border-strong); }
.ib-steps__dot.is-active,
.ib-steps__dot.is-done { background: linear-gradient(90deg, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c); }

/* ---------- Movimientos / listas ---------- */

.ib-mov {
  display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--ib-border);
}
.ib-mov:last-child { border-bottom: none; }
.ib-mov__icon {
  width: 38px; height: 38px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  background: var(--ib-surface-2); flex-shrink: 0;
}
.ib-mov__body { flex: 1; min-width: 0; }
.ib-mov__title { font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ib-mov__sub { font-size: 11.5px; color: var(--ib-text-faint); }
.ib-mov__monto { font-size: 13.5px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* El signo +/- y el ícono de dirección ya distinguen cargo de abono; aquí solo variamos el peso */
.ib-mov__monto.cargo { color: var(--ib-rojo); }
.ib-mov__monto.abono { color: var(--ib-verde); font-weight: 800; }

/* ---------- Empty state ---------- */

.ib-empty { text-align: center; padding: 60px 20px; color: var(--ib-text-faint); }
.ib-empty svg {
  width: 30px; height: 30px; padding: 14px; margin-bottom: 14px;
  border-radius: 999px;
  background: radial-gradient(circle, var(--ib-accent-dim), rgba(212,175,55,.03) 70%);
  stroke: url(#ibGoldGrad);
  color: #d4af37;
  opacity: .85;
}

/* ---------- Token digital ---------- */

.ib-token { text-align: center; padding: 30px 10px; }
.ib-token__code { font-size: 44px; font-weight: 800; letter-spacing: .18em; color: var(--ib-accent-strong); margin: 14px 0; }
.ib-token__bar { height: 5px; border-radius: 5px; background: var(--ib-surface-2); overflow: hidden; margin-top: 16px; }
.ib-token__bar-fill { height: 100%; background: var(--ib-accent); transition: width 1s linear; }

/* ---------- Admin: tablas y sidebar ---------- */

.ib-admin-shell { display: flex; min-height: 100dvh; max-width: var(--ib-max-width); margin: 0 auto; position: relative; z-index: 1; }

/* Por debajo de 860px el sidebar es un cajón (drawer) que entra desde la izquierda — antes
   simplemente desaparecía (display:none) sin ninguna otra forma de navegar entre secciones desde
   un teléfono. Ver Ampliación 35. */
.ib-admin-side {
  width: 250px; flex-shrink: 0; background: var(--ib-bg-elev); border-right: 1px solid var(--ib-border);
  padding: 20px 14px;
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 90;
  overflow-y: auto;
  transform: translateX(-100%);
  transition: transform .25s ease;
}
.ib-admin-side.is-open { transform: translateX(0); box-shadow: var(--ib-shadow-elevated); }
.ib-admin-side__logo { width: 110px; margin: 0 auto 22px; display: block; }
.ib-admin-side a {
  display: flex; align-items: center; gap: 10px; padding: 13px 12px; border-radius: 10px;
  color: var(--ib-text-dim); font-size: 14px; font-weight: 600; margin-bottom: 4px;
}
.ib-admin-side a.is-active { background: var(--ib-accent-dim); color: var(--ib-accent-strong); }
.ib-admin-side a { transition: background .15s ease, color .15s ease; }
@media (hover: hover) {
  .ib-admin-side a:not(.is-active):hover { background: var(--ib-surface-2); color: var(--ib-text); }
}
.ib-admin-main { flex: 1; min-width: 0; }

@media (min-width: 860px) {
  .ib-admin-side {
    position: static; transform: none; transition: none; z-index: 1;
    width: 210px; box-shadow: none;
  }
}

.ib-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ib-table th { text-align: left; color: var(--ib-text-faint); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; padding: 8px 10px; border-bottom: 1px solid var(--ib-border-strong); }
.ib-table td { padding: 11px 10px; border-bottom: 1px solid var(--ib-border); vertical-align: middle; }
.ib-table tr:last-child td { border-bottom: none; }
.ib-table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--ib-border); border-radius: var(--ib-radius); }
/* Sombra hacia adentro en el borde derecho: avisa que hay más columnas por deslizar — solo
   aparece cuando el contenido de verdad se desborda (app.js la agrega/quita). Con box-shadow
   en vez de mask-image, que es más caro para el navegador. */
.ib-table-wrap--desborda { box-shadow: inset -22px 0 16px -18px rgba(0, 0, 0, .65); }
@media (hover: hover) {
  .ib-table tbody tr:hover { background: rgba(248, 246, 240, 0.03); }
}

/* ---------- Tarjetas de enlace (dashboard admin, listas de accesos) ---------- */

.ib-linkcard {
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  background: var(--ib-surface); border: 1px solid var(--ib-border); border-radius: var(--ib-radius);
  margin-bottom: 12px; transition: transform .12s ease, border-color .15s ease, background .15s ease;
}
.ib-linkcard:active { transform: scale(0.98); }
@media (hover: hover) {
  .ib-linkcard:hover { border-color: var(--ib-border-strong); background: var(--ib-surface-2); }
}
.ib-linkcard__icon {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 12px; display: flex;
  align-items: center; justify-content: center; background: var(--ib-accent-dim);
}
.ib-linkcard__icon svg { stroke: url(#ibGoldGrad); color: #d4af37; }
.ib-linkcard__body { flex: 1; min-width: 0; }
.ib-linkcard__title { font-size: 14px; font-weight: 700; color: var(--ib-text); }
.ib-linkcard__sub { font-size: 11.5px; color: var(--ib-text-faint); margin-top: 1px; }
.ib-linkcard__chevron { flex-shrink: 0; color: var(--ib-text-faint); }

.ib-searchbar { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.ib-searchbar input,
.ib-searchbar select {
  min-width: 0;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border-strong);
  border-radius: 12px;
  padding: 11px 13px;
  color: var(--ib-text);
  font-size: 16px; /* igual que .ib-field input: evita el zoom automático de Safari en iPhone */
  font-family: inherit;
}
.ib-searchbar input { flex: 2 1 180px; }
.ib-searchbar select { flex: 1 1 130px; }
.ib-searchbar input:focus,
.ib-searchbar select:focus { outline: none; border-color: var(--ib-accent); }
.ib-searchbar .ib-btn { flex-shrink: 0; width: auto; }

.ib-statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 18px; }
.ib-stat { background: var(--ib-surface); border: 1px solid var(--ib-border); border-radius: var(--ib-radius); padding: 16px; }
.ib-stat__value { font-size: 22px; font-weight: 800; color: var(--ib-silver-strong); font-variant-numeric: tabular-nums; }
.ib-stat__label { font-size: 11.5px; color: var(--ib-text-faint); }

.ib-tabs { display: flex; gap: 4px; background: var(--ib-surface-2); border-radius: 12px; padding: 4px; margin-bottom: 16px; }
.ib-tabs a { flex: 1; text-align: center; padding: 9px; border-radius: 9px; font-size: 12.5px; font-weight: 700; color: var(--ib-text-dim); }
.ib-tabs a.is-active { background: linear-gradient(to right, #bf953f, #fcf6ba, #b38728, #fbf5b7, #aa771c); color: rgb(121, 103, 3); }

.ib-actionbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }

.ib-drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 80; display: none; }
.ib-drawer-overlay.is-open { display: block; }

@media (min-width: 860px) {
  #ibAdminMenuBtn { display: none !important; }
}

hr.ib-hr { border: none; border-top: 1px solid var(--ib-border); margin: 14px 0; }

.ib-text-center { text-align: center; }
.ib-mt { margin-top: 14px; }
.ib-mb-0 { margin-bottom: 0; }

/* Número de versión: discreto, casi invisible, solo para soporte/depuración */
.ib-app-version { margin: 16px 0 0; text-align: center; font-size: 10.5px; color: var(--ib-text-faint); opacity: .6; }
.ib-admin-side .ib-app-version { margin-top: 10px; }

/* ---------- Carga de INE: tarjetas grandes y táctiles ----------
   Reemplaza el <input type="file"> nativo (diminuto, difícil de tocar) por una tarjeta con buen
   contraste y una etiqueta grande. Todo en unidades relativas y con min-height (no height fija)
   para que, si el usuario tiene la letra del sistema muy grande (accesibilidad), el texto pueda
   crecer y hacer más alta la tarjeta en vez de recortarse. */

.ib-ine-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 6px; }
@media (max-width: 360px) {
  .ib-ine-grid { grid-template-columns: 1fr; }
}

.ib-ine-slot { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }

.ib-ine-slot__preview,
.ib-ine-slot__empty {
  width: 100%;
  aspect-ratio: 8 / 5;
  border-radius: 12px;
}
.ib-ine-slot__preview { object-fit: cover; border: 1px solid var(--ib-border-strong); }
.ib-ine-slot__empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border: 1.5px dashed var(--ib-border-strong);
  color: var(--ib-text-faint);
  font-size: 12.5px;
  text-align: center;
  padding: 8px;
}

/* La etiqueta ES el botón (envuelve/apunta al input real, que queda oculto pero accesible) —
   min-height 44px cumple el tamaño mínimo de toque recomendado (Apple/Google), y crece con el
   contenido si el texto es más grande de lo normal. */
.ib-ine-slot__label {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px;
  padding: 10px 10px;
  border-radius: 12px;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border-strong);
  color: var(--ib-silver-strong);
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  line-height: 1.25;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.ib-ine-slot__label svg { flex-shrink: 0; }
.ib-ine-slot__label.is-ready { background: var(--ib-verde-dim); border-color: rgba(52,211,153,.35); color: var(--ib-verde); }
.ib-ine-slot__label:active { background: var(--ib-surface); }

/* Oculto visualmente pero sigue siendo accesible por teclado/lector de pantalla (nunca display:none). */
.ib-ine-slot__input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
