/* =========================
   main.css (Unificado 2025-05-30)
   ÚNICO archivo de estilos para la parte pública
   ========================= */

/* Importar estilos adicionales para el menú de usuario */
@import url('userMenu.css');

   /* === 1. Variables globales === */
:root {
  --color-pastel-1: #b3e5fc;
  --color-pastel-2: #ffd6e0;
  --color-pastel-3: #ffe082;
  --color-pastel-4: #c8e6c9;
  --color-pastel-5: #f8bbd0;
  --color-pastel-6: #d1c4e9;
  --color-pastel-7: #fff9c4;
  --color-pastel-8: #b2dfdb;

  /* Escala de z-index de las superficies flotantes (ver AUDITORIA_DISENO.md
     §2.6 #2 — antes de esto .modal-usuario quedaba por debajo de .side-menu
     y .modal-sugerir, con riesgo real de aparecer tapado). */
  --z-popover: 100;
  --z-panel: 40000;
  --z-modal: 70000;

  /* Identidad oscura unificada de las superficies flotantes (side-menu,
     paneles, modales, popover). Ver AUDITORIA_DISENO.md sección 4 —
     cada valor está anclado a uno ya presente en el código, elegido como
     canónico entre las variantes que antes divergían sin razón. */
  --surface-bg:          #181b1f;
  --surface-bg-raised:   #23272d;
  --surface-border:      #23272d;
  --surface-hairline:    #333;
  --surface-text:        #fff;
  --surface-text-muted:  #ccc;
  --on-accent:           #181b1f;

  --surface-radius:      16px;
  --surface-radius-sm:   10px;

  --surface-shadow:         0 8px 32px rgba(0,0,0,0.32);
  --surface-shadow-popover: 0 4px 16px rgba(0,0,0,0.35);
  --panel-shadow-left:   2px 0 24px rgba(0,0,0,0.18);
  --panel-shadow-right: -2px 0 24px rgba(0,0,0,0.18);

  --overlay-bg:   rgba(0,0,0,0.8);
  --overlay-fade: opacity 0.25s;

  --panel-pad:   1.1em 0.9em;
  --panel-slide: transform 0.3s cubic-bezier(.4,1.25,.55,1);

  --input-bg:     #23272d;
  --input-border: #333;
}

/* === 2. Estilos globales y splash === */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  box-sizing: border-box;
}
body {
  background: #000;
  color: #fff;
  font-family: 'Montserrat', Arial, sans-serif;
}
/* Bloqueo de scroll mientras hay un panel/menú abierto — ver
   bloquearScrollBody()/desbloquearScrollBody() en utils.js. */
body.scroll-lock {
  overflow: hidden;
}
#app {
  height: 100vh;
  height: 100dvh;
  min-height: 100vh;
  min-height: 100dvh;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Splash de inicio */
#splash {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  width: 100vw;
  width: 100dvw;
  height: 100vh;
  height: 100dvh;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  opacity: 0;
  transition: opacity 0.7s ease;
}
#splash img {
  max-width: 70vw;
  max-height: 40vh;
  opacity: 0;
  transition: opacity 0.7s ease;
}
#splash.visible { opacity: 1; }
#splash img.visible { opacity: 1; }
@media (hover: none) and (pointer: coarse) {
  #splash img {
    max-width: 90vw;
    max-height: 30vh;
  }
}

/* === 3. Header y navegación === */
.main-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 1rem;
  background: transparent;
  min-height: 56px;
}
.logo-header {
  height: 36px;
  width: auto;
}
.header-brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}
/* Aviso de "reproduciendo colección/lista" — visible para cualquiera, con o
   sin sesión (a diferencia de su equivalente dentro de #user-panel, solo
   alcanzable con login). Mismos tokens y tamaños que ese aviso (ver
   .user-panel-modo-especial / .btn-volver-reproduccion-normal en
   userMenu.css) — no un estilo nuevo, solo en línea por espacio de header.
   Ver app.js/aplicarFiltroCitas(). */
