/* ============================================================
   Gymetric Design System (basado en prototipo Claude Design)
   Tokens, shell de panel (sidebar + topbar), cards, formularios.
   ============================================================ */

:root {
  --navy: #0F2A47;
  --navy-2: #06142A;
  --navy-3: #1a3356;
  --accent: #C6EF43;
  --accent-soft: rgba(198, 239, 67, 0.15);
  --bg: #EDEEEA;
  --surface: #FFFFFF;
  --surface-2: #F4F5F1;
  --surface-3: #F1F2EE;
  --border: rgba(15, 42, 71, 0.08);
  --border-strong: rgba(15, 42, 71, 0.16);
  --text: #0F2A47;
  --muted: #6B7A85;
  --danger: #E04040;
  --warn: #E6A23C;
  --success: #3FB950;
  --info: #2A9DCC;

  --radius-card: 14px;
  --radius-input: 7px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 3px rgba(15, 42, 71, 0.06);
  --shadow-md: 0 8px 24px -10px rgba(15, 42, 71, 0.18);
  --shadow-lg: 0 18px 40px -16px rgba(15, 42, 71, 0.28);

  --sidebar-w: 240px;
  --sidebar-w-collapsed: 72px;
  --topbar-h: 64px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.005em;
}

/* Tipografía display para títulos y números */
.gm-display {
  font-family: 'Manrope', sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* ============================================================
   Login (split-screen)
   ============================================================ */
.gm-login { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }

.gm-login-brand {
  position: relative;
  background: radial-gradient(ellipse at 30% 20%, var(--navy-3) 0%, var(--navy) 45%, var(--navy-2) 100%);
  color: #F1F2EE;
  padding: 48px 56px;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.gm-login-brand::before {
  content: ''; position: absolute; top: -200px; right: -180px;
  width: 520px; height: 520px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,239,67,.28), transparent 60%);
  filter: blur(20px);
}
.gm-login-brand::after {
  content: ''; position: absolute; bottom: -180px; left: -120px;
  width: 480px; height: 480px; border-radius: 50%;
  background: radial-gradient(circle, rgba(36,64,94,.7), transparent 65%);
  filter: blur(30px);
}
.gm-login-grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-login-top { position: relative; z-index: 2; display: flex; justify-content: space-between; align-items: center; }
.gm-login-logo { display: flex; align-items: center; gap: 14px; }
.gm-login-logo-text { font-family: 'Manrope', sans-serif; font-weight: 700; letter-spacing: .12em; font-size: 18px; color: var(--accent); }
.gm-login-logo-sub { font-size: 11px; color: rgba(241,242,238,.55); letter-spacing: .12em; text-transform: uppercase; margin-top: 4px; }
.gm-login-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border-radius: var(--radius-pill);
  background: rgba(198,239,67,.12); color: var(--accent);
  font-size: 12px; font-weight: 600; border: 1px solid rgba(198,239,67,.25);
}
.gm-login-status span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  animation: gm-pulse 1.6s infinite; box-shadow: 0 0 8px var(--accent);
}
@keyframes gm-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

.gm-login-hero { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 36px; margin: 60px 0; }
.gm-login-eyebrow { display: inline-flex; align-items: center; gap: 10px; font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: rgba(241,242,238,.55); font-weight: 700; }
.gm-login-eyebrow::before { content: ''; width: 32px; height: 1px; background: var(--accent); }
.gm-login-title { font-family: 'Manrope', sans-serif; font-size: 60px; font-weight: 700; letter-spacing: -.035em; line-height: 1.02; margin: 0; color: #F1F2EE; }
.gm-login-title em { font-style: normal; color: var(--accent); position: relative; display: inline-block; }
.gm-login-title em::after { content: ''; position: absolute; left: 0; right: 0; bottom: 6px; height: 14px; background: rgba(198,239,67,.18); z-index: -1; border-radius: 4px; }
.gm-login-lede { font-size: 17px; color: rgba(241,242,238,.7); max-width: 460px; line-height: 1.55; margin: 0; }

.gm-login-fp { display: flex; align-items: center; gap: 18px; padding: 18px 22px; border-radius: 16px; background: rgba(241,242,238,.04); border: 1px solid rgba(241,242,238,.08); width: fit-content; }
.gm-login-fp-ring {
  width: 56px; height: 56px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(198,239,67,.2), rgba(198,239,67,.04));
  border: 1.5px solid rgba(198,239,67,.35);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); position: relative; overflow: hidden;
}
.gm-login-fp-ring::after {
  content: ''; position: absolute; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 12px var(--accent);
  animation: gm-scan 1.8s ease-in-out infinite;
}
@keyframes gm-scan { 0% { top: 6%; } 50% { top: 92%; } 100% { top: 6%; } }
.gm-login-fp-text-l { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: rgba(241,242,238,.5); font-weight: 700; }
.gm-login-fp-text-v { font-family: 'Manrope', sans-serif; font-weight: 700; color: var(--accent); margin-top: 2px; }

.gm-login-stats { position: relative; z-index: 2; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; padding-top: 28px; border-top: 1px solid rgba(241,242,238,.08); }
.gm-login-stat-l { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: rgba(241,242,238,.5); font-weight: 700; }
.gm-login-stat-v { font-family: 'Manrope', sans-serif; font-size: 28px; font-weight: 700; color: var(--accent); margin-top: 4px; letter-spacing: -.02em; }
.gm-login-stat-s { font-size: 12px; color: rgba(241,242,238,.6); margin-top: 2px; }

.gm-login-form-wrap { background: var(--surface); padding: 48px 56px; display: flex; flex-direction: column; min-height: 100vh; }
.gm-login-form-body { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 0; }
.gm-login-form-top { display: flex; justify-content: space-between; align-items: center; }
.gm-login-lang { display: flex; gap: 4px; padding: 4px; background: var(--surface-2); border-radius: var(--radius-pill); }
.gm-login-lang button { padding: 5px 12px; border-radius: var(--radius-pill); background: transparent; border: none; cursor: pointer; color: var(--muted); font-family: inherit; font-weight: 600; font-size: 12px; }
.gm-login-lang button.is-active { background: var(--navy); color: var(--accent); }
.gm-login-help { color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.gm-login-help:hover { color: var(--text); }

.gm-login-form { max-width: 420px; width: 100%; align-self: center; display: flex; flex-direction: column; gap: 22px; }
.gm-login-form h1 { font-family: 'Manrope', sans-serif; font-size: 32px; font-weight: 700; letter-spacing: -.02em; margin: 0; color: var(--text); }
.gm-login-form .gm-login-subtitle { color: var(--muted); margin: 6px 0 0; font-size: 14px; }

.gm-field { display: flex; flex-direction: column; gap: 7px; }
.gm-field-label {
  font-size: 12px; font-weight: 600; color: var(--text);
  /* El asterisco de requerido queda pegado al texto del label (no separado a la derecha) */
  display: inline-flex; align-items: center; gap: 3px;
  text-transform: uppercase; letter-spacing: .06em;
}
.gm-field-input {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-input);
  padding: 0 12px; transition: border-color .15s, box-shadow .15s;
}
/* Focus: navy + halo verde accent (consistente con el DateForge df-active) */
.gm-field-input:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-field-input.is-invalid { border-color: var(--danger); box-shadow: 0 0 0 4px rgba(224,64,64,.08); }
/* Cuando un input/textarea/select queda inválido fuera del wrapper estándar
   (caso hero edit del cliente), pintamos el borde rojo en el input mismo. */
.gm-heroedit-field input.is-invalid,
.gm-heroedit-field select.is-invalid,
.gm-heroedit-field textarea.is-invalid {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 3px rgba(224,64,64,.10);
}
/* Variante textarea: padding vertical en lugar de altura fija, sin auto-center */
.gm-field-input.gm-field-input-textarea {
  align-items: stretch;
  padding: 8px 12px;
}
.gm-field-input.gm-field-input-textarea textarea {
  padding: 0;
  resize: vertical;
  min-height: 64px;     /* ~3 rows */
  line-height: 1.45;
}
.gm-field-input input,
.gm-field-input select,
.gm-field-input textarea {
  flex: 1; border: none; outline: none; background: transparent;
  padding: 8px 0; font-size: 14px; font-family: inherit; color: var(--text);
  line-height: 1.4;            /* iguala line-height entre input/select/textarea */
  min-width: 0;
  box-sizing: border-box;
}
/* Altura uniforme: 36px efectivos = 8 (pad) + 14*1.4 (line) + 8 (pad). */
.gm-field-input input[type="text"],
.gm-field-input input[type="email"],
.gm-field-input input[type="password"],
.gm-field-input input[type="number"],
.gm-field-input input[type="tel"],
.gm-field-input input[type="search"],
.gm-field-input input[type="url"],
.gm-field-input input[type="date"],
.gm-field-input select {
  height: 36px;
}
.gm-field-input select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  /* Flecha chevron en accent, más separada del texto, transition al focus */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230F2A47' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 2px center;
  padding-right: 26px;
  cursor: pointer;
  color: var(--text);
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.gm-field-input:focus-within select {
  /* La flecha rota suavemente al abrir el select para indicar interacción */
}
.gm-field-input select:disabled {
  cursor: not-allowed; opacity: .6;
  background-image: none;
}
.gm-field-input input:disabled,
.gm-field-input textarea:disabled {
  cursor: not-allowed; opacity: .6;
  background: transparent;
}
.gm-field-input:has(input:disabled),
.gm-field-input:has(textarea:disabled) {
  background: var(--surface-2, rgba(15, 42, 71, .04));
  border-color: var(--border, rgba(15, 42, 71, .12));
}
.gm-field-input select::-ms-expand { display: none; }
/* Estilos de las options nativas (alcance limitado por browser, pero
   los principales —Chrome, Edge— lo respetan en parte). */
.gm-field-input select option {
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  padding: 10px 12px;
}
.gm-field-input select option:checked,
.gm-field-input select option:hover {
  background: var(--accent-soft, rgba(198,239,67,.20));
  color: var(--text);
}
.gm-field-input select option[value=""] {
  color: var(--muted);
  font-style: italic;
}

/* Cuando un .gm-field-input vive DENTRO de un .gm-heroedit-field
   (caso País en el hero edit), tiene que igualar el look del hero
   (border 1.5px, height 38px) en lugar del look del drawer. */
.gm-heroedit-field > .gm-field-input {
  height: 38px;
  border: 1.5px solid var(--border);
  padding: 0 12px;
}
.gm-heroedit-field > .gm-field-input .gm-select-button {
  height: 100%;
  padding: 0;
}

/* El .gm-detail-hero tiene overflow:hidden (para clipear el ripple), pero
   en modo edit con dropdowns de select adentro, eso atrapaba el listado.
   En modo edit permitimos overflow visible: el ripple ya no se ejecuta
   estando en este estado (solo corre en la transición de apertura/cierre,
   no durante la edición), así que es seguro.
   El `.is-rippling` y `.is-rippling-rev` se sacan al final de la animación. */
.gm-detail-hero.is-editing:not(.is-rippling):not(.is-rippling-rev) {
  overflow: visible;
}
/* Z-index alto para que el dropdown se vea por encima del hero y el panel */
.gm-detail-hero.is-editing .gm-select-list {
  z-index: 100;
}

/* Aplicar el mismo refinamiento a los selects nativos dentro del hero edit */
.gm-heroedit-field select {
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230F2A47' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-position: right 10px center;
  padding-right: 32px !important;
}
.gm-heroedit-field select option {
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  padding: 10px 12px;
}
.gm-field-input button.gm-field-eye {
  background: none; border: none; color: var(--muted); cursor: pointer;
  display: flex; padding: 4px;
}
.gm-field-link { font-size: 12px; color: var(--navy); text-decoration: none; font-weight: 600; }
.gm-field-error { font-size: 12px; color: var(--danger); min-height: 0; display: none; }
.gm-field-input.is-invalid + .gm-field-error,
.gm-field-error.is-visible { display: block; }

.gm-check { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); cursor: pointer; user-select: none; }
.gm-check input { display: none; }
.gm-check-box {
  width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong);
  display: flex; align-items: center; justify-content: center;
  transition: all .15s; color: var(--navy); background: var(--surface);
}
.gm-check input:checked + .gm-check-box { background: var(--accent); border-color: var(--accent); }
.gm-check input:not(:checked) + .gm-check-box svg { display: none; }

.gm-btn-primary {
  width: 100%; padding: 14px 18px; border-radius: 12px;
  background: var(--navy); color: var(--accent);
  border: none; cursor: pointer;
  font-family: inherit; font-weight: 700; font-size: 14px; letter-spacing: .02em;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  transition: transform .2s, box-shadow .2s, opacity .2s;
}
.gm-btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 30px -10px rgba(15,42,71,.4); }
.gm-btn-primary:disabled { opacity: .65; cursor: not-allowed; transform: none; box-shadow: none; }
.gm-btn-primary .gm-btn-loading { display: none; }
.gm-btn-primary.is-loading .gm-btn-text { display: none; }
.gm-btn-primary.is-loading .gm-btn-loading { display: inline-flex; align-items: center; gap: 8px; }

.gm-spinner {
  width: 14px; height: 14px;
  border: 2px solid var(--accent);
  border-right-color: transparent;
  border-radius: 50%;
  animation: gm-spin .7s linear infinite;
  display: inline-block;
}
@keyframes gm-spin { to { transform: rotate(360deg); } }
/* Dentro de botones: hereda el color del texto del botón */
button .gm-spinner,
.gm-btn .gm-spinner,
.gm-btn-primary .gm-spinner {
  border-color: currentColor;
  border-right-color: transparent;
}
/* Variante grande */
.gm-spinner.is-lg { width: 28px; height: 28px; border-width: 3px; }
/* Estado "loading" centrado: contenedor con spinner verde grande y texto opcional */
.gm-loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px;
  padding: 40px 20px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}
.gm-loading .gm-spinner { width: 32px; height: 32px; border-width: 3px; }

.gm-login-foot { display: flex; justify-content: space-between; align-items: center; color: var(--muted); font-size: 12px; margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--border); }
.gm-login-foot a { color: var(--muted); text-decoration: none; }
.gm-login-foot a:hover { color: var(--text); }

/* Mobile hero: header navy compacto, solo visible en mobile */
.gm-login-mobile-hero { display: none; }

@media (max-width: 920px) {
  /* Mobile en LOGIN: ocupa exactamente el viewport, sin scroll.
     Solo aplica en la pantalla de login (body.gm-login-page). */
  body.gm-login-page { overflow: hidden; }
  body.gm-login-page html { overflow: hidden; }
  .gm-login {
    grid-template-columns: 1fr;
    min-height: 0;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }
  /* Oculto el panel navy grande (lo reemplaza el hero compacto) */
  .gm-login-brand { display: none; }
  /* Oculto la barra superior del form (selector idioma + soporte) */
  .gm-login-form-top { display: none; }

  .gm-login-form-wrap {
    padding: 0;
    min-height: 0;
    height: 100%;
    background: var(--surface);
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    overflow: hidden;
  }

  /* Header navy compacto arriba del form */
  .gm-login-mobile-hero {
    position: relative;
    display: block;
    background: radial-gradient(ellipse at 30% 30%, var(--navy-3) 0%, var(--navy) 55%, var(--navy-2) 100%);
    color: #F1F2EE;
    padding: 16px 24px 18px;
    border-radius: 0 0 22px 22px;
    overflow: hidden;
    box-shadow: 0 8px 22px -14px rgba(15, 42, 71, .35);
    margin-bottom: 0;
  }
  .gm-login-mobile-hero-grid {
    position: absolute; inset: 0;
    background-image:
      linear-gradient(rgba(241,242,238,.05) 1px, transparent 1px),
      linear-gradient(90deg, rgba(241,242,238,.05) 1px, transparent 1px);
    background-size: 36px 36px;
    -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
    mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
    pointer-events: none;
  }
  .gm-login-mobile-hero-glow {
    position: absolute; top: -80px; right: -60px;
    width: 240px; height: 240px; border-radius: 50%;
    background: radial-gradient(circle, rgba(198,239,67,.28), transparent 60%);
    filter: blur(18px); pointer-events: none;
  }
  .gm-login-mobile-hero-content {
    position: relative;
    z-index: 1;
    display: flex; flex-direction: column; gap: 8px;
  }
  .gm-login-mobile-hero-brand {
    display: flex; align-items: center; gap: 12px;
  }
  .gm-login-mobile-hero-brand img { display: block; flex-shrink: 0; }
  .gm-login-mobile-hero-brand strong {
    font-family: 'Manrope', sans-serif;
    font-weight: 700; letter-spacing: .12em; font-size: 15px;
    color: var(--accent);
    display: block;
  }
  .gm-login-mobile-hero-brand small {
    font-size: 11px;
    color: rgba(241,242,238,.55);
    letter-spacing: .12em;
    text-transform: uppercase;
    display: block;
    margin-top: 2px;
  }
  .gm-login-mobile-hero-tagline {
    font-family: 'Manrope', sans-serif;
    font-size: 17px; font-weight: 700;
    letter-spacing: -.015em;
    line-height: 1.15;
    color: #F1F2EE;
  }
  .gm-login-mobile-hero-tagline em {
    font-style: normal;
    color: var(--accent);
    position: relative;
    display: inline-block;
  }
  .gm-login-mobile-hero-tagline em::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 2px;
    height: 8px;
    background: rgba(198,239,67,.18);
    z-index: -1;
    border-radius: 3px;
  }

  /* El form se renderiza con padding lateral (el wrap ya no tiene) */
  .gm-login-form {
    flex: 1 1 auto;
    min-height: 0;
    padding: 18px 24px 12px;
    max-width: 100%;
    gap: 8px;
    justify-content: center;
    overflow: hidden;
  }
  .gm-login-form h1 { font-size: 20px; }
  .gm-login-form .gm-login-subtitle { font-size: 12px; margin-top: 2px; }
  .gm-login-form .gm-field { gap: 3px; }
  .gm-login-form .gm-field-label { font-size: 11px; }
  .gm-login-form .gm-field-input input { padding: 10px 0; font-size: 14px; }
  .gm-login-form .gm-check { font-size: 12px; }
  .gm-login-form .gm-btn-primary { padding: 12px 18px; }

  /* Espaciado de 15px entre contraseña → check "Mantener sesión" → botón */
  .gm-login-form .gm-field:last-of-type { margin-bottom: 15px; }
  .gm-login-form .gm-check { margin-bottom: 15px; }
  .gm-login-foot {
    padding: 4px 24px 12px;
    font-size: 11px;
  }
}

/* ============================================================
   Shell del panel: sidebar + topbar + content
   ============================================================ */
body.gm-app-body { background: var(--bg); }
/* Shell raíz: flex de 2 columnas (sidebar fijo + main fluido).
   Nota: no usamos row/col de Bootstrap acá porque el ancho del sidebar
   se anima con transición (240px ↔ 72px). El sistema de grid de Bootstrap
   sí se usa en todo el contenido dentro de .gm-content. */
.gm-app {
  min-height: 100vh;
  display: flex;
}
.gm-sidebar { width: var(--sidebar-w); flex-shrink: 0; transition: width .25s ease; }
.gm-app.is-collapsed .gm-sidebar { width: var(--sidebar-w-collapsed); }
.gm-main { flex: 1; min-width: 0; }

.gm-sidebar {
  position: sticky; top: 0; align-self: start;
  height: 100vh;
  background: var(--navy);
  color: #DDE5EE;
  display: flex; flex-direction: column;
  overflow: visible;
  z-index: 40;
}

/* Pestaña pegada al borde derecho del sidebar (desktop)
   Sobresale del sidebar para colapsar/expandir el panel. */
.gm-sidebar-tab {
  position: absolute;
  /* Posición FIJA en px, anclada justo debajo del logo del header.
     (header ≈ 78px: padding 20+20 + logo 38). No usar % porque depende
     de la altura del viewport y el botón "sube" en pantallas bajas. */
  top: 84px; right: -17px;
  width: 17px; height: 24px;
  border-radius: 0 10px 10px 0;
  background: var(--navy);
  border: 1px solid rgba(255,255,255,.08);
  border-left: none;
  color: rgba(221,229,238,.55);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  z-index: 1;
  transition: background .15s, color .15s, width .15s, right .15s;
  box-shadow: 4px 0 12px rgba(0, 0, 0, 0.08);
}
.gm-sidebar-tab svg {
  width: 14px; height: 14px;
  display: block;
  flex-shrink: 0;
  transition: transform .25s ease;
  margin-right: 5px;
}
.gm-sidebar-tab:hover {
  background: var(--navy-2, #1a3a5c);
  color: var(--accent);
  width: 19px;
}
.gm-app.is-collapsed .gm-sidebar-tab svg {
  transform: rotate(180deg);
}
.gm-sidebar-head {
  padding: 20px 18px;
  display: flex; align-items: center; gap: 12px;
}
.gm-sidebar-logo {
  width: 38px; height: 38px; flex-shrink: 0;
  background: rgba(198,239,67,.12);
  border: 1px solid rgba(198,239,67,.24);
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
}
.gm-sidebar-logo img { width: 26px; height: 26px; }
.gm-sidebar-brand {
  display: flex; flex-direction: column;
  font-family: 'Manrope', sans-serif;
  letter-spacing: .12em;
  font-weight: 700; font-size: 14px;
  color: var(--accent);
  white-space: nowrap;
}
.gm-sidebar-brand small {
  font-family: 'Manrope', sans-serif;
  font-weight: 600; font-size: 10px; letter-spacing: .14em;
  color: rgba(221,229,238,.55); text-transform: uppercase;
  margin-top: 3px;
}
.gm-app.is-collapsed .gm-sidebar-brand,
.gm-app.is-collapsed .gm-sidebar-section-label,
.gm-app.is-collapsed .gm-sidebar-link span { display: none; }

.gm-sidebar-section-label {
  padding: 18px 18px 8px;
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(221,229,238,.4); font-weight: 700;
}
.gm-sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 0 10px; flex: 1; }
.gm-sidebar-link {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; border-radius: 10px;
  color: rgba(221,229,238,.78);
  text-decoration: none; font-size: 13px; font-weight: 500;
  transition: background .15s, color .15s;
  white-space: nowrap;
}
.gm-sidebar-link:hover { background: rgba(255,255,255,.05); color: #fff; }
.gm-sidebar-link.is-active {
  background: rgba(198,239,67,.12);
  color: var(--accent);
  box-shadow: inset 2px 0 0 var(--accent);
}
.gm-sidebar-link svg { width: 18px; height: 18px; flex-shrink: 0; }
.gm-app.is-collapsed .gm-sidebar-link { justify-content: center; padding: 11px; }

.gm-sidebar-foot {
  margin-top: auto;
  padding: 14px;
  border-top: 1px solid rgba(255,255,255,.06);
}

/* Indicadores de estado del sidebar (Internet + Lector) — apilados verticalmente */
.gm-sidebar-status {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}
.gm-sidebar-status-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.05);
  font-size: 12px;
  min-width: 0;
  transition: background .15s, border-color .15s;
  cursor: default;
}
.gm-sidebar-status-item:hover { background: rgba(255,255,255,.05); }
.gm-sidebar-status-ico {
  width: 16px; height: 16px;
  flex-shrink: 0;
  color: rgba(221,229,238,.55);
  transition: color .15s;
}
/* Animación sutil del icono cuando está online — mismo tempo que el dot */
.gm-sidebar-status-item[data-state="online"] .gm-sidebar-status-ico {
  animation: gmStatusIcoPulse 2s ease-in-out infinite;
}
@keyframes gmStatusIcoPulse {
  0%, 100% { opacity: .85; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.08); }
}
.gm-sidebar-status-text {
  display: flex; flex-direction: column;
  flex: 1; min-width: 0;
  line-height: 1.15;
}
.gm-sidebar-status-label {
  font-size: 10px; letter-spacing: .08em;
  color: rgba(221,229,238,.4);
  font-weight: 700; text-transform: uppercase;
}
.gm-sidebar-status-val {
  font-size: 12px; font-weight: 600;
  color: rgba(221,229,238,.85);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-sidebar-status-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--accent);
  box-shadow: 0 0 8px rgba(198,239,67,.6);
  animation: gmStatusPulse 2s ease-in-out infinite;
}
@keyframes gmStatusPulse {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.15); }
}

/* Estados visuales */
.gm-sidebar-status-item[data-state="online"] .gm-sidebar-status-ico { color: var(--accent); }
.gm-sidebar-status-item[data-state="online"] .gm-sidebar-status-dot { background: var(--accent); box-shadow: 0 0 8px rgba(198,239,67,.6); }

.gm-sidebar-status-item[data-state="warn"] .gm-sidebar-status-ico { color: #FFB02E; }
.gm-sidebar-status-item[data-state="warn"] .gm-sidebar-status-dot { background: #FFB02E; box-shadow: 0 0 8px rgba(255,176,46,.55); }

.gm-sidebar-status-item[data-state="offline"] .gm-sidebar-status-ico { color: #ff6b6b; }
.gm-sidebar-status-item[data-state="offline"] .gm-sidebar-status-dot {
  background: #ff6b6b; box-shadow: 0 0 8px rgba(220,62,62,.55);
  animation: none; /* offline no pulsa */
}
.gm-sidebar-status-item[data-state="offline"] .gm-sidebar-status-val { color: rgba(221,229,238,.55); }

/* Sidebar colapsado: apila los items (vuelven a vertical) y oculta texto */
.gm-app.is-collapsed .gm-sidebar-status { grid-template-columns: 1fr; gap: 4px; }
.gm-app.is-collapsed .gm-sidebar-status-item {
  justify-content: center;
  padding: 8px;
  gap: 6px;
}
.gm-app.is-collapsed .gm-sidebar-status-text { display: none; }
.gm-sidebar-logout {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border-radius: 10px;
  background: transparent;
  color: rgba(221,229,238,.7);
  border: 1px solid rgba(255,255,255,.06);
  text-decoration: none;
  font-family: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.gm-sidebar-logout:hover {
  background: rgba(224, 64, 64, 0.12);
  color: #fff;
  border-color: rgba(224, 64, 64, 0.4);
}
.gm-sidebar-logout svg { width: 18px; height: 18px; flex-shrink: 0; }
.gm-app.is-collapsed .gm-sidebar-logout { justify-content: center; padding: 11px; }
.gm-app.is-collapsed .gm-sidebar-logout span { display: none; }

/* Bloque de usuario en el topbar */
.gm-topbar-user-wrap { position: relative; display: inline-flex; }
.gm-topbar-user {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 12px 6px 6px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  max-width: 220px;
  cursor: pointer;
  font-family: inherit;
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.gm-topbar-user:hover { background: var(--surface); border-color: rgba(15,42,71,.18); }
.gm-topbar-user:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(15,42,71,.12); }
.gm-topbar-user[aria-expanded="true"] {
  background: var(--surface); border-color: rgba(15,42,71,.22);
}
.gm-topbar-user-chev {
  color: var(--muted);
  flex-shrink: 0;
  transition: transform .2s ease, color .15s;
}
.gm-topbar-user[aria-expanded="true"] .gm-topbar-user-chev { transform: rotate(180deg); color: var(--text); }
.gm-topbar-user-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--navy); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 12.5px;
  flex-shrink: 0;
}
.gm-topbar-user-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.1; }
.gm-topbar-user-text strong {
  color: var(--text); font-size: 12.5px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: 'Manrope', sans-serif; letter-spacing: -.005em;
}
.gm-topbar-user-text small { color: var(--muted); font-size: 10.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 600px) {
  .gm-topbar-user-text { display: none; }
  .gm-topbar-user { padding: 4px; gap: 6px; }
  .gm-topbar-user-chev { display: none; }
}

/* ===== Popover de usuario en el topbar ===== */
.gm-user-popover {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 60;
  width: 280px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 20px 60px -20px rgba(15, 42, 71, .28), 0 4px 14px -6px rgba(15, 42, 71, .16);
  overflow: hidden;
  animation: gmUserPopIn .14s ease-out;
}
.gm-user-popover[hidden] { display: none; }
@keyframes gmUserPopIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.gm-user-popover-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.gm-user-popover-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--navy); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 17px;
  flex-shrink: 0;
}
.gm-user-popover-id { min-width: 0; flex: 1; }
.gm-user-popover-id strong {
  display: block;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 14px;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.2;
}
.gm-user-popover-id small {
  display: block;
  font-size: 12px; color: var(--muted);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.gm-user-popover-meta { padding: 8px 4px; }
.gm-user-popover-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 12px;
  font-size: 13px;
}
.gm-user-popover-row-l {
  color: var(--muted);
  font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
}
.gm-user-popover-row-v {
  color: var(--text); font-weight: 600;
  text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 60%;
}

.gm-user-popover-foot {
  border-top: 1px solid var(--border);
  padding: 10px;
}
.gm-user-popover-profile,
.gm-user-popover-logout {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 10px 14px;
  border-radius: 10px;
  background: transparent;
  font-family: inherit; font-weight: 600; font-size: 13px;
  text-decoration: none;
  transition: background .15s, color .15s;
}
.gm-user-popover-profile { color: var(--text); }
.gm-user-popover-profile:hover { background: var(--surface-2); color: var(--text); }
.gm-user-popover-logout {
  color: var(--danger, #b43333);
  margin-top: 4px;
  border-top: 1px solid var(--border);
  border-radius: 0;
  padding-top: 14px;
}
.gm-user-popover-logout:hover {
  background: rgba(220, 62, 62, .08);
  color: #8d2929;
}

/* En mobile: el popover se centra y respeta los bordes */
@media (max-width: 600px) {
  .gm-user-popover {
    right: -8px;
    width: calc(100vw - 24px);
    max-width: 320px;
  }
}

.gm-main { display: flex; flex-direction: column; min-width: 0; }

.gm-topbar {
  position: sticky; top: 0; z-index: 50;
  min-height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 16px;
  padding: 0 24px;
}
.gm-topbar-toggle {
  display: none;
  width: 38px; height: 38px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text); cursor: pointer;
  align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.gm-topbar-toggle:hover { background: var(--surface); border-color: var(--border-strong); }
.gm-topbar-title {
  font-family: 'Manrope', sans-serif;
  font-size: 18px; font-weight: 700; letter-spacing: -.01em;
  display: flex; align-items: center; gap: 10px;
  min-width: 0; flex: 0 1 auto;
  overflow: hidden;
}
.gm-topbar-title > span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gm-topbar-title .gm-topbar-crumb {
  font-family: 'Manrope', sans-serif;
  font-weight: 600; font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted);
}
.gm-topbar-spacer { flex: 1; }
.gm-topbar-actions { display: flex; align-items: center; gap: 10px; }
.gm-topbar-btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 36px; padding: 0 14px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text); text-decoration: none;
  font-family: inherit; font-weight: 600; font-size: 13px;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
  cursor: pointer;
}
.gm-topbar-btn:hover { background: var(--surface); border-color: var(--border-strong); }
.gm-topbar-btn.is-primary { background: var(--navy); border-color: var(--navy); color: var(--accent); }
.gm-topbar-btn.is-primary:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); background: var(--navy); }
.gm-topbar-btn svg { width: 14px; height: 14px; }

