/* ==========================================================================
   Fonts
   ========================================================================== */
/* Avada: Montserrat (headings/nav) + Fira Sans (cuerpo) */
/*@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&family=Fira+Sans:wght@400;500;600&display=swap'); */

/* Antes: Ubuntu (cuerpo) + Roboto Condensed (títulos) + Montserrat 800 (números del hero). */
/* REDISEÑO: dos familias distintas para títulos y cuerpo.
   - Space Grotesk: títulos (tecnológica, con detalles propios en la "g" y la "a"). Grosores 500-700 (no tiene 800).
   - DM Sans: cuerpo, menús y botones (muy legible en tamaños pequeños).
   Probadas y aparcadas (comparativa de 11 fuentes): Sora 800 (la primera del rediseño) y Manrope 800.
   Para volver a una: descomentar su @import y sus variables, y comentar las de Space Grotesk.
   OJO: esos @import piden la fuente a Google (le mandan la IP del visitante). Para usar una
   de verdad, bajar sus .woff2 a static/directory/fonts/ y añadirla a fonts.css, como Space Grotesk. */
/* @import url('https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&display=swap'); */
/* @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@600;700;800&family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&display=swap'); */
/* Space Grotesk + DM Sans, servidas desde nuestro servidor (antes, este @import era a Google Fonts) */
@import url('fonts.css');

:root {
  /* Todo el sitio usa estas variables para tipografía: cambiarlas aquí
     (junto con las reglas de fonts.css) cambia la fuente en todas partes. */
  /* --font-heading: "Sora", Arial, Helvetica, sans-serif; */
  /* --font-heading: "Manrope", Arial, Helvetica, sans-serif; */
  --font-heading: "Space Grotesk", Arial, Helvetica, sans-serif;
  --font-body: "DM Sans", Arial, Helvetica, sans-serif;

  /* Grosor "fuerte" de los títulos grandes (h1, título del hero, números de los contadores).
     - Variable propia porque depende de la fuente: Space Grotesk llega a 700; Sora y Manrope, a 800. */
  /* --heading-weight-strong: 800; */   /* Sora / Manrope */
  --heading-weight-strong: 700;          /* Space Grotesk */

  /* Escala de títulos (clamp = mínimo en móvil, crece con la ventana, máximo en escritorio).
     - Saltos grandes entre niveles: el h1 se distingue de un vistazo del h2.
     - --hero-size: solo el título de la portada (home.css), mucho más grande que un h1. */
  --hero-size: clamp(2.2rem, 1.1rem + 4.6vw, 4.5rem);
  --h1-size: clamp(2.1rem, 1.3rem + 3.4vw, 3.75rem);
  --h2-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.1rem);
  --h3-size: clamp(1.15rem, 1.05rem + 0.4vw, 1.35rem);

  /* Espaciado vertical entre secciones: amplio para las importantes, ceñido para las relacionadas. */
  --space-section-lg: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  --space-section-sm: clamp(1.25rem, 1rem + 1vw, 1.75rem);
}

/* ==========================================================================
   Variables de Tema: Claro (Light, default — paleta del WordPress/Avada
   original) y Oscuro (Dark Navy). El tema activo se controla con el
   atributo data-theme en <html>, fijado por el script inline en base.html
   (lee/guarda en localStorage).
   ========================================================================== */
:root,
:root[data-theme="light"] {
  --bg-primary: #f4f9fd;       /* Azul-blanco muy sutil, para tarjetas/elementos secundarios */
  --bg-secondary: #ffffff;     /* Blanco puro, para el contenedor principal */
  --bg-tertiary: #c8e6f7;      /* Azul muy claro (AWB color 2), para tags/separadores */

  --accent-primary: #2397c9;   /* Azul cian brillante (AWB color 4 = link_color de Avada), un pelín más oscuro que el original */
  --accent-hover: #2c6b9d;     /* Azul acero (AWB color 8 = link_hover_color de Avada) */

  --text-main: #004560;        /* Azul marino oscuro (AWB color 6 = body/heading color de Avada) */
  --text-muted: #2880bb;       /* Azul medio (AWB color 7), para texto secundario */

  --border-color: #a9ceed;     /* Azul claro (AWB color 3 = sep_color de Avada) */
  /* --csic-red: #AF071F; */   /* Rojo corporativo CSIC (PANTONE 1807C = R175 G7 B31, manual de identidad). Probado y aparcado */
  /* --bcb-orange: #c38800; */ /* Naranja BCB (el de los círculos del logo CSIC Hub). Probado y aparcado */
  --link-orange: #9a6400;      /* Naranja BCB oscurecido para texto: contraste 5:1 sobre blanco (el #c38800 se queda en 3:1). Enlace "BCB Connection" del pie */
  /* PRUEBA "sin redondeos ni sombras": esquinas rectas y sin sombra; separan los bordes y el contraste de color.
     - "0px" y no "0": hay reglas con calc(var(--radius) - 2px), y un 0 sin unidad no se puede restar a 2px */
  --radius: 0px;
  --shadow: none;
  /* --radius: 8px; */
  /* --shadow: 0 10px 15px -3px rgba(0, 69, 96, 0.08), 0 4px 6px -4px rgba(0, 69, 96, 0.05); */
  --autofill-bg: #fff6c9;      /* Amarillo suave: campos autorellenados por ORCID/GitHub */
}

:root[data-theme="dark"] {
  --bg-primary: #0f172a;       /* Azul noche profundo */
  --bg-secondary: #1e293b;     /* Azul pizarra para tarjetas y tablas */
  --bg-tertiary: #334155;      /* Bordes y elementos secundarios */

  --accent-primary: #32aadf;   /* Azul cian brillante para links y destacados, un pelín más oscuro que el original */
  --accent-hover: #7dd3fc;     /* Estado hover de enlaces */

  --text-main: #f8fafc;        /* Texto principal blanco suave */
  --text-muted: #94a3b8;       /* Texto secundario/etiquetas */

  --border-color: #334155;
  /* --csic-red: #E0354D; */   /* Rojo CSIC aclarado: el #AF071F original apenas se ve sobre azul noche */
  /* --bcb-orange: #d99a12; */ /* Naranja BCB algo más claro: el #c38800 se apaga sobre azul noche */
  --link-orange: #d99a12;      /* Contraste 6:1 sobre el azul pizarra del pie */
  /* PRUEBA "sin redondeos ni sombras" (ver tema claro) */
  --radius: 0px;
  --shadow: none;
  /* --radius: 8px; */
  /* --shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -4px rgba(0, 0, 0, 0.2); */
  --autofill-bg: #8a7420;      /* Amarillo/mostaza: campos autorellenados desde ORCID/repo */
}

/* ==========================================================================
   Estilos Base y Tipografía
   ========================================================================== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: var(--bg-primary);
  color: var(--text-main);
  font-family: var(--font-body);
  font-size: 1.0625rem;        /* 17px: DM Sans es algo pequeña a 16px */
  line-height: 1.7;            /* cuerpo: 1.6-1.8 */
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;           /* Como mínimo, alto de pantalla: así el footer baja al fondo aunque haya poco contenido */
}

/* Ninguna imagen más ancha que su contenedor (si no, en móvil se sale por la derecha).
   - height: auto: al estrecharse, el alto baja en proporción y la imagen no se deforma.
   - Selector "img" a secas (lo más débil): cualquier regla con clase que fije un tamaño gana sobre esta. */
img {
  max-width: 100%;
  height: auto;
}

/* ==========================================================================
   Banner superior (logo)
   ========================================================================== */
.top-banner {
  width: 100%;
  background-color: var(--bg-secondary);
  padding: 0.5rem 1rem;
  /* border-bottom: 3px solid var(--csic-red); */   /* línea roja CSIC: probada y aparcada */
  /* border-bottom: 3px solid var(--bcb-orange); */   /* línea naranja BCB: probada y aparcada */
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: center;
}

/* Alto del logo flexible: 38 px en móvil (360 px de ancho) → 60 px a partir de ~920 px, creciendo poco a poco.
   - El logo (logo-header-bcb-csic.jpg) es muy apaisado (7,5 : 1): a 38 px ocupa ~285 px de ancho, cabe en un móvil;
     a 60 px, ~450 px.
   - clamp(mínimo, preferido, máximo): el preferido depende del ancho de la ventana (vw = 1 % del ancho). */
.top-banner-logo {
  height: clamp(38px, 24px + 3.9vw, 60px);   /* algo más grande que antes (34 -> 50 px) */
  width: auto;
}

/* ==========================================================================
   Navegación
   ========================================================================== */