.modo-especial-header {
  display: flex;
  align-items: center;
  gap: 0.6em;
  min-width: 0;
}
.modo-especial-header.oculto { display: none; }
#modo-especial-header-texto {
  font-size: 0.85em;
  color: var(--surface-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 32vw;
}
.btn-volver-modo-especial {
  background: var(--color-pastel-1, #b3e5fc);
  color: var(--on-accent);
  border: none;
  border-radius: 8px;
  padding: 0.3em 0.7em;
  font-size: 0.85em;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.header-actions {
  display: flex;
  gap: 0.5rem;
}
.icon-btn.hamburger {
  display: none;
}
@media (hover: none) and (pointer: coarse) {
  .main-header {
    padding: 0.3rem 0.5rem;
    min-height: 48px;
  }
  .logo-header { height: 28px; }
  .icon-btn.hamburger {
    display: flex;
  }
  .header-actions { display: none; }
  #modo-especial-header-texto { max-width: 24vw; }
}

/* === 4. Botones de acción === */
.icon-btn {
  background: none;
  border: none;
  padding: 0.3em;
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.2s;
  cursor: pointer;
}
.icon-btn img {
  width: 28px;
  height: 28px;
}
/* Ícono de usuario logueado — amarillo intenso, ver usuarioSesion.js. */
.icon-btn img.usuario-activo {
  filter: brightness(1.2) sepia(1) hue-rotate(-40deg) saturate(8);
}
.icon-btn:active {
  background: rgba(255,255,255,0.08);
}

/* === 5. Área segura de citas === */
#safe-area {
  flex: 1 1 auto;
  /* Contexto de posicionamiento para citaCont (position:absolute en renderCita.js,
     tanto en móvil como en escritorio) — sin esto, el navegador lo resuelve contra
     el viewport y la cita aparece superpuesta con el header en vez de contenida aquí. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1em;
  color: #fff;
  text-align: center;
  box-sizing: border-box;
}
@media (hover: none) and (pointer: coarse) {
  #safe-area {
    justify-content: center;
    align-items: center;
  }
}
/* El texto de la cita puede venir con varios <p> (prosa multi-párrafo o,
   igual de frecuente, un poema/aforismo con un verso por párrafo). En ambos
   casos se elimina el espacio entre párrafos que el navegador aplica por
   defecto — decisión de diseño confirmada, no un descuido. */
.cita-texto p {
  margin: 0;
}
.cita-texto {
  font-family: 'Montserrat', sans-serif;
  color: #fff;
  line-height: 1.4;
  text-align: left;
  word-break: break-word;
  margin: 0;
  /* font-size se calcula en renderCita.js (ajuste "nunca scroll") — queda inline a propósito. */
}
.cita-firma {
  font-family: 'Montserrat', sans-serif;
  margin-top: 0.7em;
  text-align: left;
  margin-left: 0;
  /* color (pastel aleatorio) y font-size (calculado) quedan inline a propósito. */
}
/* Contenedor de la cita — ver renderizarCita() en renderCita.js. */
.cita-wrapper-movil {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}
.cita-contenedor {
  /* box-sizing debe persistir durante TODO el ciclo de vida (medición y
     posicionado final), no solo mientras dura .midiendo — de lo contrario el
     ancho ya ajustado por el bucle de "nunca scroll" cambiaría de significado
     apenas se revela la cita. */
  box-sizing: border-box;
  /* Fade in/out controlado por app.js (mostrarCitaActual()) vía estas clases,
     no por estilos inline — ver AUDITORIA_DISENO.md §2.3. */
  opacity: 0;
  transition: opacity 1.5s;
}
.cita-contenedor.sin-transicion {
  transition: none;
}
.cita-contenedor.visible {
  opacity: 1;
}
.cita-contenedor.midiendo {
  /* Fase de medición: fuera de pantalla y oculto, para calcular tamaño sin parpadeo. */
  position: absolute;
  visibility: hidden;
  left: -9999px;
  top: -9999px;
}
.cita-contenedor.movil {
  max-width: 90vw;
  min-width: 60vw;
  margin: 0 auto;
}
.cita-contenedor.escritorio {
  position: absolute;
  max-width: 60vw;
  min-width: 30vw;
}

/* === 6. Controles principales (footer) === */
.main-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.2em;
  padding: 0.7em 0;
  background: transparent;
  min-height: 56px;
}
@media (hover: none) and (pointer: coarse) {
  .main-controls { min-height: 48px; }
}

/* === 7. Créditos de la cita === */
#creditos-cita {
  width: 100%;
  /* Alto FIJO (no min-height): reserva siempre el mismo espacio, se muestren
     o no los créditos, para que nunca desplacen a los controles del footer.
     Calculado para ~3 renglones a este tamaño de fuente. Si la referencia es
     más larga, creditos.js reduce su fuente hasta que quepa — mismo principio
     de "nunca scroll" ya aplicado al texto de la cita en renderCita.js.
     overflow:hidden queda solo como red de seguridad, no como mecanismo real. */
  height: 4.4em;
  overflow: hidden;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 1.05em;
  font-family: 'Montserrat', Arial, sans-serif;
  color: var(--pastel-actual, #a3e3ff);
  margin: 0 auto 0.2em auto;
  transition: opacity 0.7s;
  opacity: 1;
  pointer-events: none;
  user-select: text;
}
/* Sin esto, el margen por defecto del navegador en <p> infla el scrollHeight
   que mide creditos.js para decidir si la fuente debe encogerse. */
#creditos-cita p {
  margin: 0;
}