.gm-content {
  /* Espacio uniforme de 24px (arriba = laterales). Abajo un poco más para el scroll. */
  padding: 24px 24px 40px;
  display: flex; flex-direction: column; gap: 22px;
}
/* El contenedor de alertas vacío NO debe ocupar espacio ni generar gap
   (si no, suma altura + gap de 22px y deja un hueco grande bajo el header). */
.gm-content > .alerts-container:empty { display: none; }

/* ============================================================
   Sección minimalista (.gm-section)
   Wrapper liviano para gráficas y bloques que necesitan altura
   pero NO un look de tarjeta. Sin fondo, sin sombra, sin borde
   alrededor: solo un encabezado opcional y padding interno.
   ============================================================ */
.gm-section { display: flex; flex-direction: column; gap: 12px; }
.gm-section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 0;
}
.gm-section-head h2,
.gm-section-head h3 {
  font-family: 'Manrope', sans-serif;
  font-size: 14px; font-weight: 700; letter-spacing: -.005em;
  margin: 0;
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--text);
}
.gm-section-head .gm-section-icon { color: var(--accent); display: inline-flex; }
.gm-section-body { min-height: 0; }

/* Filtros y barras de acción */
.gm-filterbar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: 14px;
  align-items: end;
}
/* ============================================================
   Paginación (.gm-pagination)
   Componente reusable para listas/tablas con muchos resultados.
   Layout: izquierda = info de rango, derecha = botones prev/numbers/next.
   ============================================================ */
.gm-pagination {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding: 14px 4px;
  font-size: 13px;
  color: var(--muted);
}
.gm-pagination-info { font-size: 12px; }
.gm-pagination-info strong { color: var(--text); font-weight: 600; font-family: 'Manrope', sans-serif; font-variant-numeric: tabular-nums; }
.gm-pagination-pages {
  display: inline-flex; align-items: center; gap: 4px;
}
.gm-pagination-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; height: 34px;
  padding: 0 10px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  transition: background .12s, border-color .12s, color .12s;
}
.gm-pagination-btn:hover:not(:disabled):not([data-active="true"]) {
  background: var(--surface-2);
  border-color: var(--border-strong);
}
.gm-pagination-btn[data-active="true"] {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--accent);
  cursor: default;
}
.gm-pagination-btn:disabled {
  opacity: .4;
  cursor: not-allowed;
}
.gm-pagination-btn svg { width: 14px; height: 14px; }
.gm-pagination-ellipsis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px;
  color: var(--muted);
  font-weight: 700;
}
@media (max-width: 600px) {
  .gm-pagination { gap: 8px; padding: 12px 0; }
  .gm-pagination-info { width: 100%; text-align: center; }
  .gm-pagination-pages { width: 100%; justify-content: center; }
  .gm-pagination-btn { min-width: 32px; height: 32px; padding: 0 8px; font-size: 12px; }
}

/* ============================================================
   Custom select / combobox (.gm-select)
   Reemplaza el <select> nativo que el SO dibuja sin estilos.
   El JS gm-select.js infla cualquier <select> con clase .gm-native
   o dentro de un .gm-field-input y crea esta estructura.
   ============================================================ */
.gm-select { position: relative; width: 100%; min-width: 0; }
.gm-select-native {
  /* El <select> original queda oculto pero sigue siendo el source of truth
     para forms (su .value se sincroniza desde el JS). */
  position: absolute; inset: 0;
  opacity: 0; pointer-events: none;
  width: 100%; height: 100%;
}
.gm-select-button {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-width: 0;
  background: transparent; border: none;
  padding: 8px 22px 8px 0;            /* mismo padding vertical que .gm-field-input input */
  font-family: inherit; font-size: 14px; color: var(--text);
  cursor: pointer; text-align: left;
  position: relative;
}
.gm-select-button:focus { outline: none; }
.gm-select-value {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gm-select-value.is-placeholder { color: var(--muted); }
.gm-select-chevron {
  position: absolute; right: 0; top: 50%;
  transform: translateY(-50%) rotate(0deg);
  transition: transform .15s ease;
  color: var(--muted);
  pointer-events: none;
  display: inline-flex;
}
.gm-select.is-open .gm-select-chevron { transform: translateY(-50%) rotate(180deg); }

.gm-select-list {
  position: absolute;
  top: calc(100% + 6px);
  left: -14px; right: -14px;
  z-index: 60;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-lg);
  padding: 6px;
  max-height: 280px;
  overflow-y: auto;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  list-style: none; margin: 0;
  /* Cerrado: fuera del layout para que el dropdown absolute no extienda el
     scrollHeight del contenedor scrolleable (p.ej. el body del wizard), lo que
     generaba scroll/espacio en blanco fantasma al final del paso. */
  display: none;
}
.gm-select.is-open .gm-select-list {
  display: block;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.gm-select.drops-up .gm-select-list {
  top: auto; bottom: calc(100% + 6px);
  transform: translateY(4px);
}
.gm-select.is-open.drops-up .gm-select-list { transform: translateY(0); }

.gm-select-option {
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 13.5px;
  color: var(--text);
  cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  transition: background .1s, color .1s;
  user-select: none;
}
.gm-select-option:hover,
.gm-select-option.is-active {
  background: var(--surface-2);
  color: var(--text);
}
.gm-select-option.is-selected {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 600;
}
.gm-select-option.is-selected::after {
  content: '';
  margin-left: auto;
  width: 14px; height: 14px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230F2A47' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 12 10 18 20 6'/></svg>");
  background-repeat: no-repeat; background-position: center;
}
.gm-select-option.is-disabled {
  color: var(--muted); cursor: not-allowed; opacity: .6;
}
.gm-select-empty {
  padding: 14px 12px;
  color: var(--muted); font-size: 13px;
  text-align: center;
}

/* En filterbar la lista alinea con el borde del input */
.gm-filterbar .gm-select-list {
  left: -14px; right: -14px;
}

/* Variante dentro de un input wrapper: el botón ocupa todo el alto */
.gm-field-input > .gm-select { display: flex; }
.gm-field-input > .gm-select > .gm-select-button { padding-left: 0; }

/* Acciones dentro del filterbar: el botón ocupa toda la altura del input
   y se alinea con la base de los inputs (no con la base de las labels). */
.gm-filterbar-action {
  display: flex; align-items: stretch;
}
.gm-filterbar-action .gm-btn {
  width: 100%;
  height: auto;
  min-height: 47px;
  padding: 0 16px;
}

/* ============================================================
   Toolbar minimalista (.gm-toolbar)
   Barra pelada (sin card) con search + acciones + popover de filtros.
   ============================================================ */
.gm-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.gm-toolbar-search {
  width: 280px; max-width: 100%;
  display: flex; align-items: center; gap: 10px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-input);
  padding: 0 14px;
  height: 47px;
  transition: border-color .15s, box-shadow .15s;
}
@media (max-width: 600px) {
  .gm-toolbar { justify-content: stretch; }
  .gm-toolbar-search { width: 100%; order: -1; }
}
.gm-toolbar-search:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(15,42,71,.08);
}
.gm-toolbar-search svg { color: var(--muted); flex-shrink: 0; }
.gm-toolbar-search input {
  flex: 1; min-width: 0;
  border: none; outline: none; background: transparent;
  font-size: 14px; font-family: inherit; color: var(--text);
  padding: 0;
}
.gm-toolbar-search input::placeholder { color: var(--muted); }
.gm-toolbar-search-clear {
  background: none; border: none; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  color: var(--muted);
}
.gm-toolbar-search.has-value .gm-toolbar-search-clear { display: inline-flex; }
.gm-toolbar-search-clear:hover { background: var(--surface-2); color: var(--text); }

.gm-toolbar-action {
  height: 47px;
  padding: 0 14px;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-input);
  color: var(--text);
  font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
  position: relative;
  white-space: nowrap;
}
.gm-toolbar-action:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
.gm-toolbar-action.has-active {
  border-color: var(--navy);
  background: var(--navy);
  color: var(--accent);
}
.gm-toolbar-action svg { width: 16px; height: 16px; }
.gm-toolbar-action-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--accent); color: var(--navy);
  font-size: 11px; font-weight: 700;
  margin-left: 2px;
}
.gm-toolbar-action.is-icon-only {
  width: 47px;
  padding: 0;
  justify-content: center;
}

/* Popover de filtros (anclado al .gm-toolbar-action que lo abre) */
.gm-filter-popover {
  position: absolute;
  z-index: 80;
  top: calc(100% + 8px);
  right: 0;
  min-width: 320px;
  max-width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  opacity: 0; pointer-events: none;
  transform: translateY(-4px);
  transition: opacity .14s ease, transform .14s ease;
}
.gm-filter-popover.is-open {
  opacity: 1; pointer-events: auto;
  transform: translateY(0);
}
.gm-filter-popover-body {
  padding: 14px 18px;
  display: flex; flex-direction: column; gap: 14px;
  max-height: calc(100vh - 200px);
  overflow-y: auto;
}

/* Chips de filtros activos (debajo de la toolbar) */
.gm-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 4px;
}
.gm-chips:empty { display: none; }
.gm-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 4px 5px 12px;
  background: var(--accent-soft);
  border: 1px solid rgba(198,239,67,.45);
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.gm-chip-label { color: var(--muted); font-weight: 500; }
.gm-chip-value { color: var(--text); }
.gm-chip-remove {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  background: transparent; border: none;
  border-radius: 50%;
  color: var(--muted); cursor: pointer;
  margin-left: 2px;
}
.gm-chip-remove:hover { background: rgba(15,42,71,.1); color: var(--text); }

@media (max-width: 920px) {
  .gm-filter-popover {
    left: 0; right: 0;
    min-width: 0;
  }
}

/* ============================================================
   Tabla (.gm-table)
   Va envuelta en .gm-table-wrap, que actúa como card:
   surface + border + radius + overflow oculto.
   Look del design: eyebrow uppercase, filas con respiración,
   hover navy ultra-suave, separadores muy tenues.
   ============================================================ */
.gm-table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  position: relative;
}
.gm-table-wrap > .gm-table { display: table; }
.gm-table-wrap.is-scroll { overflow-x: auto; }
.gm-table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: 13.5px;
}
.gm-table thead th {
  text-align: left;
  font-family: 'Manrope', sans-serif;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  white-space: nowrap;
  position: sticky; top: 0;
}
.gm-table thead th:first-child { padding-left: 26px; }
.gm-table thead th:last-child { padding-right: 26px; }
.gm-table tbody td {
  padding: 16px 22px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}
.gm-table tbody td:first-child { padding-left: 26px; }
.gm-table tbody td:last-child { padding-right: 26px; }
.gm-table tbody tr {
  transition: background .12s;
}
.gm-table tbody tr:last-child td { border-bottom: none; }
.gm-table tbody tr:hover td {
  background: rgba(15, 42, 71, 0.025);
}
.gm-table .gm-table-empty {
  text-align: center; color: var(--muted); padding: 56px 22px;
  font-size: 13px;
}
.gm-table .gm-cell-strong {
  font-weight: 700; color: var(--text);
  font-family: 'Manrope', sans-serif;
  letter-spacing: -.005em;
}
.gm-table .gm-cell-muted { color: var(--muted); }
.gm-table .gm-cell-time {
  font-family: 'Manrope', sans-serif; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.gm-table .gm-cell-num {
  font-family: 'Manrope', sans-serif; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.gm-table .gm-cell-actions { text-align: right; white-space: nowrap; }
.gm-table .gm-cell-actions .gm-btn { height: 32px; padding: 0 12px; font-size: 12px; }

/* @deprecated — usar .gm-pill.is-* en su lugar */
.gm-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: capitalize;
  border: 1px solid transparent;
  white-space: nowrap;
}
.gm-badge.gm-badge-success   { background: rgba(198,239,67,.18); color: #5a7300; border-color: rgba(198,239,67,.45); }
.gm-badge.gm-badge-info      { background: rgba(42,157,204,.12); color: #1B6B8C; border-color: rgba(42,157,204,.24); }
.gm-badge.gm-badge-primary   { background: rgba(15,42,71,.08); color: var(--navy); border-color: rgba(15,42,71,.18); }
.gm-badge.gm-badge-secondary { background: rgba(107,122,133,.12); color: var(--muted); border-color: rgba(107,122,133,.24); }
.gm-badge.gm-badge-warn      { background: rgba(230,162,60,.14); color: #8A5B1F; border-color: rgba(230,162,60,.28); }
.gm-badge.gm-badge-danger    { background: rgba(224,64,64,.12); color: #962020; border-color: rgba(224,64,64,.28); }
.gm-badge.gm-badge-accent    { background: var(--accent-soft); color: #51661B; border-color: rgba(198,239,67,.45); }

/* Empty / loading state genérico */
.gm-state {
  text-align: center; padding: 60px 24px; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.gm-state svg { color: var(--muted); opacity: .55; }

/* Alerts */
.gm-alert {
  border-radius: 12px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  background: var(--surface);
  display: flex; align-items: center; gap: 10px;
  font-size: 13px;
  color: var(--text);
}
.gm-alert.gm-alert-success { background: rgba(63,185,80,.08); border-color: rgba(63,185,80,.3); color: #2E7D38; }
.gm-alert.gm-alert-danger { background: rgba(224,64,64,.08); border-color: rgba(224,64,64,.3); color: #962020; }
.gm-alert.gm-alert-warning { background: rgba(230,162,60,.10); border-color: rgba(230,162,60,.3); color: #8A5B1F; }
.gm-alert.gm-alert-info { background: rgba(42,157,204,.08); border-color: rgba(42,157,204,.28); color: #1B6B8C; }
.gm-alert .gm-alert-close {
  margin-left: auto; background: none; border: none; cursor: pointer; color: inherit; opacity: .65;
}
.gm-alert .gm-alert-close:hover { opacity: 1; }

/* Cards de tarjetas (móvil para asistencia) */
.gm-mobile-cards { display: none; flex-direction: column; gap: 12px; }
.gm-mobile-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.gm-mobile-card-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; }
.gm-mobile-card-row .gm-mobile-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }

/* Chart container helpers */
.gm-chart-wrap { position: relative; min-height: 280px; padding: 4px 0 0; }
.gm-chart-wrap.is-square { display: flex; justify-content: center; align-items: center; min-height: 320px; }
.gm-chart-wrap.is-square > div { width: 100%; max-width: 460px; }
.gm-chart-empty { color: var(--muted); text-align: center; padding: 48px 0; font-size: 13px; }

/* ============================================================
   Dashboard de métricas (/metrics)
   Toolbar con presets + grid de chart cards (2 cols en desktop).
   ============================================================ */
.gm-metrics-toolbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 16px;
  padding-bottom: 4px;
}
.gm-metrics-presets {
  display: inline-flex; flex-wrap: wrap; gap: 8px;
}
.gm-metrics-presets .gm-chip {
  display: inline-flex; align-items: center;
  height: 34px; padding: 0 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
}
.gm-metrics-presets .gm-chip:hover {
  background: var(--surface-2);
  border-color: var(--border-strong);
}
.gm-metrics-presets .gm-chip.is-active {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--accent);
}
.gm-metrics-dates {
  display: inline-flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.gm-field.gm-field-compact { min-width: 150px; }
.gm-field.gm-field-compact .gm-field-input { height: 38px; }

/* ====== DateForge: estandarización global ======
   Todos los DateForge (métricas, hero edit, nueva membresía, fechas de cliente)
   usan el mismo tamaño/radius/focus que el resto de los inputs del sistema. */
/* DateForge inyecta su propio <style> con font-family:'Inter' en .df-wrap;
   el <style> inyectado llega al DOM después del <link> y gana en cascada.
   Subimos especificidad con el elemento para asegurar que Manrope prevalezca. */
div.df-wrap { font-family: 'Manrope', sans-serif; }
.df-fields { gap: 8px !important; }
.df-input {
  padding: 0 12px !important;
  height: 38px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  border-radius: var(--radius-input) !important;
  border: 1.5px solid var(--border) !important;
  background: var(--surface) !important;
  box-sizing: border-box !important;
  line-height: 1.4 !important;
}
.df-input:focus,
.df-input.df-active {
  border-color: var(--navy) !important;
  box-shadow: 0 0 0 4px rgba(198,239,67,.35) !important;
}
.df-label {
  font-size: 10.5px !important;
  margin-bottom: 5px !important;
}
.df-days-input {
  padding: 0 10px !important;
  height: 38px !important;
  font-size: 14px !important;
  border-radius: var(--radius-input) !important;
}

/* Alinear vertical el botón Aplicar con los inputs cuando hay label encima */
.gm-metrics-dates #calculateBtn { align-self: flex-end; }

/* ====== Métricas: rango de fechas como UN solo control ======
   DateForge en modo range genera 2 campos (inicio/fin). En esta pantalla los
   fusionamos visualmente en una única caja con un guion en medio, para que no
   se perciba como "dos datepickers". Scoped a #metricsDateForge: no afecta a
   otros DateForge de la app. */
#metricsDateForge .df-fields.df-fields-2 {
  grid-template-columns: 96px auto 96px !important;
  width: max-content;
  align-items: center;
  gap: 0 !important;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-input);
  background: var(--surface);
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s;
}
/* Inputs compactos: solo lo ancho que necesita "DD/MM/YYYY". */
#metricsDateForge .df-input { width: 96px !important; padding: 0 6px !important; }
/* Foco: resalta toda la caja cuando cualquiera de los 2 inputs está activo. */
#metricsDateForge .df-fields.df-fields-2:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
/* Ocultamos las etiquetas "Inicio"/"Fin" duplicadas. */
#metricsDateForge .df-field .df-label { display: none !important; }
/* Los inputs pierden su borde/fondo/sombra propios: la caja los envuelve. */
#metricsDateForge .df-input {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  text-align: center;
}
#metricsDateForge .df-input.df-start { text-align: right; }
#metricsDateForge .df-input.df-end { text-align: left; }
/* Posiciones explícitas: campo inicio → col 1, guion → col 2, fin → col 3. */
#metricsDateForge .df-fields.df-fields-2 > .df-field:nth-of-type(1) { grid-column: 1; }
#metricsDateForge .df-fields.df-fields-2 > .df-field:nth-of-type(2) { grid-column: 3; }
/* Guion separador entre inicio y fin (pseudo-elemento en la columna 2). */
#metricsDateForge .df-fields.df-fields-2::before {
  content: '–';
  grid-column: 2; grid-row: 1;
  color: var(--muted);
  padding: 0 4px;
  align-self: center;
  pointer-events: none;
}
/* Etiqueta única del control. La añadimos por CSS sobre el wrap. */
#metricsDateForge .df-wrap::before {
  content: 'Rango de fechas';
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 5px;
  letter-spacing: .02em;
}

/* Grid de gráficas y alertas: ahora se maneja con Bootstrap (row/col).
   La altura de las cards se iguala con height:100% para que las gráficas
   en la misma fila queden a la par. */
.gm-chart-card {
  display: flex; flex-direction: column;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s;
}
.gm-chart-card:hover { border-color: var(--border-strong); }
.gm-chart-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--border);
}
.gm-chart-card .gm-chart-wrap {
  padding: 18px 22px 18px;
}

/* ============================================================
   Card de alertas (4 tiles de contador por severidad)
   ============================================================ */
/* Grid de alertas ahora se maneja con Bootstrap (row/col).
   El tile se estira a 100% para llenar la col cuando hay alturas distintas. */
.gm-alerts-card { }
.gm-alert-tile {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 16px 16px;
  height: 100%;
  border-radius: 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  transition: background .15s, border-color .15s, transform .15s;
  position: relative;
  overflow: hidden;
}
.gm-alert-tile::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--muted);
  opacity: .35;
}
.gm-alert-icon {
  width: 38px; height: 38px;
  border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: rgba(15, 42, 71, 0.06);
  color: var(--navy);
  font-size: 15px;
}
.gm-alert-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gm-alert-count {
  font-family: 'Manrope', sans-serif;
  font-size: 26px; font-weight: 700; line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.gm-alert-label {
  font-size: 13px; font-weight: 700; color: var(--text);
}
.gm-alert-hint {
  font-size: 11.5px; color: var(--muted); font-weight: 500;
}

/* Severidades — solo aplican cuando count > 0 */
.gm-alert-tile[data-severity="warn"]:not(.is-zero) { background: rgba(230, 162, 60, 0.08); border-color: rgba(230, 162, 60, 0.25); }
.gm-alert-tile[data-severity="warn"]:not(.is-zero)::before { background: #E6A23C; opacity: 1; }
.gm-alert-tile[data-severity="warn"]:not(.is-zero) .gm-alert-icon { background: rgba(230, 162, 60, 0.18); color: #C57B1A; }

.gm-alert-tile[data-severity="danger"]:not(.is-zero) { background: rgba(224, 64, 64, 0.08); border-color: rgba(224, 64, 64, 0.25); }
.gm-alert-tile[data-severity="danger"]:not(.is-zero)::before { background: #E04040; opacity: 1; }
.gm-alert-tile[data-severity="danger"]:not(.is-zero) .gm-alert-icon { background: rgba(224, 64, 64, 0.18); color: #C12B2B; }

.gm-alert-tile[data-severity="info"]:not(.is-zero) { background: rgba(42, 157, 204, 0.08); border-color: rgba(42, 157, 204, 0.25); }
.gm-alert-tile[data-severity="info"]:not(.is-zero)::before { background: #2A9DCC; opacity: 1; }
.gm-alert-tile[data-severity="info"]:not(.is-zero) .gm-alert-icon { background: rgba(42, 157, 204, 0.18); color: #1F7CA3; }

/* Estado cero o cargando: tono neutro */
.gm-alert-tile.is-zero .gm-alert-count,
.gm-alert-tile.is-loading .gm-alert-count { color: var(--muted); }
.gm-alert-tile.is-loading { opacity: .7; }
.gm-chart-card-title {
  display: inline-flex; align-items: center; gap: 10px;
}
.gm-chart-card-title h2,
.gm-chart-card-title h3 {
  font-family: 'Manrope', sans-serif;
  font-size: 14px; font-weight: 700; letter-spacing: -.005em;
  margin: 0;
  color: var(--text);
}
.gm-chart-card-title .gm-section-icon { color: var(--accent); display: inline-flex; }
.gm-chart-card-range {
  font-size: 11.5px; font-weight: 600;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}

/* Botones secundarios */
.gm-btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 16px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text); cursor: pointer;
  font-family: inherit; font-weight: 600; font-size: 13px;
  transition: background .15s, border-color .15s, transform .15s, box-shadow .15s;
  text-decoration: none;
}
.gm-btn:hover { background: var(--surface); border-color: var(--border-strong); }
.gm-btn.is-primary { background: var(--navy); color: var(--accent); border-color: var(--navy); }
.gm-btn.is-primary:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.gm-btn:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }
.gm-btn svg { width: 14px; height: 14px; }
/* Variante peligro full color: rojo sólido relleno. */
.gm-btn.gm-btn-danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}
.gm-btn.gm-btn-danger:hover {
  background: #c62f2f;
  border-color: #c62f2f;
  color: #fff;
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

/* Util tipográficos */
.gm-muted { color: var(--muted); }
.gm-strong { font-weight: 600; color: var(--text); }
.gm-tnum { font-variant-numeric: tabular-nums; }

/* Responsivo */
@media (max-width: 920px) {
  :root { --sidebar-w: 240px; }
  .gm-app { grid-template-columns: 1fr; }
  .gm-sidebar {
    position: fixed; left: 0; top: 0; z-index: 100;
    width: var(--sidebar-w);
    height: 100vh;
    height: 100dvh; /* descontar la barra del navegador mobile */
    transform: translateX(-100%);
    transition: transform .25s ease;
    box-shadow: 0 0 40px rgba(0,0,0,.3);
    overflow-y: auto; /* si el contenido excede, el sidebar scrollea internamente — el foot siempre alcanza */
    -webkit-overflow-scrolling: touch;
  }
  /* La barra de navegación scrollea, pero el foot se queda anclado al final
     del flujo (margin-top: auto + flex). Aseguramos que no quede flotante. */
  .gm-sidebar-foot { position: sticky; bottom: 0; background: var(--navy); }
  .gm-app.is-mobile-open .gm-sidebar { transform: translateX(0); }
  .gm-app.is-collapsed { grid-template-columns: 1fr; }
  .gm-sidebar-overlay {
    display: none;
    position: fixed; inset: 0; background: rgba(6,20,42,.45); z-index: 99;
  }
  .gm-app.is-mobile-open .gm-sidebar-overlay { display: block; }
  .gm-sidebar-tab { display: none; }
  .gm-topbar-toggle { display: inline-flex; }
  .gm-content { padding: 16px 16px 32px; }
  .gm-topbar { padding: 0 14px; gap: 10px; }
  .gm-topbar-title { font-size: 16px; }
  .gm-table-wrap { display: none; }
  .gm-mobile-cards { display: flex; }
  .gm-table thead th { padding: 12px 16px; }
  .gm-table tbody td { padding: 12px 16px; }
}

@media (max-width: 600px) {
  .gm-topbar { padding: 0 12px; gap: 8px; min-height: 56px; }
  .gm-topbar-toggle { width: 40px; height: 40px; flex-shrink: 0; }
  .gm-topbar-title { font-size: 15px; }
  .gm-topbar-title .gm-topbar-crumb { display: none; }
  .gm-topbar-actions { gap: 6px; }
  .gm-topbar-btn {
    width: 40px; height: 40px;
    padding: 0; gap: 0;
    justify-content: center;
    flex-shrink: 0;
  }
  .gm-topbar-btn > span,
  .gm-topbar-btn { font-size: 0; }
  .gm-topbar-btn svg { width: 16px; height: 16px; }
}
@media (min-width: 921px) {
  .gm-mobile-cards { display: none !important; }
  .gm-sidebar-overlay { display: none !important; }
}

/* ============================================================
   Drawer (.gm-drawer)
   - Mobile <1100px: overlay con backdrop oscuro, drawer 480px desde
     la derecha (clásico).
   - Desktop ≥1100px: TRANSICIÓN DE PÁGINA. El sidebar y topbar quedan
     quietos. El .gm-content se desliza fuera a la izquierda y desde la
     derecha entra el drawer que ocupa toda la zona de contenido. El
     form interno queda centrado a 520px para mantenerse legible.
   El <body> recibe la clase `.gm-drawer-open` cuando hay drawer activo.
   ============================================================ */
.gm-drawer-overlay {
  position: fixed; inset: 0;
  z-index: 190;
  background: rgba(6, 20, 42, .55);
  backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease;
}
.gm-drawer-overlay.is-open { opacity: 1; pointer-events: auto; }

.gm-drawer {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  z-index: 200;
  width: 480px;
  max-width: 100vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -16px 0 40px -16px rgba(15, 42, 71, .25);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform .28s cubic-bezier(.2, .7, .2, 1);
}
.gm-drawer.is-open { transform: translateX(0); }

.gm-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.gm-drawer-head h3 {
  font-family: 'Manrope', sans-serif;
  font-size: 16px; font-weight: 700;
  margin: 0;
  display: inline-flex; align-items: center; gap: 10px;
}
.gm-drawer-close {
  background: transparent; border: none; cursor: pointer;
  width: 32px; height: 32px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted);
  transition: background .15s, color .15s;
}
.gm-drawer-close:hover { background: var(--surface-2); color: var(--text); }

.gm-drawer-body {
  padding: 20px 22px;
  overflow-y: auto;
  flex: 1;
  display: flex; flex-direction: column; gap: 16px;
}

.gm-drawer-foot {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px;
  padding: 14px 22px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  flex-shrink: 0;
}

/* ========== Desktop ≥1100px: drawer "push" (anterior comportamiento) ==========
   El drawer queda fijo a la derecha, el .gm-content reserva margen para
   que la tabla siga visible al lado. Sin overlay. */
@media (min-width: 1100px) {
  .gm-drawer { box-shadow: -8px 0 24px -16px rgba(15, 42, 71, .15); }

  body.gm-drawer-open .gm-drawer-overlay { display: none; }
  body.gm-drawer-open .gm-content {
    margin-right: 480px;
    transition: margin-right .22s cubic-bezier(.2, .7, .2, 1);
  }
  body.gm-drawer-open .gm-topbar {
    padding-right: calc(24px + 480px);
    transition: padding-right .22s cubic-bezier(.2, .7, .2, 1);
  }
}
.gm-content { transition: margin-right .22s cubic-bezier(.2, .7, .2, 1); }
.gm-topbar { transition: padding-right .22s cubic-bezier(.2, .7, .2, 1); }

/* Grid de form inputs (drawer / modal).
   Custom porque el dev raramente toca el reparto interno;
   si necesitás otro reparto en una nueva pantalla, usá row/col de Bootstrap. */
.gm-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.gm-form-grid .gm-field-full { grid-column: 1 / -1; }
@media (max-width: 520px) {
  .gm-form-grid { grid-template-columns: 1fr; }
}

/* Action buttons en tabla */
.gm-row-actions { display: inline-flex; gap: 4px; }
.gm-icon-btn {
  width: 32px; height: 32px; border-radius: 8px;
  background: transparent; border: 1px solid transparent;
  color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s, border-color .15s;
}
.gm-icon-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border); }
.gm-icon-btn.is-danger:hover { background: rgba(224,64,64,.08); color: #962020; border-color: rgba(224,64,64,.28); }
.gm-icon-btn svg { width: 14px; height: 14px; }

/* ============================================================
   Clients module (.gm-clients-*)
   Layout 2 columnas: lista de clientes con búsqueda+filtros (izq 360px)
   + detalle con hero navy + acordeones (der). Apila en mobile <1100px.
   ============================================================ */
/* Wrapper de acordeones del detalle/edición — fluye con la página (sin scroll interno) */
.gm-client-accordions {
  display: flex; flex-direction: column; gap: 14px;
  padding-bottom: 12px;
}

/* Chips de filtro de clientes (toolbar de la tabla) */
.gm-clients-list-chips {
  display: flex; gap: 6px;
  overflow-x: auto;
  margin: 0 -2px;
  padding: 0 2px 2px;
}
.gm-clients-list-chips::-webkit-scrollbar { display: none; }
.gm-clients-list-chips button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 12px; font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s;
}
.gm-clients-list-chips button:hover { color: var(--text); }
.gm-clients-list-chips button[data-active="true"] {
  background: var(--navy);
  color: var(--accent);
  border-color: var(--navy);
}

/* Avatar reutilizado en la tabla de clientes y en el hero del detalle */
.gm-client-row-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--navy);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 13px;
  flex-shrink: 0;
}