/* Tamaños flexibles de la barra: encogen con la ventana por debajo de ~650 px.
   - Variables CSS: se definen aquí y las usan los botones de dentro (las variables se heredan a los hijos).
   - Cada una es clamp(mínimo, fórmula que crece con el ancho, escritorio).
   - Mínimos pensados para un móvil de 320 px (el más estrecho en uso): por encima, manda la fórmula.
     Con mínimos más altos, por debajo de ~360 px la fila dejaba de encoger y el último icono bajaba de línea.
   - Tamaño completo a partir de ~650 px: la fila del menú ☰ cerrado (☰, People, Resources, Search,
     Assistant, usuario y tema) a tamaño completo ocupa ~640 px. Antes llegaban a 860-960 px y los
     botones encogían con sitio de sobra. Los valores a 320 px son los mismos de antes.
   - Relleno vertical fijo y pequeño: la barra es igual de fina en todos los tamaños. */
nav {
  --nav-font: clamp(0.72rem, 0.56rem + 0.97vw, 0.95rem);      /* letra de enlaces y píldoras */
  --nav-pad-x: clamp(0.45rem, 0.21rem + 1.28vw, 0.9rem);      /* relleno lateral de las píldoras (completo ya a ~560 px) */
  --nav-icon-pad-x: clamp(0.3rem, 0.07rem + 1.31vw, 0.6rem);  /* relleno lateral de ☰, usuario y tema */
  --nav-gap: clamp(0.2rem, 8vw - 1.8rem, 2rem);               /* hueco entre botones: más lento que el resto (mínimo hasta ~400 px, completo a ~760 px), para que quepa Assistant */

  width: 100%;
  background-color: var(--bg-secondary);
  padding: 0.5rem clamp(0.4rem, 5.24vw - 0.63rem, 1.5rem);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem var(--nav-gap);
  justify-content: flex-start;
}

nav a,
.footer-links a {              /* Footer: mismos enlaces que el menú de arriba */
  color: var(--text-main);
  text-decoration: none;
  /* REDISEÑO: DM Sans en minúscula normal (antes Roboto Condensed en MAYÚSCULAS). */
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--nav-font, 0.9rem);  /* El footer está fuera de la nav, no tiene la variable: usa el valor de reserva */
  letter-spacing: 0;
  transition: color 0.2s ease-in-out;
}

nav a:hover,
.footer-links a:hover {
  color: var(--accent-primary);
}

.nav-right {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem var(--nav-gap);
  margin-left: auto;
}

/* Botón ☰ del menú hamburguesa (base.html).
   - Mismo aspecto que el del menú de usuario (.nav-user-toggle), para que los iconos de la barra vayan a juego.
   - display: none: en escritorio no se ve; la media query de abajo lo muestra. */
.nav-burger {
  display: none;
  align-items: center;
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  border-radius: var(--radius);
  padding: 0.3rem var(--nav-icon-pad-x);
  cursor: pointer;
}

.nav-burger:hover,
.nav-burger[aria-expanded="true"] {          /* Abierto: borde azul, para que se note que está activo */
  border-color: var(--accent-primary);
}

/* Menú hamburguesa (nav.nav-compact): solo cuando la fila completa NO cabe.
   - Ya no hay un ancho fijo. Antes era 960 px, pensado para el caso más largo (sin sesión, con "Join us | Log in"):
     con sesión iniciada sobraba sitio y pasaba a ☰ demasiado pronto.
   - La clase nav-compact la pone o quita el JS de base.html (justo después de la <nav>), midiendo si la fila cabe.
   - Cerrado: solo ☰, People, Resources, Search, Assistant y, a la derecha, usuario y tema.
   - Abierto (nav.menu-open, la pone el JS al pulsar ☰): los .nav-secondary aparecen debajo, uno por línea. */
nav.nav-compact .nav-burger {
  display: flex;
}

/* Ocultos mientras el menú está cerrado. La barrita entre Join us y Log in, siempre: en el menú van uno debajo de otro. */
nav.nav-compact .nav-secondary,
nav.nav-compact .nav-sep {
  display: none;
}

/* display: contents: el div .nav-right "desaparece" como caja y sus hijos pasan a ser hijos directos de la nav.
   - Así Join us y Log in (que están dentro) pueden bajar al menú desplegado con los demás enlaces. */
nav.nav-compact .nav-right {
  display: contents;
}

/* Usuario y tema, empujados a la derecha (margin-left: auto se come el espacio libre).
   - Con sesión iniciada el primero es el icono de usuario: el tema va justo detrás, sin empuje propio. */
nav.nav-compact .nav-user-menu,
nav.nav-compact .theme-toggle {
  margin-left: auto;
}

nav.nav-compact .nav-user-menu + .theme-toggle {
  margin-left: 0;
}

/* Menú abierto: cada enlace secundario en su propia línea, debajo de la fila de botones.
   - order: 1: se colocan después de todo lo demás (por defecto todos tienen order 0), aunque en el HTML vayan antes. */
nav.nav-compact.menu-open .nav-secondary {
  display: block;
  order: 1;
  width: 100%;
  padding: 0.4rem 0;
  border-top: 1px solid var(--border-color);
}

/* Fila completa (sin ☰): todos los enlaces en una sola línea.
   - nowrap (en la nav, en .nav-right y en el texto): si no cabe, la fila se sale por la derecha en vez de bajar
     enlaces a otra línea. Eso es lo que mide el JS (scrollWidth > clientWidth) para pasar a ☰.
   - Hueco flexible: 0.6rem a ~960 px → 2rem a partir de ~1250 px. Por debajo de 960 px se queda en 0.6rem. */
nav:not(.nav-compact) {
  flex-wrap: nowrap;
  --nav-gap: clamp(0.6rem, 7.75vw - 4.06rem, 2rem);
}

nav:not(.nav-compact) .nav-right {
  flex-wrap: nowrap;
}

nav:not(.nav-compact) a,
nav:not(.nav-compact) button {
  white-space: nowrap;
}

/* Menú del usuario (base.html): icono junto al botón de tema que despliega
   nombre de usuario, Profile, Stats/Admin (staff) y Log out.
   - Reutiliza .nav-dropdown / .nav-dropdown-menu (más abajo), pero sin la píldora azul:
     el botón imita al de tema (.theme-toggle) para que los dos iconos vayan a juego.
   - Ojo, orden: estas reglas van ANTES que las de .nav-dropdown, así que las que
     chocan llevan dos clases (.nav-dropdown.nav-user-menu) para ganar igualmente. */
.nav-dropdown.nav-user-menu {
  background: none;
}

.nav-user-toggle {
  display: flex;
  align-items: center;
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  /* Redondo (igual que .theme-toggle):
     - 50%, no var(--radius): sigue redondo aunque el resto de la web vaya con esquinas rectas.
     - Mismo relleno en los 4 lados: el icono es cuadrado (18x18), así sale un círculo y no un óvalo. */
  border-radius: 50%;
  padding: 0.3rem;
  cursor: pointer;
}

.nav-user-toggle:hover {
  border-color: var(--accent-primary);
}

/* El menú se alinea por la derecha: está al borde de la pantalla y, alineado
   por la izquierda (como People/Resources), se saldría. */
.nav-user-menu .nav-dropdown-menu {
  left: auto;
  right: 0;
}

/* Nombre de usuario arriba del menú: informativo, no es un enlace.
   - Selector largo a propósito: .nav-dropdown-menu li (y su :hover) quitan padding y
     bordes a todos los <li> del menú; este tiene que ganarles para mantener la raya. */
.nav-user-menu .nav-dropdown-menu li.nav-user-name {
  padding: 0 1rem 0.5rem;
  margin-bottom: 0.3rem;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.8rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Log out es un botón (va en un form POST): se le quita el aspecto de botón para
   que parezca una opción más del menú, igual que .nav-dropdown-menu a. */
.nav-user-logout {
  width: 100%;
  padding: 0.5rem 1rem;
  border: none;
  background: none;
  color: var(--text-main);
  text-align: left;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
}

.nav-user-logout:hover {
  color: var(--accent-primary);
}

/* "Change password" bajo el título de profile_no_researcher.html: discreto, a la derecha */
.profile-account-links {
  margin-top: -0.5rem;
  font-size: 0.85rem;
  text-align: right;
}

/* Datos de la cuenta (username, account email) arriba de profile.html, antes de "Personal info" */
.profile-account p {
  margin: 0.3rem 0;
}

/* "Change password", separado un poco del "(linked to your account)" */
.profile-password-link {
  margin-left: 1rem;
  font-size: 0.85rem;
}


/* Menú desplegable de la nav (People, Resources y el menú de usuario): botón + lista oculta.
   - Se abre al pulsar: el JS de base.html pone la clase .open en .nav-dropdown.
   - Con ratón, también al pasar por encima (:hover, solo en aparatos con hover de verdad; ver más abajo). */

/* display: flex: la caja se ajusta exactamente al botón de dentro.
   - Sin él, la caja trata al botón como texto en una línea, y esa línea mide como mínimo
     lo que la letra normal de la página (~27 px): al encoger las píldoras, People/Resources
     se quedaban más altos que Search. */
.nav-dropdown {
  display: flex;
  position: relative;
  background-color: var(--accent-primary);
  color: #ffffff;
  border-radius: 999px; /*redondito*/
}

.nav-dropdown-toggle {
  border: none;
  color: #ffffff;

  background-color: var(--accent-primary);
  /* Mismo relleno y alto de línea que Search (.nav-search-link), para que las tres píldoras sean idénticas.
     - line-height fijo: un <button> no hereda el del body (1.6) y un <a> sí; fijándolo en los dos, miden igual.
     - Relleno de arriba/abajo en em (proporcional a la letra): encoge con ella. */
  padding: 0.5em var(--nav-pad-x);
  line-height: 1.2;
  border-radius: 999px;

  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--nav-font);
  cursor: pointer;
  transition: color 0.2s ease-in-out;
}