/* Botón "guardar en lista", elemento separado (no adentro de #creditos-cita,
   que tiene alto fijo con su propio algoritmo de ajuste — ver creditos.js).
   Alto FIJO y SIEMPRE presente en el flujo (igual criterio que #creditos-cita):
   listasFavoritos.js alterna opacidad/pointer-events, nunca "display", para
   que su alto nunca cambie — así ajustarAltoZonaSegura() (utils.js) puede
   medirlo una sola vez sin tener que recalcularse cada vez que se pausa o
   se reanuda (si el alto cambiara con display:none, el footer se desplazaría
   hacia abajo cada vez que aparece la estrella, quedando cortado). */
.guardar-cita-wrapper {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 2em;
  margin: 0 auto;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}
.guardar-cita-wrapper.visible {
  opacity: 1;
  pointer-events: auto;
}
.btn-guardar-cita {
  background: none;
  border: none;
  font-size: 1.7em;
  line-height: 1;
  color: #ffd54f;
  cursor: pointer;
  padding: 0.15em 0.3em;
}
.btn-guardar-cita:hover {
  transform: scale(1.12);
}
.popover-listas {
  display: none;
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-bg-raised);
  border-radius: var(--surface-radius-sm);
  padding: 0.8em 1em;
  min-width: 210px;
  max-width: 80vw;
  box-shadow: var(--surface-shadow-popover);
  z-index: var(--z-popover);
}
.popover-listas.open {
  display: block;
}
.popover-lista-item {
  display: flex;
  align-items: center;
  gap: 0.5em;
  color: var(--surface-text);
  font-size: 0.95em;
  padding: 0.3em 0;
  cursor: pointer;
}
.popover-listas-vacio {
  color: var(--surface-text-muted);
  font-size: 0.88em;
  margin-bottom: 0.4em;
}
.popover-nueva-lista input {
  width: 100%;
  box-sizing: border-box;
  margin-top: 0.5em;
  padding: 0.4em 0.6em;
  border-radius: 6px;
  border: 1px solid var(--input-border);
  background: var(--surface-bg);
  color: var(--surface-text);
  font-size: 0.9em;
}

/* === 8. Animaciones de fade === */
/* El !important es necesario en los dos: #creditos-cita (más abajo) fija su
   propia opacity/pointer-events a nivel de ID, que le gana a una clase sola
   por especificidad — sin !important, .fade-out nunca lograría ocultar los
   créditos. (La auditoría había sugerido quitarlos asumiendo que el inline
   que ponía creditos.js ya resolvía esto; al quitar ese inline en esta misma
   ronda, se verificó que hacen falta de verdad.) */