.gm-client-hero {
  position: relative;
  background: radial-gradient(ellipse at 30% 0%, var(--navy-3) 0%, var(--navy) 55%, var(--navy-2) 100%);
  color: #F1F2EE;
  border-radius: var(--radius-card);
  overflow: hidden;
  flex-shrink: 0; /* nunca se comprime, mantiene su altura natural */
}
.gm-client-hero::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-client-hero-main {
  position: relative; z-index: 1;
  padding: 24px;
  display: flex; align-items: center; gap: 20px;
  flex-wrap: wrap;
}
.gm-client-hero-avatar {
  width: 76px; height: 76px;
  border-radius: 50%;
  background: rgba(241,242,238,.1);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 24px;
  flex-shrink: 0;
}
.gm-client-hero-body { flex: 1; min-width: 200px; }
.gm-client-hero-name {
  font-family: 'Manrope', sans-serif;
  font-size: 26px; font-weight: 700;
  letter-spacing: -.02em;
  margin-top: 6px;
}
.gm-client-hero-meta {
  display: flex; flex-wrap: wrap; gap: 16px;
  margin-top: 8px;
  color: rgba(241,242,238,.75);
  font-size: 13px;
}
.gm-client-hero-meta span {
  display: inline-flex; align-items: center; gap: 6px;
}
.gm-client-hero-meta svg { width: 12px; height: 12px; flex-shrink: 0; }
.gm-client-hero-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.gm-client-hero-actions .gm-btn {
  background: rgba(241,242,238,.06);
  border-color: rgba(241,242,238,.18);
  color: #F1F2EE;
}
.gm-client-hero-actions .gm-btn:hover {
  background: rgba(241,242,238,.12);
  border-color: rgba(241,242,238,.32);
}
.gm-client-hero-actions .gm-btn.is-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--navy);
}
.gm-client-hero-actions .gm-btn.is-accent:hover {
  filter: brightness(.95);
  transform: translateY(-1px);
}

.gm-client-hero-stats {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
  border-top: 1px solid rgba(241,242,238,.08);
}
.gm-client-stat {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-right: 1px solid rgba(241,242,238,.08);
}
.gm-client-stat:last-child { border-right: none; }
.gm-client-stat svg { width: 18px; height: 18px; flex-shrink: 0; color: rgba(241,242,238,.6); }
.gm-client-stat.is-accent svg { color: var(--accent); }
.gm-client-stat-label {
  font-size: 10px; letter-spacing: .08em;
  color: rgba(241,242,238,.55);
  text-transform: uppercase; font-weight: 600;
}
.gm-client-stat-value {
  font-family: 'Manrope', sans-serif;
  font-size: 16px; font-weight: 700;
  color: #F1F2EE;
  margin-top: 2px;
}
.gm-client-stat.is-accent .gm-client-stat-value { color: var(--accent); }

/* Accordion (.gm-accordion) — usado en el detalle del cliente */
.gm-accordion {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  /* Altura total cerrada: ~70px (header + bordes). Abierta: header + altura del contenido.
     El contenido tiene su propio max-height por categoría. */
  flex-shrink: 0;
}
.gm-accordion-trigger {
  width: 100%;
  padding: 16px 22px;
  display: flex; align-items: center; gap: 14px;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  color: var(--text);
  transition: background .12s;
}
.gm-accordion-trigger:hover { background: var(--surface-2); }
.gm-accordion-icon {
  width: 34px; height: 34px;
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.gm-accordion-icon svg { width: 18px; height: 18px; }
.gm-accordion-title {
  flex: 1;
  text-align: left;
  font-family: 'Manrope', sans-serif;
  font-size: 15px; font-weight: 700;
}
.gm-accordion-meta { color: var(--muted); font-size: 12px; }
.gm-accordion-chev {
  color: var(--muted);
  transition: transform .2s ease;
  display: inline-flex;
  flex-shrink: 0;
}
.gm-accordion.is-open .gm-accordion-chev { transform: rotate(180deg); }
.gm-accordion-content {
  padding: 16px 22px 22px;
  display: none;
  overflow-y: auto;
}
.gm-accordion.is-open .gm-accordion-content { display: block; }

/* Slide horizontal dentro del card de Membresía (lectura ↔ formulario).
   Mismo patrón que .gm-edit-pages pero local al card. */
.gm-membership-pages {
  position: relative;
  width: 100%;
  overflow: hidden;
}
/* Vista de LECTURA (las 2 cards): visible por defecto, en flujo normal. */
.gm-membership-pages > .gm-mem-view-read {
  display: flex; flex-direction: column; gap: 14px;
  transition: transform .28s cubic-bezier(.2, .7, .2, 1);
  will-change: transform;
}
/* Vista de FORM: oculta a la derecha, NO ocupa espacio (max-height 0).
   Sin contenedor propio (transparente): el head + las 2 cards (Datos y Pagos)
   flotan separados, cada card con su propio fondo blanco. */
.gm-membership-pages > .gm-mem-view-form {
  box-sizing: border-box;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  transform: translateX(100%);
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  pointer-events: none;
  transition: transform .28s cubic-bezier(.2, .7, .2, 1), opacity .2s ease;
  will-change: transform;
}
/* En modo form: la lectura se va (y se colapsa para no sumar altura),
   el form entra y toma su ALTURA NATURAL (sin forzar 100%). */
.gm-membership-pages[data-view="form"] > .gm-mem-view-read {
  transform: translateX(-100%);
  max-height: 0; overflow: hidden;
}
.gm-membership-pages[data-view="form"] > .gm-mem-view-form {
  transform: translateX(0);
  opacity: 1;
  max-height: none;
  overflow: visible;
  pointer-events: auto;
}
/* El contenedor del form-view es transparente para que el detalle de
   membresía (memFormEditCardsHtml) muestre sus 2 cards independientes.
   Pero los forms standalone (Registrar/Editar pago, Nueva membresía) NO
   traen card propia: van head + <form> sueltos. Cuando el form-view NO
   contiene las editcards, le devolvemos el estilo de card para que no
   floten sobre el blanco. */
.gm-membership-pages > .gm-mem-view-form:not(:has(.gm-mem-editcards)) {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 18px;
}

.gm-mem-form-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 14px;
}
.gm-mem-form-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text); cursor: pointer;
  flex-shrink: 0;
}
.gm-mem-form-back:hover { background: var(--surface); border-color: var(--border-strong); }
.gm-mem-form-back svg { width: 14px; height: 14px; }
/* Botón Volver bloqueado mientras hay cards en edición sin guardar:
   atenuado + cursor no-allowed (el click muestra el aviso, no cierra). */
.gm-mem-form-back.is-locked {
  opacity: .45;
  cursor: not-allowed;
}
.gm-mem-form-back.is-locked:hover {
  background: var(--surface-2); border-color: var(--border);
}
/* Sacudida del botón Volver cuando se intenta salir con cambios pendientes. */
.gm-mem-form-back.is-shake { animation: gmBackShake .4s ease; }
@keyframes gmBackShake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}
/* Resaltar las cards en edición que bloquean la salida. */
.gm-edit-card.is-flash {
  animation: gmCardFlash .8s ease;
}
@keyframes gmCardFlash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(15,42,71,0); }
  30% { box-shadow: 0 0 0 3px rgba(198,239,67,.55); }
}
.gm-mem-form-title {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 14px;
}
.gm-mem-form-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Botones de acción dentro de la vista lectura de Membresía */
.gm-mem-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.gm-mem-actions .gm-btn { height: 34px; padding: 0 12px; font-size: 12.5px; }
.gm-mem-actions .gm-btn svg { width: 13px; height: 13px; }

/* Alturas fijas por categoría cuando el acordeón está abierto.
   Si el contenido propio (lista de pagos, heatmap, etc.) excede el máximo,
   aparece scroll interno dentro del acordeón. */
.gm-accordion[data-acc-key="personal"] .gm-accordion-content { max-height: 300px; }
.gm-accordion[data-acc-key="membership"] .gm-accordion-content { max-height: 420px; }
.gm-accordion[data-acc-key="measurements"] .gm-accordion-content { max-height: 220px; }
.gm-accordion[data-acc-key="medical"] .gm-accordion-content { max-height: 300px; }
.gm-accordion[data-acc-key="attendance"] .gm-accordion-content { max-height: 280px; }

/* Scrollbar más sutil dentro de los acordeones */
.gm-accordion-content::-webkit-scrollbar { width: 6px; }
.gm-accordion-content::-webkit-scrollbar-track { background: transparent; }
.gm-accordion-content::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.gm-accordion-content::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* Grid de campos label/valor dentro del accordion */
.gm-fields-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: 18px;
}
.gm-field-readonly {
  min-width: 0;
}
.gm-field-readonly.is-wide { grid-column: 1 / -1; }
.gm-field-readonly-label {
  font-size: 10px; letter-spacing: .08em;
  color: var(--muted);
  text-transform: uppercase; font-weight: 700;
}
.gm-field-readonly-value {
  font-size: 14px; font-weight: 500;
  margin-top: 4px;
  word-break: break-word;
}
.gm-field-readonly-value.is-muted { color: var(--muted); font-style: italic; }

/* Tabla de pagos (dentro del accordion de Membresía) */
.gm-payments-list {
  display: flex; flex-direction: column;
  max-height: 200px;
  overflow-y: auto;
  margin-top: 6px;
  /* Padding-right para que el scrollbar no tape el contenido */
  padding-right: 4px;
}
.gm-payments-list::-webkit-scrollbar { width: 6px; }
.gm-payments-list::-webkit-scrollbar-track { background: transparent; }
.gm-payments-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.gm-payments-list::-webkit-scrollbar-thumb:hover { background: var(--muted); }
/* Heatmap de asistencia (estilo GitHub) */
.gm-attendance-heatmap {
  display: grid;
  grid-template-columns: repeat(auto-fill, 18px);
  gap: 3px;
  margin-bottom: 12px;
}
.gm-attendance-heatmap-cell {
  width: 18px; height: 18px;
  border-radius: 3px;
  background: rgba(198, 239, 67, .08);
}
.gm-attendance-heatmap-cell.is-l1 { background: rgba(198, 239, 67, .25); }
.gm-attendance-heatmap-cell.is-l2 { background: rgba(198, 239, 67, .55); }
.gm-attendance-heatmap-cell.is-l3 { background: rgba(198, 239, 67, .95); }
.gm-attendance-heatmap-legend {
  font-size: 11px; color: var(--muted);
  display: flex; align-items: center; gap: 8px;
}
.gm-attendance-heatmap-legend .gm-attendance-heatmap-cell { width: 12px; height: 12px; }

/* Placeholder "Próximamente" en acordeones sin backend aún */
.gm-coming-soon {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
  padding: 32px 20px;
  color: var(--muted);
  text-align: center;
  font-size: 13px;
}
.gm-coming-soon svg { width: 28px; height: 28px; opacity: .5; }

/* ============================================================
   Vista de edición del cliente — cards editables (.gm-edit-*)
   Usado dentro de la vista de edición de un cliente (Paso 1).
   Cada card tiene modo lectura (campos label+valor) o modo edición
   (campos input). Una sola card puede estar en edición a la vez.
   ============================================================ */
.gm-edit-view {
  display: flex; flex-direction: column;
  gap: 14px;
}
.gm-edit-view-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.gm-edit-view-head-left {
  display: flex; align-items: center; gap: 14px;
  min-width: 0;
}
.gm-edit-view-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); cursor: pointer;
  transition: background .12s, border-color .12s;
  flex-shrink: 0;
}
.gm-edit-view-back:hover { background: var(--surface-2); border-color: var(--border-strong); }
.gm-edit-view-back svg { width: 16px; height: 16px; }
.gm-edit-view-title {
  font-family: 'Manrope', sans-serif;
  font-size: 20px; font-weight: 700;
  letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.gm-edit-view-subtitle {
  color: var(--muted); font-size: 12px;
  margin-top: 2px;
}

.gm-edit-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: border-color .15s;
}
.gm-edit-card.is-editing { border-color: var(--navy); }
.gm-edit-card.is-disabled { opacity: .6; }

.gm-edit-card-head {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--border);
}
.gm-edit-card-icon {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.gm-edit-card-icon svg { width: 18px; height: 18px; }
.gm-edit-card-title {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.gm-edit-card-title h3 {
  font-family: 'Manrope', sans-serif;
  font-size: 15px; font-weight: 700;
  margin: 0;
}
.gm-edit-card-title-meta {
  font-size: 11px; color: var(--muted);
  font-weight: 500;
}
.gm-edit-card-actions {
  display: flex; gap: 8px; flex-shrink: 0;
}
.gm-edit-card-actions .gm-btn { height: 36px; padding: 0 12px; font-size: 13px; }
.gm-edit-card-actions .gm-btn svg { width: 14px; height: 14px; }

.gm-edit-card-body { padding: 22px; }
.gm-edit-card-body.is-locked { padding-top: 22px; padding-bottom: 22px; }

/* Banner "próximamente" dentro de una card que aún no tiene backend */
.gm-edit-card-coming {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
  padding: 28px 20px;
  color: var(--muted);
  text-align: center;
  font-size: 13px;
}
.gm-edit-card-coming svg { width: 28px; height: 28px; opacity: .5; }

/* Animación de transición desktop ↔ vista de edición (Paso 2)
   Estrategia robusta: las dos páginas son hermanas posicionadas
   absolutamente dentro del wrapper. Cada una se anima con su propio
   translateX según la clase `.is-edit` del wrapper. */
.gm-edit-pages {
  position: relative;
  width: 100%;
  max-width: 100%;
  /* Oculta el desborde horizontal de la vista que sale por la derecha durante el slide,
     sin crear scroll vertical interno (el scroll lo maneja la página). */
  overflow: hidden;
}
@media (min-width: 1100px) {
  /* Slide horizontal SIN altura fija: la página entera scrollea normalmente.
     La vista de edición se apila en la misma celda de grid y se desplaza con transform.
     Usamos minmax(0, 1fr) (no 1fr a secas) para que el grid respete el ancho del
     contenedor y los hijos puedan encogerse — si no, contenido ancho expande la celda. */
  .gm-edit-pages { display: grid; grid-template-columns: minmax(0, 1fr); }
  .gm-edit-pages > .gm-edit-pages-list,
  .gm-edit-pages > .gm-edit-pages-edit {
    grid-area: 1 / 1;            /* ambas en la misma celda, superpuestas */
    width: 100%;
    min-width: 0;                /* permite a los hijos encogerse */
    transition: transform .28s cubic-bezier(.2, .7, .2, 1);
    will-change: transform;
    box-sizing: border-box;
  }
  /* Estado por defecto: lista visible (en flujo), edición fuera a la derecha (oculta) */
  .gm-edit-pages > .gm-edit-pages-list { transform: translateX(0); visibility: visible; }
  .gm-edit-pages > .gm-edit-pages-edit { transform: translateX(100%); visibility: hidden; }
  /* Estado is-edit: lista a la izquierda (oculta), edición entra */
  .gm-edit-pages.is-edit > .gm-edit-pages-list { transform: translateX(-100%); visibility: hidden; }
  .gm-edit-pages.is-edit > .gm-edit-pages-edit { transform: translateX(0); visibility: visible; }
  /* La vista oculta no debe sumar altura al grid (si no, la página quedaría con
     la altura de la más larga). Colapsamos la que no se ve. */
  .gm-edit-pages:not(.is-edit) > .gm-edit-pages-edit { max-height: 0; overflow: hidden; }
  .gm-edit-pages.is-edit > .gm-edit-pages-list { max-height: 0; overflow: hidden; }
}
/* En mobile no hay slide: ocultamos/mostramos */
@media (max-width: 1099px) {
  /* Garantizar que el wrapper de la lista respete el ancho disponible */
  .gm-edit-pages > .gm-edit-pages-list { width: 100%; min-width: 0; box-sizing: border-box; }
  .gm-edit-pages > .gm-edit-pages-edit { display: none; }
  .gm-edit-pages.is-edit > .gm-edit-pages-list { display: none; }
  .gm-edit-pages.is-edit > .gm-edit-pages-edit { display: block; }
}

/* Estado "Seleccioná un cliente" cuando no hay cliente activo */
.gm-clients-empty-state {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px;
  min-height: 320px;
  padding: 40px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  color: var(--muted);
  text-align: center;
}
.gm-clients-empty-state svg { width: 40px; height: 40px; opacity: .4; }

/* ============================================================
   Roles module (.gm-roles-*)
   Layout 2 columnas: lista de roles a la izquierda (360px) + panel
   detalle a la derecha. Se apila en mobile <1100px.
   ============================================================ */
.gm-roles-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  align-items: start;
}
@media (min-width: 1100px) {
  .gm-roles-grid { grid-template-columns: 360px minmax(0, 1fr); }
}

.gm-roles-list { display: flex; flex-direction: column; gap: 10px; }

.gm-role-card {
  display: flex; align-items: center; gap: 14px;
  width: 100%;
  padding: 14px 16px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-card);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: border-color .15s, background .15s, transform .12s;
}
.gm-role-card:hover { border-color: var(--border-strong); background: var(--surface-2); }
.gm-role-card[data-active="true"] {
  border-color: var(--navy);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(15,42,71,.08);
}
.gm-role-card-icon {
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: 12px;
  background: var(--accent);
  color: var(--navy);
  display: flex; align-items: center; justify-content: center;
}
.gm-role-card-icon svg { width: 22px; height: 22px; }
.gm-role-card[data-active="true"] .gm-role-card-icon { background: var(--navy); color: var(--accent); }
.gm-role-card.is-inactive { opacity: .6; }
.gm-role-card.is-inactive .gm-role-card-icon { background: var(--surface-2); color: var(--muted); }

.gm-role-card-body { flex: 1; min-width: 0; }
.gm-role-card-name {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 15px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gm-role-card-meta {
  font-size: 12px; color: var(--muted);
  margin-top: 2px;
}
.gm-role-card-chev { color: var(--muted); flex-shrink: 0; }
.gm-role-card[data-active="true"] .gm-role-card-chev { color: var(--navy); }

.gm-role-detail {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
}
.gm-role-detail-hero {
  position: relative;
  padding: 24px;
  background: radial-gradient(ellipse at 30% 0%, var(--navy-3) 0%, var(--navy) 55%, var(--navy-2) 100%);
  color: #F1F2EE;
  overflow: hidden;
}
.gm-role-detail-hero::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-role-detail-hero::after {
  content: ''; position: absolute; top: -60px; right: -40px;
  width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,239,67,.2), transparent 60%);
  filter: blur(14px); pointer-events: none;
}
.gm-role-detail-hero-inner {
  position: relative; z-index: 1;
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap;
}
.gm-role-detail-eyebrow {
  font-size: 12px; letter-spacing: .12em;
  color: rgba(241,242,238,.6);
  text-transform: uppercase; font-weight: 600;
}
.gm-role-detail-name {
  font-family: 'Manrope', sans-serif;
  font-size: 28px; font-weight: 700;
  letter-spacing: -.02em;
  margin-top: 4px;
}
.gm-role-detail-desc {
  color: rgba(241,242,238,.75);
  margin-top: 6px;
  font-size: 13px;
  max-width: 520px;
}
.gm-role-detail-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.gm-role-detail-actions .gm-btn {
  background: rgba(241,242,238,.06);
  border-color: rgba(241,242,238,.18);
  color: #F1F2EE;
}
.gm-role-detail-actions .gm-btn:hover {
  background: rgba(241,242,238,.12);
  border-color: rgba(241,242,238,.32);
}
.gm-role-detail-actions .gm-btn.is-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--navy);
}
.gm-role-detail-actions .gm-btn.is-accent:hover {
  background: var(--accent);
  border-color: var(--accent);
  filter: brightness(.95);
  transform: translateY(-1px);
}

.gm-role-detail-body { padding: 24px; }
.gm-role-detail-section-label {
  font-size: 12px; letter-spacing: .08em;
  color: var(--muted);
  text-transform: uppercase; font-weight: 600;
  margin-bottom: 14px;
}
.gm-role-perm-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}
.gm-role-perm-item {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.gm-role-perm-icon {
  width: 36px; height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  color: var(--navy);
}
.gm-role-perm-icon svg { width: 16px; height: 16px; }
.gm-role-perm-name {
  flex: 1; min-width: 0;
  font-weight: 600;
  font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Segmento de 3 estados para permisos (Sin acceso / Solo ver / Gestionar)
   Usado en el drawer de edición de roles. */
.gm-perm-toggle {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2px;
  gap: 2px;
}
.gm-perm-toggle button {
  flex: 1;
  padding: 6px 10px;
  border-radius: 6px;
  background: transparent;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 11px; font-weight: 600;
  color: var(--muted);
  transition: background .12s, color .12s;
  white-space: nowrap;
}
.gm-perm-toggle button:hover:not([data-active="true"]) {
  background: var(--surface-2);
  color: var(--text);
}
.gm-perm-toggle button[data-active="true"][data-value="0"] { background: var(--surface-2); color: var(--muted); }
.gm-perm-toggle button[data-active="true"][data-value="1"] { background: rgba(42,157,204,.16); color: #1B6B8C; }
.gm-perm-toggle button[data-active="true"][data-value="2"] { background: var(--accent); color: var(--navy); }

/* Users-in-role: chips/avatars */
.gm-role-users {
  display: flex; flex-wrap: wrap; gap: 8px;
}
.gm-role-user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 14px 6px 6px;
  background: var(--surface-2);
  border-radius: var(--radius-pill);
  font-size: 13px;
}
.gm-role-user-chip-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 11px;
}
.gm-role-user-chip-name { font-weight: 600; color: var(--text); }
.gm-role-user-chip-meta { color: var(--muted); font-size: 12px; }

/* ============================================================
   Reader card (.gm-reader-card)
   Tarjeta navy compacta para mostrar el estado del lector biométrico
   y dar acceso al modo kiosk fullscreen. Va al lado de la tabla en
   /attendance-control en desktop ≥1100px.
   ============================================================ */
/* Layout ahora se maneja con Bootstrap: row > col-12 col-xl-8 (main) + col-12 col-xl-4 (side).
   El stacking vertical interno (toolbar + tabla / card + card) sigue siendo flex column. */
.gm-attendance-main { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.gm-attendance-side { display: flex; flex-direction: column; gap: 14px; }

.gm-reader-card {
  position: relative;
  background: radial-gradient(ellipse at 30% 0%, var(--navy-3) 0%, var(--navy) 55%, var(--navy-2) 100%);
  color: #F1F2EE;
  border-radius: var(--radius-card);
  padding: 24px;
  overflow: hidden;
  display: flex; flex-direction: column; gap: 14px;
}
.gm-reader-card::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-reader-card::after {
  content: ''; position: absolute; top: -80px; right: -60px;
  width: 220px; height: 220px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,239,67,.22), transparent 60%);
  filter: blur(14px); pointer-events: none;
}
.gm-reader-card > * { position: relative; z-index: 1; }

.gm-reader-card-head {
  display: flex; align-items: center; justify-content: space-between;
}
.gm-reader-card-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: rgba(198,239,67,.14);
  border: 1px solid rgba(198,239,67,.32);
  color: var(--accent);
  font-size: 12px; font-weight: 600;
}
.gm-reader-card-status .gm-reader-card-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  animation: gm-pulse 1.6s infinite;
}
.gm-reader-card-icon {
  color: var(--accent);
  display: inline-flex;
}
.gm-reader-card-eyebrow {
  font-size: 11px; letter-spacing: .12em;
  color: rgba(241,242,238,.55);
  text-transform: uppercase; font-weight: 700;
}
.gm-reader-card-title {
  font-family: 'Manrope', sans-serif;
  font-size: 22px; font-weight: 700;
  letter-spacing: -.01em;
  color: var(--accent);
  margin-top: 2px;
}
.gm-reader-card-desc {
  font-size: 13px;
  color: rgba(241,242,238,.7);
  line-height: 1.5;
}
.gm-reader-card-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--navy);
  border: none;
  cursor: pointer;
  font-family: inherit; font-weight: 700; font-size: 14px;
  letter-spacing: .02em;
  text-decoration: none;
  transition: transform .15s, box-shadow .15s;
  margin-top: 4px;
}
.gm-reader-card-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 28px -10px rgba(198,239,67,.5);
}
.gm-reader-card-btn svg { width: 16px; height: 16px; }

/* ============================================================
   Kiosk fullscreen (.gm-kiosk)
   Pantalla de auto-servicio con lector de huella. Fondo navy oscuro
   con grid sutil. Topbar propio + 3 columnas: fecha + feed | ring | stats.
   Sin sidebar/topbar del shell.
   ============================================================ */
body.gm-kiosk-body {
  background: var(--navy-2);
  color: #F1F2EE;
  overflow: hidden;
}
.gm-kiosk {
  position: fixed; inset: 0;
  background: radial-gradient(ellipse at 30% 20%, var(--navy-3) 0%, var(--navy) 45%, var(--navy-2) 100%);
  display: flex; flex-direction: column;
  color: #F1F2EE;
  overflow: hidden;
}
.gm-kiosk::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-kiosk::after {
  content: ''; position: absolute; top: -200px; right: -180px;
  width: 520px; height: 520px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,239,67,.16), transparent 60%);
  filter: blur(20px); pointer-events: none;
}

.gm-kiosk-topbar {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 32px;
  border-bottom: 1px solid rgba(241,242,238,.08);
  flex-shrink: 0;
}
.gm-kiosk-brand {
  display: flex; align-items: center; gap: 12px;
}
.gm-kiosk-brand img {
  width: 30px; height: 30px;
}
.gm-kiosk-brand-text {
  display: flex; flex-direction: column;
}
.gm-kiosk-brand-text strong {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; letter-spacing: .12em; font-size: 14px;
  color: var(--accent);
}
.gm-kiosk-brand-text small {
  font-size: 11px; color: rgba(241,242,238,.6);
  letter-spacing: .04em; margin-top: 2px;
}
.gm-kiosk-topbar-right {
  display: flex; align-items: center; gap: 18px;
}
.gm-kiosk-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: rgba(198,239,67,.12);
  border: 1px solid rgba(198,239,67,.25);
  color: var(--accent);
  font-size: 12px; font-weight: 600;
}
.gm-kiosk-pill .gm-kiosk-pill-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  animation: gm-pulse 1.6s infinite;
}
.gm-kiosk-clock {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 18px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.gm-kiosk-exit {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border-radius: 10px;
  background: transparent;
  border: 1px solid rgba(241,242,238,.12);
  color: rgba(241,242,238,.65);
  font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.gm-kiosk-exit:hover {
  background: rgba(220,62,62,.12);
  border-color: rgba(220,62,62,.4);
  color: #ff8a8a;
}

.gm-kiosk-main {
  position: relative; z-index: 2;
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1.3fr 1fr;
  gap: 32px;
  padding: 36px 48px 48px;
  overflow: hidden;
}
.gm-kiosk-left,
.gm-kiosk-right {
  display: flex; flex-direction: column;
  min-height: 0;
}
.gm-kiosk-center {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
}

/* Fecha grande (izquierda) */
.gm-kiosk-day {
  font-size: 14px; letter-spacing: .2em;
  color: var(--accent);
  font-weight: 600;
  text-transform: uppercase;
}
.gm-kiosk-date {
  font-family: 'Manrope', sans-serif;
  font-size: 64px; font-weight: 700;
  letter-spacing: -.03em; line-height: 1;
  margin-top: 8px;
  text-transform: lowercase;
}
.gm-kiosk-tagline {
  font-size: 22px; color: rgba(241,242,238,.7);
  margin-top: 12px;
}

.gm-kiosk-feed-label {
  font-size: 11px; letter-spacing: .12em;
  color: rgba(241,242,238,.5);
  text-transform: uppercase; font-weight: 600;
  margin-top: 48px;
  margin-bottom: 14px;
}
.gm-kiosk-feed {
  display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto;
  flex: 1;
}
.gm-kiosk-feed::-webkit-scrollbar { width: 0; }
.gm-kiosk-feed-item {
  display: flex; align-items: center; gap: 12px;
  transition: opacity .4s ease;
}
/* Degradado por antigüedad: el ingreso más reciente (arriba) va a opacidad
   plena y los más viejos (hacia abajo) se desvanecen progresivamente. Solo se
   muestran 5 ingresos (ver renderFeed); los extras quedan casi invisibles. */
.gm-kiosk-feed-item:nth-child(1) { opacity: 1; }
.gm-kiosk-feed-item:nth-child(2) { opacity: .80; }
.gm-kiosk-feed-item:nth-child(3) { opacity: .58; }
.gm-kiosk-feed-item:nth-child(4) { opacity: .36; }
.gm-kiosk-feed-item:nth-child(5) { opacity: .16; }
.gm-kiosk-feed-item:nth-child(n+6) { opacity: 0; }
.gm-kiosk-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--navy-3);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 13px;
  color: rgba(241,242,238,.85);
  flex-shrink: 0;
}
.gm-kiosk-feed-name {
  font-weight: 600; font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-kiosk-feed-sub {
  font-size: 12px; color: rgba(241,242,238,.55);
  margin-top: 2px;
}
.gm-kiosk-feed-time {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 14px;
  color: var(--accent);
  flex-shrink: 0;
}
.gm-kiosk-feed-empty {
  color: rgba(241,242,238,.4);
  font-size: 13px;
  padding: 12px 0;
}

/* Centro: huella ring (animación copiada del mini kiosk, escalada a 320px) */
.gm-fp-ring {
  position: relative;
  width: 320px; height: 320px;
  display: flex; align-items: center; justify-content: center;
  transition: transform .3s cubic-bezier(.2,.7,.2,1);
}
.gm-fp-ring.state-scanning { transform: scale(.98); }
.gm-fp-ring.state-success { transform: scale(1.04); }
.gm-fp-ring.state-deny { transform: scale(.96); }

/* Anillos concéntricos + brackets (copiados del mini kiosk .gm-mk-ring) */
.gm-fp-rings, .gm-fp-brackets {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;
}
.gm-fp-brackets { padding: 74px; box-sizing: border-box; } /* equivale al 60/260 del mini, escalado para 320 */
.gm-fp-spin     { transform-origin: 130px 130px; animation: gmMkSpin 7s linear infinite; }
.gm-fp-spin-rev { transform-origin: 130px 130px; animation: gmMkSpinRev 11s linear infinite; }
.gm-fp-ticks    { transform-origin: 130px 130px; animation: gmMkSpin 22s linear infinite; }

.gm-fp-inner {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 0 16px rgba(198,239,67,.45));
  animation: gmMkPulse 2.4s ease-in-out infinite;
  transition: filter .3s;
}
/* Estados: el "inner" deja de ser un círculo con fondo y pasa a ser solo
   el contenedor del fingerprint. El feedback visual se mantiene con drop-shadow. */
