/* web/static/css/app.css
   CSS propio y ligero, sin build de Node ni Tailwind compilado.
   Paleta Esmeralda: fondo #EFFDF5, tarjetas blancas, verde #059669,
   texto #0C1F16 / #5F6B66. El backend Go sirve este archivo en /static/css/app.css
   con caché larga y compresión gzip/brotli (PLAN §7).
*/

:root {
  color-scheme: light;
  --bg: #EFFDF5;
  --card: #ffffff;
  --blue: #059669;
  --blue-dark: #047857;
  --link: #059669;
  --text: #0C1F16;
  --muted: #5F6B66;
  --border: #ccd0d5;
  --danger: #e41e3f;
  --secondary-bg: #e4e6eb;
  --active-bg: #D1FAE5;
  --flash-bg: #fff4e5;
  --flash-border: #f5c542;
  --error-bg: #fde8e8;
  --error-border: #f5c2c2;
  --error-text: #9b1c1c;
  --ok-bg: #d4edda;
  --ok-text: #155724;
  --warn-bg: #fff3cd;
  --warn-text: #856404;
  /* Tarjeta de usuario suspendido/baneado (admin/usuarios): tintes
     claramente más fuertes que los de las insignias, para que el
     estado se distinga a simple vista. */
  --user-suspended-bg: #ffe0b3;
  --user-suspended-border: #e8a04c;
  --user-suspended-accent: #d97706;
  --user-banned-bg: #fad3d3;
  --user-banned-border: #e88f8f;
  --user-banned-accent: #d92d20;
  --radius: 8px;
  --shadow: 0 1px 2px rgba(0, 0, 0, .1);
  --topbar-h: 56px;
  --max-feed: 680px;
}

/* Modo oscuro (por defecto, ver el script del <head> en layout.html):
   mismas variables, superficies oscuras y sombra más marcada. El verde
   se mantiene; --blue-dark se aclara para seguir legible sobre fondo
   oscuro. color-scheme: dark hace que los controles nativos (diálogos,
   selects, scrollbars) sigan el tema. */
[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0E1B15;
  --card: #152420;
  --text: #D1FAE5;
  --muted: #8FA89B;
  --border: #3a3b3c;
  --blue-dark: #34D399;
  --link: #34D399;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4);
  --secondary-bg: #3a3b3c;
  --active-bg: #064E3B;
  --flash-bg: #33291a;
  --flash-border: #7a5c1e;
  --error-bg: #3a1d1d;
  --error-border: #7a2e2e;
  --error-text: #f1a8a8;
  --ok-bg: #1e3a24;
  --ok-text: #8fd6a0;
  --warn-bg: #3d2f10;
  --warn-text: #f5c542;
  --user-suspended-bg: #4d2e05;
  --user-suspended-border: #b45309;
  --user-suspended-accent: #f59e0b;
  --user-banned-bg: #4d1719;
  --user-banned-border: #b91c1c;
  --user-banned-accent: #f87171;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.4;
  padding-bottom: 0;
}
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: none; }
h1 { font-size: 20px; margin: 0 0 8px; }
h2 { font-size: 17px; margin: 0 0 8px; }
p { margin: 0 0 12px; }
small, .muted { color: var(--muted); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }
img { max-width: 100%; }

/* ---------- Tarjetas, avatares y botones ---------- */
.card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 16px;
}
.avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; background: var(--border); flex: none; }
.avatar-sm { width: 32px; height: 32px; }
.btn {
  display: inline-block;
  border: 0;
  border-radius: 6px;
  padding: 9px 16px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
}
.btn:hover { text-decoration: none; }
/* Botón desactivado (p. ej. mientras se comprime o se prepara una
   imagen): se ve apagado y no se puede pulsar. */