.fade-in {
  opacity: 1 !important;
  pointer-events: auto !important;
  transition: opacity 0.7s;
}
.fade-out {
  opacity: 0 !important;
  pointer-events: none !important;
  transition: opacity 0.7s;
}

/* === 9. Menú lateral (side-menu) === */
.side-menu {
  position: fixed;
  top: 0;
  right: 0;
  left: auto;
  width: 60vw;
  max-width: 340px;
  height: 100vh;
  height: 100dvh;
  background: var(--surface-bg);
  color: var(--surface-text);
  box-shadow: var(--panel-shadow-right);
  border-left: 1.5px solid var(--surface-border);
  z-index: var(--z-panel);
  transform: translateX(100%);
  transition: var(--panel-slide);
  display: flex;
  flex-direction: column;
  padding: var(--panel-pad);
  /* Reservar espacio para el notch y la barra inferior en iPhone */
  padding-top: calc(1.1em + env(safe-area-inset-top));
  padding-right: calc(0.9em + env(safe-area-inset-right));
  padding-bottom: calc(1.1em + env(safe-area-inset-bottom));
  overflow-y: auto;
}
.side-menu.open { transform: translateX(0); }
.side-menu-actions {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1.5em;
  margin-top: 2em;
}
.side-menu-actions .icon-btn img {
  width: 56px;
  height: 56px;
}
@media (hover: none) and (pointer: coarse) {
  .side-menu {
    width: 80vw;
    max-width: 98vw;
    padding: var(--panel-pad);
  }
  .side-menu-actions {
    align-items: flex-end;
    padding-right: 1.2em; /* margen de seguridad derecho */
  }
  .side-menu-actions .icon-btn img {
    width: 48px;
    height: 48px;
  }
}

/* === 10. Modal de sugerencia === */
/* Base compartida de los 2 modales públicos (sugerir, usuario) — el overlay
   a pantalla completa es idéntico en ambos; el contenido y el botón de cierre
   comparten look pero difieren en medidas puntuales (max-width, padding, unidad
   em/rem), que quedan como override en cada selector específico. */