.gm-fp-ring.state-scanning .gm-fp-inner {
  filter: drop-shadow(0 0 24px rgba(198,239,67,.7));
}
.gm-fp-ring.state-success .gm-fp-inner {
  filter: drop-shadow(0 0 36px rgba(198,239,67,.9));
}
.gm-fp-ring.state-deny .gm-fp-inner {
  filter: drop-shadow(0 0 28px rgba(220,62,62,.6));
  animation: none;
}

.gm-fp-icon {
  color: var(--accent);
  display: block;
  flex-shrink: 0;
  transition: color .3s;
}
.gm-fp-ring.state-success .gm-fp-icon { color: #d4ff5a; }
.gm-fp-ring.state-deny .gm-fp-icon { color: #ff8a8a; }

.gm-fp-scanner {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: 200px; height: 3px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 18px var(--accent);
  animation: gm-fp-scan 1.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes gm-fp-scan {
  0% { top: 20%; }
  50% { top: 80%; }
  100% { top: 20%; }
}

.gm-kiosk-message {
  margin-top: 36px;
  text-align: center;
  min-height: 130px;
  max-width: 520px;
}
.gm-kiosk-message-title {
  font-family: 'Manrope', sans-serif;
  font-size: 36px; font-weight: 700;
  letter-spacing: -.01em;
}
.gm-kiosk-message-sub {
  color: rgba(241,242,238,.65);
  font-size: 16px;
  margin-top: 10px;
}
.gm-kiosk-message-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
}
.gm-kiosk-message-pill.is-success {
  background: var(--accent); color: var(--navy);
}
.gm-kiosk-message-pill.is-deny {
  background: rgba(220,62,62,.2); color: #ff8a8a;
  border: 1px solid rgba(220,62,62,.4);
}
.gm-kiosk-message-pill.is-info {
  background: rgba(198,239,67,.14); color: var(--accent);
  border: 1px solid rgba(198,239,67,.32);
}

/* Derecha: stats + sim */
.gm-kiosk-right-label {
  font-size: 11px; letter-spacing: .12em;
  color: rgba(241,242,238,.5);
  text-transform: uppercase; font-weight: 600;
}
.gm-kiosk-stat-big {
  font-family: 'Manrope', sans-serif;
  font-size: 56px; font-weight: 700;
  color: var(--accent);
  margin-top: 6px;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.gm-kiosk-stat-sub {
  color: rgba(241,242,238,.6);
  font-size: 14px;
}

.gm-kiosk-tip {
  margin-top: auto;
  padding: 16px 20px;
  border-radius: 14px;
  background: rgba(241,242,238,.04);
  border: 1px solid rgba(241,242,238,.08);
}
.gm-kiosk-tip strong {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; color: var(--accent);
  display: block; margin-bottom: 4px;
}
.gm-kiosk-tip p {
  color: rgba(241,242,238,.7);
  font-size: 13px;
  line-height: 1.5;
  margin: 0;
}

.gm-kiosk-sim {
  margin-top: 20px;
  padding: 16px;
  border-radius: 14px;
  background: rgba(241,242,238,.03);
  border: 1px dashed rgba(241,242,238,.12);
  display: flex; flex-direction: column; gap: 8px;
}
.gm-kiosk-sim-label {
  font-size: 10px; letter-spacing: .14em;
  color: rgba(241,242,238,.4);
  text-transform: uppercase; font-weight: 700;
  margin-bottom: 2px;
}
.gm-sim-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  border-radius: 10px;
  background: rgba(241,242,238,.04);
  border: 1px solid rgba(241,242,238,.12);
  color: rgba(241,242,238,.75);
  font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.gm-sim-btn:hover:not(:disabled) {
  background: rgba(198,239,67,.1);
  border-color: rgba(198,239,67,.4);
  color: var(--accent);
}
.gm-sim-btn:disabled {
  opacity: .35; cursor: not-allowed;
}
.gm-sim-btn svg { width: 14px; height: 14px; }

/* Responsive del kiosk */
@media (max-width: 1100px) {
  .gm-kiosk-main {
    grid-template-columns: 1fr;
    gap: 24px;
    padding: 24px 24px 32px;
    overflow-y: auto;
  }
  /* Reorden mobile: simulación arriba → huella → lista de últimos ingresos abajo */
  .gm-kiosk-right  { order: 1; display: flex; flex-direction: column; padding: 0; gap: 0; }
  .gm-kiosk-center { order: 2; padding: 12px 0; }
  .gm-kiosk-left   { order: 3; display: flex; flex-direction: column; padding: 0 4px; }
  /* En mobile mostramos SOLO el bloque de simulación de la columna derecha,
     no el resto (stats, fallback de huella, etc.) */
  .gm-kiosk-right > *:not(.gm-kiosk-sim) { display: none; }
  .gm-kiosk-right .gm-kiosk-sim { display: flex; flex-direction: column; gap: 10px; padding: 0 12px; }
  /* La lista no debe scrollear internamente en mobile: que fluya con el scroll del kiosk */
  .gm-kiosk-feed { max-height: none; overflow: visible; }
  .gm-fp-ring { width: 240px; height: 240px; }
  /* Aseguro que el inner ocupe todo el ring y centre el fingerprint en mobile */
  .gm-fp-inner { position: absolute; inset: 0; width: auto; height: auto; display: flex; align-items: center; justify-content: center; }
  .gm-fp-inner svg.gm-fp-icon { width: 80px; height: 80px; }
  /* Brackets proporcionales al ring mobile (74 * 240/320 ≈ 56) */
  .gm-fp-brackets { padding: 56px; }
  .gm-kiosk-date { font-size: 44px; }
  .gm-kiosk-message-title { font-size: 28px; }
}
@media (max-width: 600px) {
  /* Topbar: en una sola fila, el botón Salir SIEMPRE a la derecha (sin wrap).
     El brand se comprime con min-width:0 + ellipsis si hace falta. */
  .gm-kiosk-topbar { padding: 14px 16px; gap: 10px; flex-wrap: nowrap; }
  .gm-kiosk-brand { min-width: 0; flex: 1; }
  .gm-kiosk-brand-text { min-width: 0; }
  .gm-kiosk-brand-text strong,
  .gm-kiosk-brand-text small {
    font-size: 12px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .gm-kiosk-brand img { width: 26px; height: 26px; }
  .gm-kiosk-topbar-right { gap: 10px; flex-shrink: 0; }
  .gm-kiosk-clock { font-size: 16px; }
  .gm-kiosk-exit { padding: 6px 10px; font-size: 12px; flex-shrink: 0; }
  .gm-kiosk-pill { padding: 4px 10px; font-size: 11px; }
}
/* En pantallas muy pequeñas (<380px), ocultar elementos no esenciales del medio
   para dejar SIEMPRE visible el brand a la izq y Salir a la der. */
@media (max-width: 380px) {
  .gm-kiosk-brand-text small { display: none; }
  .gm-kiosk-clock { display: none; }
  .gm-kiosk-pill { display: none; }
  .gm-kiosk-exit { padding: 6px 9px; font-size: 11px; }
  .gm-kiosk-exit span { display: none; } /* solo icono X */
}

/* Tooltips de info icon */
.gm-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  color: var(--muted); cursor: help;
  position: relative;
}
.gm-info:hover { color: var(--text); }
.gm-info[data-tooltip]:hover::after {
  content: attr(data-tooltip);
  position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--navy); color: #F1F2EE;
  padding: 8px 12px; border-radius: 8px; font-size: 12px; font-weight: 500;
  white-space: normal; width: max-content; max-width: 260px;
  box-shadow: var(--shadow-lg); z-index: 60;
  text-transform: none; letter-spacing: 0;
}

/* ============================================================
   Modal de confirmación del kiosk (salir del modo)
   ============================================================ */
.gm-kiosk-modal {
  position: fixed; inset: 0;
  z-index: 200;
  display: none;
  align-items: center; justify-content: center;
  padding: 24px;
}
.gm-kiosk-modal.is-open { display: flex; }
.gm-kiosk-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(6, 20, 42, 0.65);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: gmKioskFadeIn .18s ease;
}
.gm-kiosk-modal-card {
  position: relative;
  width: 100%; max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 28px 28px 22px;
  box-shadow: 0 30px 60px rgba(6, 20, 42, 0.35);
  text-align: center;
  animation: gmKioskPop .22s cubic-bezier(.2,.9,.3,1.2);
}
.gm-kiosk-modal-icon {
  width: 56px; height: 56px;
  margin: 0 auto 16px;
  border-radius: 16px;
  background: rgba(230, 162, 60, 0.14);
  color: #C57B1A;
  display: flex; align-items: center; justify-content: center;
}
.gm-kiosk-modal-icon svg { width: 26px; height: 26px; }
.gm-kiosk-modal-title {
  font-family: 'Manrope', sans-serif;
  font-size: 19px; font-weight: 700; letter-spacing: -.01em;
  color: var(--text);
  margin: 0 0 8px;
}
.gm-kiosk-modal-desc {
  font-size: 13.5px; color: var(--muted);
  margin: 0 0 22px;
  line-height: 1.5;
}
.gm-kiosk-modal-actions {
  display: flex; gap: 10px; justify-content: center;
}
.gm-kiosk-modal-btn {
  flex: 1;
  height: 44px;
  padding: 0 18px;
  border-radius: 12px;
  font-family: inherit; font-size: 14px; font-weight: 700;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
  border: 1px solid transparent;
}
.gm-kiosk-modal-btn.is-ghost {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
.gm-kiosk-modal-btn.is-ghost:hover {
  background: var(--surface);
  border-color: var(--border-strong);
}
.gm-kiosk-modal-btn.is-primary {
  background: var(--navy);
  color: var(--accent);
  border-color: var(--navy);
  box-shadow: 0 4px 14px rgba(15, 42, 71, 0.2);
}
.gm-kiosk-modal-btn.is-primary:hover {
  background: var(--navy-2, #1a3a5c);
  border-color: var(--navy-2, #1a3a5c);
  transform: translateY(-1px);
}
.gm-kiosk-modal-btn:active { transform: scale(.97); }

@keyframes gmKioskFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes gmKioskPop {
  from { opacity: 0; transform: translateY(8px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ============================================================
   Rediseño Asistencia (Claude Design v1 — attendance.jsx)
   ============================================================ */

/* Navegador de fecha (cabecera con flechas y label "Hoy") */
.gm-att-card { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; }
.gm-date-nav {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.gm-date-arrow {
  width: 34px; height: 34px; border-radius: 9px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s;
  flex-shrink: 0;
}
.gm-date-arrow:hover:not(:disabled) { background: var(--navy); color: var(--accent); border-color: var(--navy); }
.gm-date-arrow:disabled { opacity: .35; cursor: not-allowed; }
.gm-date-display { display: flex; flex-direction: column; min-width: 0; padding: 0 4px; }
.gm-date-day {
  font-family: 'Manrope', sans-serif;
  font-size: 17px; font-weight: 700;
  letter-spacing: -.01em; text-transform: capitalize; line-height: 1.1;
}
.gm-date-full {
  font-size: 12px; color: var(--muted);
  margin-top: 2px; text-transform: capitalize;
}
.gm-date-spacer { flex: 1; }
.gm-date-meta {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--muted);
}
.gm-date-meta strong { color: var(--text); font-family: 'Manrope', sans-serif; font-weight: 700; }

/* Botón pill "Volver a hoy" (chip-button con data-active) */
.gm-att-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px; font-weight: 600; color: var(--muted);
  cursor: pointer;
  transition: all .15s;
  font-family: inherit;
  white-space: nowrap;
}
.gm-att-chip:hover { border-color: var(--navy); color: var(--text); }
.gm-att-chip[data-active="true"] { background: var(--navy); color: var(--accent); border-color: var(--navy); }
/* Por defecto el icono dentro del chip no se muestra (solo el texto) */
.gm-att-chip .gm-att-chip-ico { display: none; }

/* Botón circular pequeño tipo "más opciones" */
.gm-icon-btn-sm {
  width: 30px; height: 30px; border-radius: 8px;
  background: transparent; border: 1px solid transparent;
  color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s;
}
.gm-icon-btn-sm:hover { background: var(--surface-2); color: var(--text); border-color: var(--border); }
.gm-icon-btn-sm[aria-expanded="true"] { background: var(--navy); color: var(--accent); border-color: var(--navy); }

/* Host invisible de DateForge: ocultamos el <input> y label que crea la librería,
   nos quedamos solo con su popup (.df-popup) que se ancla al botón calendario. */
.gm-date-host {
  position: absolute;
  width: 0; height: 0;
  overflow: hidden;
  visibility: hidden;
  pointer-events: none;
}

/* Search bar inline (edge-to-edge, sin gaps internos) */
.gm-search-input {
  display: flex; align-items: stretch;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s;
}
.gm-search-input:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-search-input input {
  flex: 1; border: none; outline: none; background: transparent;
  padding: 11px 14px; font-size: 14px; font-family: inherit; color: var(--text);
}
.gm-search-input input::placeholder { color: var(--muted); }
.gm-search-clear {
  width: 36px;
  background: transparent; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); transition: all .15s;
  flex-shrink: 0;
}
.gm-search-clear:hover { background: rgba(15,42,71,.06); color: var(--text); }
.gm-search-submit {
  width: 48px;
  background: var(--navy); color: var(--accent);
  border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s;
  flex-shrink: 0;
  border-left: 1px solid var(--border);
}
.gm-search-submit:hover { background: var(--accent); color: var(--navy); }

/* Filas de asistencia — grid de 7 columnas:
   tiempo | barra | cliente | plan+racha | countdown | pill | menu */
.gm-att-row {
  display: grid;
  /* Columnas: hora · barra · cliente · días restantes · estado · acciones.
     Todas fijas salvo "cliente" (toma el espacio sobrante con 1fr). Esto hace
     que días/estado/acciones queden alineados en columna entre TODAS las filas
     (antes la pill y las acciones eran `auto` y variaban según su contenido). */
  /* Acciones con ancho FIJO (150px): clave para la "sensación de tabla".
     Con `max-content` la columna variaba entre filas (botón "Extender" más
     ancho que "Crear"), lo que corría las columnas intermedias (días, estado)
     a distinta x entre filas → se veían desalineadas. Un ancho fijo deja TODAS
     las columnas alineadas verticalmente. La columna "cliente" (1fr) absorbe
     la diferencia. Los botones se alinean a la derecha dentro de su columna. */
  grid-template-columns: 70px 4px minmax(120px,1fr) 140px 95px 150px;
  gap: 16px; align-items: center;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  transition: background .12s;
}
.gm-att-row:last-child { border-bottom: none; }
.gm-att-row:hover { background: var(--surface-2); }

/* — Columna 1: tiempo —
   Ancla arriba (flex-start) y reserva la línea de su label opcional (.gm-att-row-time-l)
   con un ::after, igual que la columna de días. Así el número de hora (22px)
   queda SIEMPRE a la misma altura que el número de días, sin importar que una
   columna tenga label y la otra no. */
.gm-att-row-time {
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: flex-start;
}
.gm-att-row-time::after {
  content: ''; display: block;
  font-size: 10px; line-height: 1; height: 10px; margin-top: 3px;
}
.gm-att-row-time:has(.gm-att-row-time-l)::after { display: none; }
.gm-att-row-time-h {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; letter-spacing: -.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: baseline; gap: 3px;
  white-space: nowrap;
}
.gm-att-row-time-hm { font-size: 22px; }
.gm-att-row-time-mer {
  font-size: 11px; font-weight: 600;
  color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.gm-att-row-time-l {
  font-size: 10px; color: var(--muted); letter-spacing: .08em;
  font-weight: 600; margin-top: 4px; text-transform: uppercase;
}

/* — Columna 2: barra de color — */
.gm-att-row-bar {
  width: 4px; align-self: stretch; min-height: 44px; border-radius: 3px;
}
.gm-att-row-bar.is-ok   { background: var(--accent); box-shadow: 0 0 0 1px rgba(198,239,67,.3); }
.gm-att-row-bar.is-warn { background: #FFB02E; }
.gm-att-row-bar.is-err  { background: #DC3E3E; }
.gm-att-row-bar.is-navy { background: var(--navy); }

/* — Columna 3: datos del cliente — */
.gm-att-client { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gm-att-name {
  font-weight: 700; font-size: 15px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-att-id {
  font-size: 12px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-att-dot {
  display: inline-block;
  margin: 0 4px;
  color: var(--muted);
}

/* — Columna 4: countdown de días restantes —
   El número (22px) va arriba y el label opcional ("DÍAS RESTANTES") debajo.
   La fila usa align-items:center, así que si una celda tiene 2 líneas y otra
   1 sola, el número queda a distinta altura entre filas. Para que el número
   SIEMPRE arranque a la misma altura (alineado con el nombre del cliente),
   anclamos la celda arriba (flex-start) y, cuando NO hay label, reservamos su
   línea con un ::after del mismo alto. Así "12 / DÍAS" y "—" sin label dejan
   el número alineado verticalmente en todas las filas. */
.gm-att-membership { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; }
.gm-att-membership::after {
  content: ''; display: block;
  font-size: 10px; line-height: 1; height: 10px; margin-top: 3px;
}
.gm-att-membership:has(.gm-att-days-label)::after { display: none; }
.gm-att-days {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 22px; letter-spacing: -.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.gm-att-days-ok   { color: #5a7300; }
.gm-att-days-warn { color: #9a6a00; }
.gm-att-days-err  { color: #b43333; }
.gm-att-days-label {
  font-size: 10px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em;
  margin-top: 3px; line-height: 1;
}

/* Retro-compat: clases viejas que puede seguir usando el JS existente */
.gm-att-row-name { font-weight: 600; font-size: 15px; color: var(--text); }
.gm-att-row-sub  { font-size: 12px; color: var(--muted); margin-top: 2px; }
/* La pill de estado se alinea a la izquierda de su columna (ancho fijo) para
   que su borde inicial quede alineado entre todas las filas. */
.gm-att-row > .gm-pill { justify-self: start; }

/* Pills — sistema unificado de estado */
.gm-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600; letter-spacing: .01em;
  white-space: nowrap;
}
.gm-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.gm-pill.is-ok    { background: rgba(198,239,67,.16); color: #5a7300; }
.gm-pill.is-warn  { background: rgba(255,176,46,.15); color: #9a6a00; }
.gm-pill.is-err   { background: rgba(220,62,62,.12); color: #b43333; }
.gm-pill.is-lime  { background: var(--accent); color: var(--navy); }
.gm-pill.is-navy  { background: var(--navy); color: var(--accent); }
.gm-pill.is-info  { background: rgba(42,157,204,.13); color: #1B6B8C; }
.gm-pill.is-muted { background: rgba(107,122,133,.13); color: var(--muted); }

/* Card "preview" del lector (right panel) */
.gm-kiosk-preview-card {
  position: relative; overflow: hidden;
  background: var(--navy); color: #F1F2EE;
  border-radius: 14px;
}
/* Desktop ≥1200px: la columna lateral acompaña al scroll. */
@media (min-width: 1200px) {
  .gm-attendance-side-sticky {
    position: sticky;
    top: calc(var(--topbar-h) + 16px);
    align-self: flex-start;
  }
}
/* Rango 1200-1399 (col-xl-5 ≈ 41%): kiosk con ancho cómodo, pero ajustamos
   los stats laterales y el padding interno para que no quede apretado. */
@media (min-width: 1200px) and (max-width: 1399.98px) {
  .gm-attendance-side-sticky .gm-mk { padding: 20px 18px 18px; }
  .gm-attendance-side-sticky .gm-mk-stats { gap: 8px; }
  .gm-attendance-side-sticky .gm-mk-stat { gap: 6px; }
  .gm-attendance-side-sticky .gm-mk-stat-l,
  .gm-attendance-side-sticky .gm-mk-stat-v { font-size: 10.5px; }
  .gm-attendance-side-sticky .gm-mk-stat svg { width: 16px; height: 16px; }
}
/* Solo a partir de 1400px reducimos para compensar la columna más estrecha (col-xxl-3) */
@media (min-width: 1400px) {
  .gm-attendance-side-sticky .gm-mk { padding: 19px 19px 18px; }
  .gm-attendance-side-sticky .gm-mk-ring { width: 208px; height: 208px; margin: 11px auto 3px; }
  .gm-attendance-side-sticky .gm-mk-fp svg { width: 70px; height: 70px; }
  .gm-attendance-side-sticky .gm-mk-title { font-size: 19px; margin-top: 11px; }
  .gm-attendance-side-sticky .gm-mk-sub { font-size: 11px; margin-top: 3px; }
  .gm-attendance-side-sticky .gm-mk-divider { margin: 16px 0 13px; }
  .gm-attendance-side-sticky .gm-mk-stats { gap: 10px; margin-bottom: 16px; }
  .gm-attendance-side-sticky .gm-mk-stat-l,
  .gm-attendance-side-sticky .gm-mk-stat-v { font-size: 10px; }
  .gm-attendance-side-sticky .gm-mk-stat svg { width: 15px; height: 15px; }
  .gm-attendance-side-sticky .gm-mk-cta { padding: 11px 14px; font-size: 13px; border-radius: 10px; }
  .gm-attendance-side-sticky .gm-mk-cta svg { width: 15px; height: 15px; }
}
.gm-kiosk-preview-mesh {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.05) 1px, transparent 1px);
  background-size: 36px 36px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
  pointer-events: none;
}
.gm-kiosk-preview-glow {
  position: absolute; top: -60px; right: -60px;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(circle, rgba(198,239,67,.28), transparent 60%);
  filter: blur(18px); pointer-events: none;
}
.gm-kiosk-preview-body {
  position: relative; padding: 24px;
  display: flex; flex-direction: column; align-items: center;
}
.gm-kiosk-preview-fp {
  position: relative; width: 200px; height: 200px;
  display: flex; align-items: center; justify-content: center;
  margin-top: 6px;
}
.gm-kiosk-preview-inner {
  position: relative; width: 150px; height: 150px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(198,239,67,.15), rgba(198,239,67,.02));
  border: 2px solid rgba(198,239,67,.3);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  box-shadow: 0 0 40px rgba(198,239,67,.18);
}
.gm-kiosk-preview-scanner {
  position: absolute; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 16px var(--accent);
  animation: gmAttScan 1.8s ease-in-out infinite;
}
.gm-kiosk-preview-orbit {
  position: absolute; inset: 0;
  animation: gmAttSpin 60s linear infinite;
}
.gm-kiosk-preview-cta {
  margin-top: 24px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 20px; border-radius: 12px;
  background: var(--accent); color: var(--navy);
  font-weight: 700; font-size: 14px; text-decoration: none;
  border: none; cursor: pointer;
  transition: transform .15s, box-shadow .15s;
}
.gm-kiosk-preview-cta:hover { transform: translateY(-1px); box-shadow: 0 8px 20px -8px rgba(198,239,67,.5); color: var(--navy); }

@keyframes gmAttScan {
  0%, 100% { transform: translateY(0); opacity: 0; }
  10% { opacity: 1; }
  50% { transform: translateY(140px); opacity: 1; }
  90% { opacity: 1; }
}
@keyframes gmAttSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ≤1400: ocultar el countdown de días; quedan 5 columnas
   (hora · barra · cliente · estado · acciones). Estado y acciones siguen con
   ancho fijo para que queden alineadas entre filas. */
@media (max-width: 1400px) {
  .gm-att-row {
    grid-template-columns: 70px 4px minmax(0,1fr) 95px 150px;
  }
  .gm-att-membership { display: none; }
}
/* A ≤900 el texto de los botones se oculta (icon-only): la columna de acciones
   se reduce a un fijo que acomoda los 2 íconos, manteniendo la grilla pareja. */
@media (max-width: 900px) {
  .gm-att-row {
    grid-template-columns: 70px 4px minmax(0,1fr) 95px 84px;
  }
}

/* Mobile (≤720): compresión final, fila más densa */
@media (max-width: 720px) {
  .gm-date-nav { gap: 8px; padding: 12px; flex-wrap: wrap; }
  .gm-date-display { min-width: 120px; flex: 1; }
  .gm-date-meta { font-size: 12px; }
  .gm-att-row {
    grid-template-columns: 58px 4px minmax(0,1fr) 90px 84px;
    gap: 12px; padding: 12px;
  }
  .gm-att-row-time-hm { font-size: 18px; }
  .gm-att-row-time-mer { font-size: 10px; }
  .gm-att-name { font-size: 14px; }
  .gm-att-days { font-size: 18px; }

  /* "Volver a hoy" pasa a ser icon-only en mobile */
  #btnBackToToday { padding: 6px 10px; }
  #btnBackToToday .gm-att-chip-ico { display: inline-flex; }
  #btnBackToToday .gm-att-chip-text { display: none; }
}

/* Muy chico (≤460): la pill de estado se va; queda solo nombre + acciones.
   La barra de color pierde el halo (box-shadow) para no pisar la hora.
   La hora se achica a 16px y se oculta el meridiano (AM/PM). Como ya no
   hay meridiano, centramos la hora dentro de la columna para que no quede
   "pegada" a un lado con espacio vacío al otro. */
@media (max-width: 460px) {
  .gm-att-row {
    grid-template-columns: 56px 4px minmax(0,1fr) 84px;
    gap: 10px; padding: 10px;
  }
  .gm-att-row > .gm-pill { display: none; }
  .gm-att-row-bar { box-shadow: none !important; }
  .gm-att-row-time {
    align-items: center;            /* sin meridiano, centrar la hora */
    justify-content: center;
  }
  .gm-att-row-time-hm { font-size: 16px; }
  .gm-att-row-time-mer { display: none; }
  /* Sin gap interno cuando el meridiano no está */
  .gm-att-row-time-h { gap: 0; max-width: 100%; }
}

/* ============================================================
   Mini Kiosk preview v3 (Claude Design — attendance.jsx .gm-mk)
   Reemplaza al wrapper .gm-kiosk-preview-body interior.
   ============================================================ */
.gm-mk {
  position: relative; z-index: 1;
  padding: 24px 24px 22px;
  display: flex; flex-direction: column; align-items: stretch;
}
.gm-mk-top { display: flex; }

.gm-mk-ring {
  position: relative;
  /* Responsive: nunca más ancho que su contenedor, mantiene proporción 1:1.
     Así el anillo se encoge con la card y nunca se sale en pantallas chicas. */
  width: 100%;
  max-width: 260px;
  aspect-ratio: 1 / 1;
  margin: 14px auto 4px;
}
.gm-mk-rings, .gm-mk-brackets {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
/* Brackets proporcionales al anillo (≈23% de padding, equivalente a 60/260) */
.gm-mk-brackets { padding: 23%; box-sizing: border-box; }
.gm-mk-spin     { transform-origin: 130px 130px; animation: gmMkSpin 7s linear infinite; }
.gm-mk-spin-rev { transform-origin: 130px 130px; animation: gmMkSpinRev 11s linear infinite; }
.gm-mk-ticks    { transform-origin: 130px 130px; animation: gmMkSpin 22s linear infinite; }
@keyframes gmMkSpin    { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes gmMkSpinRev { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }

.gm-mk-fp {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 0 12px rgba(198,239,67,.45));
  animation: gmMkPulse 2.4s ease-in-out infinite;
}
@keyframes gmMkPulse {
  0%, 100% { filter: drop-shadow(0 0 10px rgba(198,239,67,.35)); }
  50%      { filter: drop-shadow(0 0 18px rgba(198,239,67,.65)); }
}

.gm-mk-title {
  font-family: 'Manrope', sans-serif;
  font-size: 24px; font-weight: 700;
  text-align: center; letter-spacing: -.01em;
  margin-top: 14px;
  color: #F1F2EE;
}
.gm-mk-sub {
  text-align: center; font-size: 13px;
  color: rgba(241,242,238,.65); margin-top: 4px;
}

.gm-mk-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(241,242,238,.12), transparent);
  margin: 20px 0 16px;
}

.gm-mk-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  margin-bottom: 20px;
}
.gm-mk-stat {
  display: flex; align-items: flex-start; gap: 8px;
}
.gm-mk-stat-l {
  font-size: 11px; font-weight: 700;
  color: #F1F2EE; line-height: 1.2;
}
.gm-mk-stat-v {
  font-size: 11px; color: rgba(241,242,238,.55);
  margin-top: 2px;
}

.gm-mk-cta {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--accent); color: var(--navy);
  border: none; border-radius: 12px;
  padding: 14px 18px; cursor: pointer;
  font-family: inherit; font-weight: 700; font-size: 15px;
  letter-spacing: .01em;
  text-decoration: none;
  transition: all .2s;
  box-shadow: 0 12px 30px -10px rgba(198,239,67,.45);
}
.gm-mk-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 40px -8px rgba(198,239,67,.6);
  color: var(--navy);
}

/* === Simulación provisional del mini kiosk (botones + estados) === */
.gm-mk-sim {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed rgba(241,242,238,.12);
}
.gm-mk-sim-label {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(241,242,238,.4); font-weight: 700;
  text-align: center; margin-bottom: 8px;
}
.gm-mk-sim-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}
.gm-mk-sim-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 10px; border-radius: 10px;
  background: rgba(241,242,238,.06);
  border: 1px solid rgba(241,242,238,.1);
  color: rgba(241,242,238,.75);
  font-family: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer;
  transition: all .15s;
}
.gm-mk-sim-btn:hover { background: rgba(241,242,238,.1); color: #F1F2EE; }
.gm-mk-sim-btn.is-ok:hover {
  background: rgba(198,239,67,.15); border-color: rgba(198,239,67,.4); color: var(--accent);
}
.gm-mk-sim-btn.is-err:hover {
  background: rgba(220,62,62,.12); border-color: rgba(220,62,62,.4); color: #ff8a8a;
}

/* === Mini kiosk responsive: encapsular todo en pantallas chicas === */
/* En la columna apilada (mobile/tablet, <1200px la card es full-width pero
   en md puede ser estrecha). Reducimos padding y stats para que no desborde. */
@media (max-width: 560px) {
  .gm-mk { padding: 18px 16px 18px; }
  .gm-mk-ring { max-width: 200px; }
  .gm-mk-title { font-size: 20px; margin-top: 10px; }
  .gm-mk-sub { font-size: 12px; }
  .gm-mk-divider { margin: 16px 0 14px; }
  /* Stats: de 3 columnas a 1 columna (icono + texto en línea), más legible */
  .gm-mk-stats { grid-template-columns: 1fr; gap: 10px; }
  .gm-mk-stat { align-items: center; }
  .gm-mk-stat-l, .gm-mk-stat-v { font-size: 12px; }
  .gm-mk-cta { padding: 12px 16px; font-size: 14px; }
}
/* Tablet / md angosto: 2 columnas de stats para que no se aprieten */
@media (min-width: 561px) and (max-width: 991px) {
  .gm-mk-stats { grid-template-columns: 1fr 1fr; gap: 10px; }
}

/* ============================================================
   Clientes — vista de tabla (rediseño)
   ============================================================ */
.gm-clients-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center; gap: 12px;
  margin-bottom: 16px;
  width: 100%; max-width: 100%; box-sizing: border-box;
}
.gm-clients-toolbar > * { min-width: 0; }
.gm-clients-table th { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
/* Columna Acciones: header y celda centrados (todo el ancho de la columna).
   `text-align: center` mueve el contenido inline (botón inline-flex también). */
.gm-clients-table th.gm-clients-actions-cell,
.gm-clients-table td.gm-clients-actions-cell {
  text-align: center;
  width: 90px;                 /* ancho fijo: 34px botón + paddings sobran */
  min-width: 90px;
  white-space: nowrap;
}
/* En la celda, achicar el padding lateral para que el botón siempre
   entre cómodo (el ancho fijo + padding default colisionaban en
   pantallas estrechas tipo ~940px). */
.gm-clients-table th.gm-clients-actions-cell,
.gm-clients-table td.gm-clients-actions-cell:last-child {
  padding-left: 8px !important;
  padding-right: 12px !important;
}
.gm-clients-table tbody tr {
  cursor: pointer;
  transition: background .12s;
}
.gm-clients-table tbody tr:hover { background: var(--surface-2); }

.gm-cell-user {
  display: inline-flex; align-items: center; gap: 10px;
  min-width: 0;
}
.gm-cell-user .gm-client-row-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--navy); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 12px;
  flex-shrink: 0;
}
.gm-cell-strong { font-weight: 600; color: var(--text); font-size: 14px; line-height: 1.2; }
.gm-cell-sub    { font-size: 12px; color: var(--muted); margin-top: 2px; }

.gm-btn-icon {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text); font-family: inherit; font-weight: 600; font-size: 12px;
  cursor: pointer;
  transition: all .15s;
}
.gm-btn-icon:hover {
  background: var(--navy); color: var(--accent); border-color: var(--navy);
}
.gm-btn-icon svg { flex-shrink: 0; }
/* Variante solo-icono: cuadrada, sin texto */
.gm-btn-icon.is-icon-only {
  padding: 0;
  width: 34px; height: 34px;
  justify-content: center;
}

/* Tabla de clientes: solo 4 columnas (Cliente, Documento, Estado, Acciones).
   Cliente, Estado y Acciones NUNCA se ocultan. La única columna que se
   esconde antes de pasar a cards es Documento, a partir de 720px (cuando
   el ancho ya aprieta). A 920px la tabla entera pasa a cards mobile. */
@media (max-width: 720px) {
  .gm-clients-table .col-doc { display: none; }
}

/* Tabla de planes: mismo patrón progresivo.
   Prioridad de oculto (de menos a más importante):
     1. Días congelamiento  <=1200px
     2. Adicional           <=1080px
   Por debajo de 900px se cambia a cards (sin más ocultamiento de columnas).
   Las columnas que NUNCA se ocultan: Plan, Estado, Acciones.

   Nota: las reglas globales (línea ~1540) ocultan .gm-table-wrap y muestran
   .gm-mobile-cards a partir de 920px. Para planes queremos que ese switch
   ocurra exactamente en 900px, así que sobreescribimos en el rango 920→901. */
@media (max-width: 1200px) {
  .gm-plans-table .col-frozen { display: none; }
}
@media (max-width: 1080px) {
  .gm-plans-table .col-additional { display: none; }
}
/* En el rango 901→920 queremos seguir viendo la tabla (override del global) */
@media (max-width: 920px) and (min-width: 901px) {
  .gm-table-wrap:has(.gm-plans-table) { display: block !important; }
  #plansMobileCards { display: none !important; }
}
/* A partir de 900px → cards (la regla global ya oculta la tabla y muestra cards) */
@media (max-width: 900px) {
  .gm-table-wrap:has(.gm-plans-table) { display: none !important; }
  #plansMobileCards { display: flex !important; }
}

/* ============================================================
   Detalle de plan (página completa) — header navy + grid de campos
   ============================================================ */
/* Detalle a ancho completo (las cards ocupan todo el ancho del contenido). */
/* Arrancamos pegados al topbar como el detalle de cliente: subimos 8px para
   compensar el padding-top de .gm-content y que el botón Volver no quede tan
   abajo. */
.gm-plan-detail { display: flex; flex-direction: column; gap: 14px; margin-top: -8px; }
/* El botón "Volver" trae margin propio del detalle de cliente; aquí el gap del
   flex ya separa, así que lo anulamos para no acumular espacio con el navy. */
.gm-plan-detail > .gm-detail-back-float { margin: 0; }

/* Header de la card "Configuración del plan": título + acción Editar/Guardar.
   min-height fija la altura igual en lectura/edición y centra el botón sin que
   toque el borde superior de la card. */
.gm-plan-cfg-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 16px; min-height: 40px;
}
.gm-plan-cfg-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
/* Slide al alternar lectura↔edición del cuerpo de la card. */
.gm-plan-cfg-anim { animation: gmFieldIn .3s cubic-bezier(.2,.85,.25,1); }
.gm-plan-cfg-form .gm-section-label:first-child { margin-top: 0; }

.gm-plan-detail-hero {
  position: relative; overflow: hidden;
  background: var(--navy); color: #F1F2EE;
  padding: 0; border: none;
}
.gm-plan-detail-hero-inner {
  position: relative; z-index: 1;
  padding: 28px; display: flex; flex-direction: column; gap: 22px;
}
/* Fila superior: ícono + identidad (izq) · precio (centro-der) · Eliminar (der).
   Aprovecha el ancho empujando el precio al extremo derecho. */
.gm-plan-hero-top {
  display: flex; align-items: flex-start; gap: 22px; flex-wrap: wrap;
}
.gm-plan-hero-price {
  display: flex; flex-direction: column; align-items: flex-end; justify-content: center;
  flex-shrink: 0; text-align: right; padding-left: 12px;
}
.gm-plan-hero-price .gm-plan-detail-price { margin-top: 0; }
/* Banner inferior: estadísticas clave repartidas a lo ancho del navy. */
.gm-plan-hero-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, max-content));
  gap: 14px 56px;
  padding-top: 20px;
  border-top: 1px solid rgba(241,242,238,.12);
}
.gm-plan-hero-stat { display: flex; align-items: center; gap: 12px; min-width: 0; }
.gm-plan-hero-stat-ico {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(241,242,238,.07); color: rgba(241,242,238,.85);
}
.gm-plan-hero-stat-ico.is-accent { background: rgba(64,153,201,.18); color: #6fc2ec; }
.gm-plan-hero-stat-ico svg { width: 17px; height: 17px; }
.gm-plan-hero-stat-body { display: flex; flex-direction: column; min-width: 0; }
.gm-plan-hero-stat-label {
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  font-weight: 700; color: rgba(241,242,238,.5);
}
.gm-plan-hero-stat-value {
  font-size: 15px; font-weight: 600; margin-top: 2px; color: #F1F2EE;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Badge de estado sobre el navy: verde vivo (acento), no el lima apagado del
   listado sobre fondo claro. */
.gm-pill-hero.is-ok {
  background: rgba(198,239,67,.18);
  color: var(--accent);
}
.gm-pill-hero.is-muted {
  background: rgba(241,242,238,.12);
  color: rgba(241,242,238,.72);
}
.gm-plan-detail-name {
  font-family: 'Manrope', sans-serif; font-size: 34px; font-weight: 700;
  letter-spacing: -.02em; line-height: 1.1;
}
.gm-plan-detail-desc {
  color: rgba(241,242,238,.75); font-size: 14px; margin-top: 6px;
  max-width: 540px; line-height: 1.55;
}
.gm-plan-detail-price { display: flex; align-items: baseline; gap: 6px; margin-top: 14px; }
.gm-plan-detail-price-cur { font-size: 16px; font-weight: 600; color: rgba(241,242,238,.6); }
.gm-plan-detail-price-num {
  font-family: 'Manrope', sans-serif; font-size: 40px; font-weight: 700;
  letter-spacing: -.02em; color: var(--accent);
}
.gm-plan-detail-actions { display: flex; gap: 10px; flex-shrink: 0; }

.gm-plan-fields-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; }
.gm-plan-field {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 16px 4px; border-bottom: 1px dashed var(--border);
}
.gm-plan-field-ico {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.gm-plan-field-ico svg { width: 17px; height: 17px; }
.gm-plan-field-label {
  font-size: 11px; color: var(--muted); letter-spacing: .06em;
  text-transform: uppercase; font-weight: 700;
}
.gm-plan-field-value { font-size: 15px; font-weight: 600; margin-top: 3px; color: var(--text); }

@media (max-width: 720px) {
  .gm-plan-fields-grid { grid-template-columns: 1fr; }
  .gm-plan-detail-actions { width: 100%; }
  .gm-plan-detail-name { font-size: 27px; }
}

/* Toolbar responsive con grid-template-areas (más predecible que flex-wrap) */
/* Por defecto (>1400): una fila — search | chips | botón.
   El área "btn" la ocupa el botón de alta de cada pantalla
   (#btnNewClient en Clientes, #btnNewPlan en Planes). */
.gm-clients-toolbar {
  grid-template-areas: "search chips btn";
}
.gm-clients-toolbar #clientSearchForm,
.gm-clients-toolbar #planSearchForm { grid-area: search; }
.gm-clients-toolbar .gm-clients-list-chips { grid-area: chips; }
.gm-clients-toolbar #btnNewClient,
.gm-clients-toolbar #btnNewPlan { grid-area: btn; white-space: nowrap; flex-shrink: 0; margin-left: 0; }

/* Variante sin botón de alta: solo search + chips */
.gm-clients-toolbar:not(:has(#btnNewClient)):not(:has(#btnNewPlan)) {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "search chips";
}

/* ≤1400: search arriba ancho completo, chips + botón abajo */
@media (max-width: 1400px) {
  .gm-clients-toolbar {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "search search"
      "chips  btn";
    gap: 10px 12px;
  }
  .gm-clients-toolbar:not(:has(#btnNewClient)):not(:has(#btnNewPlan)) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "search"
      "chips";
  }
  .gm-clients-toolbar #clientSearchForm,
  .gm-clients-toolbar #planSearchForm {
    max-width: none !important;
    width: 100%;
  }
  /* Chips: ocupan el espacio sobrante, scrollean horizontal si no entran */
  .gm-clients-toolbar .gm-clients-list-chips {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .gm-clients-toolbar #btnNewClient,
  .gm-clients-toolbar #btnNewPlan { margin-left: 0 !important; }
}

@media (max-width: 920px) {
  /* Ocultar tabla, mostrar cards */
  .gm-clients-table { display: none; }
}

/* ≤560: 3 filas — search / chips / botón */
@media (max-width: 560px) {
  .gm-clients-toolbar {
    grid-template-columns: 1fr;
    grid-template-areas:
      "search"
      "chips"
      "btn";
  }
  .gm-clients-toolbar #btnNewClient { justify-self: stretch; justify-content: center; }
}
@media (min-width: 921px) {
  #clientsMobileCards { display: none; }
}

/* ============================================================
   Mi perfil (/profile)
   ============================================================ */
.gm-profile-wrap { max-width: 920px; margin: 0 auto; }
.gm-profile-head {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 24px;
}
.gm-profile-avatar {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--navy); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 26px;
  flex-shrink: 0;
}
.gm-profile-title {
  font-family: 'Manrope', sans-serif;
  font-size: 28px; font-weight: 700;
  margin: 0; color: var(--text); letter-spacing: -.01em;
}
.gm-profile-sub { margin: 4px 0 0; color: var(--muted); font-size: 14px; }

.gm-profile-grid {
  display: grid; gap: 20px;
  grid-template-columns: 1fr;
}

.gm-profile-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px 24px;
}
.gm-profile-card-head { margin-bottom: 18px; }
.gm-profile-card-head h2 {
  font-family: 'Manrope', sans-serif;
  font-size: 18px; font-weight: 700;
  margin: 0; color: var(--text); letter-spacing: -.01em;
}
.gm-profile-card-actions {
  display: flex; justify-content: flex-end;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

@media (max-width: 600px) {
  .gm-profile-head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .gm-profile-avatar { width: 52px; height: 52px; font-size: 22px; }
  .gm-profile-title { font-size: 22px; }
  .gm-profile-card { padding: 18px; }
  .gm-profile-card-actions .gm-btn { width: 100%; justify-content: center; }
}

/* ============================================================
   Barra delgada del lector (Control de Asistencia) — gm-fpbar
   Reemplaza al mini kiosk vertical grande por una barra horizontal compacta.
   ============================================================ */
.gm-attendance-stack { display: flex; flex-direction: column; gap: 16px; }

.gm-fpbar {
  display: flex; align-items: center; gap: 16px;
  background: var(--navy); color: #F1F2EE;
  border-radius: 12px;
  padding: 12px 16px;
  position: relative; overflow: hidden;
}
/* mesh sutil de fondo */
.gm-fpbar::before {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.05) 1px, transparent 1px);
  background-size: 30px 30px;
  -webkit-mask-image: radial-gradient(ellipse at center, black 20%, transparent 75%);
  mask-image: radial-gradient(ellipse at center, black 20%, transparent 75%);
  pointer-events: none;
}

/* Botón "Abrir kiosko" (izquierda) */
.gm-fpbar-cta {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--accent); color: var(--navy);
  border: none; border-radius: 10px;
  padding: 11px 16px; cursor: pointer;
  font-family: inherit; font-weight: 700; font-size: 14px;
  text-decoration: none;
  flex-shrink: 0;
  transition: transform .15s, box-shadow .15s;
  box-shadow: 0 8px 22px -10px rgba(198,239,67,.5);
}
.gm-fpbar-cta:hover { transform: translateY(-1px); box-shadow: 0 12px 28px -8px rgba(198,239,67,.6); color: var(--navy); }
.gm-fpbar-cta svg { flex-shrink: 0; }

/* Info central (pill + texto de estado) */
.gm-fpbar-info {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 14px;
  flex: 1; min-width: 0;
}
.gm-fpbar-text { min-width: 0; }
.gm-fpbar-title {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 15px; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-fpbar-sub {
  font-size: 12px; color: rgba(241,242,238,.6);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Anillo de huella compacto (derecha) — reusa .gm-fp-ring del kiosk pero a 56px */
.gm-fpbar-ring.gm-fp-ring {
  position: relative; z-index: 1;
  width: 56px; height: 56px;
  flex-shrink: 0;
  margin: 0;
}
/* El fingerprint del kiosk es grande; en la barra lo reducimos */
.gm-fpbar-ring .gm-fp-icon { width: 26px !important; height: 26px !important; }
/* Drop-shadow del inner más sutil a esta escala */
.gm-fpbar-ring .gm-fp-inner { filter: drop-shadow(0 0 6px rgba(198,239,67,.45)); }
.gm-fpbar-ring.state-scanning .gm-fp-inner { filter: drop-shadow(0 0 10px rgba(198,239,67,.7)); }
.gm-fpbar-ring.state-success .gm-fp-inner { filter: drop-shadow(0 0 12px rgba(198,239,67,.9)); }
.gm-fpbar-ring.state-deny .gm-fp-inner    { filter: drop-shadow(0 0 10px rgba(220,62,62,.6)); }
/* Scanner line proporcional al anillo chico */
.gm-fpbar-ring .gm-fp-scanner { width: 44px; }

/* Botones de simulación compactos (provisional) */
.gm-fpbar-sim {
  position: relative; z-index: 1;
  display: flex; gap: 6px; flex-shrink: 0;
}
.gm-fpbar-sim .gm-mk-sim-btn {
  width: 32px; height: 32px; padding: 0;
  justify-content: center;
}

/* Responsive móvil: UNA fila — botón kiosko (izq) | sim (medio) | huella (derecha).
   Ocultamos el bloque de info (pill + título + subtítulo) para liberar espacio. */
@media (max-width: 600px) {
  .gm-fpbar {
    display: flex !important;
    align-items: center;
    gap: 10px;
    padding: 12px !important;
    grid-template-columns: none;
    grid-template-areas: none;
  }
  .gm-fpbar-info { display: none !important; }
  /* Orden visual con flex: cta(1) → sim(2, centrado) → ring(3, pegado al borde derecho) */
  .gm-fpbar-cta  {
    order: 1;
    padding: 9px 12px; font-size: 12px;
    flex-shrink: 0;
  }
  .gm-fpbar-cta svg { width: 14px; height: 14px; }
  .gm-fpbar-sim  {
    order: 2;
    flex: 1;                    /* ocupa el espacio sobrante entre CTA y huella */
    justify-content: center;    /* sim buttons en el medio */
    padding-right: 0 !important;
    margin-right: 0 !important;
  }
  .gm-fpbar-ring {
    order: 3;
    flex-shrink: 0;
    margin-right: 0 !important;
    justify-self: auto;
  }
}

/* Pantallas muy chicas (≤360px): compactar más para que entre todo */
@media (max-width: 360px) {
  .gm-fpbar { gap: 6px; padding: 10px !important; }
  .gm-fpbar-cta { padding: 8px 10px; font-size: 11.5px; }
  .gm-fpbar-cta svg { width: 13px; height: 13px; }
}


/* ============================================================
   Modal de huella digital (cliente)
   ============================================================ */
.gm-fp-modal {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: gmKioskFadeIn .15s ease;
}
.gm-fp-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(6, 20, 42, .55);
  backdrop-filter: blur(2px);
}
.gm-fp-modal-card {
  position: relative; z-index: 1;
  background: var(--navy); color: #F1F2EE;
  border-radius: 18px;
  padding: 32px 28px 24px;
  width: 100%; max-width: 420px;
  text-align: center;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.5);
  animation: gmKioskPop .2s ease;
  max-height: 92vh;
  overflow-y: auto;
}
/* Variante kiosk: header con avatar + feed grande + sim */
.gm-fp-kiosk { max-width: 440px; padding: 22px 26px 22px; }
.gm-fp-kiosk-head {
  display: flex; align-items: center; gap: 12px;
  text-align: left;
  margin-bottom: 8px;
}
.gm-fp-kiosk-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(198,239,67,.18); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 15px;
  flex-shrink: 0;
}
.gm-fp-kiosk-meta { flex: 1; min-width: 0; }
.gm-fp-kiosk-name {
  font-family: 'Manrope', sans-serif;
  font-size: 15px; font-weight: 700; color: #F1F2EE;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-fp-kiosk-state-pill { margin-top: 4px; }

.gm-fp-kiosk-feed {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid rgba(241,242,238,.08);
}
/* Dots de los 3 intentos en el modal de captura: el feed es text-align:center
   pero los dots son un flex container, así que los centramos explícitamente. */
.gm-fp-kiosk-feed .gm-fpw-dots { justify-content: center; margin-top: 14px; }
.gm-fp-kiosk-title {
  font-family: 'Manrope', sans-serif;
  font-size: 19px; font-weight: 700; margin: 0;
  color: #F1F2EE;
  transition: color .2s ease;
}
.gm-fp-kiosk-sub {
  font-size: 13.5px; color: rgba(241,242,238,.65);
  margin: 6px 0 0; line-height: 1.45;
}
/* Estados de color del título según state del ring */
.gm-fp-ring.state-success ~ .gm-fp-kiosk-feed .gm-fp-kiosk-title { color: var(--accent); }
.gm-fp-ring.state-deny    ~ .gm-fp-kiosk-feed .gm-fp-kiosk-title { color: #ffb4b4; }

/* Variante prominente para errores que requieren atención inmediata del
   operario (ej. huella duplicada). Fondo + borde rojo lo hace lucir como
   un badge en vez de texto suelto. Se aplica via JS por encima del
   color base del state-deny. */
.gm-fp-kiosk-title.is-fp-error {
    display: inline-block;
    background: rgba(220, 62, 62, .18);
    color: #ff6b6b !important;
    border: 1px solid rgba(220, 62, 62, .45);
    padding: 6px 14px;
    border-radius: 999px;
    font-weight: 800;
}

/* Bloque de simulación dentro del modal */
.gm-fp-kiosk-sim {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px dashed rgba(241,242,238,.15);
}
.gm-fp-kiosk-sim-label {
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; color: rgba(241,242,238,.45);
  margin-bottom: 8px;
}
.gm-fp-kiosk-sim-row {
  display: flex; gap: 8px; justify-content: center;
  flex-wrap: wrap;
}
.gm-fp-kiosk-sim-row .gm-mk-sim-btn { padding: 8px 14px; }
.gm-fp-modal-close {
  position: absolute; top: 14px; right: 14px;
  width: 32px; height: 32px; border-radius: 8px;
  background: rgba(241,242,238,.08); border: none;
  color: rgba(241,242,238,.7); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.gm-fp-modal-close:hover { background: rgba(241,242,238,.16); color: #F1F2EE; }
.gm-fp-modal-ring {
  width: 200px; height: 200px;
  margin: 12px auto 18px;
  position: relative;
}
.gm-fp-modal-ring .gm-fp-icon { width: 80px !important; height: 80px !important; }
/* Barra de scanner: ajustada al tamaño del ring del modal (200px). */
.gm-fp-modal-ring .gm-fp-scanner {
  width: 150px; height: 3px;
}
.gm-fp-modal-title {
  font-family: 'Manrope', sans-serif;
  font-size: 22px; font-weight: 700; margin: 0;
}
.gm-fp-modal-sub {
  font-size: 14px; color: rgba(241,242,238,.7);
  margin: 8px 0 0; line-height: 1.5;
}
.gm-fp-modal-sub strong { color: var(--accent); }
.gm-fp-modal-actions {
  display: flex; gap: 10px; justify-content: center;
  margin-top: 22px;
}
.gm-fp-modal-actions .gm-btn { flex: 1; justify-content: center; }

/* ============================================================
   Detalle del cliente — Hero Navy + Tabs
   ============================================================ */
.gm-detail-hero {
  position: relative; overflow: hidden;
  background: radial-gradient(ellipse at 25% 0%, var(--navy-3, #1a3a5c) 0%, var(--navy) 55%, var(--navy-2, #0c2138) 100%);
  color: #F1F2EE;
  border-radius: 16px;
  padding: 22px 24px;
  margin-bottom: 16px;
}
.gm-detail-hero-mesh {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(241,242,238,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,242,238,.04) 1px, transparent 1px);
  background-size: 34px 34px;
  -webkit-mask-image: radial-gradient(ellipse at 25% 0%, black 30%, transparent 75%);
  mask-image: radial-gradient(ellipse at 25% 0%, black 30%, transparent 75%);
  pointer-events: none;
}
.gm-detail-hero-back {
  position: relative; z-index: 1;
  width: 34px; height: 34px; border-radius: 9px;
  background: rgba(241,242,238,.08); border: 1px solid rgba(241,242,238,.12);
  color: rgba(241,242,238,.85); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 16px;
  transition: background .15s, color .15s;
}
.gm-detail-hero-back:hover { background: rgba(241,242,238,.16); color: #fff; }
.gm-detail-hero-back svg { width: 17px; height: 17px; }
.gm-detail-hero-body {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 16px;
}
.gm-detail-hero-avatar {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--accent); color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 24px;
  flex-shrink: 0;
}
.gm-detail-hero-info { min-width: 0; }
.gm-detail-hero-name {
  font-family: 'Manrope', sans-serif;
  font-size: 24px; font-weight: 700; letter-spacing: -.01em;
  line-height: 1.1;
}
.gm-detail-hero-tipo {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 8px;
}
.gm-detail-hero-email { font-size: 13px; color: rgba(241,242,238,.6); }
.gm-detail-hero-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 10px;
}
/* Nota / observación del cliente: bloque debajo del hero.
   Look minimalista: label uppercase encima + contenedor blanco con borde
   sutil y radius. El label tiene un dot accent que da pista de color. */
.gm-detail-clientnote {
  margin: 14px 0 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.gm-detail-clientnote-label {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: 'Manrope', sans-serif;
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 700; color: var(--muted);
  padding-left: 2px;
}
.gm-detail-clientnote-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px rgba(198,239,67,.20);
}
.gm-detail-clientnote-body {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 0 10px 10px 0;
  padding: 12px 14px;
  transition: border-color .15s, box-shadow .15s;
}
.gm-detail-clientnote-body:hover {
  border-color: var(--border-strong);
  border-left-color: var(--accent);
  box-shadow: 0 2px 8px -4px rgba(15,42,71,.10);
}
.gm-detail-clientnote-text {
  margin: 0;
  font-size: 13.5px; line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
  word-wrap: break-word;
}
.gm-hero-chip {
  display: inline-flex; align-items: center;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(241,242,238,.07); border: 1px solid rgba(241,242,238,.1);
  font-size: 12px; color: rgba(241,242,238,.8); font-weight: 500;
}

/* Tabs del detalle de cliente — estilo "levantarse del papel".
   Todos los tabs apoyan en un border-bottom común. El activo se eleva
   del papel con fondo blanco + sombra sutil + subrayado accent abajo
   (que tapa el border-bottom del contenedor para conectarse al panel).
   Los inactivos son texto plano: al hover crece un underline accent
   desde el centro hacia los costados. */
.gm-detail-tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;             /* reducido: las cards ya tienen su propio padding/border */
  overflow-x: auto;
  padding: 4px 0 0;
}
.gm-detail-tabs::-webkit-scrollbar { display: none; }

.gm-detail-tab {
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 18px 13px;
  background: transparent;
  border: none;
  border-radius: 10px 10px 0 0;
  color: var(--muted);
  font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer; white-space: nowrap;
  transition: color .2s ease, background .22s ease, box-shadow .22s ease;
  margin-bottom: -1px;
}
.gm-detail-tab svg {
  width: 16px; height: 16px; flex-shrink: 0;
  transition: color .2s ease;
}

/* Underline animado para tabs INACTIVOS: crece desde el centro al hover.
   Implementado con un pseudo-element ::before que escala en X desde 0 a 1
   con transform-origin: center. */
.gm-detail-tab::before {
  content: '';
  position: absolute;
  left: 14px; right: 14px;
  bottom: 0;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .28s cubic-bezier(.3,.7,.3,1),
              opacity .2s ease,
              height .22s ease;
  opacity: .8;
  pointer-events: none;
}
.gm-detail-tab:not(.is-active):hover {
  color: var(--text);
}
.gm-detail-tab:not(.is-active):hover::before {
  transform: scaleX(1);
}
.gm-detail-tab:not(.is-active):hover svg {
  color: var(--accent);
}

/* Tab activo: "levantado del papel".
   Fondo blanco que se conecta visualmente con el panel de abajo (sin línea
   inferior entre tab y contenido). Bordes laterales + superior con un
   shadow plano del color del border. Sombra superior difusa para dar la
   sensación de "levantado". */
.gm-detail-tab.is-active {
  color: var(--navy);
  background: var(--surface);
  box-shadow:
    -1px 0 0 var(--border),
    1px 0 0 var(--border),
    0 -1px 0 var(--border),
    0 -4px 14px -10px rgba(15,42,71,.18);
}
.gm-detail-tab.is-active svg { color: var(--navy); }
/* El underline accent del tab activo queda full + tapa el border-bottom
   del contenedor para que la pestaña parezca "conectada" al panel. */
.gm-detail-tab.is-active::before {
  transform: scaleX(1);
  opacity: 1;
  height: 3px;
  bottom: -1px;
}

.gm-detail-tabpanel { display: flex; flex-direction: column; gap: 14px; }

@media (max-width: 600px) {
  .gm-detail-hero-avatar { width: 52px; height: 52px; font-size: 20px; }
  .gm-detail-hero-name { font-size: 20px; }
  .gm-detail-tab span { display: none; } /* solo iconos en mobile */
  .gm-detail-tab { padding: 11px 14px; }
}

/* ============================================================
   Botones pequeños y responsive (membresía / acciones de card)
   ============================================================ */
.gm-btn-sm {
  height: 32px !important;
  padding: 0 10px !important;
  font-size: 12px !important;
  gap: 5px;
}
.gm-btn-sm svg { width: 13px !important; height: 13px !important; }

/* En la cabecera de card de membresía: permitir que las acciones no aprieten el título */
.gm-edit-card[data-card="membership"] .gm-edit-card-head { flex-wrap: wrap; row-gap: 8px; }

/* Botón "Editar" en el Hero Navy */
.gm-detail-hero-edit {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 9px;
  background: rgba(241,242,238,.1); border: 1px solid rgba(241,242,238,.18);
  color: #F1F2EE; font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer; flex-shrink: 0;
  transition: background .15s, border-color .15s;
}
.gm-detail-hero-edit:hover { background: rgba(241,242,238,.18); }
.gm-detail-hero-edit svg { width: 15px; height: 15px; }
/* Botón eliminar del hero: al hover el ícono (papelera) se pone rojo. */
.gm-hero-del:hover svg { color: #ff6b6b; }

/* Wrapper de acciones del Hero (huella + editar).
   Apilado a la derecha; en mobile se enrolla a la siguiente línea. */
.gm-detail-hero-actions {
  position: relative; z-index: 1;
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 8px;
  flex-wrap: wrap; justify-content: flex-end;
  align-self: flex-start;
  flex-shrink: 0;
  max-width: 100%;
}

/* Variante "registrada" cuando vive sobre el hero navy:
   tono verde lima/accent para que destaque sobre fondo oscuro */
.gm-detail-hero-actions .gm-fp-btn.is-registered {
  background: rgba(198,239,67,.16);
  border-color: rgba(198,239,67,.45);
  color: var(--accent);
}
.gm-detail-hero-actions .gm-fp-btn.is-registered:hover {
  background: rgba(198,239,67,.26);
}
.gm-detail-hero-actions .gm-fp-btn.is-registered .gm-fp-btn-check {
  background: var(--accent);
  color: var(--navy);
}

/* Mobile: botones de huella + editar solo icono */
@media (max-width: 600px) {
  .gm-btn-responsive .gm-btn-label { display: none; }
  .gm-btn-responsive { padding: 0 9px !important; }
  .gm-detail-hero-edit span,
  .gm-detail-hero-actions .gm-fp-btn .gm-fp-btn-label { display: none; }
  .gm-detail-hero-edit,
  .gm-detail-hero-actions .gm-fp-btn { padding: 8px 10px; }
}

/* ============================================================
   Hero en modo edición (ripple blanco + inputs en su lugar)
   ============================================================ */
.gm-detail-hero { position: relative; }

/* Ripple blanco que se expande desde el botón Editar */
.gm-detail-hero-ripple {
  position: absolute;
  border-radius: 50%;
  background: var(--surface);
  transform: scale(0);
  opacity: 0;
  pointer-events: none;
  z-index: 1; /* sobre el mesh, debajo del contenido */
}
.gm-detail-hero.is-rippling .gm-detail-hero-ripple {
  animation: gmHeroRipple .5s cubic-bezier(.3,.7,.3,1) forwards;
}
@keyframes gmHeroRipple {
  0%   { transform: scale(0); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Hero crece al abrir el modo edición (sincronizado con el ripple blanco) */
.gm-detail-hero.is-rippling {
  animation: gmHeroGrow .5s cubic-bezier(.3,.7,.3,1);
  transform-origin: center center;
  will-change: transform;
}
@keyframes gmHeroGrow {
  0%   { transform: scale(.96); }
  55%  { transform: scale(1.025); }
  100% { transform: scale(1); }
}

/* Estado editando: Hero blanco, texto oscuro.
   - Sin ripple: fondo blanco directo (ej. al re-renderizar).
   - Con ripple (is-rippling): el fondo arranca navy y el círculo blanco lo revela. */
.gm-detail-hero.is-editing {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
.gm-detail-hero.is-editing.is-rippling { background: var(--navy); }
.gm-detail-hero.is-editing .gm-detail-hero-mesh { opacity: 0; }
.gm-detail-hero.is-editing .gm-detail-hero-back {
  background: var(--surface-2); border-color: var(--border); color: var(--text);
}
.gm-detail-hero.is-editing .gm-detail-hero-body { align-items: flex-start; }

/* Grid de inputs del hero en edición */
.gm-detail-hero-editgrid {
  flex: 1; min-width: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px;
  position: relative; z-index: 2;
}
.gm-heroedit-wide { grid-column: 1 / -1; }
.gm-heroedit-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.gm-heroedit-field > label {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}
.gm-heroedit-field input,
.gm-heroedit-field select,
.gm-heroedit-field textarea {
  width: 100%; min-width: 0;
  border: 1.5px solid var(--border); border-radius: var(--radius-input);
  padding: 0 12px; font-size: 14px; font-family: inherit; color: var(--text);
  background: var(--surface); outline: none;
  transition: border-color .15s, box-shadow .15s;
  box-sizing: border-box;
  height: 38px;                       /* altura uniforme para input + select nativo */
  line-height: 1.4;
}
.gm-heroedit-field select { padding-right: 28px; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7A85' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; cursor: pointer;
}
/* Textarea: altura fija de 3 rows + permite redimensionar vertical */
.gm-heroedit-field textarea {
  height: auto;
  min-height: 78px;
  padding: 9px 12px;
  resize: vertical;
  line-height: 1.4;
}
.gm-heroedit-field input:focus,
.gm-heroedit-field select:focus,
.gm-heroedit-field textarea:focus {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-heroedit-row { display: flex; gap: 8px; }
.gm-heroedit-row input, .gm-heroedit-row select { flex: 1; }

/* Fila combinada: Nombres | Apellidos | check "Es prospecto" — los tres
   en la misma altura para liberar la columna "Tipo de Cliente" del grid. */
.gm-heroedit-namesrow {
  display: grid !important;
  grid-template-columns: 1fr 1fr auto;
  align-items: end;             /* el check queda alineado con la base del input */
  gap: 12px 14px;
}
@media (max-width: 600px) {
  .gm-heroedit-namesrow {
    grid-template-columns: 1fr 1fr;
  }
  .gm-heroedit-namesrow .gm-heroedit-check { grid-column: 1 / -1; }
}

/* Checkbox "Es prospecto" estilo design system (igual al de pago inicial) */
.gm-heroedit-check {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  border-radius: var(--radius-input);
  border: 1.5px solid var(--border);
  background: var(--surface);
  font-size: 13px; font-weight: 600;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  height: 38px;
  white-space: nowrap;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.gm-heroedit-check input[type="checkbox"] {
  position: absolute; opacity: 0; pointer-events: none;
  width: 0; height: 0;
}
.gm-heroedit-check-box {
  flex-shrink: 0;
  width: 18px; height: 18px;
  border-radius: 5px;
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--navy);
  transition: all .15s;
}
.gm-heroedit-check-box svg { width: 11px; height: 11px; display: none; }
.gm-heroedit-check input:checked + .gm-heroedit-check-box {
  background: var(--accent);
  border-color: var(--accent);
}
.gm-heroedit-check input:checked + .gm-heroedit-check-box svg { display: block; }
.gm-heroedit-check:hover {
  border-color: var(--border-strong);
}
.gm-heroedit-check input:focus-visible + .gm-heroedit-check-box {
  box-shadow: 0 0 0 3px rgba(198,239,67,.35);
}
.gm-heroedit-check-text { line-height: 1; }
/* DateForge embebido en un .gm-heroedit-field (ej. fecha de nacimiento):
   ocultar el label interno duplicado del DateForge y normalizar el alto
   del input al mismo 38px del resto de campos del hero edit. */
.gm-heroedit-field > div[id$="_forge"] .df-label,
.gm-heroedit-field > div[id$="dateforge"] .df-label { display: none; }
/* DateForge de FECHA DE NACIMIENTO en el wizard (modo single): ocultar su
   label interno "Fecha" que duplica la etiqueta del campo. NO aplicar al
   DateForge de membresía (#wzDateforge), que sí necesita sus labels
   (Fecha de inicio / Fecha final / Días). */
.gm-wz-field > #wzBirthForge .df-label { display: none; }
.gm-heroedit-field > div[id$="_forge"] .df-fields,
.gm-heroedit-field > div[id$="dateforge"] .df-fields { gap: 0; }
.gm-heroedit-field > div[id$="_forge"] .df-input,
.gm-heroedit-field > div[id$="dateforge"] .df-input {
  height: 38px !important;
  font-size: 14px !important;
  padding: 0 12px !important;
  border-width: 1.5px !important;
}
.gm-heroedit-actions {
  grid-column: 1 / -1;
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 4px; padding-top: 12px;
  border-top: 1px solid var(--border);
}
/* El botón Eliminar queda anclado a la izquierda; Cancelar/Guardar a la derecha. */
.gm-heroedit-actions .gm-heroedit-delete { margin-right: auto; }

@media (max-width: 600px) {
  .gm-detail-hero-editgrid { grid-template-columns: 1fr; }
  .gm-detail-hero.is-editing .gm-detail-hero-avatar { display: none; }
}

/* ============================================================
   Ripple INVERSO (al guardar): gradiente navy que rellena el Hero
   ============================================================ */
/* Mientras corre el ripple inverso, el hero está en lectura (navy) pero
   arranca blanco y el círculo navy lo cubre desde el botón Guardar. */
.gm-detail-hero.is-rippling-rev { background: var(--surface); }
.gm-detail-hero.is-rippling-rev .gm-detail-hero-ripple {
  display: block;
  background: radial-gradient(circle at center, var(--navy-3, #1a3a5c) 0%, var(--navy) 60%, var(--navy-2, #0c2138) 100%);
  z-index: 1;
  animation: gmHeroRippleRev .55s cubic-bezier(.3,.7,.3,1) forwards;
}
@keyframes gmHeroRippleRev {
  0%   { transform: scale(0); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
/* Hero se "encoge" al cerrar el modo edición.
   El cambio principal de altura lo controla JS via inline `height` (transition).
   Esta keyframe agrega un sutil "squeeze" horizontal para acentuar el efecto. */
.gm-detail-hero.is-rippling-rev {
  animation: gmHeroShrink .55s cubic-bezier(.3,.7,.3,1);
  transform-origin: center center;
  will-change: transform;
}
@keyframes gmHeroShrink {
  0%   { transform: scale(1.015); }
  100% { transform: scale(1); }
}
/* El contenido (avatar/nombre) aparece por encima del ripple navy */
.gm-detail-hero.is-rippling-rev .gm-detail-hero-body,
.gm-detail-hero.is-rippling-rev .gm-detail-hero-back { z-index: 2; }
/* Mientras el ripple navy se expande, el mesh y el contenido ya son claros sobre navy */
.gm-detail-hero.is-rippling-rev .gm-detail-hero-mesh { opacity: 1; z-index: 1; }

/* ============================================================
   Botón "Volver" — magnético con bounce.
   En hover: la flecha hace overshoot a la izquierda (-8px) y se
   asienta en -4px con un rebote elástico. El texto la sigue con
   un leve retraso, dando sensación de "goma". El fondo cambia
   a navy/accent.
   ============================================================ */
.gm-detail-hero-wrap {
  position: relative;
  padding-top: 0;
  margin-bottom: 0;
}

/* En el detalle del cliente arrancamos pegados al topbar — sacamos el
   padding-top del .gm-content y el gap del flex previo para que el botón
   Volver y el hero queden visibles inmediatamente abajo del topbar. */
.gm-edit-pages.is-edit { margin-top: -8px; }

.gm-detail-back-float {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 38px;
  padding: 0 18px 0 14px;
  margin: 0 0 14px 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background .22s ease,
              color .22s ease,
              border-color .22s ease,
              box-shadow .22s ease;
}

.gm-detail-back-arrow,
.gm-detail-back-label {
  display: inline-flex; align-items: center;
}
.gm-detail-back-arrow svg { width: 16px; height: 16px; }
.gm-detail-back-label { white-space: nowrap; }

/* La franja oculta de la variante anterior — fuera del flujo */
.gm-detail-back-bg { display: none; }

/* Animaciones bounce: la flecha hace overshoot y rebote;
   el texto la persigue con un leve retraso (efecto goma). */
@keyframes gmBackArrowBounce {
  0%   { transform: translateX(0); }
  35%  { transform: translateX(-8px); }   /* overshoot */
  60%  { transform: translateX(-2px); }   /* rebote */
  100% { transform: translateX(-4px); }   /* asiento */
}
@keyframes gmBackLabelFollow {
  0%   { transform: translateX(0); }
  20%  { transform: translateX(0); }      /* delay vs flecha */
  55%  { transform: translateX(-4px); }
  100% { transform: translateX(-2px); }
}

/* Hover: navy + accent, flecha y texto se desplazan con bounce */
.gm-detail-back-float:hover {
  background: var(--navy);
  color: var(--accent);
  border-color: var(--navy);
  box-shadow: 0 12px 24px -12px rgba(15,42,71,.4);
}
.gm-detail-back-float:hover .gm-detail-back-arrow {
  animation: gmBackArrowBounce .5s cubic-bezier(.34, 1.56, .64, 1) forwards;
  color: var(--accent);
}
.gm-detail-back-float:hover .gm-detail-back-label {
  animation: gmBackLabelFollow .55s cubic-bezier(.34, 1.56, .64, 1) forwards;
}

/* Salida del hover: ambos vuelven a su posición original suavemente */
.gm-detail-back-float .gm-detail-back-arrow,
.gm-detail-back-float .gm-detail-back-label {
  transform: translateX(0);
  transition: transform .32s cubic-bezier(.3,.7,.3,1),
              color .22s ease;
}

.gm-detail-back-float:active {
  transform: scale(.97);
  transition-duration: .1s;
}

.gm-detail-back-float:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(198,239,67,.45),
              0 12px 24px -12px rgba(15,42,71,.3);
}

@media (max-width: 600px) {
  .gm-detail-back-float {
    padding: 0 14px 0 12px;
    height: 36px;
  }
  .gm-detail-back-label { display: none; }
}

/* ============================================================
   Tab Membresías — Card actual + Historial (estilo asistencia)
   ============================================================ */
/* Barra vertical de color (igual al feed de asistencia) */
.gm-mem-bar {
  display: inline-block; width: 5px; align-self: stretch; min-height: 38px;
  border-radius: 3px; flex-shrink: 0;
}
.gm-mem-bar.is-ok   { background: var(--accent); box-shadow: 0 0 0 1px rgba(198,239,67,.3); }
.gm-mem-bar.is-warn { background: #FFB02E; }
.gm-mem-bar.is-err  { background: #DC3E3E; }
.gm-mem-bar.is-navy { background: var(--navy); }

/* Membresía actual */
.gm-mem-current { display: flex; flex-direction: column; gap: 16px; }
/* La lista de pagos se pega al título "Pagos registrados" anulando
   el gap del padre flex (solo entre esos dos elementos). */
.gm-mem-current > .gm-mem-pay-label + .gm-payments-list { margin-top: -10px; }
.gm-mem-current-top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.gm-mem-current-head { display: flex; align-items: stretch; gap: 12px; }
.gm-mem-current-plan {
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 18px; color: var(--text);
}
.gm-mem-current-dates { font-size: 13px; color: var(--muted); margin-top: 3px; }
.gm-mem-current-badges { display: flex; gap: 6px; flex-wrap: wrap; }

/* Resumen de pago: total / pagado / saldo + barra de progreso */
.gm-mem-pay {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 12px; padding: 16px;
}
.gm-mem-pay-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.gm-mem-pay-cell {
  display: flex; flex-direction: column; gap: 4px;
  padding-left: 12px; border-left: 3px solid var(--border);
}
.gm-mem-pay-cell:nth-child(1) { border-left-color: var(--navy); }
.gm-mem-pay-cell:nth-child(2) { border-left-color: var(--accent); }
.gm-mem-pay-cell:nth-child(3) { border-left-color: #DC3E3E; }
.gm-mem-pay-cell span {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 700;
}
.gm-mem-pay-cell strong {
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 18px; color: var(--text);
}
.gm-mem-pay-cell strong.is-balance { color: var(--danger, #b43333); }
.gm-mem-pay-cell strong.is-balance.is-zero { color: #5a7300; }
.gm-mem-pay-cell:nth-child(3).is-zero-cell { border-left-color: var(--accent); }
.gm-mem-pay-bar {
  height: 8px; border-radius: 999px; background: var(--border);
  margin-top: 14px; overflow: hidden;
}
.gm-mem-pay-bar-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), #aadd2e);
  transition: width .5s cubic-bezier(.3,.7,.3,1);
}
.gm-mem-pay-label {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 700;
  margin: 14px 0 0;           /* respiración arriba; abajo lo da el padding del border */
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
/* Lista de pagos pegada al título */
.gm-mem-pay-label + .gm-payments-list { margin-top: 8px; }

/* ---- Form de edición de membresía como 2 cards (Datos + Pagos) ----
   Reusa .gm-edit-card (borde navy en is-editing) + .gm-mem-pay + .gm-payments-list.
   El "slide" lectura↔edición es el swap del body con una transición suave de
   opacidad/desplazamiento, en paridad con el patrón de las cards del cliente. */
.gm-mem-editcards {
  display: flex; flex-direction: column; gap: 14px;
}
/* Botones del head un poco más compactos para que entren con el título */
.gm-mem-editcards .gm-edit-card-actions .gm-btn-sm { height: 32px; }
/* La card de pagos no necesita el padding extra de gm-edit-card-body arriba
   de la barra; la barra ya trae su propio espaciado. */
.gm-mem-editcards .gm-edit-card-body .gm-mem-pay { margin-top: 0; }
.gm-mem-editcards .gm-edit-card-body .gm-mem-pay-label { margin-top: 16px; }

/* Slide horizontal del body al entrar/salir de edición. El JS aplica
   .is-slide-out-fwd/.is-slide-out-back ANTES de reemplazar el body
   (lectura sale hacia un lado), y .is-slide-in-fwd/.is-slide-in-back
   DESPUÉS (el nuevo contenido entra desde el otro lado).
   fwd = entrar a edición (lectura sale ←, inputs entran →).
   back = salir de edición (inputs salen →, lectura entra ←). */
.gm-mem-editcards .gm-edit-card-body { overflow: hidden; }
.gm-mem-editcards .gm-edit-card-body.is-slide-out-fwd  { animation: gmCardSlideOutLeft  .16s ease forwards; }
.gm-mem-editcards .gm-edit-card-body.is-slide-out-back { animation: gmCardSlideOutRight .16s ease forwards; }
.gm-mem-editcards .gm-edit-card-body.is-slide-in-fwd   { animation: gmCardSlideInRight  .22s cubic-bezier(.2,.8,.25,1); }
.gm-mem-editcards .gm-edit-card-body.is-slide-in-back  { animation: gmCardSlideInLeft   .22s cubic-bezier(.2,.8,.25,1); }
@keyframes gmCardSlideOutLeft  { from { opacity:1; transform:translateX(0); } to { opacity:0; transform:translateX(-24px); } }
@keyframes gmCardSlideOutRight { from { opacity:1; transform:translateX(0); } to { opacity:0; transform:translateX(24px); } }
@keyframes gmCardSlideInRight  { from { opacity:0; transform:translateX(28px); } to { opacity:1; transform:translateX(0); } }
@keyframes gmCardSlideInLeft   { from { opacity:0; transform:translateX(-28px); } to { opacity:1; transform:translateX(0); } }

/* Card 2 "Pagos": las acciones de fila (editar/eliminar) SOLO se ven cuando
   la card está en modo gestión (lista con .is-managing). En modo lectura los
   pagos se muestran sin acciones. Scopeado a la card de pagos para no afectar
   el período actual ni el acordeón del detalle (que comparten .gm-payments-list). */
.gm-edit-card[data-memcard="mempay"] .gm-payments-list:not(.is-managing) .gm-payment-row-actions {
  display: none;
}

/* Filas de pago — más visuales (icono + monto + método) */
.gm-payment-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; border-radius: 10px;
  background: var(--surface-2);
  margin-bottom: 8px;
  transition: background .12s;
}
.gm-payment-row:last-child { margin-bottom: 0; }
.gm-payment-row:hover { background: var(--border); }
/* Variante clickeable (pago editable): cursor + hover más prominente */
.gm-payment-row.is-clickable { cursor: pointer; border: 1px solid transparent; }
.gm-payment-row.is-clickable:hover {
  background: var(--surface);
  border-color: var(--border);
  transform: translateX(2px);
  box-shadow: var(--shadow-sm);
}
.gm-payment-row.is-clickable:focus-visible {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(198,239,67,.35);
}
/* Chevron a la derecha indicando que es clickeable */
.gm-payment-row-chev {
  flex-shrink: 0;
  color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: -4px;
  transition: transform .2s, color .15s;
}
.gm-payment-row-chev svg { width: 16px; height: 16px; }
.gm-payment-row.is-clickable:hover .gm-payment-row-chev {
  color: var(--navy);
  transform: translateX(3px);
}
.gm-payment-row-ico {
  width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0;
  background: rgba(198,239,67,.16); color: #5a7300;
  display: inline-flex; align-items: center; justify-content: center;
}
.gm-payment-row-main { flex: 1; min-width: 0; }
.gm-payment-row-amount { font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 15px; color: var(--text); }
.gm-payment-row-date { font-size: 12px; color: var(--muted); margin-top: 1px; }
.gm-payment-row-desc {
  font-size: 12.5px; color: var(--text); margin-top: 4px;
  line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
.gm-payment-method-chip {
  display: inline-flex; align-items: center;
  padding: 4px 11px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  font-size: 11px; font-weight: 600; color: var(--muted);
  flex-shrink: 0;
}

/* Acciones de la fila de pago (editar / eliminar). Pegadas al chip de
   método, alineadas a la derecha. Se ocultan en filas no-clickable de
   solo lectura porque el JS no las pinta cuando !canManage. */
.gm-payment-row-actions {
  display: inline-flex; align-items: center; gap: 4px;
  flex-shrink: 0; margin-left: 4px;
}
.gm-payment-row-actions .gm-btn-icon {
  width: 28px; height: 28px; padding: 0;
}
.gm-payment-row-actions .gm-btn-icon.is-danger {
  color: var(--muted);
}
.gm-payment-row-actions .gm-btn-icon.is-danger:hover {
  color: var(--danger);
  background: rgba(224, 64, 64, .08);
}

/* Historial de períodos — filas con barra de color (estilo feed asistencia) */
.gm-mem-hist { display: flex; flex-direction: column; gap: 8px; }
.gm-mem-hist-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px; border-radius: 10px;
  background: var(--surface-2);
  transition: background .12s, transform .15s, box-shadow .15s;
  border: 1px solid transparent;
}
.gm-mem-hist-row:hover { background: var(--border); }
/* Fila clickeable (modo edit): hover más prominente + cursor */
.gm-mem-hist-row.is-clickable { cursor: pointer; }
.gm-mem-hist-row.is-clickable:hover {
  background: var(--surface);
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
  transform: translateX(2px);
}
.gm-mem-hist-row.is-clickable:focus-visible {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(198,239,67,.35);
}
/* Membresía actual: borde accent sutil y fondo lima soft */
.gm-mem-hist-row.is-current {
  background: rgba(198,239,67,.08);
  border-color: rgba(198,239,67,.35);
}
.gm-mem-hist-row.is-current:hover {
  background: rgba(198,239,67,.14);
}
.gm-mem-hist-main { flex: 1; min-width: 0; }
.gm-mem-hist-plan {
  font-weight: 600; font-size: 14px; color: var(--text);
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
/* Tag "Actual" al lado del nombre del plan */
.gm-mem-hist-current-tag {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--navy);
  color: var(--accent);
  font-size: 10px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  line-height: 1.4;
}
.gm-mem-hist-dates { font-size: 12px; color: var(--muted); margin-top: 2px; }
.gm-mem-hist-cost { font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 15px; color: var(--text); flex-shrink: 0; }
.gm-mem-hist-badges { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; flex-shrink: 0; }
/* Chevron a la derecha (solo si la fila es clickeable) */
.gm-mem-hist-chev {
  flex-shrink: 0;
  color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .2s, color .15s;
  margin-left: -4px;
}
.gm-mem-hist-chev svg { width: 16px; height: 16px; }
/* La fila del historial abre el form de edición; el chevron (→) se
   desplaza al hover para indicar la navegación. */
.gm-mem-hist-row.is-clickable:hover .gm-mem-hist-chev {
  color: var(--navy);
  transform: translateX(3px);
}

.gm-mem-hist-item {
  border-radius: 12px;
  background: var(--surface-2);
  overflow: hidden;
  transition: box-shadow .15s;
}
/* La fila ocupa todo el item (ya no hay panel colapsable debajo). */
.gm-mem-hist-item > .gm-mem-hist-row {
  background: transparent;
  border-radius: 0;
}
.gm-mem-hist-item > .gm-mem-hist-row.is-clickable:hover {
  background: var(--border);
}

/* ============================================================
   Sección "Registrar pago inicial" en el form Nueva membresía
   ============================================================ */
.gm-mem-paysection {
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  transition: border-color .18s ease, background .18s ease;
}
.gm-mem-paysection:has(input:checked) {
  border-style: solid;
  border-color: var(--border);
  background: var(--surface);
}

.gm-mem-paysection-toggle {
  display: flex; align-items: flex-start; gap: 12px;
  cursor: pointer;
  user-select: none;
}
.gm-mem-paysection-toggle input[type="checkbox"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.gm-mem-paysection-box {
  flex-shrink: 0;
  width: 22px; height: 22px;
  border-radius: 6px;
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--navy);
  transition: all .15s;
  margin-top: 1px;
}
.gm-mem-paysection-box svg { width: 12px; height: 12px; display: none; }
.gm-mem-paysection-toggle input:checked + .gm-mem-paysection-box {
  background: var(--accent);
  border-color: var(--accent);
}
.gm-mem-paysection-toggle input:checked + .gm-mem-paysection-box svg { display: block; }
.gm-mem-paysection-toggle input:focus-visible + .gm-mem-paysection-box {
  box-shadow: 0 0 0 3px rgba(198,239,67,.35);
}

.gm-mem-paysection-text {
  display: flex; flex-direction: column; gap: 2px;
  flex: 1; min-width: 0;
  font-size: 14px;
  color: var(--text);
}
.gm-mem-paysection-text strong { font-weight: 600; }
.gm-mem-paysection-hint {
  font-size: 12px; color: var(--muted); line-height: 1.4;
}

.gm-mem-paysection-body {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.gm-mem-paysection-body[hidden] { display: none; }

.gm-mem-paysection-summary {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13px; font-weight: 500;
  line-height: 1.4;
}
.gm-mem-paysection-summary svg { width: 14px; height: 14px; flex-shrink: 0; }
.gm-mem-paysection-summary.is-ok {
  background: rgba(63,185,80,.10);
  color: #1f7a35;
  border: 1px solid rgba(63,185,80,.30);
}
.gm-mem-paysection-summary.is-warn {
  background: rgba(230,162,60,.10);
  color: #8a5a10;
  border: 1px solid rgba(230,162,60,.40);
}

/* Botón eliminar dentro del head del form de membresía (modo edit) */
.gm-mem-form-delete {
  margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--danger);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.gm-mem-form-delete:hover {
  background: rgba(224,64,64,.08);
  border-color: rgba(224,64,64,.4);
  color: #962020;
}
.gm-mem-form-delete svg { width: 15px; height: 15px; }

@media (max-width: 600px) {
  .gm-mem-pay-row { grid-template-columns: 1fr; gap: 10px; }
  .gm-mem-hist-cost { display: none; }
  .gm-mem-hist-badges { flex-direction: column; align-items: flex-end; }
}

/* ============================================================
   Form de pago — banner de saldo pendiente
   ============================================================ */
.gm-pay-saldo {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; margin-bottom: 16px;
  background: rgba(220,62,62,.06);
  border: 1px solid rgba(220,62,62,.2);
  border-radius: 10px;
}
.gm-pay-saldo-info { display: flex; flex-direction: column; gap: 2px; }
.gm-pay-saldo-label {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 700;
}
.gm-pay-saldo-value {
  font-family: 'Manrope', sans-serif; font-weight: 700; font-size: 18px;
  color: #b43333;
}

/* ============================================================
   Control de asistencia: 2 versiones del kiosk preview
   - Desktop (≥1200px): card grande en columna lateral
   - Mobile (<1200px): barra delgada arriba del feed
   ============================================================ */
/* Barra delgada: solo mobile/tablet */
.gm-fpbar--mobile { display: flex; margin-bottom: 16px; }
@media (min-width: 1200px) {
  .gm-fpbar--mobile { display: none; }
}
/* Card grande lateral: solo desktop */
.gm-attendance-side--desktop { display: none; }
@media (min-width: 1200px) {
  .gm-attendance-side--desktop { display: block; }
}

/* Precios (S/) — siempre alineados a la izquierda en tablas y resúmenes */
table .gm-tnum { text-align: left; }

/* Flechas de navegación de día — agrupadas (lado a lado) en el header de asistencia */
.gm-date-arrows {
  display: inline-flex; align-items: center; gap: 4px;
  flex-shrink: 0;
}

/* ============================================================
   Modal de confirmación global (reemplazo del confirm() del browser).
   Usar `openConfirmModal({ title, message, confirmLabel, tone })`.
   Tones: danger | info
   ============================================================ */
.gm-confirm-modal {
  position: fixed; inset: 0; z-index: 1300;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: gmKioskFadeIn .15s ease;
}
.gm-confirm-backdrop {
  position: absolute; inset: 0;
  background: rgba(6, 20, 42, .55);
  backdrop-filter: blur(2px);
}
.gm-confirm-card {
  position: relative; z-index: 1;
  background: var(--surface);
  border-radius: 14px;
  padding: 28px 28px 22px;
  width: 100%; max-width: 420px;
  text-align: center;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.45);
  animation: gmKioskPop .22s ease;
}
.gm-confirm-icon {
  width: 56px; height: 56px;
  margin: 0 auto 14px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.gm-confirm-icon svg { width: 28px; height: 28px; }
.gm-confirm-tone-danger .gm-confirm-icon {
  background: rgba(224,64,64,.12);
  color: var(--danger);
}
.gm-confirm-tone-info .gm-confirm-icon {
  background: rgba(42,157,204,.12);
  color: var(--info);
}
.gm-confirm-title {
  font-family: 'Manrope', sans-serif;
  font-size: 19px; font-weight: 700;
  margin: 0 0 8px;
  color: var(--text);
}
.gm-confirm-msg {
  font-size: 14px; color: var(--muted);
  margin: 0; line-height: 1.5;
}
.gm-confirm-actions {
  display: flex; gap: 10px; justify-content: center;
  margin-top: 22px;
}
.gm-confirm-actions .gm-btn { flex: 1; max-width: 180px; justify-content: center; }

/* Botón "confirmar" según el tone */
.gm-confirm-btn-danger {
  background: var(--danger) !important;
  color: #FFFFFF !important;
  border: 1px solid var(--danger) !important;
  font-weight: 700;
}
.gm-confirm-btn-danger:hover {
  background: #c43838 !important;
  border-color: #c43838 !important;
}
.gm-confirm-btn-info {
  background: var(--info) !important;
  color: #FFFFFF !important;
  border: 1px solid var(--info) !important;
  font-weight: 700;
}

/* ============================================================
   Huella digital — pill de estado + botones (Información personal)
   ============================================================ */
/* Pill que muestra si el cliente ya tiene huella registrada o no. */
.gm-fp-status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  border: 1px solid transparent;
}
.gm-fp-status svg { width: 14px; height: 14px; flex-shrink: 0; }
.gm-fp-status.is-registered {
  background: rgba(63,185,80,.12);
  color: #1f7a35;
  border-color: rgba(63,185,80,.30);
}
.gm-fp-status.is-empty {
  background: var(--surface-2);
  color: var(--muted);
  border-color: var(--border);
}

/* ============================================================
   Botón único de huella en el Hero (estado + acción combinados).
   Muestra el estado actual (registrada/sin huella) Y al click
   abre el modal de captura tipo mini-kiosk.
   ============================================================ */
.gm-fp-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  font-family: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer;
  transition: transform .15s ease, background .18s ease, color .18s ease,
              border-color .18s ease, box-shadow .18s ease;
  white-space: nowrap;
}
.gm-fp-btn .gm-fp-btn-icon { display: inline-flex; }
.gm-fp-btn .gm-fp-btn-icon svg { width: 16px; height: 16px; }
.gm-fp-btn .gm-fp-btn-label { line-height: 1; }
.gm-fp-btn .gm-fp-btn-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent); color: var(--navy);
}
.gm-fp-btn .gm-fp-btn-check svg { width: 12px; height: 12px; }

/* Variante "sin huella" (acción primaria — llama la atención) */
.gm-fp-btn.is-empty {
  background: var(--accent);
  color: var(--navy);
  border: 1px solid var(--accent);
  font-weight: 700;
  box-shadow: 0 6px 18px -10px rgba(198,239,67,.65);
}
.gm-fp-btn.is-empty:hover {
  background: #d2f55c;
  transform: translateY(-1px);
  box-shadow: 0 10px 22px -10px rgba(198,239,67,.75);
}

/* Variante "registrada" (informativo — muestra check, secundario) */
.gm-fp-btn.is-registered {
  background: rgba(63,185,80,.10);
  color: #1f7a35;
  border: 1px solid rgba(63,185,80,.40);
}
.gm-fp-btn.is-registered:hover {
  background: rgba(63,185,80,.18);
  transform: translateY(-1px);
}

/* Variante "eliminar" — botón solo dentro del modal de huella */
.gm-fp-btn.is-delete {
  background: var(--surface);
  color: var(--danger);
  border: 1px solid var(--border);
  padding: 8px 14px;
}
.gm-fp-btn.is-delete:hover {
  background: rgba(224,64,64,.08);
  border-color: rgba(224,64,64,.4);
  color: #962020;
}
.gm-fp-btn.is-delete svg { width: 15px; height: 15px; }

/* Layout del header del card: mantener los elementos en línea y permitir
   que el pill de status + botones se acomoden bien en mobile */
@media (max-width: 560px) {
  .gm-edit-card-actions .gm-fp-status { display: none; }
}

/* ============================================================
   Botones de acción por fila en Control de Asistencia
   Dos botones directos al final de la fila (sin dropdown):
    - "Crear membresía" (accent) o "Editar membresía" (outline)
    - "Ver cliente" (solo ícono)
   ============================================================ */
.gm-att-row-actions {
  display: flex; align-items: center; gap: 6px;
  flex-shrink: 0;
  /* La columna de acciones tiene ancho fijo; los botones se pegan a la
     derecha para que la grilla quede pareja entre filas. */
  justify-content: flex-end;
}
.gm-att-row-action {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 12px;
  border-radius: var(--radius-pill);
  font-family: inherit; font-weight: 600; font-size: 12.5px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s, transform .12s, box-shadow .15s;
}
.gm-att-row-action svg { width: 14px; height: 14px; flex-shrink: 0; }
.gm-att-row-action:hover { transform: translateY(-1px); }

/* Variante "tag": el ícono vive en una cajita gris a la izquierda del
   texto (estilo subíndice/etiqueta), botón en blanco con borde sutil.
   El ícono recortado en la cajita es el indicador visual de que es
   clickeable, sin recurrir a colores primarios. */
.gm-att-row-action {
  padding-left: 4px;            /* la cajita del ícono ocupa el espacio izq */
}
.gm-att-row-action svg {
  width: 12px !important; height: 12px !important;
  padding: 6px;
  box-sizing: content-box;
  background: var(--surface-2);
  border-radius: 999px;
  color: var(--muted);
  transition: background .15s, color .15s;
}

/* Crear membresía: blanco con borde gris, ícono en cajita gris.
   Hover: el borde se acentúa y la cajita del ícono se oscurece. */
.gm-att-row-action.is-create,
.gm-att-row-action.is-edit {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(15,42,71,.04);
}
.gm-att-row-action.is-create:hover,
.gm-att-row-action.is-edit:hover {
  background: var(--surface);
  border-color: var(--border-strong);
  box-shadow: 0 4px 10px -6px rgba(15,42,71,.18);
}
.gm-att-row-action.is-create:hover svg,
.gm-att-row-action.is-edit:hover svg {
  background: var(--text);
  color: var(--surface);
}

/* Ver cliente: ícono en cajita gris (mismo tratamiento que el de
   crear/editar membresía para mantener un lenguaje visual unificado).
   El botón es un tag chico sin texto; al hover, la cajita del ícono
   se invierte (oscuro con ícono blanco) igual que en los otros. */
.gm-att-row-action.is-icon {
  width: auto; padding: 0 4px 0 4px;
  justify-content: center;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(15,42,71,.04);
}
.gm-att-row-action.is-icon:hover {
  background: var(--surface);
  border-color: var(--border-strong);
  box-shadow: 0 4px 10px -6px rgba(15,42,71,.18);
}
.gm-att-row-action.is-icon:hover svg {
  background: var(--text);
  color: var(--surface);
}

/* Mobile/pantallas chicas: ocultar el texto del botón de membresía
   (queda solo el ícono) para que entre en la fila. */
@media (max-width: 900px) {
  .gm-att-row-action.is-create span,
  .gm-att-row-action.is-edit span { display: none; }
  .gm-att-row-action.is-create,
  .gm-att-row-action.is-edit { width: 32px; padding: 0; justify-content: center; }
}

/* ============================================================
   Modal in-place de membresía desde Control de Asistencia
   Scroll global: el modal NO tiene scroll propio. Si el contenido
   excede la altura del viewport, el overlay completo scrollea
   (igual que una página normal). Esto evita el patrón "scroll
   dentro de scroll" que el usuario rechaza.
   ============================================================ */
/* Cuando el modal está abierto bloqueamos el scroll del body para
   que solo aparezca el scroll del overlay (no se ven dos scrolls). */
body.gm-body-modal-open { overflow: hidden; }

/* Overlay: cubre toda la pantalla, scrollea verticalmente cuando el card
   no entra. El backdrop blurreado es el background DEL overlay (no un
   elemento separado), así envuelve al card y crece con él cuando el
   contenido es largo. Un solo scroll, visible a la derecha del viewport. */
.gm-att-mem-modal {
  position: fixed; inset: 0; z-index: 1200;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 20px;
  animation: gmKioskFadeIn .15s ease;
  background: rgba(6, 20, 42, .55);
  backdrop-filter: blur(2px);
  /* Centramos cuando el card entra; flex-start cuando es más alto que
     el viewport (margin: auto del card hace el centrado óptico). */
  display: flex; align-items: flex-start; justify-content: center;
}
/* El div .gm-att-mem-modal-backdrop existe en el DOM como capa de click
   (data-att-mem-close). Lo mantenemos invisible pero capturando clicks
   en toda el área del overlay. */
.gm-att-mem-modal-backdrop {
  position: absolute; inset: 0;
  background: transparent;
  z-index: 0;
}
.gm-att-mem-modal-card {
  position: relative; z-index: 1;
  background: var(--surface);
  border-radius: 14px;
  width: 100%; max-width: 720px;
  margin: auto 0;                   /* centrado vertical cuando entra */
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.45);
  animation: gmKioskPop .22s ease;
}
.gm-att-mem-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--border);
}
.gm-att-mem-modal-head h3 {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 17px;
  color: var(--text);
}
.gm-att-mem-modal-sub {
  margin: 4px 0 0;
  font-size: 13px; color: var(--muted);
}
.gm-att-mem-modal-close {
  background: transparent; border: none; cursor: pointer;
  width: 32px; height: 32px; border-radius: 8px;
  color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background .15s, color .15s;
}
.gm-att-mem-modal-close:hover { background: var(--surface-2); color: var(--text); }
.gm-att-mem-modal-close svg { width: 16px; height: 16px; }

/* Body sin scroll propio — el scroll vive en el overlay. */
.gm-att-mem-modal-body {
  padding: 18px 22px 22px;
  display: flex; flex-direction: column; gap: 16px;
}

/* Footer en el flujo normal, con borde divisorio arriba */
.gm-att-mem-modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  padding-top: 14px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
.gm-att-mem-modal-actions .gm-btn { min-width: 120px; justify-content: center; }

/* Modal "Extender membresía". */
/* Campo "Vencimiento actual": bloqueado (solo lectura) con candado.
   Se ve claramente deshabilitado, sin borde de foco ni cursor de texto. */
.gm-field-input.is-locked {
  background: var(--surface-2);
  border-color: var(--border);
  cursor: not-allowed;
  opacity: .85;
}
.gm-field-input.is-locked input {
  color: var(--muted);
  cursor: not-allowed;
  font-weight: 600;
}
.gm-field-input.is-locked .gm-field-lock {
  width: 15px; height: 15px; flex-shrink: 0;
  color: var(--muted);
}
/* El .gm-field del DateForge no tiene <label>, mientras que el campo
   "Vencimiento actual" de la izquierda sí lo tiene (.gm-field-label: ~16px
   + gap 7px). El campo usa el label de arriba ("Nuevo vencimiento"), así que
   ocultamos el label interno del DateForge ("Fecha") para no duplicar.
   Selector scopeado al id único del DateForge — no afecta otros DateForge. */
#aext_dateforge .df-label { display: none; }

/* Texto de ayuda pequeño bajo un campo (ej. "Se suma al costo actual"). */
.gm-field-hint {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 2px;
  line-height: 1.35;
}

/* Atajo "sumar rápido": cantidad + unidad (gm-select) + botón Aplicar. */
.gm-att-ext-shortcut {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 14px;
  border-radius: var(--radius-card);
  border: 1px dashed var(--border-strong, var(--border));
  background: var(--surface-2);
}
.gm-att-ext-shortcut-label {
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted);
}
.gm-att-ext-shortcut-fields {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: 8px; align-items: stretch;
}
/* Cantidad y unidad usan el MISMO wrapper .gm-field-input → misma altura, borde
   y radio. Así los dos campos de "sumar rápido" se ven idénticos. */
.gm-att-ext-qty-wrap, .gm-att-ext-unit-wrap { min-width: 0; }
.gm-att-ext-qty-wrap input { text-align: center; font-variant-numeric: tabular-nums; font-weight: 600; }

@media (max-width: 640px) {
  .gm-att-mem-modal { padding: 16px; }
  .gm-att-mem-modal-card { border-radius: 12px; }
}

/* Select "Unidad" inyectado al lado del input "Días" del DateForge.
   Hereda los estilos de .df-input (height/border/radius del design system)
   y replica el chevron navy + peso del resto de los <select> del sistema
   (mismo SVG/grosor/posición que .gm-field-input select), para que se
   vea idéntico al de cualquier dropdown del design system. */
.df-field-unit .df-input-select {
  appearance: none !important; -webkit-appearance: none !important; -moz-appearance: none !important;
  padding-right: 30px !important;
  /* Separamos cada sub-propiedad de background con !important individual.
     El shorthand `background: ... !important` de .df-input resetea
     background-image en cascada — por eso necesitamos forzar cada parte
     por separado (sino el chevron se borra). */
  background-color: var(--surface) !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230F2A47' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 9px center !important;
  background-size: 14px !important;
  cursor: pointer;
  color: var(--text) !important;
  font-weight: 500 !important;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.df-field-unit .df-input-select:focus {
  border-color: var(--navy) !important;
  box-shadow: 0 0 0 4px rgba(198,239,67,.35) !important;
  outline: none !important;
}
.df-field-unit .df-input-select:hover {
  border-color: color-mix(in srgb, var(--navy) 40%, transparent) !important;
}
.df-field-unit .df-input-select::-ms-expand { display: none; }
/* Estilos de las options nativas — alcance limitado por browser pero
   Chrome/Edge respetan el font + size. */
.df-field-unit .df-input-select option {
  font-family: inherit;
  font-size: 14px;
  padding: 8px 12px;
  background: var(--surface);
  color: var(--text);
}
.df-field-unit .df-input-select option:checked,
.df-field-unit .df-input-select option:hover {
  background: var(--accent-soft, rgba(198,239,67,.35));
  color: var(--text);
}
/* Cuando el DateForge tiene un .df-field-unit inyectado, el grid de 3
   columnas se expande a 4 para acomodarlo en la misma fila que Días.
   Cuando además inyectamos nuestro .df-field-qty (membresía con
   cantidad+unidad), el .df-field-days original va oculto via display:
   none, así que solo cuentan los visibles (start | end | qty | unit). */
.df-fields.df-fields-3:has(.df-field-unit) {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 90px 110px !important;
}
@media (max-width: 540px) {
  .df-fields.df-fields-3:has(.df-field-unit) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important;
  }
}
/* Input "Cantidad" inyectado: se comporta como un input numérico real
   (cursor de texto + spinners nativos visibles para subir/bajar la cantidad).
   Mantiene la fuente tabular para alinear los dígitos. */
.df-field-qty .df-input {
  font-variant-numeric: tabular-nums;
  text-align: center;
  cursor: text;
  /* dejar espacio a la izquierda para que los dígitos no queden bajo el spinner */
  padding-left: 14px; padding-right: 8px;
}
/* Spinners nativos visibles y siempre presentes (no solo al hover). */
.df-field-qty .df-input::-webkit-outer-spin-button,
.df-field-qty .df-input::-webkit-inner-spin-button {
  -webkit-appearance: inner-spin-button;
  opacity: 1;
  height: 26px;
}

/* ============================================================
   Toast notifications (.gm-toast-stack / .gm-toast)
   El JS (gm-notifications.js) inyecta el stack en el body y
   controla inline: border-left-color, chip bg/color, meta
   bg/color y progress bg/animation-duration. El CSS solo
   define layout, tipografía, animaciones y posicionamiento.
   ============================================================ */
.gm-toast-stack {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 160;
  width: 360px;
  display: flex; flex-direction: column; gap: 10px;
  pointer-events: none;
}
.gm-toast-stack > * { pointer-events: auto; }

.gm-toast {
  position: relative;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 14px 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--navy);
  border-radius: var(--radius-card);
  box-shadow: 0 14px 36px -14px rgba(15,42,71,.4);
  overflow: hidden;
  animation: gmToastIn .32s cubic-bezier(.2,.85,.25,1);
}
.gm-toast.is-leaving { animation: gmToastOut .24s ease forwards; }

/* El stack ahora vive abajo a la derecha: las notificaciones entran con un
   slide DESDE ABAJO y se desvanecen hacia abajo al salir. */
@keyframes gmToastIn {
  from { opacity: 0; transform: translateY(40px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes gmToastOut {
  from { opacity: 1; transform: translateY(0); max-height: 200px; }
  to   { opacity: 0; transform: translateY(40px); max-height: 0; padding-top: 0; padding-bottom: 0; margin-top: -10px; }
}

.gm-toast-chip {
  width: 30px; height: 30px;
  border-radius: 9px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.gm-toast-chip svg { width: 15px; height: 15px; }

.gm-toast-body { flex: 1; min-width: 0; }

/* Reservamos espacio a la derecha para que el botón X no tape el timestamp */
.gm-toast-top {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-right: 28px;
}

.gm-toast-kind {
  font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
}
.gm-toast-time {
  font-size: 11px; color: var(--muted);
  font-family: 'Manrope', sans-serif;
  font-weight: 600;
}
.gm-toast-title {
  font-size: 14px; font-weight: 700;
  color: var(--text);
  margin-top: 3px;
  letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gm-toast-msg {
  font-size: 12px; color: var(--muted);
  margin-top: 2px; line-height: 1.4;
}
.gm-toast-meta {
  display: inline-block;
  margin-top: 8px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 700;
}

/* Botón cerrar: anclado arriba-derecha, fuera del flujo del body */
.gm-toast-close {
  position: absolute;
  top: 8px; right: 8px;
  width: 22px; height: 22px;
  border-radius: 6px;
  background: transparent; border: none;
  cursor: pointer;
  color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.gm-toast-close:hover { background: var(--surface-2); color: var(--text); }

/* Barra de progreso — el JS setea background y animation-duration inline */
.gm-toast-progress {
  position: absolute; left: 0; bottom: 0;
  height: 2px; width: 100%;
  transform-origin: left;
  animation: gmToastProgress linear forwards;
  opacity: .55;
}
@keyframes gmToastProgress {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

@media (max-width: 720px) {
  .gm-toast-stack { width: auto; left: 12px; right: 12px; }
}

/* === Notificaciones · variante Compacto ===
   Pill redondeada con ícono circular + anillo giratorio (indicador de tiempo). */
.gm-ntf {
  position: relative; pointer-events: auto;
  animation: gmToastIn .32s cubic-bezier(.2,.85,.25,1);
}
.gm-ntf.is-leaving { animation: gmToastOut .24s ease forwards; }
.gm-ntf-x {
  background: none; border: none; cursor: pointer; color: inherit; opacity: .5;
  display: flex; align-items: center; justify-content: center;
  padding: 2px; border-radius: 6px; flex-shrink: 0; transition: opacity .15s;
}
.gm-ntf-x:hover { opacity: 1; }

.gm-ntf-compact {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px 11px 11px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: 0 12px 30px -16px rgba(15,42,71,.45);
}
.gm-ntf-comp-ico {
  position: relative; width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.gm-ntf-comp-ico svg { width: 18px; height: 18px; }
.gm-ntf-comp-ring {
  position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid; border-color: inherit;
  opacity: .5;
  animation: gmRingSpin linear forwards;
  clip-path: inset(0 0 50% 0);
}
@keyframes gmRingSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.gm-ntf-comp-body { flex: 1; min-width: 0; }
.gm-ntf-comp-title { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gm-ntf-comp-msg { font-size: 11px; color: var(--muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Notificaciones · variante Sólido
   Fondo del color del tono; el texto y el ícono van encima (el JS setea los
   colores inline por tono). Usada para los ingresos de clientes. */
.gm-ntf-solid {
  position: relative;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 36px 16px 14px;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 14px 36px -14px rgba(15,42,71,.5);
}
.gm-ntf-solid-ico {
  width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.gm-ntf-solid-ico svg { width: 19px; height: 19px; }
.gm-ntf-solid-body { flex: 1; min-width: 0; }
.gm-ntf-solid-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.gm-ntf-solid-kind { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; opacity: .8; }
.gm-ntf-solid-time { font-size: 11px; font-family: 'Manrope', sans-serif; font-weight: 600; }
.gm-ntf-solid-title { font-size: 14px; font-weight: 700; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gm-ntf-solid-msg { font-size: 12px; margin-top: 2px; line-height: 1.4; }
.gm-ntf-solid .gm-ntf-x { position: absolute; top: 11px; right: 11px; }

/* Notificaciones · variante FUSIÓN minimal + sólido (.gm-ntf-ms)
   Píldora de una sola fila (compacta como "minimal") con el fondo del color
   del tono (como "sólido"). Ícono pequeño en chip translúcido, título +
   mensaje finos en columna, hora a la derecha, y barra de progreso. El JS
   setea background/color por tono inline. */
.gm-ntf-ms {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 11px 12px 13px 12px;
  border-radius: 12px; overflow: hidden;
  box-shadow: 0 14px 36px -14px rgba(15,42,71,.5);
}
.gm-ntf-ms-ico {
  width: 32px; height: 32px; border-radius: 9px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.gm-ntf-ms-ico svg { width: 17px; height: 17px; }
.gm-ntf-ms-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.gm-ntf-ms-title { font-size: 13px; font-weight: 700; letter-spacing: -.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gm-ntf-ms-msg { font-size: 11px; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gm-ntf-ms-time { font-size: 10.5px; font-family: 'Manrope', sans-serif; font-weight: 600; flex-shrink: 0; align-self: flex-start; }
.gm-ntf-ms .gm-ntf-x { flex-shrink: 0; }

/* ===== Wizard de creación de clientes ===== */

/* Contenedor raíz: fijo sobre todo el contenido pero debajo de modales (200+).
   El drawer de EDICIÓN también está en z-index 200, pero el wizard nunca
   coexiste con él (son flujos mutuamente excluyentes). */
.gm-wzdrawer-root { position: fixed; inset: 0; z-index: 195; pointer-events: none; }
.gm-wzdrawer-root.is-open { pointer-events: auto; }

.gm-wzdrawer-backdrop {
  position: absolute; inset: 0;
  background: rgba(8, 18, 33, 0);
  transition: background .3s ease;
}
.gm-wzdrawer-root.is-open .gm-wzdrawer-backdrop {
  background: rgba(8, 18, 33, .5);
  backdrop-filter: blur(2px);
}

.gm-wzdrawer {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(560px, 100%);
  background: var(--bg);
  display: flex; flex-direction: column;
  box-shadow: -20px 0 60px -20px rgba(8, 18, 33, .5);
  transform: translateX(100%);
  transition: transform .32s cubic-bezier(.4, 0, .1, 1);
}
.gm-wzdrawer-root.is-open .gm-wzdrawer { transform: translateX(0); }

/* Cuando el contenido del drawer está envuelto en un <form> (Roles, Planes),
   el form debe ser transparente al flex layout: ocupa todo el drawer y
   propaga el flex column a head/body/foot. Sin esto el form genera su propio
   scroll además del .gm-wzdrawer-body → doble scroll. */
.gm-wzdrawer > form {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0;
}

.gm-wzdrawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 24px;
  background: var(--navy);
  color: #F1F2EE;
  flex-shrink: 0;
}
.gm-wzdrawer-head-icon {
  width: 42px; height: 42px;
  border-radius: 12px;
  background: rgba(241, 242, 238, .08);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.gm-wzdrawer-close {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: rgba(241, 242, 238, .08);
  color: #F1F2EE;
  border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s;
}
.gm-wzdrawer-close:hover { background: rgba(220, 62, 62, .25); }

.gm-wzdrawer-body {
  flex: 1; overflow-y: auto;
  padding: 22px 24px;
}

.gm-wzdrawer-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 24px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Stepper horizontal */
.gm-stepper {
  display: flex; align-items: center; gap: 6px;
  padding: 16px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.gm-step {
  display: flex; align-items: center; gap: 9px;
  background: none; border: none; cursor: default;
  font-family: inherit; padding: 0;
}
.gm-step[data-state="done"] { cursor: pointer; }

.gm-step-dot {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--muted);
  box-shadow: inset 0 0 0 1.5px var(--border);
  transition: all .2s;
}
.gm-step[data-state="active"] .gm-step-dot { background: var(--navy); color: var(--accent); box-shadow: none; }
.gm-step[data-state="done"]   .gm-step-dot { background: var(--accent); color: var(--navy); box-shadow: none; }

.gm-step-label { font-size: 13px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.gm-step[data-state="active"] .gm-step-label,
.gm-step[data-state="done"]   .gm-step-label { color: var(--text); }

.gm-step-line {
  flex: 1; height: 2px; border-radius: 2px;
  background: var(--border); transition: background .2s;
}
.gm-step-line[data-done="true"] { background: var(--accent); }

/* Paso / contenido del form */
.gm-wz-step    { display: flex; flex-direction: column; gap: 24px; }
/* El atributo [hidden] debe ganarle al display:flex de arriba (sino los 3
   pasos se ven apilados en el paso 1). */
.gm-wz-step[hidden] { display: none !important; }
.gm-wz-section { display: flex; flex-direction: column; gap: 12px; }
.gm-wz-grid    { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* El contenedor del paso de membresía (#wzMembershipOn) es un div hijo de
   .gm-wz-step que el JS muestra/oculta. Como no es directamente una
   .gm-wz-section, no recibe el gap:24px del step. Lo replicamos aquí para
   que sus secciones internas (Elegir plan / Vigencia / Pago) tengan el
   mismo ritmo vertical que las del paso 1. */
#wzMembershipOn {
  display: flex; flex-direction: column; gap: 24px;
}
/* El display:flex de arriba le ganaba al atributo [hidden] (que el JS usa para
   ocultar el form cuando el cliente es prospecto). Restauramos el ocultado. */
#wzMembershipOn[hidden] { display: none; }

/* DateForge de vigencia del wizard: solo un respiro arriba (separa del label
   "VIGENCIA"). Los campos Cantidad/Unidad se inyectan con el mismo patrón
   canónico (.df-field-qty / .df-field-unit + .df-input-select), así que no
   necesita grid custom ni estilo de select propio. */
#wzDateforge {
  margin-top: 4px;
}

.gm-wz-field { display: flex; flex-direction: column; gap: 6px; }
.gm-wz-field[data-wide="true"] { grid-column: 1 / -1; }
/* Fila Plan + Costo en el wizard de membresía: el plan toma el espacio
   sobrante y el costo es una columna angosta a su derecha. */
.gm-wz-planrow {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 140px;
  gap: 12px;
  align-items: start;
}
.gm-wz-planrow .gm-wz-field { min-width: 0; }
@media (max-width: 480px) {
  .gm-wz-planrow { grid-template-columns: 1fr; }
}
.gm-wz-field label {
  font-size: 12px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: 4px;
}
.gm-req { color: #dc3e3e; }

/* Inputs del wizard: mismo look que el resto de la app (.gm-field-input):
   fondo blanco, borde sólido 1.5px, focus navy + halo verde accent. */
.gm-wz-input {
  width: 100%; background: var(--surface); color: var(--text);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-input);
  padding: 8px 12px; min-height: 36px;
  font-family: inherit; font-size: 14px; line-height: 1.4;
  box-sizing: border-box;
  transition: border-color .15s, box-shadow .15s;
}
.gm-wz-input:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-wz-input.is-invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 4px rgba(224,64,64,.08);
}
.gm-wz-input::placeholder { color: var(--muted); }
.gm-wz-textarea { resize: vertical; min-height: 70px; padding: 8px 12px; }

/* Readonly (valor calculado, ej. fecha de vencimiento): se mantiene en
   gris como campo deshabilitado/de solo lectura. */
.gm-wz-readonly {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; min-height: 36px; border-radius: var(--radius-input);
  background: var(--surface-2); color: var(--text);
  font-size: 14px; font-weight: 500; box-sizing: border-box;
}

/* Input de dinero (S/ + número): mismo look que el resto de la app. */
.gm-wz-money {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border-radius: var(--radius-input);
  padding: 0 12px; min-height: 36px;
  border: 1.5px solid var(--border);
  transition: border-color .15s, box-shadow .15s;
}
.gm-wz-money:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-wz-money span { color: var(--muted); font-size: 14px; font-weight: 600; }
.gm-wz-money input { flex: 1; background: transparent; border: none; outline: none; box-shadow: none; padding: 8px 0; font-family: inherit; font-size: 14px; color: var(--text); min-width: 0; }
.gm-wz-money input:disabled { cursor: not-allowed; opacity: .6; }
.gm-wz-money:has(input:disabled) {
  background: var(--surface-2, rgba(15, 42, 71, .04));
  border-color: var(--border, rgba(15, 42, 71, .12));
}

.gm-wz-optional {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 16px;
  border-radius: var(--radius-card); background: var(--surface);
  border: 1px solid var(--border); cursor: pointer;
}
.gm-wz-empty {
  text-align: center; padding: 32px 20px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius-card);
}

/* Plan picker */
.gm-plan-picker { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.gm-plan-opt {
  text-align: left; cursor: pointer; font-family: inherit;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; transition: all .15s;
}
.gm-plan-opt:hover { border-color: var(--navy); }
.gm-plan-opt[data-active="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1.5px var(--accent);
  background: var(--surface-2);
}

.gm-wz-summary {
  display: flex; flex-direction: column; gap: 2px;
  margin-top: 14px; padding: 14px 16px;
  background: var(--surface-2); border-radius: 12px;
}
.gm-wz-summary > div {
  display: flex; justify-content: space-between; align-items: center;
  padding: 5px 0; font-size: 14px;
}
.gm-wz-summary > div span   { color: var(--muted); }
.gm-wz-summary > div strong { font-family: 'Manrope', sans-serif; }
.gm-wz-summary > div[data-due="true"] strong { color: #dc3e3e; }

/* Switch / toggle iOS */
.gm-switch {
  width: 44px; height: 26px; border-radius: var(--radius-pill);
  flex-shrink: 0;
  background: var(--border); border: none; cursor: pointer;
  position: relative; transition: background .2s; padding: 0;
}
.gm-switch span {
  position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff; transition: transform .2s;
}
.gm-switch[data-on="true"] { background: var(--accent); }
.gm-switch[data-on="true"] span { transform: translateX(18px); }

/* Captura de huella (paso 3 — mini-kiosk embebido en el drawer) */
/* Anula el padding del body del drawer (22px top/bottom, 24px left/right)
   para que el fondo navy llegue de borde a borde del drawer. */
.gm-wz-fp {
  align-items: stretch;
  margin: -22px -24px;
  /* Llena todo el alto del body del drawer (block con altura definida). El +44
     compensa el margin negativo vertical (-22 arriba/abajo) para que el navy
     llegue hasta el footer sin dejar franja blanca. */
  min-height: calc(100% + 44px);
}

.gm-fpw {
  width: 100%; max-width: none; margin: 0;
  background: var(--navy); border-radius: 0;
  padding: 0 24px 26px;
  display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start; flex: 1;
  color: #F1F2EE; position: relative; overflow: hidden;
}
/* Ring centrado en el espacio superior; el bloque de texto (título, sub, dots,
   skip) se empuja hacia el bottom. El ring lleva un spacer flexible arriba y el
   título otro, así el texto queda cerca del fondo. */
.gm-fpw > #wzFpRing { margin-top: auto; }
.gm-fpw > .gm-fpw-title { margin-top: auto; }

.gm-fpw-ring    { position: relative; width: 220px; height: 220px; }
.gm-fpw-rings,
.gm-fpw-brackets { position: absolute; inset: 0; width: 100%; height: 100%; }
.gm-fpw-brackets  { padding: 50px; box-sizing: border-box; }

/* Reutiliza gmMkSpin del kiosk para el anillo exterior giratorio */
.gm-fpw-spin {
  transform-origin: 110px 110px;
  animation: gmMkSpin 7s linear infinite;
  opacity: 0; transition: opacity .3s;
}
.gm-fpw.scanning .gm-fpw-spin { opacity: 1; }

.gm-fpw-core {
  position: absolute; inset: 0; margin: auto;
  width: 150px; height: 150px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(198, 239, 67, .16), rgba(198, 239, 67, .03));
  border: 2px solid rgba(198, 239, 67, .3);
  color: var(--accent); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; transition: all .3s;
}
.gm-fpw-core:disabled { cursor: default; }
.gm-fpw.scanning .gm-fpw-core { border-color: var(--accent); box-shadow: 0 0 50px rgba(198, 239, 67, .35); }
.gm-fpw.success  .gm-fpw-core { background: var(--accent); color: var(--navy); border-color: var(--accent); box-shadow: 0 0 70px rgba(198, 239, 67, .55); }

/* Línea de scan: reutiliza gm-fp-scan (arriba→abajo, kiosk fullscreen) */
.gm-fpw-scan {
  position: absolute; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 16px var(--accent);
  animation: gm-fp-scan 1.6s ease-in-out infinite;
}

/* Pulso del ícono: reutiliza gmMkPulse (kiosk mini) */
.gm-fpw-inner-pulse { animation: gmMkPulse 2.4s ease-in-out infinite; }

.gm-fpw-title {
  font-family: 'Manrope', sans-serif;
  font-size: 22px; font-weight: 700;
  margin-top: 18px; text-align: center;
}
.gm-fpw.success .gm-fpw-title { color: var(--accent); }

.gm-fpw-sub  { font-size: 13px; color: rgba(241, 242, 238, .65); margin-top: 4px; text-align: center; }
.gm-fpw-dots { display: flex; gap: 12px; margin-top: 18px; }

.gm-fpw-dot {
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-size: 13px; font-weight: 700;
  background: rgba(241, 242, 238, .06); color: rgba(241, 242, 238, .5);
  box-shadow: inset 0 0 0 1.5px rgba(241, 242, 238, .12);
  transition: all .25s;
}
.gm-fpw-dot[data-state="active"] {
  background: rgba(198, 239, 67, .15); color: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--accent);
  animation: gmWzFpDotPulse 1.2s infinite;
}
.gm-fpw-dot[data-state="ok"] { background: var(--accent); color: var(--navy); box-shadow: none; }

/* Pulso del dot de captura — distinto al gmMkPulse (opacity, no drop-shadow) */
@keyframes gmWzFpDotPulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: .45; }
}

.gm-fpw-cta,
.gm-fpw-reset {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 20px; padding: 11px 20px;
  border-radius: var(--radius-input); font-family: inherit;
  font-weight: 700; font-size: 14px; cursor: pointer;
  border: none; transition: all .15s;
}
.gm-fpw-cta               { background: var(--accent); color: var(--navy); }
.gm-fpw-cta:hover         { transform: translateY(-1px); }
.gm-fpw-reset             { background: rgba(241, 242, 238, .08); color: #F1F2EE; }
.gm-fpw-reset:hover       { background: rgba(241, 242, 238, .14); }

.gm-fpw-skip {
  font-size: 11px; color: rgba(241, 242, 238, .45);
  margin-top: 16px; text-align: center; max-width: 280px;
}

/* Ring del kiosk embebido en el drawer (paso 3 del wizard de cliente).
   Scopeado a #wzFpRing para no afectar el kiosk fullscreen ni el modal de recaptura. */
#wzFpRing {
  width: 290px; height: 290px;
  margin: 0 auto;
}
/* transform-origin ajustado al viewBox 260 del kiosk,
   escalado visualmente a 290px via width/height del contenedor. */
#wzFpRing .gm-fp-spin     { transform-origin: 130px 130px; }
#wzFpRing .gm-fp-spin-rev { transform-origin: 130px 130px; }
#wzFpRing .gm-fp-ticks    { transform-origin: 130px 130px; }
/* Brackets: proporcional (50px en 220px → ~66px en 290px) */
#wzFpRing .gm-fp-brackets { padding: 66px; }
/* Icono de huella: escala de 68px → 88px */
#wzFpRing .gm-fp-icon { width: 88px; height: 88px; }
/* Scanner: escala proporcional de 140px → 184px */
#wzFpRing .gm-fp-scanner { width: 184px; }

/* Responsive del wizard */
@media (max-width: 560px) {
  .gm-wz-grid,
  .gm-plan-picker { grid-template-columns: 1fr; }
  .gm-step-label  { display: none; }
}

/* ===== Módulo de usuarios ===== */

/* -- Etiqueta de sección dentro del wizard (label + dot decorativo) -- */
.gm-section-label {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.gm-section-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0;
}

/* -- Página y toolbar -- */
.gm-users-page { display: flex; flex-direction: column; gap: 16px; }
.gm-users-toolbar {
  display: flex; align-items: center;
  justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.gm-users-stats { display: flex; gap: 28px; }
.gm-users-toolbar-right {
  display: flex; align-items: center;
  gap: 10px; flex-wrap: wrap;
}
.gm-stat-block { display: flex; flex-direction: column; }
.gm-stat-value {
  font-family: 'Manrope', sans-serif;
  font-size: 26px; font-weight: 700;
  color: var(--text); line-height: 1;
}
.gm-stat-label {
  font-size: 12px; color: var(--muted);
  margin-top: 4px;
  text-transform: uppercase; letter-spacing: .06em; font-weight: 600;
}

/* -- Tabla de usuarios -- */
.gm-users-table th.gm-users-actions-cell,
.gm-users-table td.gm-users-actions-cell { text-align: right; width: 90px; }
.gm-users-table th.col-created,
.gm-users-table td.col-created { white-space: nowrap; width: 130px; }

/* Antes de pasar a cards, ocultamos primero "Creado" y luego "Rol" para que la
   tabla no se apriete. */
@media (max-width: 980px) {
  .gm-users-table .col-created { display: none; }
}
@media (max-width: 720px) {
  .gm-users-table .col-role { display: none; }
}

/* A 920px la regla global ya oculta .gm-table-wrap y muestra .gm-mobile-cards.
   No redefinimos ese comportamiento; el #usersMobileCards usa .gm-mobile-cards
   que ya tiene display:flex en ≤920px. */

/* -- Role picker (cards verticales, layout columna) -- */
.gm-role-picker { display: flex; flex-direction: column; gap: 10px; }

.gm-role-opt {
  text-align: left; cursor: pointer; font-family: inherit;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; transition: all .15s; width: 100%;
}
.gm-role-opt:hover { border-color: var(--navy); }
.gm-role-opt[data-active="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1.5px var(--accent);
  background: var(--surface-2);
}
.gm-role-opt-top {
  display: flex; align-items: center; gap: 10px;
}
.gm-role-opt-ic {
  width: 28px; height: 28px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.gm-role-opt-top strong { flex: 1; }
.gm-role-opt-check { color: var(--navy); display: inline-flex; }
.gm-role-opt-desc { font-size: 12px; color: var(--muted); margin-top: 8px; line-height: 1.4; }

/* -- Desplegable de permisos por rol (dentro del role-picker del wizard) -- */
.gm-role-opt-wrap { display: flex; flex-direction: column; }
/* El botón del rol pierde el radio inferior cuando hay desplegable debajo. */
.gm-role-opt-wrap .gm-role-opt { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.gm-role-perm-toggle {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; cursor: pointer; font-family: inherit;
  font-size: 12px; font-weight: 600; color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border); border-top: none;
  border-radius: 0 0 12px 12px;
  padding: 8px 12px; transition: color .15s, background .15s;
}
.gm-role-perm-toggle:hover { color: var(--navy); background: var(--surface); }
.gm-role-perm-chev { transition: transform .2s ease; }
.gm-role-perm-toggle[aria-expanded="true"] .gm-role-perm-chev { transform: rotate(180deg); }
.gm-role-perms {
  list-style: none; margin: 0; padding: 8px 14px 12px;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border); border-top: none;
  border-radius: 0 0 12px 12px;
}
/* Sin esto, el `display: flex` arriba pisa al `display: none` implícito de
   [hidden] y el desplegable se queda siempre abierto. */
.gm-role-perms[hidden] { display: none; }
/* Cuando la lista está visible, el toggle deja de redondear su borde inferior. */
.gm-role-opt-wrap:has(.gm-role-perms:not([hidden])) .gm-role-perm-toggle {
  border-radius: 0;
}
.gm-role-perm {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text);
}
.gm-role-perm::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0;
}
.gm-role-perm.is-empty { color: var(--muted); }
.gm-role-perm.is-empty::before { background: var(--border); }

/* -- Campo password con ojo -- mismo look que el resto de la app -- */
.gm-wz-pw {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border-radius: var(--radius-input);
  padding: 0 12px; min-height: 36px;
  border: 1.5px solid var(--border);
  transition: border-color .15s, box-shadow .15s;
}
.gm-wz-pw:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-wz-pw input {
  flex: 1; background: transparent; border: none; outline: none;
  box-shadow: none; padding: 8px 0;
  font-family: inherit; font-size: 14px; color: var(--text); min-width: 0;
}
.gm-wz-pw-eye {
  background: none; border: none; cursor: pointer;
  color: var(--muted); display: flex; padding: 4px;
}
.gm-wz-pw-eye:hover { color: var(--text); }
/* El JS marca is-invalid en el wrapper o en el input interno (#uwzPassword);
   cubrimos ambos para que el borde rojo aparezca igual. */
.gm-wz-pw.is-invalid,
.gm-wz-pw:has(input.is-invalid) {
  border-color: var(--danger);
  box-shadow: 0 0 0 4px rgba(224,64,64,.08);
}

/* -- Requisitos de password (checklist que se va vaciando) -- */
.gm-pw-reqs {
  list-style: none; margin: 2px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.gm-pw-req {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px; color: var(--muted);
  /* Transición de colapso: cada ítem cumplido se desvanece y reduce su alto. */
  max-height: 20px; overflow: hidden;
  transition: max-height .25s ease, opacity .2s ease, margin .25s ease;
}
.gm-pw-req-mark {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--muted); flex-shrink: 0; transition: background .2s;
}
/* Requisito cumplido → se oculta (desaparece de la lista). */
.gm-pw-req.is-done {
  max-height: 0; opacity: 0; margin: 0; pointer-events: none;
}
/* Todos cumplidos → la lista entera desaparece sin dejar hueco. */
.gm-pw-reqs.is-complete { max-height: 0; margin: 0; overflow: hidden; }
.gm-pw-mismatch { font-size: 11px; color: var(--danger); }
.gm-pw-edit-note { font-size: 11px; color: var(--muted); }

/* -- Lista de toggles de acceso -- */
.gm-utoggle-list { display: flex; flex-direction: column; gap: 10px; }
.gm-utoggle {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; border-radius: 12px;
  background: var(--surface-2); cursor: pointer;
}
.gm-utoggle-text { flex: 1; }
.gm-utoggle-title { font-size: 14px; font-weight: 600; color: var(--text); }
.gm-utoggle-desc  { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* === Métricas corporales (mapa anatómico + historial) === */

/* Figura anatómica (SVG por piezas) */
.gm-anat-wrap {
  display: flex; justify-content: center; align-items: flex-start;
  width: 100%; height: 326px; overflow: hidden;
}
.gm-anat {
  width: 207px; height: 520px; position: relative;
  transform: scale(.6); transform-origin: top center;
}
.gm-anat svg { position: absolute; left: 50%; fill: #b9c5cf; transition: fill .18s; }
.gm-anat svg.head { margin-left: -28.5px; top: 4px; }
.gm-anat svg.shoulder { margin-left: -53.5px; top: 79px; }
/* z-index por encima de las piernas (z:5): los cuadrantes del antebrazo
   solapan en bounding box con el muslo; al estar arriba, el click cae en el
   antebrazo donde hay path de brazo (extremos) y en el muslo donde no. */
.gm-anat svg.arm { margin-left: -78px; top: 122px; z-index: 6; }
.gm-anat svg.cheast { margin-left: -43.5px; top: 98px; }
/* z-index por encima de brazos (z:6) y piernas (z:5): el bounding box
   rectangular de los cuadrantes del brazo solapa la zona del abdomen y, al
   tener z mayor, robaba el click del abdomen (que quedaba sin responder). El
   path del abdomen es central y angosto, así que estar arriba no roba clicks
   de los brazos (que están a los lados, fuera del path). */
.gm-anat svg.stomach { margin-left: -37.5px; top: 140px; z-index: 7; }
.gm-anat svg.legs { margin-left: -46.5px; top: 215px; z-index: 5; }
.gm-anat svg.hands { margin-left: -102.5px; top: 234px; }
.gm-anat svg.clickable { cursor: pointer; }
.gm-anat svg.clickable:hover, .gm-anat svg.is-hover { fill: var(--navy); }
.gm-anat svg.is-active { fill: var(--accent); }

/* Layout del componente */
.gm-body-layout { display: grid; grid-template-columns: 280px 1fr; gap: 0; }
.gm-body-figure-wrap {
  display: flex; flex-direction: column; align-items: center;
  padding: 24px; position: relative;
  background: var(--surface-2);
  border-right: 1px solid var(--border);
}
/* Selector contextual de músculo (popover al hacer click en brazo/muslo) */
.gm-muscle-pop {
  position: absolute; z-index: 40;
  transform: translate(-50%, calc(-100% - 12px));
  display: flex; flex-direction: column; gap: 2px;
  padding: 5px; min-width: 132px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 30px -8px rgba(15,42,71,.35);
  animation: gmMusclePopIn .14s cubic-bezier(.2,.8,.2,1);
}
.gm-muscle-pop::after {
  content: ''; position: absolute; left: 50%; bottom: -6px;
  width: 12px; height: 12px; background: var(--surface);
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  transform: translateX(-50%) rotate(45deg);
}
@keyframes gmMusclePopIn { from { opacity: 0; transform: translate(-50%, calc(-100% - 4px)); } to { opacity: 1; transform: translate(-50%, calc(-100% - 12px)); } }
.gm-muscle-pop button {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; border-radius: 8px;
  background: transparent; border: none; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text);
  text-align: left; transition: all .12s;
}
.gm-muscle-pop button:hover { background: var(--surface-2); }
.gm-muscle-pop button[data-active="true"] { background: var(--navy); color: var(--accent); }
.gm-muscle-pop-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
.gm-muscle-pop button[data-active="true"] .gm-muscle-pop-dot { box-shadow: 0 0 0 2px rgba(255,255,255,.25); }

.gm-body-hint { margin-top: 16px; font-size: 12px; color: var(--muted); text-align: center; max-width: 200px; }
.gm-body-panel { padding: 22px; display: flex; flex-direction: column; gap: 18px; }
.gm-body-comp { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.gm-comp-cell { padding: 14px; border-radius: 12px; background: var(--surface-2); }
.gm-body-selected { padding: 18px; border-radius: 14px; background: var(--surface-2); }

/* Inputs de medición (mismo look que el input canónico .gm-field-input) */
.gm-measure-input {
  display: flex; align-items: center; gap: 6px;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-input); padding: 0 10px; margin-top: 6px;
  transition: border-color .15s, box-shadow .15s;
}
.gm-measure-input:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 4px rgba(198,239,67,.35);
}
.gm-measure-input input {
  width: 100%; border: none; outline: none; background: transparent;
  font-family: 'Manrope', sans-serif; font-size: 18px; font-weight: 700;
  color: var(--text); padding: 8px 0;
  -moz-appearance: textfield;
}
.gm-measure-input input::-webkit-outer-spin-button,
.gm-measure-input input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.gm-measure-input span { font-size: 13px; color: var(--muted); font-weight: 600; }
.gm-measure-input-lg input { font-size: 32px; padding: 10px 0; }

/* Historial de mediciones (cards) */
/* align-items:start → cada card del historial toma su propio alto (no se
   estira a la más alta de la fila), manteniendo intacto el grid de columnas. */
.gm-measure-history { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 12px; align-items: start; }
/* Las líneas separadoras se dibujan con border en cada celda (no con gap+fondo),
   así la última fila incompleta NO muestra una franja gris de "slots vacíos"
   (el bug de espacio que se acumulaba al final de cada tabla de medición). */
.gm-measure-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 0; background: var(--surface); }
.gm-measure-card-cell { padding: 12px 14px; background: var(--surface); min-width: 0; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.gm-measure-card-acts { display: inline-flex; gap: 6px; }

/* Chip seleccionable (reusable si no existe ya) */
.gm-mchip {
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  background: var(--surface); color: var(--muted);
  border: 1px solid var(--border); font-family: inherit;
  font-size: 12px; font-weight: 600; transition: all .15s;
}
.gm-mchip:hover { border-color: var(--navy); color: var(--text); }
.gm-mchip[data-active="true"] { background: var(--navy); color: var(--accent); border-color: var(--navy); }

@media (max-width: 760px) {
  .gm-body-layout { grid-template-columns: 1fr; }
  .gm-body-figure-wrap { border-right: none; border-bottom: 1px solid var(--border); }
}

/* ============================================================
   Modal "Historial de logins" (.gm-lh-modal)
   Sigue el patrón de .gm-att-mem-modal: overlay scrollable,
   card centrada, head/body/foot con borde divisorio.
   ============================================================ */
.gm-lh-modal {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: rgba(6, 20, 42, .55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: gmKioskFadeIn .15s ease;
}
.gm-lh-modal-backdrop {
  position: absolute; inset: 0;
  background: transparent;
  z-index: 0;
}
.gm-lh-modal-card {
  position: relative; z-index: 1;
  background: var(--surface);
  border-radius: 16px;
  width: 100%; max-width: 900px;
  margin: auto 0;
  display: flex; flex-direction: column;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .45);
  animation: gmKioskPop .22s ease;
  overflow: hidden;
}
.gm-lh-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.gm-lh-modal-head-title {
  font-family: 'Manrope', sans-serif;
  font-weight: 700; font-size: 17px;
  color: var(--text);
  margin: 0;
}
.gm-lh-modal-head-sub {
  font-size: 12px; color: var(--muted);
  margin: 3px 0 0;
}
.gm-lh-modal-close {
  background: transparent; border: none; cursor: pointer;
  width: 32px; height: 32px; border-radius: 8px;
  color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background .15s, color .15s;
  padding: 0;
}
.gm-lh-modal-close:hover { background: var(--surface-2); color: var(--text); }
.gm-lh-modal-close svg { width: 16px; height: 16px; }
.gm-lh-modal-body {
  flex: 1;
  overflow-x: auto;
}
.gm-lh-modal-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  flex-shrink: 0;
}
.gm-lh-modal-page-info {
  font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.gm-lh-modal-pager { display: flex; gap: 6px; }

/* Tabla interna — sin border-radius (la card ya tiene el radio exterior) */
.gm-lh-modal .gm-table-wrap {
  border-radius: 0;
  border: none;
  box-shadow: none;
}
.gm-lh-modal .gm-table thead th:first-child,
.gm-lh-modal .gm-table thead th:last-child { border-radius: 0; }

/* Columnas de datos sensibles (IP, dispositivo) */
.gm-lh-col-meta {
  font-size: 11.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gm-lh-col-device {
  font-size: 11.5px;
  color: var(--muted);
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gm-lh-col-date {
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.gm-lh-col-score {
  font-size: 12px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.gm-lh-col-reason { font-size: 12px; }

/* Estado vacío / error dentro del modal */
.gm-lh-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px;
  padding: 40px 24px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}
.gm-lh-state.is-error { color: var(--danger, #E04040); }

@media (max-width: 640px) {
  .gm-lh-modal { padding: 12px 8px; }
  .gm-lh-modal-card { border-radius: 12px; }
  .gm-lh-modal-head { padding: 14px 16px 12px; }
  .gm-lh-modal-foot { padding: 10px 14px; flex-wrap: wrap; gap: 8px; }
}
/* ============================================================
   Dashboard de métricas (rediseño)
   Encabezados de dos líneas (overline + título) y layout AlertRow.
   ============================================================ */

/* Encabezado de card con overline + título grande */
.gm-metric-card-overline-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.gm-metric-card-overline {
  font-family: 'Manrope', sans-serif;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1;
}
.gm-metric-card-title {
  font-family: 'Space Grotesk', 'Manrope', sans-serif;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--text);
  margin: 0;
  line-height: 1.2;
}

/* Cuando el encabezado de la card usa el overline-group,
   aumentamos el padding vertical para que respire */
.gm-chart-card-head:has(.gm-metric-card-overline-group) {
  padding: 16px 20px;
}

/* Contenedor de filas de alerta (reemplaza el row Bootstrap interno) */
.gm-alert-rows {
  display: flex;
  flex-direction: column;
  padding: 8px 0;
  flex: 1;
}

/* Rediseño AlertRow: fila horizontal icono + texto + número */
.gm-alert-rows .gm-alert-tile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 20px;
  border-radius: 0;
  border: none;
  border-bottom: 1px solid var(--border);
  background: transparent;
  box-shadow: none;
  position: relative;
  transition: background .12s;
}
.gm-alert-rows .gm-alert-tile:last-child {
  border-bottom: none;
}
.gm-alert-rows .gm-alert-tile::before {
  display: none;
}
.gm-alert-rows .gm-alert-tile:hover {
  background: var(--surface-2);
}

/* Icono cuadrado con fondo tonal */
.gm-alert-rows .gm-alert-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  background: var(--surface-2);
  color: var(--muted);
  transition: background .12s, color .12s;
}

/* Texto apilado: label + hint */
.gm-alert-rows .gm-alert-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.gm-alert-rows .gm-alert-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gm-alert-rows .gm-alert-hint {
  font-size: 11.5px;
  color: var(--muted);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Número al extremo derecho */
.gm-alert-rows .gm-alert-count {
  font-family: 'Space Grotesk', 'Manrope', sans-serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  min-width: 36px;
  text-align: right;
  line-height: 1;
}

/* Estados de severidad en modo AlertRow */
.gm-alert-rows .gm-alert-tile[data-severity="warn"]:not(.is-zero) {
  background: rgba(230, 162, 60, 0.06);
}
.gm-alert-rows .gm-alert-tile[data-severity="warn"]:not(.is-zero) .gm-alert-icon {
  background: rgba(230, 162, 60, 0.18);
  color: #9a6a00;
}
.gm-alert-rows .gm-alert-tile[data-severity="warn"]:not(.is-zero) .gm-alert-count {
  color: #9a6a00;
}

.gm-alert-rows .gm-alert-tile[data-severity="danger"]:not(.is-zero) {
  background: rgba(220, 62, 62, 0.06);
}
.gm-alert-rows .gm-alert-tile[data-severity="danger"]:not(.is-zero) .gm-alert-icon {
  background: rgba(220, 62, 62, 0.12);
  color: #b43333;
}
.gm-alert-rows .gm-alert-tile[data-severity="danger"]:not(.is-zero) .gm-alert-count {
  color: #b43333;
}

.gm-alert-rows .gm-alert-tile[data-severity="info"]:not(.is-zero) {
  background: rgba(42, 157, 204, 0.06);
}
.gm-alert-rows .gm-alert-tile[data-severity="info"]:not(.is-zero) .gm-alert-icon {
  background: rgba(42, 157, 204, 0.18);
  color: #1a7ca3;
}
.gm-alert-rows .gm-alert-tile[data-severity="info"]:not(.is-zero) .gm-alert-count {
  color: #1a7ca3;
}

/* Estado cero y loading en AlertRow */
.gm-alert-rows .gm-alert-tile.is-loading {
  opacity: .6;
}
.gm-alert-rows .gm-alert-tile.is-zero .gm-alert-count {
  color: var(--muted);
}

/* La card de alertas ocupa toda la altura disponible en su columna */
.gm-alerts-card {
  height: 100%;
}
.gm-alerts-card .gm-chart-card-head {
  border-bottom: 1px solid var(--border);
}

/* Ajuste de altura mínima del wrap en la card protagonista (flujo por hora) */
.col-lg-8 .gm-chart-wrap {
  min-height: 320px;
}

@media (max-width: 991px) {
  .gm-metric-card-title { font-size: 15px; }
  .gm-alert-rows .gm-alert-tile { padding: 11px 16px; }
  .gm-alert-rows .gm-alert-count { font-size: 20px; }
}

/* ============================================================
   Gráficos de barras del dashboard (reemplazo Chart.js)
   ============================================================ */
.gm-barchart { display:flex; align-items:flex-end; gap:8px; height:220px; padding-top:24px; }
.gm-bar-col { flex:1; display:flex; flex-direction:column; align-items:center; gap:8px; height:100%; }
.gm-bar-track { flex:1; width:100%; display:flex; align-items:flex-end; }
.gm-bar { width:100%; background:var(--navy); border-radius:8px 8px 2px 2px; position:relative; transition:height .4s cubic-bezier(.2,.8,.2,1); min-height:2px; }
.gm-bar.is-hi { background:var(--accent); }
.gm-bar-val { position:absolute; top:-22px; left:50%; transform:translateX(-50%); font-size:11px; font-weight:700; color:var(--text); white-space:nowrap; opacity:0; transition:opacity .15s; }
.gm-bar.is-hi .gm-bar-val, .gm-bar-col:hover .gm-bar-val { opacity:1; }
.gm-bar-label { font-size:11px; color:var(--muted); font-family:'Space Grotesk','Manrope',sans-serif; letter-spacing:.02em; white-space:nowrap; }

/* Barras de progreso horizontales (estado de clientes / distribución por plan) */
.gm-progress-list { display:flex; flex-direction:column; gap:14px; }
.gm-progress-head { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:6px; }
.gm-progress-name { font-size:14px; font-weight:600; }
.gm-progress-val { font-family:'Space Grotesk','Manrope',sans-serif; font-weight:700; }
.gm-progress-pct { font-size:12px; color:var(--muted); font-weight:500; margin-left:6px; }
.gm-progress-track { height:8px; border-radius:999px; background:var(--surface-2); overflow:hidden; }
.gm-progress-fill { height:100%; border-radius:999px; transition:width .4s ease; }

/* Dona SVG "Estado de clientes" */
.gm-donut-wrap {
  display:flex; align-items:center; gap:28px; flex-wrap:wrap;
  justify-content:center; padding:8px 4px;
}
.gm-donut-chart { position:relative; flex-shrink:0; width:140px; height:140px; }
.gm-donut-chart svg { display:block; }
.gm-donut-chart circle { transition: stroke-dasharray .5s cubic-bezier(.2,.8,.2,1); }
.gm-donut-center {
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; text-align:center; pointer-events:none;
}
.gm-donut-total {
  font-family:'Space Grotesk','Manrope',sans-serif; font-weight:700;
  font-size:28px; line-height:1; color:var(--text); letter-spacing:-.02em;
}
.gm-donut-total-label {
  font-size:11px; color:var(--muted); text-transform:uppercase;
  letter-spacing:.06em; font-weight:600; margin-top:3px;
}
.gm-donut-legend { display:flex; flex-direction:column; gap:10px; min-width:160px; }
.gm-donut-legend-row { display:flex; align-items:center; gap:10px; }
.gm-donut-legend-dot { width:10px; height:10px; border-radius:3px; flex-shrink:0; }
.gm-donut-legend-name { font-size:14px; font-weight:600; color:var(--text); flex:1; }
.gm-donut-legend-val {
  font-family:'Space Grotesk','Manrope',sans-serif; font-weight:700; color:var(--text);
}
.gm-donut-legend-pct { font-size:12px; color:var(--muted); font-weight:500; margin-left:6px; }

/* Planes más usados (contrataciones + ingreso por plan) */
.gm-planuse-list { display:flex; flex-direction:column; gap:16px; padding:4px 2px; }
.gm-planuse-head { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:7px; gap:12px; }
.gm-planuse-name { font-size:14px; font-weight:600; color:var(--text); }
.gm-planuse-rev {
  font-family:'Space Grotesk','Manrope',sans-serif; font-weight:700;
  color:var(--text); white-space:nowrap;
}
.gm-planuse-bar-line { display:flex; align-items:center; gap:12px; }
.gm-planuse-track { flex:1; height:8px; border-radius:999px; background:var(--surface-2); overflow:hidden; }
.gm-planuse-fill { height:100%; border-radius:999px; transition:width .4s ease; }
.gm-planuse-count { font-size:12px; color:var(--muted); font-weight:500; white-space:nowrap; }

/* ============================================================
   View Transitions: navegación fluida entre páginas
   ------------------------------------------------------------
   El sidebar y el topbar reciben un view-transition-name propio,
   así el navegador los trata como elementos PERSISTENTES entre
   páginas: se quedan quietos (sin parpadeo/recarga visual)
   mientras solo el contenido principal se desliza. Emula el
   slide interno del detalle de Clientes cuando navegamos entre
   páginas distintas (p.ej. Control de asistencia → detalle de
   cliente). Se activa automáticamente en navegaciones del mismo
   origen (MPA View Transitions) en navegadores que la soportan;
   en el resto, la navegación es normal (sin animación).
   ============================================================ */
/* Opt-in a las transiciones de navegación entre documentos (mismo origen). */
@view-transition { navigation: auto; }

@supports (view-transition-name: none) {
  .gm-sidebar { view-transition-name: gm-sidebar; }
  .gm-topbar  { view-transition-name: gm-topbar; }
  /* El contenido bajo el topbar es lo único que anima. */
  .gm-content { view-transition-name: gm-content; }

  /* Sidebar y topbar: sin animación (persisten en su sitio). */
  ::view-transition-group(gm-sidebar),
  ::view-transition-group(gm-topbar) { animation-duration: 0s; }
  ::view-transition-old(gm-sidebar),
  ::view-transition-new(gm-sidebar),
  ::view-transition-old(gm-topbar),
  ::view-transition-new(gm-topbar) { animation: none; mix-blend-mode: normal; }

  /* Contenido: cross-fade + leve deslizamiento horizontal. */
  ::view-transition-old(gm-content) {
    animation: gmVtContentOut .28s cubic-bezier(.2,.7,.2,1) both;
  }
  ::view-transition-new(gm-content) {
    animation: gmVtContentIn .32s cubic-bezier(.2,.7,.2,1) both;
  }
  /* Sentido inverso (al volver) marcado con una clase en <html>. */
  html.gm-vt-back ::view-transition-old(gm-content) {
    animation: gmVtContentOutBack .28s cubic-bezier(.2,.7,.2,1) both;
  }
  html.gm-vt-back ::view-transition-new(gm-content) {
    animation: gmVtContentInBack .32s cubic-bezier(.2,.7,.2,1) both;
  }
}
@keyframes gmVtContentIn   { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes gmVtContentOut  { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(-24px); } }
@keyframes gmVtContentInBack  { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
@keyframes gmVtContentOutBack { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(24px); } }