.btn:disabled { cursor: not-allowed; opacity: .6; }
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-dark); }
.btn-danger { background: #d92d20; color: #fff; }
.btn-danger:hover { background: #b42318; }
/* Botón + con pulso constante y sutil: un anillo que se expande y se
   desvanece (~2 s, infinito). Solo se anima el anillo, el botón no se
   mueve. Con prefers-reduced-motion no hay animación. */
.btn-pulse { position: relative; }
.btn-pulse::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(24, 119, 242, .45);
  animation: btn-pulse-ring 2s ease-out infinite; pointer-events: none;
}
@keyframes btn-pulse-ring {
  0% { box-shadow: 0 0 0 0 rgba(24, 119, 242, .45); }
  70% { box-shadow: 0 0 0 12px rgba(24, 119, 242, 0); }
  100% { box-shadow: 0 0 0 0 rgba(24, 119, 242, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .btn-pulse::after { animation: none; }
}
.btn-secondary { background: var(--secondary-bg); color: var(--text); }
.btn-ghost { background: transparent; color: var(--blue); }
.btn-sm { padding: 7px 12px; font-size: 14px; }
.btn-block { display: block; width: 100%; margin-top: 8px; }
.badge {
  background: var(--danger); color: #fff; border-radius: 999px;
  font-size: 12px; font-weight: 700; padding: 1px 7px; margin-left: 6px;
}
/* Insignia de estado de usuario (admin/usuarios): Activo verde,
   Suspendido ámbar, Baneado rojo, para distinguirlos a simple vista. */
.status-badge {
  display: inline-block; border-radius: 999px; padding: 2px 10px;
  font-size: 12px; font-weight: 700;
}
.status-active { background: var(--ok-bg); color: var(--ok-text); }
.status-suspended { background: var(--warn-bg); color: var(--warn-text); }
.status-banned { background: var(--error-bg); color: var(--error-text); }
/* Estados de una respuesta (detalle de solicitud): pendiente ámbar,
   confirmada verde, rechazada rojo, vencida gris. */
.status-pending { background: var(--warn-bg); color: var(--warn-text); }
.status-confirmed { background: var(--ok-bg); color: var(--ok-text); }
.status-rejected { background: var(--error-bg); color: var(--error-text); }
.status-expired { background: var(--bg); color: var(--muted); }
/* Tarjeta completa teñida por estado (admin/usuarios): franja lateral
   gruesa de acento (4px, naranja sólido para suspendido, rojo sólido
   para baneado) más fondo teñido fuerte, para que el estado se vea a
   simple vista en claro y en oscuro. Las insignias se mantienen; la
   tarjeta activa queda como está. */
.user-card-suspended {
  background: var(--user-suspended-bg);
  border: 1px solid var(--user-suspended-border);
  border-left: 4px solid var(--user-suspended-accent);
}
.user-card-banned {
  background: var(--user-banned-bg);
  border: 1px solid var(--user-banned-border);
  border-left: 4px solid var(--user-banned-accent);
}
/* Panel rápido de notificaciones (campana del header y barra móvil):
   desplegable tipo Facebook con las recientes, las no leídas
   destacadas y el enlace a todas. Fijo bajo la barra superior en
   escritorio y sobre la barra inferior en móvil. */
.notif-panel {
  position: fixed; top: calc(var(--topbar-h) + 8px); right: 16px; width: 360px;
  max-width: calc(100vw - 32px); max-height: calc(100vh - 80px);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .2); z-index: 80; overflow-y: auto;
}
.notif-panel:not([hidden]) { display: flex; flex-direction: column; }
/* Aunque el CSS cacheado no tenga estas reglas, el panel nunca se ve
   sin estilo: con hidden siempre está oculto, lo tenga o no el CSS
   viejo (el [hidden] del UA se puede anular con una regla de autor;
   esta no se puede). */
.notif-panel[hidden] { display: none !important; }
.notif-panel-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px 8px; }
.notif-panel-head strong { font-size: 17px; }
.notif-close { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 4px; border-radius: 50%; }
.notif-close:hover { background: var(--bg); }
.notif-list { display: flex; flex-direction: column; }
.notif-item { display: flex; flex-direction: row; align-items: flex-start; gap: 10px; padding: 10px 16px; color: var(--text); border-top: 1px solid var(--border); }
.notif-item:hover { background: var(--bg); text-decoration: none; }
.notif-item small { color: var(--muted); }
.notif-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.notif-body p { margin: 0; }
/* Avatar de notificación estilo Facebook: foto de quien generó el
   aviso (o su inicial si no tiene) con el círculo del tipo sobre la
   esquina inferior derecha. Sin actor, solo el círculo del tipo. */
.notif-avatar-wrap { position: relative; flex: none; width: 40px; height: 40px; }
.notif-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; display: block; background: var(--border); }
.notif-avatar-initial { display: flex; align-items: center; justify-content: center; background: var(--active-bg); color: var(--text); font-weight: 700; font-size: 17px; }
.notif-type-badge { position: absolute; right: -2px; bottom: -2px; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--card); display: flex; align-items: center; justify-content: center; font-size: 11px; color: #fff; }
.notif-type-badge-alone { flex: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 19px; color: #fff; }
.notif-badge-blue { background: #059669; }
.notif-badge-green { background: #31a24c; }
.notif-badge-red { background: #d92d20; }
.notif-badge-amber { background: #f59e0b; }
.notif-badge-silver { background: linear-gradient(135deg, #e8eaed, #9ba0a6 55%, #c9ccd1); color: #23262b; }
.notif-unread { background: var(--active-bg); }
.notif-empty { padding: 16px; }
.notif-all { display: block; text-align: center; font-weight: 600; padding: 12px; border-top: 1px solid var(--border); }
/* Botón de acción de una sección del admin (Banear usuario, Poner
   strike): fila propia entre el encabezado y la lista, con aire. */
.admin-actions { margin-bottom: 16px; }
/* Cabecera de un <dialog> modal (baneos, strikes): título a la
   izquierda y X de cierre a la derecha, como el panel de
   notificaciones. */
.dialog-head { display: flex; align-items: center; justify-content: space-between; }
.dialog-close { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 4px; border-radius: 50%; flex: none; }
.dialog-close:hover { background: var(--bg); }
.flash {
  background: var(--flash-bg); border: 1px solid var(--flash-border); border-radius: var(--radius);
  padding: 12px; margin-bottom: 16px;
}
.form-error {
  background: var(--error-bg); border: 1px solid var(--error-border); color: var(--error-text);
  border-radius: var(--radius); padding: 10px 12px; margin-bottom: 12px;
}
.field-error { display: block; color: var(--danger); margin: 4px 0 8px; }

/* Aviso amarillo del dedup de enlaces (un enlace, una solicitud
   activa): aparece en vivo bajo el campo del enlace y al enviar el
   formulario con un enlace en uso. */
.link-warning {
  background: var(--warn-bg); color: var(--warn-text);
  border: 1px solid var(--flash-border); border-radius: var(--radius);
  padding: 10px 12px; margin: 8px 0;
}

/* Aviso amarillo de solicitud oculta en Mis solicitudes: por qué no se
   muestra en el feed (y por qué no se puede borrar aún, si hay
   pendientes). Mismos colores que .link-warning. */
.hidden-notice {
  background: var(--warn-bg); color: var(--warn-text);
  border: 1px solid var(--flash-border); border-radius: var(--radius);
  padding: 10px 12px; margin: 8px 0;
}
.hidden-notice p { margin: 0; }
.hidden-notice p + p { margin-top: 4px; }

/* Menú de 3 puntos de Mis solicitudes: el botón ⋯ en la cabecera de la
   tarjeta y la lista desplegable con la opción de borrar. */
.card-menu { position: relative; flex: none; }
.card-menu-btn { background: none; border: 0; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; padding: 4px 8px; border-radius: 50%; }
.card-menu-btn:hover { background: var(--bg); }
.card-menu-list { position: absolute; right: 0; top: calc(100% + 4px); min-width: 200px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0, 0, 0, .2); z-index: 30; padding: 6px; }
.card-menu-list[hidden] { display: none !important; }
.card-menu-list form { margin: 0; }
.card-menu-item { display: block; width: 100%; text-align: left; background: none; border: 0; color: var(--text); font: inherit; cursor: pointer; padding: 8px 10px; border-radius: 6px; }
.card-menu-item:hover:not(:disabled) { background: var(--bg); }
.card-menu-item:disabled { color: var(--muted); cursor: not-allowed; }
.card-menu-note { margin: 0; padding: 4px 10px 8px; color: var(--muted); font-size: 13px; }

/* ---------- Barra superior ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  height: var(--topbar-h);
  background: var(--card);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
}
.topbar-inner {
  max-width: 1280px; height: 100%; margin: 0 auto; padding: 0 16px;
  display: flex; align-items: center; gap: 16px;
}
.logo { display: flex; align-items: center; gap: 8px; color: var(--text); font-weight: 800; font-size: 18px; }
.logo:hover { text-decoration: none; }
.logo-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--blue); color: #fff; font-size: 28px; line-height: 1;
}
.top-search { flex: 1; max-width: 320px; }
.top-search input {
  width: 100%; border: 0; border-radius: 999px; background: var(--bg);
  padding: 9px 14px; font-size: 15px; outline: none; color: var(--text);
}
/* Acciones del header (campana + crear): van al extremo derecho de la
   barra, no pegadas al buscador. Sin este margin la búsqueda (flex:1 con
   max-width) deja el espacio libre al final y las acciones quedan junto
   a ella, en el centro. En móvil no afecta: campana y crear están
   ocultos en el header y viven en la barra inferior. */
.top-user { display: flex; align-items: center; gap: 8px; margin-left: auto; }
/* Campana del header: solo escritorio; en móvil vive en la barra inferior.
   Esta regla base va ANTES del bloque responsive: si queda después, la
   cascada anula el display:none del media query. */
.top-bell { display: inline-flex; align-items: center; color: var(--muted); font-size: 20px; padding: 6px; border-radius: 50%; background: none; border: 0; cursor: pointer; }
.top-bell:hover { background: var(--bg); text-decoration: none; }
/* Desplegable de resultados en vivo del buscador del header. Se esconde
   solo cuando está vacío: el endpoint devuelve vacío sin coincidencias. */
.live-results { position: absolute; top: 100%; left: 8px; right: 8px; max-width: 560px; margin: 0 auto; z-index: 70; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: 0 4px 16px rgba(0, 0, 0, .2); max-height: 320px; overflow-y: auto; }
.live-results:empty { display: none; }
.live-group { margin: 0; padding: 10px 12px 4px; color: var(--muted); font-size: 13px; font-weight: 700; }
.live-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; color: var(--text); }
.live-item:hover { background: var(--bg); text-decoration: none; }
.live-item span { display: flex; flex-direction: column; min-width: 0; }
.live-item strong { overflow-wrap: anywhere; }
.live-item small { color: var(--muted); }
.live-reaction { flex: none; font-size: 20px; }
.live-reaction .icon { width: 20px; height: 20px; }

/* Buscador en vivo del modal de baneo: el desplegable reutiliza
   .live-results, anclado al campo en vez de al header. */
.user-pick { position: relative; }
.user-pick .live-results { left: 0; right: 0; max-width: none; margin: 0; }
.user-pick .live-item { width: 100%; background: none; border: 0; font: inherit; text-align: left; cursor: pointer; }

/* Miniatura de vista previa al elegir una imagen (prueba, confirmación,
   avatar y foto de referencia). */
.img-preview { display: block; max-width: 160px; max-height: 160px; border-radius: 8px; margin: 8px 0; border: 1px solid var(--border); }
.img-preview[hidden] { display: none; }

/* Recorte de la foto de perfil en un modal (<dialog>): molde cuadrado
   fijo donde se encuadra la foto; se mueve arrastrando y se acerca con
   el zoom. En escritorio el modal es centrado de 480 px; en móvil ocupa
   casi toda la pantalla. Entrada con fade + escala suave, y salida con
   la clase .closing (el JS cierra tras 160 ms). Sin animación con
   prefers-reduced-motion. */
.crop-dialog { max-width: 480px; width: calc(100vw - 32px); max-height: calc(100dvh - 32px); overflow: auto; }
.crop-dialog::backdrop { background: rgba(0, 0, 0, 0.6); }
.crop-dialog[open] { animation: dialog-in .18s ease-out; }
.crop-dialog[open]::backdrop { animation: backdrop-in .18s ease-out; }
.crop-dialog.closing { animation: dialog-out .15s ease-in forwards; }
.crop-dialog.closing::backdrop { animation: backdrop-out .15s ease-in forwards; }
@keyframes dialog-in { from { opacity: 0; transform: translateY(10px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes dialog-out { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(8px) scale(.97); } }
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes backdrop-out { from { opacity: 1; } to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .crop-dialog[open], .crop-dialog[open]::backdrop,
  .crop-dialog.closing, .crop-dialog.closing::backdrop,
  .leave-dialog[open], .leave-dialog[open]::backdrop { animation: none; }
}
@media (max-width: 480px) {
  .crop-dialog { padding: 16px; }
}
.crop-dialog .crop-frame { margin: 0 auto; }
.crop-dialog .crop-controls { margin: 8px auto; }
.crop-frame { width: 256px; max-width: 100%; aspect-ratio: 1; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.crop-frame canvas { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
.crop-frame canvas:active { cursor: grabbing; }
/* Carga del recorte: spinner girando + texto, mientras la foto se
   comprime y se carga en el molde. El botón de guardar está
   desactivado hasta que termina. */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner { display: inline-block; width: 32px; height: 32px; border: 3px solid var(--border); border-top-color: var(--blue); border-radius: 50%; animation: spin .8s linear infinite; }
.crop-loading { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 32px 0; text-align: center; }
.crop-loading[hidden] { display: none; }
/* Foto de perfil grande (168 px, círculo estilo Facebook) con el
   botón redondo de lápiz sobrepuesto abajo a la derecha. */
.profile-photo-wrap { position: relative; width: 168px; max-width: 100%; flex: none; }
.profile-photo { width: 168px; height: 168px; }
.profile-photo-btn { padding: 0; border: 0; background: none; cursor: pointer; border-radius: 50%; display: block; }
.profile-photo-edit { position: absolute; right: 0; bottom: 8px; width: 40px; height: 40px; border-radius: 50%; background: var(--blue); color: #fff; border: 3px solid var(--card); display: flex; align-items: center; justify-content: center; cursor: pointer; text-decoration: none; font-size: 18px; }
.profile-photo-edit:hover { background: var(--blue-dark); }

/* Perfil completo: Resumen, estadísticas y pestañas. */
.profile-summary { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.profile-summary li { display: flex; align-items: center; gap: 8px; }
.profile-stats { display: flex; gap: 16px; text-align: center; }
.profile-stat { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.profile-stat strong { font-size: 20px; }
.profile-stat span { color: var(--muted); font-size: 13px; }
.profile-tabs { display: flex; gap: 4px; margin: 16px 0; border-bottom: 1px solid var(--border); }
.profile-tab { padding: 8px 16px; color: var(--muted); text-decoration: none; font-weight: 700; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.profile-tab.active { color: var(--link); border-bottom-color: var(--link); }
.crop-controls { display: flex; align-items: center; gap: 8px; margin: 8px 0; max-width: 256px; }
.crop-controls button { flex: none; width: 32px; height: 32px; font-size: 18px; line-height: 1; border: 1px solid var(--border); border-radius: 8px; background: var(--card); color: var(--text); cursor: pointer; }
.crop-controls input[type="range"] { flex: 1; min-width: 0; }

/* Foto de referencia de una solicitud: abre el enlace de Facebook de la
   publicación (con el aviso de salida), no se amplía en la app. */
.ref-img-btn { display: block; width: 100%; background: none; border: 0; padding: 0; text-align: left; cursor: pointer; }
.reference-img { display: block; max-width: 100%; border-radius: 8px; margin: 12px 0 0; cursor: pointer; }

/* ---------- Layout 3 columnas (desktop) ---------- */
.layout {
  max-width: 1280px; margin: 0 auto; padding: 16px;
  display: grid; grid-template-columns: 280px minmax(0, 1fr) 320px; gap: 24px;
  align-items: start;
}
.sidebar-left, .sidebar-right { position: sticky; top: calc(var(--topbar-h) + 16px); }
.feed-col { min-width: 0; max-width: var(--max-feed); margin: 0 auto; width: 100%; }
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar-link {
  display: flex; align-items: center; gap: 10px;
  color: var(--text); font-weight: 600; padding: 10px 12px; border-radius: 8px;
}
.sidebar-link:hover { background: var(--secondary-bg); text-decoration: none; }
.sidebar-link.active { background: var(--active-bg); color: var(--link); }
/* "Cerrar sesión" va aparte al final del menú, en el color de peligro
   que ya existe, para que se vea como una acción distinta. */
.sidebar-link.logout-link, .drawer-nav a.logout-link { color: var(--danger); }
/* Los enlaces de crear ahora son botones que abren el diálogo: mismo
   aspecto que los enlaces, sin estilos propios de botón. */
button.sidebar-link { background: none; border: 0; font: inherit; cursor: pointer; text-align: left; width: 100%; }
.sidebar-profile { display: flex; align-items: center; gap: 10px; padding: 8px 12px; color: var(--text); }
.sidebar-profile span { display: flex; flex-direction: column; }
/* La cabecera ya no es un solo enlace (la medalla es un botón aparte,
   como en las tarjetas del feed): el nombre lleva su propio enlace con
   el mismo color que el texto. */
.sidebar-profile a { color: inherit; text-decoration: none; }
.side-card h2 { font-size: 16px; }
.side-user { display: flex; align-items: center; gap: 10px; color: var(--text); padding: 8px 0; }
.side-user span { display: flex; flex-direction: column; }
.rules-list { margin: 0 0 8px; padding-left: 18px; color: var(--muted); }
.side-footer { padding: 8px 4px; }

/* ---------- Caja crear + feed ---------- */
.create-box { display: flex; align-items: center; gap: 10px; }
.create-box-input {
  flex: 1; background: var(--bg); color: var(--muted);
  border-radius: 999px; padding: 10px 14px;
}
.create-box-input:hover { background: var(--secondary-bg); text-decoration: none; }
/* El input del composer también es ahora un botón que abre el diálogo. */
button.create-box-input { border: 0; font: inherit; text-align: left; cursor: pointer; }
.feed-card-head { display: flex; align-items: center; gap: 10px; }
.feed-card-meta { display: flex; flex-direction: column; min-width: 0; }
.feed-card-name { color: var(--text); font-weight: 700; }
.feed-card-note { margin: 12px 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.reaction-badge {
  margin-left: auto; flex: none;
  background: var(--active-bg); color: var(--link); border-radius: 999px;
  padding: 5px 10px; font-size: 13px; font-weight: 700; white-space: nowrap;
}
.reaction-badge .reaction-icon svg { width: 15px; height: 15px; }
.icon { width: 1em; height: 1em; vertical-align: -0.12em; }
.reaction-icon svg { width: 18px; height: 18px; }
.feed-card-link {
  display: block; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px; color: var(--text); margin-bottom: 12px; overflow-wrap: anywhere;
}
.feed-card-link small { display: block; color: var(--muted); margin-top: 4px; word-break: break-all; }
.feed-card-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; border-top: 1px solid var(--border); padding-top: 12px; }
.feed-card-count { color: var(--muted); font-size: 14px; margin-right: auto; }
.empty-state { text-align: center; padding: 32px 16px; }
.empty-icon { font-size: 40px; margin-bottom: 8px; color: var(--muted); }

/* ---------- Formularios ---------- */
.form-card { max-width: var(--max-feed); margin: 0 auto 16px; }
form label { display: block; font-weight: 600; margin: 14px 0 6px; }
form input[type="text"], form input[type="email"], form input[type="password"],
form input[type="url"], form input[type="search"], form input[type="number"],
form select, form textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 6px;
  padding: 10px 12px; font-size: 15px; font-family: inherit; background: var(--card); color: var(--text);
}
form input:focus, form select:focus, form textarea:focus { outline: 2px solid var(--blue); outline-offset: 0; border-color: var(--blue); }
form textarea { resize: vertical; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.check { display: flex; align-items: center; gap: 8px; font-weight: 400; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius); margin: 16px 0; padding: 12px; }
legend { font-weight: 700; padding: 0 6px; }
/* Dropdown de reacción: el botón cerrado muestra la selección (icono +
   texto); la lista se abre debajo con las 7 opciones. */
.reaction-dropdown { position: relative; }
.reaction-dropdown-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 9px 12px; border: 1px solid var(--border);
  border-radius: 6px; background: var(--card); color: var(--text); font: inherit; cursor: pointer;
}
.reaction-dropdown-current { display: inline-flex; align-items: center; gap: 8px; }
.reaction-dropdown .reaction-svg { width: 20px; height: 20px; }
.reaction-dropdown-caret {
  flex: none; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid var(--muted);
}
.reaction-dropdown.open .reaction-dropdown-caret { transform: rotate(180deg); }
.reaction-dropdown-list {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 60;
  background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .15);
  list-style: none; margin: 0; padding: 4px; max-height: 280px; overflow-y: auto;
}
.reaction-dropdown-list button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px 10px; border: 0; background: none; font: inherit; color: var(--text);
  cursor: pointer; border-radius: 6px; text-align: left;
}
.reaction-dropdown-list button:hover,
.reaction-dropdown-list button[aria-selected="true"] { background: var(--bg); }

/* Modo avanzado de países: colapsado por defecto, con el total de
   usuarios en un tag. */
.advanced-mode { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin: 16px 0; }
.advanced-mode summary { font-weight: 700; cursor: pointer; }
.advanced-mode p { margin: 8px 0; }
.tag {
  display: inline-block; background: var(--active-bg); color: var(--blue-dark);
  border-radius: 999px; padding: 2px 10px; font-size: 13px; font-weight: 600;
}

.country-picker { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.country-picker .check { margin: 4px 0; }

/* Países del modo avanzado como etiquetas (chips con X), estilo
   keywords: se agregan y se quitan sin lista de checkboxes. */
.country-tag-picker { margin-top: 8px; }
.country-tag-row { display: flex; gap: 8px; margin: 4px 0; }
.country-tag-row select { flex: 1; min-width: 0; }
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.tag-list:empty { margin: 0; }
.tag-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--active-bg); color: var(--blue-dark); border: 1px solid var(--border); border-radius: 999px; padding: 4px 6px 4px 10px; font-size: 14px; font-weight: 600; }
.tag-chip-x { border: 0; background: transparent; cursor: pointer; font-size: 16px; line-height: 1; color: inherit; padding: 0 2px; }
.tag-chip-x:hover { color: var(--text); }

/* Filtro de género del modo avanzado (solo Super Usuarios). */
.gender-filter { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin: 12px 0 0; }
.gender-filter legend { font-weight: 700; padding: 0 4px; }
.gender-filter .check { display: inline-block; margin: 4px 16px 4px 0; }

/* Medalla plateada de Super Usuario: medalla metálica con un pulgar
   arriba, sobre la esquina inferior derecha de la foto (dentro de un
   .avatar-wrap, como el lápiz de editar perfil). Gradiente metálico
   en grises plateados, con borde oscuro y sombra sutil: no es un
   círculo blanco plano. Es un botón: abre el modal que explica qué
   es un Super Usuario, sin navegar al perfil. El tamaño se adapta a
   la foto: 20 px en avatares de 40 px, 16 px en avatares chicos y
   36 px en la foto de perfil de 168 px. La variante .inline va junto
   al nombre (propio perfil, donde la esquina la ocupa el lápiz). */
.avatar-wrap { position: relative; flex: none; line-height: 0; }
.avatar-wrap > a { display: block; }
.avatar-wrap .avatar { display: block; }
.super-badge { position: absolute; right: -2px; bottom: -2px; z-index: 1; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; border: 1px solid #6d7178; background: linear-gradient(145deg, #ffffff 0%, #eef0f2 22%, #c9ccd1 45%, #9ba0a6 58%, #d7dade 76%, #b0b4b9 100%); box-shadow: 0 1px 3px rgba(0, 0, 0, .45), inset 0 1px 1px rgba(255, 255, 255, .95), inset 0 -1px 1px rgba(0, 0, 0, .18); color: #23262b; cursor: pointer; padding: 0; }
.super-badge .icon { width: 62%; height: 62%; }
.super-badge.inline { position: static; flex: none; }
.avatar-wrap.sm .super-badge { width: 16px; height: 16px; }
.profile-photo-wrap .super-badge { width: 36px; height: 36px; right: 0; bottom: 8px; }
.profile-name-row { display: flex; align-items: center; gap: 8px; margin: 0; }

/* Progreso a Super Usuario (/super-usuario): barra con % por
   requisito, más el % total. En gris y desactivada cuando el admin
   revocó el modo (la clase .disabled está en cada fila y en la barra
   total). */
.progress-row { margin: 16px 0; }
.progress-label { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 6px; font-size: 14px; }
.progress-bar { height: 10px; border-radius: 5px; background: var(--border, #ddd); overflow: hidden; }
.progress-fill { height: 100%; border-radius: 5px; background: linear-gradient(90deg, #059669, #10B981); transition: width .3s ease; }
.progress-overall { height: 14px; }
.progress-row.disabled .progress-fill, .progress-bar.disabled .progress-fill { background: #9aa0a6; }
.progress-row.disabled, .progress-bar.disabled { opacity: .55; }
.super-revoked-box { border: 1px solid #9aa0a6; background: #EFFDF5; border-radius: 8px; padding: 16px; margin: 16px 0; }
.super-revoked-box h2 { margin-top: 0; }

/* ---------- Auth ---------- */
.auth-wrap { min-height: calc(100vh - 32px); display: flex; align-items: center; justify-content: center; padding: 24px 16px; }
.auth-card { width: 100%; max-width: 480px; margin: 0; }
.auth-switch { text-align: center; margin: 16px 0 0; }

/* ---------- Barra inferior móvil (oculta en desktop) ---------- */
.mobile-nav { display: none; }

/* ---------- Responsive ---------- */
@media (max-width: 1023px) {
  .layout { grid-template-columns: minmax(0, 1fr); padding: 12px 12px 76px; }
  .sidebar-left, .sidebar-right { display: none; }
  .feed-col { max-width: 100%; }
  /* El buscador es ancho en móvil: ocupa el espacio entre el logo y el
     borde, igual que en la app de Facebook. */
  .top-search { display: block; flex: 1; min-width: 0; max-width: none; }
  .top-bell { display: none; }
  .top-create { display: none; }
  /* El panel de notificaciones se abre desde la barra inferior: queda
     anclado arriba de ella, a lo ancho, en vez de bajo el header. */
  .notif-panel { top: auto; bottom: 68px; left: 8px; right: 8px; width: auto; max-height: 60vh; }
  .logo-text { display: none; }
  body.app-page { padding-bottom: 64px; }
  .mobile-nav {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    background: var(--card); border-top: 1px solid var(--border);
    padding: 4px 0 calc(4px + env(safe-area-inset-bottom));
  }
  /* Barra solo con iconos, todos de 28px y centrados de verdad, como la
     app de Facebook. Sin texto bajo los iconos. */
  .mobile-nav-item {
    flex: 1; display: flex; align-items: center; justify-content: center;
    color: var(--muted); height: 48px; padding: 0;
  }
  .mobile-nav-item .icon { width: 28px; height: 28px; }
  .mobile-nav-item.active { color: var(--link); }
}
@media (max-width: 560px) {
  .card { border-radius: 0; margin-left: -12px; margin-right: -12px; padding: 12px; }
  .auth-card { border-radius: var(--radius); margin: 0; }
  .form-row { grid-template-columns: 1fr; }
  .create-box .btn-primary { display: none; }
  .feed-card-actions .btn { flex: 1; }
}

/* ---------- Capturas, vista previa y notificaciones ---------- */
.proof-img { display: block; max-width: 100%; border-radius: 8px; margin: 12px 0; }
.post-preview { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; }
.post-preview-link { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 0; color: var(--text); font: inherit; cursor: pointer; }
.post-preview-link small { display: block; color: var(--muted); word-break: break-all; }
.leave-dialog { border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; max-width: 420px; background: var(--card); color: var(--text); }
.leave-dialog::backdrop { background: rgba(0, 0, 0, 0.5); }
.leave-dialog[open] { animation: dialog-in .18s ease-out; }
.leave-dialog[open]::backdrop { animation: backdrop-in .18s ease-out; }
/* Diálogo para crear una solicitud, estilo "Crear publicación" de
   Facebook: ancho adaptado a móvil, con scroll si el contenido no cabe. */
.create-dialog { border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow-y: auto; background: var(--card); color: var(--text); }
.create-dialog::backdrop { background: rgba(0, 0, 0, 0.5); }
.create-dialog-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.create-dialog-head h2 { margin: 0; }

/* ---------- Tarjeta estilo Facebook: conteo, acciones y comentarios ---------- */
.fb-counts { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 4px 8px; color: var(--muted); font-size: 14px; }
.fb-report { background: none; border: 0; padding: 4px 8px; color: var(--muted); font: inherit; font-size: 14px; cursor: pointer; border-radius: 6px; }
.fb-report:hover { background: var(--bg); }
.fb-report:disabled { cursor: default; opacity: .7; }
/* Motivos del diálogo de reporte: radios apilados. */
.report-reasons { margin: 12px 0; }
.report-reasons label { display: block; margin: 8px 0; cursor: pointer; }
.fb-actions { display: flex; border-top: 1px solid var(--border); padding-top: 4px; }
.fb-action {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  background: none; border: 0; padding: 10px 4px; color: var(--muted);
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  border-radius: 6px; text-decoration: none;
}
.fb-action:hover { background: var(--bg); text-decoration: none; }
.fb-action .reaction-svg { width: 20px; height: 20px; }

/* Respuestas como tarjetas claras (detalle de solicitud): cabecera con
   avatar, nombre y fecha, reacción que pide y estado en palabras simples;
   nota, enlace, captura de prueba grande y, para el autor, la caja de
   confirmar o rechazar. La destacada (desde una notificación) lleva borde
   azul y fondo teñido, como las notificaciones sin leer. */
.counter-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; margin-bottom: 16px; overflow-wrap: anywhere; }
.counter-highlight { border: 2px solid var(--blue); background: var(--active-bg); }
.counter-highlight-label { color: var(--blue); font-weight: 700; font-size: 14px; margin: 0 0 8px; }
.counter-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.counter-head-meta { display: flex; flex-direction: column; min-width: 0; }
.counter-head-badges { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.counter-note { margin: 10px 0 0; }
.counter-card .post-preview { margin-top: 10px; }
.counter-proof-label { color: var(--muted); font-size: 13px; font-weight: 700; margin: 12px 0 0; }
.counter-card .proof-img { margin: 8px 0 0; cursor: zoom-in; }
.counter-next { color: var(--muted); font-size: 14px; margin: 12px 0 0; }
.counter-pending-summary { font-weight: 700; margin: 0 0 12px; }
.counter-action-box { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 12px; }
.counter-action-box > p { margin: 0 0 10px; }
.counter-confirm-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.counter-confirm-form .img-preview { margin: 0; }
/* Vista previa de la captura de confirmación (lote 26): la imagen ya
   no queda entre los botones. Al elegirla, el botón de subir se
   oculta y solo queda la imagen con una X en la esquina para quitarla.
   Mismo DOM en escritorio y en móvil, así que el arreglo vale en los
   dos: la imagen no se mete entre los botones en ningún ancho. */
.confirm-preview { position: relative; display: inline-block; }
.confirm-preview[hidden] { display: none; }
.confirm-preview .img-preview { display: block; max-width: 160px; max-height: 160px; }
.confirm-preview-x { position: absolute; top: -8px; right: -8px; width: 24px; height: 24px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 50%; background: var(--danger); color: #fff; cursor: pointer; }
.confirm-preview-x svg { width: 14px; height: 14px; }
/* Indicador de pasos del intercambio (lote 26): qué paso va y de quién
   es el turno. En móvil se apilan en columna. */
.exchange-steps { list-style: none; display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 12px 0; padding: 0; }
.exchange-steps li { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.exchange-steps li svg { width: 16px; height: 16px; }
.exchange-steps .step-num { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--border); color: var(--muted); font-size: 12px; font-weight: 700; }
.exchange-steps .step-done { color: var(--text); }
.exchange-steps .step-done svg { color: #31a24c; }
.exchange-steps .step-current { color: var(--text); font-weight: 700; }
.exchange-steps .step-current .step-num { background: var(--blue); color: #fff; }
.exchange-steps .step-ended { color: var(--danger); }
.exchange-steps .step-ended svg { color: var(--danger); }
/* Mensaje de turno y nota de rectificación (lote 26). */
.turn-hint { color: var(--muted); font-size: 14px; margin: 0 0 12px; }
.counter-rectify-note { color: var(--muted); font-size: 14px; margin: 8px 0 0; }
/* Formulario de rectificar (lote 26): solo en la tarjeta de quien
   respondió, cuando su respuesta fue rechazada y aún no rectificó. */
.rectify-form { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 12px; }
.rectify-form > p { margin: 0 0 10px; }
.rectify-form textarea { width: 100%; margin: 8px 0; }
/* Aviso de disputa (lote 26): recomendación visible para ambos, no un
   castigo. Quitar la reacción en Facebook y bloquear al otro usuario. */
.dispute-box { border: 1px solid #e6a700; background: var(--warn-bg); color: var(--warn-text); border-radius: var(--radius); padding: 12px; margin-top: 12px; }
.dispute-box > p { margin: 0 0 8px; }
.dispute-box > p:last-child { margin-bottom: 0; }
.dispute-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.dispute-actions form { display: contents; }

/* Caja de respuesta "Responder como ...". */
.comment-box { display: flex; gap: 10px; align-items: flex-start; }
.comment-box-form { flex: 1; min-width: 0; }
.comment-box-form textarea { border-radius: 18px; background: var(--bg); border: 0; }
.comment-box-form textarea:focus { outline: 2px solid var(--blue); }
.comment-box-actions { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.comment-box-actions .btn-primary { margin-left: auto; }
.fb-attach { cursor: pointer; margin: 0; }
.fb-file-input { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }

/* Vista previa del link. */
.post-preview-img { display: block; width: calc(100% + 24px); max-height: 320px; object-fit: cover; border-radius: 8px 8px 0 0; margin: -12px -12px 12px; }
.post-preview-body { overflow-wrap: anywhere; }
.post-preview-title { font-weight: 700; margin: 0 0 4px; }
.post-preview-desc { color: var(--muted); margin: 0 0 8px; }
.post-preview-meta { color: var(--muted); font-size: 13px; margin: 0 0 8px; }

/* Visor de imágenes (lightbox). */
.lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(0, 0, 0, .9); display: none; align-items: center; justify-content: center; padding: 24px; }
.lightbox.open { display: flex; }
.lightbox img { max-width: 100%; max-height: 90vh; object-fit: contain; border-radius: 4px; }
.lightbox-body { position: relative; display: flex; justify-content: center; }
.lightbox-caption { color: #fff; font-size: 20px; font-weight: 600; margin: 16px 0 0; text-align: center; }
.lightbox-caption[hidden] { display: none; }
/* Foto de perfil en el visor: círculo grande con el nombre debajo y
   el lápiz sobre la foto (solo tu perfil), como en la captura. */
.lightbox.profile { flex-direction: column; }
.lightbox.profile .lightbox-body { width: min(80vw, 320px); aspect-ratio: 1; }
.lightbox.profile img { width: 100%; height: 100%; max-height: none; border-radius: 50%; object-fit: cover; }
.lightbox.profile .profile-photo-edit { bottom: 12px; }
.lightbox-close { position: absolute; top: 16px; right: 16px; background: rgba(255, 255, 255, .15); color: #fff; border: 0; border-radius: 50%; width: 40px; height: 40px; font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.proof-img { cursor: zoom-in; }

.menu-btn { display: none; background: none; border: 0; padding: 8px; cursor: pointer; color: var(--text); font-size: 22px; }
.drawer { position: fixed; top: 0; left: 0; bottom: 0; width: 280px; max-width: 85vw; background: var(--card); z-index: 100; transform: translateX(-105%); transition: transform 0.2s ease; overflow-y: auto; padding: 12px; box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15); }
.drawer.open { transform: none; }
.drawer-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 90; display: none; }
.drawer-overlay.open { display: block; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.drawer-close { background: none; border: 0; padding: 8px; cursor: pointer; color: var(--muted); font-size: 18px; }
.drawer-nav a { display: flex; align-items: center; gap: 10px; padding: 10px 8px; border-radius: 6px; color: var(--text); font-weight: 600; }
.drawer-nav a:hover { background: var(--bg); text-decoration: none; }
/* Interruptor de tema del drawer: mismo aspecto que sus enlaces. */
.drawer-nav button { display: flex; align-items: center; gap: 10px; padding: 10px 8px; border-radius: 6px; color: var(--text); font-weight: 600; background: none; border: 0; font: inherit; cursor: pointer; width: 100%; text-align: left; }
.drawer-nav button:hover { background: var(--bg); text-decoration: none; }
@media (max-width: 1023px) {
  .menu-btn { display: inline-flex; }
  .mobile-nav-item { position: relative; }
  /* El botón central "Crear" de la barra móvil abre el diálogo. */
  button.mobile-nav-item { background: none; border: 0; font: inherit; cursor: pointer; }
  /* El centro "Crear" es un círculo azul sólido con el + en blanco y
     pulso constante, como el botón de escritorio. */
  button.mobile-nav-item.mobile-nav-create {
    flex: none; align-self: center; width: 44px; height: 44px;
    background: var(--blue); color: #fff; border-radius: 50%;
  }
  button.mobile-nav-item.mobile-nav-create .icon { width: 26px; height: 26px; }
  button.mobile-nav-item.mobile-nav-create.active { color: #fff; background: var(--blue-dark); }
  /* Insignia arriba a la derecha del icono de 28px, no del item entero. */
  .mobile-nav-item .badge { position: absolute; top: 2px; right: calc(50% - 18px); }
  .mobile-nav-item .avatar { width: 28px; height: 28px; }
}

/* ---------- Tablero admin ---------- */
.admin-alert { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.admin-alert p { margin: 0 0 8px; }
.admin-ok { background: var(--active-bg); border: 1px solid var(--border); }
.admin-ok p { margin: 0 0 4px; }
.admin-kpi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }
.admin-kpi { display: flex; flex-direction: column; gap: 4px; margin-bottom: 0; color: var(--text); }
.admin-kpi:hover { text-decoration: none; background: var(--active-bg); }
.admin-kpi-num { font-size: 28px; font-weight: 800; line-height: 1.1; }
.admin-kpi-label { font-weight: 700; display: flex; align-items: center; gap: 6px; }
.admin-kpi-sub { color: var(--muted); font-size: 13px; }
.admin-kpi-alert { border: 1px solid var(--flash-border); background: var(--flash-bg); }
.admin-quick-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }
.admin-quick { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 0; color: var(--text); }
.admin-quick:hover { text-decoration: none; background: var(--active-bg); }
.admin-quick-icon { flex: none; font-size: 22px; color: var(--blue); }
.admin-quick-icon .icon { width: 22px; height: 22px; }
.admin-quick-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.admin-quick-body small { color: var(--muted); }
@media (max-width: 1023px) {
  .admin-kpi-grid, .admin-quick-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .admin-kpi-grid, .admin-quick-grid { grid-template-columns: 1fr; }
}

/* ---------- Cáscara admin: diseño de tablero, no de feed ---------- */
.admin-page { padding-bottom: 0; }
.admin-topbar { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 12px; height: var(--topbar-h); padding: 0 16px; background: var(--card); border-bottom: 1px solid var(--border); }
.admin-brand { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 17px; color: var(--text); white-space: nowrap; }
.admin-brand:hover { text-decoration: none; }
.admin-topbar-spacer { flex: 1; }
.admin-topbar-link { color: var(--muted); font-weight: 600; white-space: nowrap; }
.admin-topbar-user { font-weight: 600; white-space: nowrap; }
.admin-menu-btn { display: none; align-items: center; justify-content: center; width: 40px; height: 40px; border: 0; border-radius: 50%; background: none; color: var(--text); cursor: pointer; }
.admin-menu-btn:hover { background: var(--bg); }
.admin-shell { display: grid; grid-template-columns: 240px minmax(0, 1fr); align-items: start; }
.admin-sidebar { position: sticky; top: var(--topbar-h); height: calc(100vh - var(--topbar-h)); overflow-y: auto; background: var(--card); border-right: 1px solid var(--border); padding: 12px; }
.admin-nav { display: flex; flex-direction: column; gap: 2px; }
.admin-nav a { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--radius); color: var(--text); font-weight: 600; }
.admin-nav a:hover { background: var(--bg); text-decoration: none; }
.admin-nav a.active { background: var(--blue); color: #fff; }
.admin-nav a.active .badge { background: #fff; color: var(--blue); }
.admin-nav .badge { margin-left: auto; }
.admin-main { padding: 20px; min-width: 0; max-width: 1100px; width: 100%; margin: 0 auto; }
@media (max-width: 1023px) {
  .admin-menu-btn { display: inline-flex; }
  .admin-sidebar { display: none; position: fixed; left: 0; top: var(--topbar-h); bottom: 0; z-index: 45; width: 260px; }
  body.admin-nav-open .admin-sidebar { display: block; }
  .admin-shell { grid-template-columns: minmax(0, 1fr); }
  .admin-topbar-user { display: none; }
  .admin-main { padding: 12px; }
}

/* ---------- Scroll infinito del feed ---------- */
.feed-sentinel { min-height: 56px; display: flex; align-items: center; justify-content: center; }
.feed-sentinel .feed-loading { display: none; color: var(--muted); }
.feed-sentinel.htmx-request .feed-loading { display: block; }
.feed-end { text-align: center; padding: 16px 0; }