.modal-overlay-base {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  width: 100vw;
  width: 100dvw;
  height: 100vh;
  height: 100dvh;
  background: var(--overlay-bg);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: var(--z-modal);
  transition: var(--overlay-fade);
}
.modal-overlay-base.visible {
  display: flex;
}
.modal-content-base {
  background: var(--surface-bg);
  color: var(--surface-text);
  border-radius: var(--surface-radius);
  box-shadow: var(--surface-shadow);
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  max-height: 90vh;
  max-height: 90dvh;
  overflow-y: auto;
}
.cerrar-modal-base {
  position: absolute;
  background: none;
  border: none;
  color: var(--surface-text);
  border-radius: 50%;
  transition: background 0.2s;
  cursor: pointer;
}
.cerrar-modal-base:active {
  background: rgba(255,255,255,0.08);
}
.modal-sugerir-content {
  padding: 2.1em 1.3em 1.5em 1.3em;
  max-width: 420px;
  width: 96vw;
  gap: 1.1em;
  font-family: 'Montserrat', Arial, sans-serif;
}
.close-modal-sugerir {
  top: 1.1em;
  right: 1.1em;
  z-index: 2;
  padding: 0.2em;
}
.modal-sugerir h2 {
  margin: 0 0 0.7em 0;
  font-size: 1.35em;
  font-weight: 700;
  text-align: left;
}
.form-group, .form-row {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
  margin-bottom: 0.7em;
}
.form-row {
  flex-direction: column; /* Siempre columna en mobile */
  gap: 0;
}
.form-row .form-group {
  flex: 1 1 0;
  margin-bottom: 0.7em;
}
@media (min-width: 700px) {
  .form-row {
    flex-direction: row;
    gap: 1em;
  }
  .form-row .form-group {
    margin-bottom: 0;
  }
}
label {
  font-size: 1em;
  font-weight: 500;
  color: var(--surface-text);
  display: flex;
  align-items: center;
  gap: 0.4em;
}
input, select, textarea {
  background: var(--input-bg);
  color: var(--surface-text);
  border: 1.5px solid var(--input-border);
  border-radius: 7px;
  padding: 0.55em 0.8em;
  font-size: 1em;
  font-family: inherit;
  outline: none;
  transition: border 0.2s;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--color-pastel-1, #b3e5fc);
}
textarea {
  min-height: 90px;
  resize: vertical;
}
.help-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--input-bg);
  color: var(--color-pastel-1, #b3e5fc);
  border-radius: 50%;
  width: 1.25em;
  height: 1.25em;
  font-size: 0.95em;
  font-weight: bold;
  cursor: help;
  margin-left: 0.2em;
  border: 1.2px solid var(--input-border);
}
.policy-group {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.6em;
  font-size: 0.98em;
  flex-wrap: wrap;
}
.policy-group .info-politica {
  flex-basis: 100%;
  width: 100%;
  margin-left: 0;
  margin-top: 0.5em;
  display: block;
  order: 2;
}
.btn-enviar {
  background: var(--color-pastel-1, #b3e5fc);
  color: var(--on-accent);
  border: none;
  border-radius: 7px;
  padding: 0.7em 1.5em;
  font-size: 1.08em;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.btn-enviar:hover, .btn-enviar:focus {
  background: #fff;
  color: var(--on-accent);
}
.mensaje-confirmacion {
  display: none;
  color: var(--color-pastel-2, #ffd6e0);
  font-size: 1.08em;
  margin-top: 0.7em;
  text-align: center;
}
.mensaje-confirmacion.visible {
  display: block;
}
@media (hover: none) and (pointer: coarse) {
  .modal-sugerir-content {
    max-width: 98vw;
    max-height: 96vh;
    max-height: 96dvh;
    padding: 1.2em 0.5em 1em 0.5em;
    padding-bottom: calc(1em + env(safe-area-inset-bottom));
    overflow-y: auto;
  }
  .close-modal-sugerir {
    top: 0.6em;
    right: 0.6em;
  }
}

/* Estilos para el grupo de 'Citado en' — oculto salvo cita indirecta (ver
   sugerirModal.js). display:block explícito al mostrarse para no heredar
   el gap de .form-group (flex), que antes no tenía al forzarse por inline. */
#grupo-citado-en {
  display: none;
}
#grupo-citado-en.visible {
  display: block;
}
/* Estilos para el grupo de 'Citado en' */
#grupo-citado-en > label {
  font-size: 1.08em;
  font-weight: 600;
  margin-bottom: 0.2em;
  color: var(--surface-text);
  display: block;
}
#grupo-citado-en .form-group {
  margin-bottom: 0.7em;
}
#grupo-citado-en input[type="text"] {
  width: 100%;
  background: var(--input-bg);
  color: var(--surface-text);
  border: 1px solid var(--input-border);
  border-radius: 7px;
  padding: 0.6em 0.9em;
  font-size: 1em;
  box-sizing: border-box;
}
#grupo-citado-en .help-icon {
  margin-left: 0.3em;
}

/* === Estilos para CKEditor === */
.ck-editor__editable_inline {
  min-height: 120px;
  max-height: 320px;
  padding: 0.8em 1em;
  font-size: 1.08em;
  background: var(--input-bg);
  color: var(--surface-text);
  border-radius: 7px;
  border: 1px solid var(--input-border);
  box-sizing: border-box;
  transition: border 0.2s;
}
.ck.ck-editor__main > .ck-editor__editable {
  background: var(--input-bg) !important;
  color: var(--surface-text) !important;
  border-radius: 7px;
  border: 1px solid var(--input-border);
  transition: border 0.2s;
}
.ck.ck-toolbar {
  background: var(--input-bg) !important;
  border-radius: 7px 7px 0 0;
  border: 1px solid var(--input-border);
  border-bottom: none;
}
.ck.ck-toolbar .ck-button {
  color: var(--surface-text) !important;
}
.ck.ck-toolbar .ck-button.ck-on {
  background: var(--surface-hairline) !important;
}
@media (hover: none) and (pointer: coarse) {
  .ck-editor__editable_inline {
    min-height: 140px;
    font-size: 1em;
  }
}