.nav-dropdown-toggle:hover {
  color: var(--accent-primary);
  background-color: var(--accent-hover);
  color: #ffffff;
  text-decoration: none;
}

.nav-dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin: 0; /*evitar que se pierda el hover desde el boton hasta el menú*/
  list-style: none;
  min-width: 180px;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0.9rem 0 0.4rem;
  z-index: 10;
}

.nav-dropdown.open .nav-dropdown-menu {
  display: block;
}

/* Abrir al pasar el ratón, solo si el aparato tiene hover de verdad (ratón, trackpad).
   - En pantallas táctiles el navegador finge un hover al tocar, y se queda "pegado":
     el segundo toque no cerraba el menú. Ahí solo vale la clase .open (abrir y cerrar al tocar). */
@media (hover: hover) {
  .nav-dropdown:hover .nav-dropdown-menu {
    display: block;
  }
}

.nav-dropdown-menu li {
  padding: 0;
  margin: 0;
  background: none;
  border: none;
  border-radius: 0;
}

.nav-dropdown-menu li:hover {
  border: none;
  transform: none;
}

/* flex: icono y texto en la misma línea, centrados en vertical. */
.nav-dropdown-menu a {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 1rem;
  color: var(--text-main);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.92rem;
  white-space: nowrap;
}

/* Icono (Lucide, SVG) a la izquierda de cada opción de People y Resources (base.html).
   - flex-shrink: 0: el texto largo ("Computing infrastructures (HPC)") no lo aplasta.
   - Color de acento: el trazo del SVG usa currentColor. */
.nav-dropdown-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--accent-primary);
}

/* Iconos de marca junto a un enlace, en el color de la marca y no en el del enlace.
   - Plataformas de código/datos (repo_link en display_fields.py, iconos en brand_icons.py):
     SVG relleno, se colorea con fill. Colores oficiales de Simple Icons.
   - Tema oscuro: los colores muy oscuros (GitHub, Bitbucket) no se verían sobre el
     fondo azul marino: GitHub usa el blanco de su propio tema oscuro; Bitbucket, su azul claro.
   - Bioconductor es una imagen (favicon) con sus propios colores: solo lleva .brand-icon.
   - YouTube (Lucide, seminario en tool_detail.html): SVG de trazo (stroke = currentColor),
     por eso se colorea con color. El rojo se ve bien en los dos temas. */