/* =====================
   ENLACES DE POLÍTICAS Y LEGALES
   ===================== */
.link-politica,
.link-privacidad,
.container a,
.info-politica a {
  color: #7db7e6; /* azul pastel tenue */
  text-decoration: underline;
  transition: color 0.2s;
}
.link-politica:hover,
.link-privacidad:hover,
.container a:hover,
.info-politica a:hover {
  color: #a3d0f7; /* azul pastel más claro al pasar el mouse */
  text-decoration: underline;
}

/* Mejorar contraste de <small> informativo */
.info-politica {
  display: block;
  margin-top: 0.5em;
  font-size: 0.95em;
  color: #b0cbe6;
}

/* === Modales de usuario (login, registro, recuperación) === */
.modal-usuario-content {
  padding: 2rem 1.5rem 1.5rem 1.5rem;
  width: 100%;
  max-width: 370px;
  gap: 1rem;
  box-sizing: border-box;
}
.close-modal-usuario {
  top: 1rem;
  right: 1rem;
  padding: 0.2rem;
  z-index: 10;
}
.modal-usuario h2 {
  margin: 0 0 1rem 0;
  font-size: 1.3rem;
  font-weight: 700;
  text-align: center;
}
.modal-usuario form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.modal-usuario .form-group {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.modal-usuario input[type="email"],
.modal-usuario input[type="password"] {
  padding: 0.7rem 0.8rem;
  border-radius: 8px;
  border: 1px solid var(--input-border);
  background: var(--input-bg);
  color: var(--surface-text);
  font-size: 1rem;
}
.modal-usuario input[type="checkbox"] {
  accent-color: var(--color-pastel-1, #b3e5fc);
}
.modal-usuario .btn-login,
.modal-usuario .btn-registro,
.modal-usuario .btn-recuperar {
  background: var(--color-pastel-1, #b3e5fc);
  color: var(--on-accent);
  border: none;
  border-radius: 8px;
  padding: 0.7rem 0;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.2s;
}
.modal-usuario .btn-login:hover,
.modal-usuario .btn-registro:hover,
.modal-usuario .btn-recuperar:hover {
  background: var(--color-pastel-2, #ffd6e0);
}
.modal-usuario .form-links {
  text-align: center;
  font-size: 0.97rem;
  margin-top: -0.5rem;
}
.modal-usuario .form-links a {
  color: var(--color-pastel-1, #b3e5fc);
  text-decoration: underline;
  cursor: pointer;
}
.modal-usuario .mensaje-login,
.modal-usuario .mensaje-registro,
.modal-usuario .mensaje-recuperar {
  display: none;
  color: #ffd6e0;
  font-size: 0.98rem;
  text-align: center;
  margin-top: 0.5rem;
}
.modal-usuario .mensaje-login.visible,
.modal-usuario .mensaje-registro.visible,
.modal-usuario .mensaje-recuperar.visible {
  display: block;
}
@media (hover: none) and (pointer: coarse) {
  .modal-usuario-content {
    max-width: 98vw;
    padding: 1.2rem 0.5rem 1.2rem 0.5rem;
    padding-bottom: calc(1.2rem + env(safe-area-inset-bottom));
  }
}

/* === Interruptores de funcionalidades (Fase 46, reemplaza a
   .pausado-produccion) === Todo punto de entrada lleva data-funcionalidad y
   nace oculto; funcionalidadesUI.js lo revela según flag + sesión. El
   !important existe por la misma razón documentada del mecanismo anterior:
   debe ganarle a las reglas de visibilidad forzada de userMenu.css en móvil
   (que además ahora llevan :not(.oculto)). */
[data-funcionalidad].oculto,
[data-funcionalidad-promovida].oculto {
  display: none !important;
}

/* Etiquetas explicativas (Fase 46) — SOLO en superficies de puntero fino:
   tooltip flotante al hover/focus, generado desde data-etiqueta. Anclado a
   la derecha del botón para que el último ícono del header (pegado al borde)
   no lo saque de la pantalla. */
@media (hover: hover) and (pointer: fine) {
  .header-actions .icon-btn[data-etiqueta] {
    position: relative;
  }
  .header-actions .icon-btn[data-etiqueta]:hover::after,
  .header-actions .icon-btn[data-etiqueta]:focus-visible::after {
    content: attr(data-etiqueta);
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    background: #23272d;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 8px;
    padding: 0.45em 0.8em;
    font-size: 0.78rem;
    white-space: nowrap;
    z-index: 300;
    pointer-events: none;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  }
}

/* Texto junto al ícono en el menú lateral (Fase 46) — la superficie táctil
   acompaña cada ícono con su función, en vez de tooltips que ahí no existen. */
.side-menu-actions .icon-btn {
  gap: 0.7em;
}
.side-menu-actions .icon-btn-texto {
  color: #fff;
  font-size: 1.05em;
  white-space: nowrap;
}

/* Mensaje de gancho (teaser, Fase 47) sobre el formulario del modal de
   usuario, cuando se abre invitando desde listas/PDF sin sesión. */
.modal-usuario-contexto {
  color: var(--surface-text, #fff);
  opacity: 0.9;
  font-size: 0.95em;
  line-height: 1.4;
  margin: 0 0 1em;
  text-align: center;
}

/* Mensaje cuando el filtro de citas no encuentra ninguna coincidencia (ver filtrosPanel.js) */
.sin-resultados-filtro {
  color: #fff;
  text-align: center;
  font-size: 1.1em;
  padding: 2em;
  opacity: 0.85;
}

/* === Modal de donar (simulación — ver ESTRATEGIA_SOSTENIBILIDAD.md) === */
.modal-donar-content {
  padding: 2rem 1.5rem 1.5rem 1.5rem;
  width: 100%;
  max-width: 380px;
  gap: 1rem;
  box-sizing: border-box;
  font-family: 'Montserrat', Arial, sans-serif;
}
.close-modal-donar {
  top: 1rem;
  right: 1rem;
  padding: 0.2rem;
  z-index: 10;
}
.modal-donar h2 {
  margin: 0 0 0.7em 0;
  font-size: 1.3rem;
  font-weight: 700;
  text-align: center;
}
.donar-texto-intro {
  margin: 0 0 1.2rem 0;
  color: var(--surface-text-muted);
  font-size: 0.95rem;
  text-align: center;
}
.opciones-donar {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.btn-opcion-donar {
  background: var(--color-pastel-3);
  color: var(--on-accent);
  border: none;
  border-radius: 8px;
  padding: 0.8rem 1rem;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.2s;
}
.btn-opcion-donar:hover {
  background: var(--color-pastel-4);
}
.donar-texto-simulacion {
  margin-top: 0.8rem;
  color: var(--surface-text-muted);
  font-size: 0.85rem;
  text-align: center;
}
.btn-volver-donar {
  margin-top: 1.2rem;
  background: none;
  border: 1px solid var(--surface-text-muted);
  color: var(--surface-text);
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font-size: 0.95rem;
  cursor: pointer;
  width: 100%;
}

/* === Utilidad genérica de visibilidad === */
/* Declarada al final a propósito: gana por orden de cascada ante cualquier
   otra regla de igual especificidad (ej. .icon-btn { display:flex }) sin
   necesitar !important. #app.oculto existe aparte porque un id siempre le
   gana a una clase sola, sin importar el orden. */
.oculto {
  display: none;
}
#app.oculto {
  display: none;
}