.brand-icon {
  vertical-align: -2px;
  margin-right: 0.35em;
}
.brand-icon--github      { fill: #181717; }
.brand-icon--gitlab      { fill: #fc6d26; }
.brand-icon--bitbucket   { fill: #0052cc; }
.brand-icon--r           { fill: #276dc3; }
.brand-icon--pypi        { fill: #3775a9; }
.brand-icon--osf         { fill: #2cb9f1; }
.brand-icon--zenodo      { fill: #1682d4; }
.brand-icon--readthedocs { fill: #8ca1af; }
[data-theme="dark"] .brand-icon--github    { fill: #f0f6fc; }
[data-theme="dark"] .brand-icon--bitbucket { fill: #2684ff; }
.brand-icon--youtube {
  color: #ff0000;
}

/* Insignias de lenguajes de programación (filtro language_badges, brand_icons.py)*/
.lang-badges {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.lang-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}
.lang-badge-icon {
  width: 12px;
  height: 12px;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

.nav-dropdown-menu a:hover {
  color: var(--accent-primary);
  text-decoration: none;
}

/* Enlace "Search" de la nav: en vez de solo texto en color de acento (se
   veía soso, sobre todo en tema claro), una pildorita — mismo lenguaje
   visual que .btn en el resto del sitio, texto blanco fijo así que se lee
   igual de bien en claro y en oscuro. */
/* Search: mismo azul que los menús People/Resources, pero un poco más oscuro, para que
   se distinga de ellos (es un enlace, no un desplegable).
   - color-mix con un 20 % de negro: sirve igual en tema claro y oscuro, sin colores nuevos.
   - La misma clase la lleva el enlace Assistant (app assistant): las dos píldoras van iguales. */
.nav-search-link {
  background-color: color-mix(in srgb, var(--accent-primary) 70%, black);
  color: #ffffff;
  padding: 0.5em var(--nav-pad-x);   /* = People/Resources (.nav-dropdown-toggle) */
  line-height: 1.2;
  border-radius: 999px;
}

.nav-search-link:hover {
  background-color: var(--accent-hover);
  color: #ffffff;
  text-decoration: none;
}


hr {
  display: none;
}

/* Margen y relleno flexibles: pequeños en móvil (360 px) → los de escritorio a partir de 900 px.
   - Con 2.5rem fijos (40 px por lado), en un móvil se perdían ~100 px de ancho entre márgenes y rellenos. */
main, container, .content {
  width: 100%;
  max-width: min(1500px, 95vw);
  background-color: var(--bg-secondary);
  margin: clamp(1rem, 0.33rem + 2.96vw, 2rem) 1rem;   /* arriba y abajo: 1rem → 2rem */
  padding: clamp(1rem, 4.44vw, 2.5rem);                /* 1rem → 2.5rem */
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid var(--border-color);
}

/* ==========================================================================
   Encabezados y Enlaces
   ========================================================================== */
/* REDISEÑO de los títulos:
   - --font-heading (Space Grotesk), interlineado apretado (1.1-1.3) y letras algo más juntas (-0.02em): en tamaños grandes
     el espaciado por defecto se ve flojo.
   - Sin la raya azul debajo de cada título: el tamaño y el peso ya marcan la jerarquía.
   - En su lugar, el h1 lleva una barrita corta de acento (::after). */
h1, h2, h3, h4, h5 {
  color: var(--text-main);
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin-bottom: 1rem;
}

h1 {
  font-size: var(--h1-size);
  font-weight: var(--heading-weight-strong);
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin-bottom: 1.75rem;
}

h1::after {
  content: '';
  display: block;
  width: 3.5rem;
  height: 4px;
  margin-top: 0.9rem;
  border-radius: 2px;
  /* background-color: var(--csic-red); */   /* rojo CSIC: probado y aparcado */
  /* background-color: var(--bcb-orange); */   /* naranja BCB: probado y aparcado */
  background-color: var(--accent-primary);
}

h2 {
  font-size: var(--h2-size);
  margin-top: 0.5rem;
}

h3 {
  font-size: var(--h3-size);
  line-height: 1.3;
}

/* Título con un logo al lado (p.ej. "BCB Connection" del registro, con el logo de la Conexión a la derecha).
   - El lado lo decide el orden en el HTML: el logo va detrás del texto.
   - flex: logo y texto en la misma línea, centrados en vertical.
   - Alto del logo en "em": crece y encoge con el tamaño del título. */
.title-with-logo {
  display: flex;
  align-items: center;
  gap: 0.5em;
}
.title-logo {
  height: 1.3em;
  width: auto;
  flex-shrink: 0;
}

/* Párrafos seguidos: separación entre ellos (el "* { margin: 0 }" de arriba la quita) */
p + p {
  margin-top: 0.9em;
}

a {
  color: var(--accent-primary);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s ease-in-out;
}

a:hover {
  color: var(--accent-hover);
  text-decoration: underline;
}

/* Botones / Enlaces de retorno. button.btn incluido: sin esto un
   <button class="btn"> (ej. "Save changes" en profile.html, "Create X" en
   request_affiliation.html) se queda con el estilo nativo feo del
   navegador, porque a.btn solo matchea enlaces.
   - Antes también a[href*="home"]: convertía en botón CUALQUIER enlace con "home"
     en la URL (webs personales como bangalab.org/home, noticias con "homenaje"...).
     El "← Return to Home" no lo necesita: ya lleva class="btn" (y la portada es "/"). */
a.btn, button.btn {
  display: inline-block;
  margin-top: 1.5rem;
  padding: 0.65rem 1.4rem;
  border: none;
  background-color: var(--accent-primary);
  color: #ffffff;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

a.btn:hover, button.btn:hover {
  background-color: var(--accent-hover);
  color: #ffffff;
  text-decoration: none;
}

/* ==========================================================================
   Textarea (Biography en form de profile.html): por defecto un <textarea> es
   estrechísimo (cols=20) pase lo que pase en rows, así que sin esto el
   rows=14 no serviría de mucho.
   ========================================================================== */
textarea {
  display: block;
  width: 100%;
  max-width: 60ch;
  font-family: inherit;
  font-size: 1rem;
  padding: 0.5rem;
}

/* ==========================================================================
   Editor de texto (RichTextEditor en widgets.py + rich_text_editor.js).
   Quill trae colores fijos (grises sobre blanco): aquí se pasan a las
   variables del tema, para que funcione igual en claro y en oscuro.
   ========================================================================== */
.ql-toolbar.ql-snow,
.ql-container.ql-snow {
  border-color: var(--border-color);
  background: var(--bg-secondary);
  color: var(--text-main);
  font-family: inherit;
  font-size: 1rem;
}
.ql-toolbar.ql-snow { border-radius: var(--radius) var(--radius) 0 0; }
.ql-container.ql-snow { border-radius: 0 0 var(--radius) var(--radius); }
.ql-editor { min-height: 12rem; }
/* Modo </> (HTML en crudo): el <textarea> ocupa el mismo sitio que el editor. */
textarea.rich-text { max-width: none; min-height: 12rem; font-family: monospace; font-size: 0.9rem; }
/* Texto con formato, en la página (filtro rich_text) y en el editor:
   - espacio entre párrafos (el "* { margin: 0 }" de arriba lo quita)
   - sangría de las listas y tamaño máximo de las imágenes */
.rich-content > * + *,
.ql-editor > * + * { margin-top: 0.75em; }
.rich-content ul, .rich-content ol { padding-left: 1.5em; }
.rich-content img { max-width: 100%; height: auto; }
/* Iconos de los botones: trazo y relleno con el color del texto; activo/hover con el acento. */
.ql-snow .ql-stroke { stroke: var(--text-main); }
.ql-snow .ql-fill { fill: var(--text-main); }
.ql-snow .ql-picker { color: var(--text-main); }
.ql-snow button:hover .ql-stroke,
.ql-snow button.ql-active .ql-stroke,
.ql-snow .ql-picker-label:hover .ql-stroke { stroke: var(--accent-primary); }
.ql-snow button:hover .ql-fill,
.ql-snow button.ql-active .ql-fill { fill: var(--accent-primary); }
.ql-snow .ql-picker-options,
.ql-snow .ql-tooltip {
  background: var(--bg-secondary);
  color: var(--text-main);
  border-color: var(--border-color);
}
.ql-snow .ql-tooltip input[type=text] {
  background: var(--bg-primary);
  color: var(--text-main);
  border-color: var(--border-color);
}
/* Texto de ejemplo del editor vacío. */
.ql-editor.ql-blank::before { color: var(--text-muted); }

/* Campos que acaba de rellenar el auto-fill de ORCID o GitHub (ver
   orcid_lookup.js/github_lookup.js): fondo amarillo suave para que se note
   qué ha tocado el JS. Se quita en cuanto la persona edita el campo a mano
   (ver el listener 'input' en esos mismos JS). */
.auto-filled {
  background-color: var(--autofill-bg) !important;
}

/* ==========================================================================
   Formulario de perfil (profile.html): asterisco de campo obligatorio +
   texto de ayuda pequeño (ej. "email vinculado a tu cuenta")
   ========================================================================== */
.required-marker {
  color: #d64545;
  margin-left: 0.15em;
  font-weight: 700;
}

.field-hint {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* Botón de ayuda con aspecto de enlace (p.ej. "ⓘ What does each committee do?" del registro).
   - Es un <button> y no un <a>: no lleva a otra página, abre un popup.
   - font: inherit, para que tenga el tamaño del texto de ayuda en el que va. */
.help-link {
  border: none;
  background: none;
  padding: 0;
  margin-left: 0.4rem;
  font: inherit;
  color: var(--accent-primary);
  text-decoration: underline;
  cursor: pointer;
}

/* Solo en tema claro: el texto de ayuda (--text-muted) y --accent-primary son dos azules casi
   iguales y el botón no destaca. Se pone en azul marino (--text-main) y en negrita.
   - :not([data-theme="dark"]): el tema claro es el de por defecto (sin data-theme o "light"). */
:root:not([data-theme="dark"]) .help-link {
  color: var(--text-main);
  font-weight: 600;
}

/* Lista de comités dentro de ese popup: nombre en negrita y su resumen debajo. */
.committees-help-list dt {
  font-weight: bold;
  margin-top: 0.75rem;
}
.committees-help-list dd {
  margin: 0.2rem 0 0;
}

/* Aviso de nombres parecidos en los formularios de "Create it" (similar_titles.js), al lado del campo. */
.similar-titles-warning {
  margin-left: 0.5rem;
  color: crimson;
  font-size: 0.8rem;
}
.similar-titles-warning a {
  color: inherit;
  text-decoration: underline;
}

/* Campo de imagen con vista previa (_image_upload_field.html):
   - flex-wrap: etiqueta en su propia línea; debajo, vista previa + botón de subir.
   - Vista previa: cuadrado de 96px, contain (no recorta logos apaisados), fondo
     blanco también en modo oscuro (logos transparentes con letras oscuras). */
.image-upload {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 1rem 0;
}
.image-upload > label {
  flex-basis: 100%;
}
.image-upload-preview {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  object-fit: contain;
  background-color: #ffffff;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 4px;
}
.image-upload-input {
  display: flex;
  flex-direction: column;
  align-items: flex-start;   /* botón y casilla con su ancho justo, no estirados */
  gap: 0.4rem;
  min-width: 0;
}

/* Botón "Choose image" / "Change image" (_image_upload_field.html): es un <label>, no un <button>,
   así que no le llega el estilo de .btn (solo a.btn y button.btn): se repite aquí. */
.image-upload-button {
  display: inline-block;
  padding: 0.4rem 1rem;
  border-radius: 999px;
  background-color: var(--accent-primary);
  color: #ffffff;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.image-upload-button:hover {
  background-color: var(--accent-hover);
}
/* Con el teclado (Tab), el foco cae en el input oculto: se marca el botón que lo contiene */
.image-upload-button:focus-within {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

/* El <input type="file"> de verdad, oculto a la vista pero no con display:none:
   así sigue recibiendo el foco con el teclado y lo leen los lectores de pantalla. */
.image-upload-file {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}

/* "Remove current image": casilla y texto en la misma línea */
.image-upload-clear {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  cursor: pointer;
}

/* Help text debajo de un <textarea> (profile.html, registration_form.html):
   - El textarea es display:block, así que el <br> que va detrás (pensado para
     los <input>, que son "inline") ya no corta la línea sino que AÑADE una
     vacía: el hueco hacía parecer que el help text era del campo siguiente.
   - Se oculta ese <br> y el help text se pega a su caja (margen solo arriba). */
textarea + br {
  display: none;
}
textarea ~ .field-hint {
  display: block;
  margin-top: 0.25rem;
}

/* Formularios del perfil (profile.html y registration_form.html, <form
   class="profile-form">): cada campo va en un <p> (etiqueta + caja + help
   text). Margen solo por debajo, para que se vea dónde acaba un campo y
   empieza el siguiente. */
.profile-form p,
.profile-form .form-field {
  margin: 0 0 1.5rem;
}

/* .form-field fuera del perfil (p.ej. Type of application en tool_edit.html):
   mismo margen que un <p> normal, para que no quede pegado a los campos de al lado.
   Menos específico que la regla de arriba, así que en el perfil sigue mandando aquella. */
.form-field {
  margin: 1em 0;
}

/* .form-field: en vez de <p>, para los campos cuyo widget es un bloque
   (buscador de afiliaciones, chips de keywords/projects, editor de la bio):
   un <div> dentro de un <p> no es HTML válido - el navegador cierra el <p>
   antes de tiempo y deja párrafos vacíos con su margen (los "espacios raros").
   Help text:
   - Si va DESPUÉS del widget (último hijo: keywords, projects, bio), en su
     propia línea y pegado al widget.
   - Si va junto al nombre del campo (afiliaciones), se queda en línea con él:
     el widget, que es un bloque, cae solo debajo. */
.profile-form .form-field > .field-hint:last-child {
  display: block;
  margin-top: 0.25rem;
}

/* Botón "Auto-fill from ORCID" junto al campo ORCID: mismo estilo que .btn
   pero sin el margin-top pensado para botones de fin de formulario, y más
   compacto para que quepa en línea junto al input. */
.btn-inline {
  margin-top: 0;
  padding: 0.35rem 0.9rem;
  font-size: 0.75rem;
  vertical-align: middle;
}

/* Fila del campo ORCID + su botón: flex en vez de dejarlos en flujo inline
   normal, para que el botón quede centrado verticalmente con el input en
   vez de pegado o descolocado. El <p> que la contiene lleva más espacio
   vertical que un <p> normal del formulario, porque el botón es más alto
   que una línea de texto suelta y si no queda todo apretado contra el campo
   de arriba (Email) y el de abajo (Name). */
.orcid-lookup-row {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
}

/* El <button> nativo trae su propio recuadro con algo más de "peso" visual
   por debajo de la línea base que un <input>/<label> normal - con
   align-items: center de arriba no queda a la vista, así que se sube un
   poco a mano. */
.orcid-lookup-row .btn-inline {
  position: relative;
  top: -0.8rem;
}

.orcid-field {
  margin-top: 1.2rem;
  margin-bottom: 1.2rem;
}

/* ==========================================================================
   Selector con buscador (research groups, service units, funded projects,
   bcb communities, tools, research lines en profile.html): caja con resumen
   de lo ya marcado (chips quitables) + filtro de texto + lista de checkboxes
   con scroll, en vez de un <select multiple> nativo. Interacción de cliente
   en directory/static/directory/js/form_widgets.js.
   ========================================================================== */
.searchable-multiselect {
  max-width: 480px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background-color: var(--bg-secondary);
  padding: 0.75rem;
}

/* Más anchos en el perfil y en el registro (los dos usan class="profile-form"):
   los títulos de proyectos y líneas son largos. En el resto de formularios, 480px. */
.profile-form .searchable-multiselect {
  max-width: 720px;
}

.searchable-multiselect-selected {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

/* [hidden]: connection_membership.js oculta el resumen (o la etiqueta del grupo "not listed");
   sin esto ganaría el display: flex de arriba. */
.searchable-multiselect-selected[hidden] {
  display: none;
}

.searchable-multiselect-none {
  color: var(--text-muted);
  font-size: 0.85rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background-color: var(--bg-tertiary);
  color: var(--text-main);
  border-radius: 999px;
  padding: 0.25rem 0.5rem 0.25rem 0.75rem;
  font-size: 0.85rem;
}

.chip-remove {
  border: none;
  background: none;
  padding: 0;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.chip-remove:hover {
  color: var(--accent-hover);
}

/* ==========================================================================
   Title tags (funded projects en profile.html): texto libre + <datalist>
   en vez de buscador+checkboxes, reutiliza .chip/.chip-remove de arriba.
   ========================================================================== */
.title-tags {
  max-width: 480px;
}

.title-tags-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

.title-tags-input {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background-color: var(--bg-primary);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.9rem;
}

/* ==========================================================================
   Multi text (link_to_main_publications_doi en request_new_tool.html/
   tool_edit.html): varias cajas de texto + botón "+ Add another", para
   campos de texto plano que a veces necesitan más de un valor (ver
   MultiTextWidget en widgets.py).
   ========================================================================== */
.multi-text {
  max-width: 480px;
}

.multi-text-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
}

.multi-text-row input[type="text"] {
  flex: 1;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background-color: var(--bg-primary);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.9rem;
}

.multi-text-remove {
  border: none;
  background: none;
  padding: 0;
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.multi-text-remove:hover {
  color: var(--accent-hover);
}

.searchable-multiselect-search {
  width: 100%;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  background-color: var(--bg-primary);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.9rem;
}

/* El scroll vive en este wrapper (no en el <ul> directamente) para poder
   meter el aviso "Can't find X? Create it" como pie fijo DENTRO del área con
   scroll (position: sticky necesita ser hijo directo del contenedor que
   scrollea) — así queda siempre a la vista mientras se recorre la lista, en
   vez de aparecer solo cuando la búsqueda no encuentra nada. */
.searchable-multiselect-scroll {
  position: relative;
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

.searchable-multiselect-options {
  list-style: none;
  margin: 0;
  padding: 0;
}

.searchable-multiselect-options li {
  padding: 0.35rem 0.6rem;
  border-bottom: 1px solid var(--border-color);
}

.searchable-multiselect-options li:last-child {
  border-bottom: none;
}

.searchable-multiselect-options label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  color: var(--text-main);
  cursor: pointer;
}

/* Afiliación pedida y aún sin aprobar (pending_pks en widgets.py): aviso debajo de su nombre. */
.searchable-multiselect-options .pending-approval {
  display: block;
  margin-left: 1.5rem;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--text-muted);
}

/* Casilla "Show only those of my research groups" (filter_by_groups en widgets.py). */
.searchable-multiselect-group-filter {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-primary);   /* azul cian de los enlaces: más llamativo que el texto secundario */
  cursor: pointer;
}

/* Aviso cuando ese filtro deja la lista vacía (o no hay grupos marcados). */
.searchable-multiselect-group-filter-empty {
  margin: 0;
  padding: 0.5rem 0.6rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.searchable-multiselect-empty-hint {
  position: sticky;
  bottom: 0;
  margin: 0;
  padding: 0.5rem 0.6rem;
  background-color: var(--bg-secondary);
  border-top: 1px solid var(--border-color);
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ==========================================================================
   Casillas pintadas como cuadraditos clicables, sin buscador ni chips:
   - .bcb-community-select: BCB communities (profile.html, registration_form.html).
     A diferencia del resto de afiliaciones, son solo un puñado.
   - .choice-tiles: cualquier otro campo de opciones fijas con casillas
     (Type of application en tool_edit.html / request_new_tool.html).
   Mismo aspecto para los dos; el borde de color marca lo elegido.
   ========================================================================== */
.bcb-community-select > div,
.choice-tiles > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.bcb-community-select label,
.choice-tiles label {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-width: 80px;
  min-height: 45px;
  padding: 0.4rem 0.6rem;
  background-color: var(--bg-tertiary);
  border: 3px solid transparent;
  border-radius: var(--radius);
  font-weight: 500;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

/* La casilla de verdad se oculta (opacity, no display:none: sigue funcionando
   con el teclado y los lectores de pantalla); lo que se ve es la etiqueta. */
.bcb-community-select input[type="checkbox"],
.choice-tiles input[type="checkbox"],
.choice-tiles input[type="radio"] {
  position: absolute;
  opacity: 0;
}

.bcb-community-select label:has(input:checked),
.choice-tiles label:has(input:checked) {
  border-color: var(--accent-primary);
}

/* Orden de preferencia (comités del registro, connection_membership.js):
   - data-order="1"/"2" en la etiqueta marcada -> circulito con el número, montado
     sobre la esquina superior derecha (top/right negativos: medio fuera del cuadradito).
   - Mismo azul que el borde de la casilla marcada, número en blanco.
   - Las casillas desactivadas (ya hay el máximo marcado) se ven apagadas. */
.choice-tiles label[data-order]::after {
  content: attr(data-order);
  position: absolute;
  top: -9px;
  right: -9px;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px; /* redondito */
  background-color: var(--accent-primary);
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 700;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.choice-tiles label:has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

.bcb-community-select label:has(input:focus-visible),
.choice-tiles label:has(input:focus-visible) {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

/* ==========================================================================
   Elección de perfil (profile_no_researcher.html): "ya tengo un perfil" vs.
   "crear perfil de investigador", una al lado de la otra.
   ========================================================================== */
.profile-choice {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.profile-choice-card {
  flex: 1 1 280px;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 1.5rem;
}

.profile-choice-card h2 {
  margin-bottom: 0.75rem;
  font-size: 1.1rem;
}

.profile-choice-card p {
  margin-bottom: 1rem;
}

/* ==========================================================================
   Mensajes flash (django.contrib.messages) - pintados una sola vez en
   base.html, así que salen en cualquier página.
   ========================================================================== */
.site-messages {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}

.site-messages li {
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  color: var(--text-main);
}

/* Avisos en franja de ancho completo (igual que .top-banner/nav), no una cajita:
   - .pending-activation-banner: cuenta pendiente de aprobación.
   - .dev-site-banner: "sitio en desarrollo" (base.html, encima del logo). */
.pending-activation-banner,
.dev-site-banner {
  width: 100%;
  margin: 0;
  padding: 0.4rem 1rem;
  background-color: #f17070;
  color: #ffffff;
  text-align: center;
  font-size: clamp(0.75rem, 0.64rem + 0.48vw, 0.9rem);  /* flexible: 0.75rem en móvil → 0.9rem a partir de 860 px */
  font-weight: 600;
}

/* El enlace, en blanco y subrayado: el color de enlace normal no se lee sobre rojo. */
.dev-site-banner a {
  color: #ffffff;
  text-decoration: underline;
}

/* ==========================================================================
   Minibanner (icono + etiqueta de categoría, en las páginas de detalle)
   ========================================================================== */
.minibanner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

/* Icono Lucide del modelo (antes, PNG del WordPress): SVG dentro de un círculo de color.
   - padding sobre el <svg>: el dibujo queda más pequeño que el círculo. */
.minibanner-icon {
  width: 32px;
  height: 32px;
  padding: 6px;
  border-radius: 50%;
  background-color: var(--bg-tertiary);
  color: var(--accent-hover);
}

/* En la cabecera de las listas (junto al h1, grande): círculo más grande */
.list-header-icon {
  width: clamp(2.5rem, 2rem + 1.5vw, 3.25rem);
  height: clamp(2.5rem, 2rem + 1.5vw, 3.25rem);
  padding: 0.6rem;
}

/* Etiqueta pequeña en MAYÚSCULAS sobre el título ("eyebrow"): el único sitio donde se mantienen. */
.minibanner-label {
  font-family: var(--font-body);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

/* ==========================================================================
   Cabecera de las listas genéricas (generic_list.html): icono + nombre del
   modelo + nº de entradas, en vez del genérico "Complete List" de antes.
   ========================================================================== */
.list-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* Sin la barrita de acento del h1 (::after): en un flex sería una pieza más de la fila, y aquí
   el icono + título + contador ya hacen de cabecera. */
.list-header::after {
  display: none;
}

.count-badge {
  display: inline-block;
  flex-shrink: 0;
  /* Va dentro de un h1/h2: sin esto heredaría Sora 800 con letras apretadas ("125entries") */
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: normal;
  line-height: 1.4;
  font-size: 0.8rem;
  color: var(--text-muted);
  background-color: var(--bg-tertiary);
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* ==========================================================================
   Tablas (para generic_detail.html)
   ========================================================================== */
table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
  margin-bottom: 1.5rem;
  background-color: var(--bg-primary);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border-color);
}

/* overflow-wrap: anywhere: una palabra larga sin espacios (URL, email, DOI) se parte en vez de ensanchar la tabla y sacarla de la pantalla. */
th, td {
  padding: 0.85rem 1.25rem;
  text-align: left;
  border-bottom: 1px solid var(--border-color);
  overflow-wrap: anywhere;
}

/* Móvil: menos relleno en las celdas, para dejar sitio al texto. */
@media (max-width: 600px) {
  th, td {
    padding: 0.6rem 0.75rem;
  }
}

td:first-child {
  width: 30%;
  color: var(--text-muted);
  font-weight: 600;
  background-color: var(--bg-tertiary);
}

/* Celda única en su fila (p.ej. la Biography de researcher_detail.html):
   - no es una "etiqueta", es el contenido -> peso normal.
   - Así se ven las negritas (<strong>) que traiga el propio texto. */
td:only-child {
  font-weight: 400;
}

tr:last-child td {
  border-bottom: none;
}

tr:hover {
  background-color: var(--bg-tertiary);
}

/* ==========================================================================
   Listas (para generic_list.html y home.html)
   ========================================================================== */
/* REDISEÑO (inspirado en https://codepen.io/amit_sheen/pen/ExooBLg): listas ligeras, sin cajas.
   - Cada elemento: un ">" de color delante y una raya fina debajo (antes, una cajita con fondo y borde).
   - Sublistas: ">>".
   - Al pasar el ratón: el texto (y los enlaces) cambian al color de acento y el ">" engorda.
   - El ">" es un ::before (no ::marker): Safari no deja cambiar el texto de ::marker. */
ul, ol {
  list-style: none;
  margin: 1rem 0;
  padding: 0;
}

li {
  position: relative;                   /* referencia para colocar el ">" (::before) */
  padding: 0.65rem 0.25rem 0.45rem 1.5rem;
  border-bottom: 1px solid color-mix(in srgb, var(--accent-primary) 22%, transparent);
  transition: color 0.3s ease;
}

/* El último, sin raya: dentro de una caja (p.ej. research groups por institución) se juntaba con su borde */
li:last-child {
  border-bottom: none;
}

li::before {
  content: '>';
  position: absolute;
  left: 0.25rem;
  top: 0.65rem;
  color: var(--accent-primary);
  font-weight: 600;
  transition: font-weight 0.2s ease;
}

/* Sublista: sangría y ">>" */
li ul,
ul ul {
  margin: 0;
  padding-left: 1.25rem;
}
ul ul > li {
  padding-left: 1.9rem;
}
ul ul > li::before {
  content: '>>';
}

li:hover,
li:hover > a {
  color: var(--accent-primary);
}

li:hover::before {
  font-weight: 800;
}

li a {
  display: block;
}

/* Listas con estilo propio: sin ">" (y sin el relleno pensado para él).
   - Menús, mensajes, buscador de afiliaciones, noticias con miniatura (home), filas de instituciones,
     listas de /stats/ y listas con viñetas de los textos legales (style="list-style: disc"). */
.nav-dropdown-menu li::before,
.site-messages li::before,
.searchable-multiselect-options li::before,
.home-news-list li::before,
.institution-rows li::before,
.detail-list li::before,
.audit-list li::before,
ul[style*="disc"] li::before {
  content: none;
}

.detail-list li,
ul[style*="disc"] li {
  padding: 0;
  border-bottom: none;
}

/* --------------------------------------------------------------------------
   ">" que despliega la ficha de cada elemento (research groups, service units, HPC, projects;
   list_summary.js + model_summary() en views.py)
   - li.has-summary: sin el ">" decorativo (::before); en su sitio va el botón, en el mismo lugar.
   - Abierto (aria-expanded="true"): el ">" gira 90° y apunta hacia abajo.
   -------------------------------------------------------------------------- */
li.has-summary::before {
  content: none;
}

.summary-toggle {
  position: absolute;
  left: -0.1rem;
  top: 0.45rem;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--accent-primary);
  font: 700 1rem/1 var(--font-body);
  cursor: pointer;
  transition: transform 0.2s ease, background-color 0.15s ease;
}

.summary-toggle:hover {
  background-color: var(--bg-tertiary);
}

.summary-toggle[aria-expanded="true"] {
  transform: rotate(90deg);
}

/* La ficha: debajo del nombre, con una raya de color a la izquierda que la une a su elemento */
.summary-card {
  margin: 0.6rem 0 0.4rem;
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--accent-primary);
  border-radius: 0 var(--radius) var(--radius) 0;
  background-color: var(--bg-primary);
  color: var(--text-main);
  font-size: 0.92rem;
}

.summary-card-description {
  margin: 0 0 0.75rem;
}

/* Campos: etiqueta a la izquierda (columna estrecha), valor a la derecha */
.summary-card-fields {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 1.25rem;
  margin: 0 0 0.75rem;
}

.summary-card-fields dt {
  font-weight: 700;
  color: var(--text-muted);
}

.summary-card-fields dd {
  margin: 0;
  overflow-wrap: anywhere;   /* URLs y emails largos no ensanchan la ficha */
}

/* Móvil: etiqueta encima del valor (en dos columnas no cabe) */
@media (max-width: 600px) {
  .summary-card-fields {
    grid-template-columns: 1fr;
    gap: 0.1rem;
  }
  .summary-card-fields dd {
    margin-bottom: 0.4rem;
  }
}

/* Los enlaces de la ficha, en línea (la regla "li a { display: block }" los pondría uno por línea) */
.summary-card a {
  display: inline;
}

.summary-card-more {
  font-weight: 600;
}

.summary-status {
  margin: 0.5rem 0;
  font-size: 0.9rem;
  color: var(--text-muted);
}

/* Fecha e investigador debajo del título en la lista de publicaciones */
.list-item-date {
  display: block;
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* Enlaces de página (« First ‹ Previous  Page 2 of 62  Next › Last ») bajo la lista */
.list-pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  justify-content: center;
  align-items: center;
}

/* El investigador, en la misma línea que la fecha: la regla "li a" (más arriba) pone
   todos los enlaces de una lista en su propia línea (display: block). */
li a.list-item-author {
  display: inline;
}

/* ==========================================================================
   Botón de cambio de tema (light/dark)
   ========================================================================== */
.theme-toggle {
  display: flex;
  align-items: center;
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  border-radius: 50%;   /* redondo: ver .nav-user-toggle */
  padding: 0.3rem;
  cursor: pointer;
  line-height: 1;
}

.theme-toggle:hover {
  border-color: var(--accent-primary);
}

/* Sol o luna (iconos Lucide, base.html): se ve el del tema activo.
   - Antes el JS cambiaba un emoji (☀️/🌙); ahora los dos SVG están siempre y el CSS elige. */
.theme-toggle svg {
  width: 18px;
  height: 18px;
}
.theme-toggle .theme-icon-moon,
[data-theme="dark"] .theme-toggle .theme-icon-sun {
  display: none;
}
[data-theme="dark"] .theme-toggle .theme-icon-moon {
  display: block;
}

/* ==========================================================================
   Iconos Lucide: <svg class="lucide ..."> que escribe {% icon %} en el HTML
   (directory/templatetags/icons.py).
   - Trazo con el color del texto (currentColor): el color se pone con "color", como un texto.
   - Trazo algo más fino que el de serie (2): más fino casa mejor con las fuentes de la web.
   ========================================================================== */
svg.lucide {
  stroke-width: 1.75;
  flex-shrink: 0;
  overflow: visible;   /* algunos iconos (p.ej. "server") dibujan hasta el borde: sin esto se cortaban los lados */
}

/* ==========================================================================
   Vista previa al hacer hover (bocadillo) - hover_preview.js
   ========================================================================== */
.preview-bubble {
  position: absolute;
  z-index: 1000;
  max-width: 300px;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 0.75rem 1rem;
  font-family: var(--font-body);
  color: var(--text-main);
}

.preview-card-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.preview-card-icon {
  width: 18px;
  height: 18px;
  color: var(--accent-primary);
}

.preview-card-title {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--text-main);
}

.preview-card-body {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.preview-card-photo {
  width: 25%;
  flex-shrink: 0;
  border-radius: var(--radius);
  object-fit: cover;
  aspect-ratio: 1 / 1;
}

/* Logos (tools...): mismo hueco cuadrado que la foto, pero sin recortar.
  ESTO ES CLAVE PARA LOGOS LARGOS (como pasa con SQANTI3).
   - contain: el logo entero cabe dentro del cuadrado; sobra espacio arriba/abajo o a los lados.
   - Los logos suelen ser apaisados, con cover se perderían los bordes. */
.preview-card-photo.preview-card-logo {
  object-fit: contain;
}

.preview-card-summary {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   Acordeón genérico <details class="collapsible"> + <summary>: útil para
   cualquier lista larga que quiera mostrarse colapsada por defecto (antes
   solo existía para "By institution" en who_we_are.css, con nombres
   específicos de esa página).
   -------------------------------------------------------------------------- */
.collapsible {
  border-bottom: 1px solid var(--border-color);
}

.collapsible summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--text-main);
}

.collapsible summary::-webkit-details-marker {
  display: none;
}

.collapsible summary::after {
  content: '+';
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  background-color: var(--accent-primary);
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1;
}

.collapsible[open] summary::after {
  content: '\2212'; /* signo menos */
}

.collapsible-content {
  margin: 0 0 1rem;
  padding-left: 0.25rem;
  color: var(--text-main);
  line-height: 1.7;
}

/* ==========================================================================
   Footer (enlaces de contacto/legales + copyright)
   - Franja de ancho completo, como .top-banner y nav (mismo fondo y borde).
   - El estilo de los enlaces está en "nav a, .footer-links a" (arriba).
   ========================================================================== */
.site-footer {
  width: 100%;
  margin-top: auto;            /* Empuja el footer al fondo (body es flex column con min-height: 100vh) */
  background-color: var(--bg-secondary);
  border-top: 1px solid var(--border-color);
  padding: 1.75rem clamp(1rem, 4vw, 2.5rem);
  /* REDISEÑO: alineado a la izquierda. Enlaces a la derecha y copyright a la izquierda en una fila
     (row-reverse: en el HTML los enlaces van primero); en móvil, uno debajo de otro. */
  display: flex;
  flex-wrap: wrap-reverse;
  flex-direction: row-reverse;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem 2rem;
  text-align: left;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;             /* En móvil, los enlaces bajan de línea en vez de salirse */
  gap: 0.5rem 1.75rem;
}

.site-footer p {
  margin: 0;
}

/* Iconos de Bluesky y YouTube al final de los enlaces del pie */
.footer-social {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
}

.footer-social a {
  display: inline-flex;
  color: var(--text-main);
}

.footer-social a:hover {
  color: var(--accent-primary);
}

.footer-social svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* Logo pequeño de la Conexión (círculos, apaisado) a la izquierda del copyright, centrados en vertical */
.footer-brand {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.footer-logo {
  height: 2.25rem;
  width: auto;
  flex-shrink: 0;
}

/* El logo es un enlace a la web de la Conexión.
   - display: flex: sin esto, el <a> deja un hueco de línea debajo de la imagen.
   - opacity al pasar el ratón: una imagen no cambia de color como un texto. */
.footer-logo-link {
  display: flex;
  flex-shrink: 0;
  transition: opacity 0.2s ease-in-out;
}

.footer-logo-link:hover {
  opacity: 0.75;
}

/* "BCB Connection" en los enlaces del pie: en naranja BCB (los demás van en el color del texto),
   para que se distinga de los enlaces propios del portal. Al pasar el ratón, azul como los demás. */
.footer-links a.footer-conexion {
  color: var(--link-orange);
}

.footer-links a.footer-conexion:hover {
  color: var(--accent-primary);
}

/* ==========================================================================
   LISTAS CON TARJETAS Y BARRA DE FILTROS
   tool_list.html y researcher_list.html (ver FilteredListView en urls.py y
   list_filter.js). Antes vivía en el <style> de tool_list.html.
   ========================================================================== */

/* Cuadrícula:
   - auto-fill + minmax: caben tantas columnas como quepan de mínimo 220px;
     el espacio que sobra se reparte entre ellas (1fr).
   - En móvil sale una sola columna, sin media query. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0 2rem;
}

/* Tarjeta: toda ella es un enlace (<a>) a la ficha.
   - flex en columna: imagen arriba, texto debajo.
   - text-decoration/color: quita el subrayado y el azul de enlace. */
.list-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  color: var(--text-main);
  text-decoration: none;
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
/* Tarjeta que no pasa los filtros (list_filter.js le pone el atributo hidden).
   Hace falta: el display: flex de arriba ganaría al hidden y no se ocultaría. */
.list-card[hidden] {
  display: none;
}
.list-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
  border-color: var(--accent-primary);
}

/* Hueco de la imagen (logo, foto): mismo alto en todas las tarjetas, haya
   imagen o no, para que los nombres queden alineados en cada fila.
   - Fondo blanco siempre (también en modo oscuro): muchos logos son PNG/SVG
     transparentes con letras oscuras, que sobre fondo oscuro no se verían. */
.list-card-media {
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ffffff;
  border-radius: var(--radius);
  padding: 0.5rem;
}
.list-card-media img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
/* Sin imagen: la inicial del nombre, grande y en el color de acento. */
.list-card-media--placeholder {
  background-color: var(--bg-tertiary);
  font-family: var(--font-heading);
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--accent-primary);
}
/* Fotos de personas: círculo que rellena (cover) en vez de logo entero (contain). */
.list-card-media--photo {
  background-color: transparent;
  padding: 0;
}
.list-card-media--photo img {
  width: 90px;
  height: 90px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--border-color);
}
/* Researcher sin foto (_researcher_card_body.html): icono de persona en el mismo círculo de 90 px */
.list-card-person-icon {
  width: 90px;
  height: 90px;
  padding: 22px;
  border-radius: 50%;
  background-color: var(--bg-tertiary);
  color: var(--accent-hover);
  stroke-width: 1.5;
}

.list-card-title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere; /* nombres largos sin espacios no desbordan la tarjeta */
}
.list-card-summary {
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-muted);
}

/* Secciones de fichas al azar + una ficha final "+N more" que lleva al listado.
   - Las usan who_we_are.html (Research groups, Researchers) y home.html (Tools, Service units, HPC...).
   - .preview-section: raya fina y espacio arriba, para separar una sección de la anterior. */
.preview-section {
  margin-top: var(--space-section-lg);
  padding-top: var(--space-section-sm);
  border-top: 1px solid var(--border-color);
}

/* Cabecera de sección: título a la izquierda y "Ver todo →" a la derecha, en la misma fila
   (en móvil, el enlace baja debajo del título). */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  margin-bottom: 0.5rem;
}
.section-head h2 {
  margin: 0;
}
.section-head-link {
  font-weight: 600;
  white-space: nowrap;
}
/* Frase corta bajo el título de sección */
.section-lead {
  max-width: 62ch;
  color: var(--text-muted);
}

/* Variante en filas (2 columnas de filas anchas en vez de fichas cuadradas):
   - Para fichas con poco contenido (service units, HPC): pastilla, nombre e institución en una fila.
   - Así cada sección de la portada tiene una forma distinta. */
/* - flex-wrap (no grid): cada ficha mide al menos 24rem y se estira para llenar su fila.
   - .card-grid-tail (home.html): la última ficha + "+N more" en un solo bloque. Así el
     "+N more" siempre va en la fila de la última ficha, más estrecho que ella. */
.card-grid--rows {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
/* Fichas estrechas (mín. 15rem, la mitad que antes): en escritorio caben todas en una fila. */
.card-grid--rows > .list-card {
  flex: 1 1 min(15rem, 100%);
  min-width: 0;
}
/* El bloque final pide algo más de sitio (22rem): si no cabe junto a las demás, baja a su propia
   fila, en vez de quedarse en la de arriba con la ficha aplastada. */
.card-grid-tail {
  flex: 1 1 min(22rem, 100%);
  min-width: 0;
  display: flex;
  gap: 0.75rem;
}
.card-grid-tail > .list-card:not(.preview-more-card) {
  flex: 1 1 12rem;
  min-width: 0;
}
.card-grid-tail > .preview-more-card {
  flex: 0 0 auto;
}
/* Dentro de cada ficha, de arriba abajo: pastilla de la comunidad (pequeña), nombre e institución
   (y CPUs). Todo a todo el ancho: la pastilla no le quita sitio al texto. */
.card-grid--rows .list-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
  padding: 0.75rem 0.9rem;
}
.card-grid--rows .list-card-title { font-size: 0.95rem; }
.card-grid--rows .list-card-summary { font-size: 0.82rem; line-height: 1.4; }
.card-grid--rows .region-badge { font-size: 0.72rem; }
/* "+N more" en filas: compacto, número arriba y "Go to the full list →" debajo */
.card-grid--rows .preview-more-card {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.6rem 1.1rem;
}
.card-grid--rows .preview-more-number {
  font-size: 1.6rem;
}
.card-grid--rows .preview-more-card .list-card-summary {
  display: none;   /* "more service units": sobra, el título de la sección ya lo dice */
}
.card-grid--rows .preview-more-card .list-card-title {
  font-size: 0.85rem;
  white-space: nowrap;
}

/* Ficha con institución (grupo, service unit, HPC): la pastilla de la comunidad arriba,
   sin estirarse a todo el ancho */
.group-card .region-badge {
  align-self: flex-start;
}

/* Ficha "+N more": mismo tamaño que las demás, discreta (fondo suave y borde
   discontinuo, como un hueco "por ver"); solo el número va en el color de acento. */
.preview-more-card {
  justify-content: center;
  align-items: center;
  text-align: center;
  background-color: var(--bg-secondary);
  border-style: dashed;
}

.preview-more-number {
  color: var(--accent-primary);
  font-family: var(--font-heading);
  font-size: 3rem;
  font-weight: 700;
  line-height: 1;
}

/* Lista de research groups (researchgroup_list.html): una columna, una caja por
   institución con sus grupos en una <ul>.
   - [hidden]: list_filter.js oculta cajas y grupos; sin esto ganaría el display. */
.institution-boxes {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 1.5rem 0 2rem;
}
.institution-box {
  padding: 1rem 1.25rem;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}
.institution-box[hidden],
.institution-box-groups li[hidden] {
  display: none;
}
.institution-box-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--border-color);
}
.institution-box-header h2 {
  margin: 0;
  font-size: 1.1rem;
  border: none;
}
.institution-box-header h2 a {
  color: var(--text-main);
}
.institution-box-header h2 a:hover {
  color: var(--accent-primary);
}
/* Sin sangría propia: la pone ya el estilo general de lista (el hueco del ">" en cada li) */
.institution-box-groups {
  margin: 0.75rem 0 0;
  line-height: 1.6;
}
/* Ciudad, en pequeño junto al nombre de la institución */
.institution-box-city {
  margin-left: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--text-muted);
}
.institution-box-meta {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Lista de institutions (institutiongroup_list.html): una fila por institución.
   - Nombre y contadores a la izquierda, pastilla de la comunidad a la derecha (space-between).
   - Una línea fina entre filas; sin viñetas. */
.institution-rows {
  margin: 0;
  padding: 0;
  list-style: none;
}
.institution-rows li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  /* 0.75rem a los lados: sin viñetas, el nombre quedaría pegado al borde de la caja */
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border-color);
}
.institution-rows li:last-child {
  border-bottom: none;
}
.institution-rows li[hidden] {
  display: none;
}
/* ">" que despliega la ficha de la institución*/
.institution-rows li.has-summary {
  padding-left: 1.75rem;
}
.institution-rows .summary-slot {
  flex-basis: 100%;
}
/* El nombre ocupa su propia línea (regla global "li a { display: block }") y la ciudad
   empieza la de abajo: sin el margen de .institution-box-city, quedan alineados. */
.institution-rows .institution-box-city {
  margin-left: 0;
}

/* Comunidad autónoma (_region_badge.html): bandera redonda + nombre.
   - --region-color: color de su bandera (COMUNIDAD_STYLE en views.py), inline; sin él, gris.
   - color-mix: el mismo color muy transparente de fondo; se lee en claro y en oscuro. */
.region-badge {
  --region-color: #8a8a8a;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.7rem 0.2rem 0.25rem;
  border: 1px solid var(--region-color);
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--region-color) 14%, transparent);
  color: var(--text-main);
  font-size: 0.8rem;
  white-space: nowrap;
}
/* Pastilla que filtra (researchgroup_list.html): aspecto de botón al pasar el ratón */
.region-badge--button {
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.15s;
}
.region-badge--button:hover {
  background-color: color-mix(in srgb, var(--region-color) 30%, transparent);
}
/* Cajita de filtro elegida (_list_filter_bar.html, aria-pressed lo pone list_filter.js):
   fondo más intenso y borde más grueso, para que se distinga de las demás. */
.region-badge--button[aria-pressed="true"] {
  background-color: color-mix(in srgb, var(--region-color) 45%, transparent);
  box-shadow: 0 0 0 1px var(--region-color);
  font-weight: 600;
}

/* Fila de cajitas de filtro dentro de la barra (filtros con 'chips': True).
   flex-basis: 100% -> ocupa una línea entera de la barra, debajo del buscador. */
.list-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  flex-basis: 100%;
}
/* Nº de entradas de cada cajita, en pequeño y apagado */
.list-filter-chip-count {
  font-size: 0.75rem;
  color: var(--text-muted);
}
/* object-fit: cover recorta la bandera (rectangular) al círculo, por el centro */
.region-flag {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--border-color);
}
/* Icono en vez de bandera (Outside Spain: 🌐), centrado en el mismo círculo */
.region-flag--icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  line-height: 1;
  border: none;
}

/* Barra de filtros, pegada arriba al hacer scroll (sticky).
   - flex-wrap: en pantallas estrechas los controles bajan a otra línea.
   - top: 0 + z-index: se queda por encima de las tarjetas al pasar por debajo. */
.list-filter-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  margin-top: 1rem;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
/* Aspecto de buscador y desplegables: colores del tema (claro/oscuro), no los del navegador. */
.list-filter-bar input[type="search"],
.list-filter-bar select {
  padding: 0.45rem 0.6rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text-main);
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}
.list-filter-bar input[type="search"]:focus,
.list-filter-bar select:focus {
  outline: 2px solid var(--accent-primary);
  outline-offset: 1px;
}
/* El buscador se lleva todo el ancho que sobra; los desplegables, el justo. */
.list-filter-bar input[type="search"] {
  flex: 1 1 220px;
  min-width: 0;
}
.list-filter-bar select {
  flex: 0 1 220px;
  min-width: 0;
}
/* Filtro de etiquetas (Keywords): caja de texto + chips de las elegidas, en línea.
   La caja usa el mismo aspecto que el buscador (regla de input[type="search"] de arriba). */
.list-filter-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  flex: 1 1 220px;
  min-width: 0;
}
.list-filter-tag-input {
  flex: 1 1 160px;
  min-width: 0;
  padding: 0.45rem 0.6rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text-main);
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}
.list-filter-tag-input:focus {
  outline: 2px solid var(--accent-primary);
  outline-offset: 1px;
}
.list-filter-tag-chips {
  display: contents; /* los chips se colocan como si fueran hijos directos de .list-filter-tags */
}
/* "Show other filters": ocupa una línea entera de la barra (flex-basis 100%).
   - Los desplegables de dentro, en cuadrícula: tantas columnas como quepan. */
.list-filter-more {
  flex-basis: 100%;
}
.list-filter-more summary {
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent-primary);
}
.list-filter-more-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.75rem;
  margin-top: 0.75rem;
}
.list-filter-more-grid select {
  width: 100%;
}
/* Con los filtros extra abiertos la barra es alta: deja de ir pegada arriba
   al hacer scroll, para no tapar media pantalla de tarjetas. */
.list-filter-bar:has(.list-filter-more[open]) {
  position: static;
}
/* Lo mismo en pantallas estrechas (mismo umbral que el menú ☰): los controles van uno debajo
   de otro y la barra, pegada arriba, tapaba media pantalla. Aquí se queda encima de la lista
   y se va con ella al hacer scroll. */
@media (max-width: 960px) {
  .list-filter-bar {
    position: static;
  }
}
/* "Clear filters": button.btn le pone margin-top: 1.5rem y lo descentra.
   .btn-inline intenta quitarlo, pero pierde: "button.btn" es más específico
   que ".btn-inline". Dos clases (esta regla) sí le ganan. */
.list-filter-bar .btn {
  margin-top: 0;
}
.list-filter-count {
  font-size: 0.9rem;
  color: var(--text-muted);
  white-space: nowrap;
}