/* =============================================================================
   Portail de recherche inter-tenants — page publique servie à la racine.
   Fichier : public_html/assets/xhelpers/css/portal.css

   Chargé APRÈS arc/index.css, dont il reprend les tokens (--admin-*). Chaque
   var() porte un repli : un token absent ne doit jamais faire retomber une
   propriété sur l'héritage sans que rien ne le signale — c'est le défaut que
   bin/css-tokens-check.php traque.

   Page volontairement sobre : c'est une porte d'entrée, pas un tableau de bord.
   ========================================================================== */

/* LE BLEU DE L'UNIVERSITE, ET RIEN D'AUTRE.
   #004D95 n'est pas choisi a l'oeil : c'est la valeur declaree dans les SVG
   officiels du depot (Logo-ULB.svg, logo-ulb-generique.svg). Le PNG echantillonne
   a #0A5296 — un ecart de compression ; le vectoriel fait foi.

   La surcharge est portee par `.portal-page`, donc elle ne vaut QUE pour le
   portail : la pile /_arc/ garde son propre --admin-primary (#0f4c81), qui n'a
   pas a suivre la charte institutionnelle.

   --admin-primary-dark est une DERIVATION pour les etats de survol (assombrissement
   d'environ 25 %), pas une seconde couleur de charte. */
.portal-page {
  --admin-primary: #004D95;
  --admin-primary-dark: #003A70;
  --portal-book-bg: #edf5ef;
  --portal-book-text: #286041;
  --portal-video-bg: #f2edf8;
  --portal-video-text: #69418b;
  --portal-link-text: #805014;

  background: var(--admin-bg, #f5f6f8);
  color: var(--admin-text, #1f2933);
  min-height: 100vh;
  /* Colonne : le pied de page reste en bas meme quand le contenu est court. */
  display: flex;
  flex-direction: column;
}

.portal-shell {
  flex: 1 0 auto;
}

/* `width: 100%` N'EST PAS REDONDANT ICI, et c'est un piege mesure le 2026-09-05 :
   `.portal-page` est un flex column, et une marge automatique sur l'axe transversal
   y NEUTRALISE l'etirement — l'element se dimensionne alors sur son contenu, borne
   par max-width. Sans cette ligne, la coque mesurait 633 px au lieu de 780 sur un
   ecran de 1440, et la barre de recherche s'en trouvait retrecie d'autant.
   Le defaut ne se voit pas en relisant la feuille : seule la valeur calculee sur
   l'element reel le montre. */
.portal-shell {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 3.5rem 1.5rem 4rem;
}

/* ---------------------------------------------------------------- en-tête */

.portal-head {
  text-align: center;
  margin-bottom: 2rem;
}

.portal-logo {
  height: 44px;
  width: auto;
  margin-bottom: 1rem;
}

.portal-title {
  font-size: clamp(1.75rem, 3vw, 2.125rem);
  font-weight: 600;
  letter-spacing: -.025em;
  margin: 0 0 0.75rem;
  color: var(--admin-text, #1f2933);
}

.portal-tagline {
  margin: 0 auto;
  color: var(--admin-muted, #6b7280);
  font-size: 1rem;
}

/* -------------------------------------------------------------- recherche */

.portal-search {
  margin-bottom: 2rem;
}

/* Le label reste dans le flux pour les lecteurs d'écran sans encombrer la page. */
.portal-search__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.portal-search__row {
  align-items: stretch;
  display: flex;
  gap: 0.5rem;
}

.portal-search__input {
  min-height: 52px;
  box-shadow: none;
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  color: var(--admin-text, #1f2933);
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
}

body.arc-admin.portal-page .portal-search__input:focus {
  box-shadow: none;
  outline: 1px solid var(--admin-primary, #004D95);
  outline-offset: 2px;
  border-color: var(--admin-primary, #004D95);
}

.portal-search__submit {
  min-height: 48px;
  flex: 0 0 auto;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: #ffffff;
  background: var(--admin-primary, #004D95);
  border: 1px solid var(--admin-primary, #004D95);
  border-radius: var(--admin-radius, 10px);
  cursor: pointer;
}

.portal-search__submit:hover {
  background: var(--admin-primary-dark, #003A70);
  border-color: var(--admin-primary-dark, #003A70);
}

/* ------------------------------------------------------------- messages */

.portal-notice {
  padding: 0.875rem 1rem;
  border-radius: var(--admin-radius, 10px);
  background: var(--admin-surface-soft, #eef1f5);
  color: var(--admin-muted, #6b7280);
  margin: 0 0 1.5rem;
}

.portal-notice--warn {
  background: var(--admin-warning-soft, #fdf3e2);
  color: var(--admin-text, #1f2933);
}

/* TYPOGRAPHIE DES GUILLEMETS. `<q>` laisse le navigateur choisir ceux de la langue
   du document — mais il les colle au mot : « comment » s'affichait «comment». La
   regle francaise demande une espace insecable a l'interieur ; l'anglais, aucune.
   D'ou cette redefinition pour le seul francais, l'anglais gardant le defaut. */
:lang(fr) q {
  quotes: '\00AB\00A0' '\00A0\00BB';
}

.portal-count {
  color: var(--admin-muted, #6b7280);
  margin: 0 0 1.25rem;
}

/* ELARGIR LE CONTENEUR N'EST PAS ELARGIR LE TEXTE, et confondre les deux est le
   piege de cette page. Mesure du 2026-09-05 sur un ecran de 1440 : a 780 px de
   coque, les extraits faisaient deja 91 CARACTERES par ligne, quand le confort de
   lecture se situe entre 45 et 75. Elargir la coque sans borner la ligne aurait
   donc degrade la lisibilite en croyant l'ameliorer.
   ATTENTION A L'UNITE : `ch` vaut la largeur du caractere « 0 », plus large que la
   moyenne des minuscules. Mesure faite : 68ch rendaient 83 caracteres reels, pas 68.
   La valeur ci-dessous est donc calibree sur le RENDU, pas sur l'intuition — 58ch
   donnent une ligne d'environ 71 caracteres. Reverifier si la police change. */
.portal-tagline,
.portal-blank__hint,
.portal-services__hint {
  font-size: .9rem;
  max-width: 58ch;
}

/* LE CENTRAGE D'UN TEXTE BORNE SE POSE DANS LA REGLE QUI DECLARE SA MARGE, jamais
   dans une regle groupee a part : `margin: 0` ecrit plus bas dans le fichier
   annulerait `margin-left/right: auto` sans le moindre signal. C'est arrive ici —
   le sous-titre du bloc « aucun contenu » se collait a gauche pendant que son titre
   restait centre. Voir aussi le piege de la media query : meme cause, l'ordre. */

/* ------------------------------------------------------- retour en haut */

/* Le defilement doux vaut pour l'ancre du bouton comme pour tout lien interne —
   mais jamais pour qui a demande a son systeme de reduire les animations. */
html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* Masque tant qu'on n'a pas defile : sur une page courte, il n'aurait rien a faire.
   `visibility` en plus de l'opacite, sinon il resterait cliquable en etant invisible. */
.portal-totop {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 20;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44 px : la cible tactile recommandee, et la meme que les controles de /_arc/. */
  width: 44px;
  height: 44px;
  color: #ffffff;
  background: var(--admin-primary, #004D95);
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.28);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.18s ease, visibility 0.18s ease;
}

.portal-totop.is-visible {
  opacity: 1;
  visibility: visible;
}

/* Sans JavaScript, la classe n'est jamais posee : le bouton doit alors rester
   utilisable des qu'on le cible au clavier, sinon il devient un piege de tabulation. */
.portal-totop:focus-visible {
  opacity: 1;
  visibility: visible;
  outline: 2px solid var(--admin-primary-dark, #003A70);
  outline-offset: 2px;
}

.portal-totop:hover {
  background: var(--admin-primary-dark, #003A70);
}

@media (max-width: 560px) {
  .portal-totop {
    right: 1rem;
    bottom: 1rem;
  }
}

/* ------------------------------------------------------------- barre haute */

/* Le lien de session vit ici plutot qu'au centre de la page : voir le commentaire
   de portal_home.php. La largeur suit celle de la coque pour que le lien s'aligne
   sur le bord droit du contenu, et non sur celui de l'ecran. */
.portal-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  /* Meme piege que la coque : sans `width`, cette barre se reduisait a la largeur
     du lien (140 px) et le « a droite » ne voulait plus rien dire. */
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 1.25rem 1.5rem 0;
}

/* Le bloc de droite de la barre haute : langue puis session, dans cet ordre — on
   choisit sa langue avant de decider de se connecter. */
.portal-topbar__actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.portal-langs--top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.875rem;
}

.portal-lang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  min-height: 44px;
  color: var(--admin-muted, #6b7280);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.portal-lang:hover,
.portal-lang:focus-visible {
  color: var(--admin-primary, #004D95);
  text-decoration: underline;
}

/* La langue courante se marque par la couleur de marque ET la graisse : jamais par
   la couleur seule, qui ne dit rien a qui ne la distingue pas. */
.portal-lang.is-active {
  color: var(--admin-primary, #004D95);
}

.portal-langs__sep {
  width: 1px;
  height: 12px;
  background: var(--admin-border, #d8dde3);
}

/* LE LOGO DE L'UNIVERSITE EN TETE, comme sur ses propres sites : c'est un portail
   ULB avant d'etre un portail Helpers. Hauteur fixe et largeur automatique, le
   fichier faisant 1621x505 — imposer les deux le deformerait. */
.portal-topbar__ulb {
  display: block;
  height: 40px;
  width: auto;
}

@media (max-width: 560px) {
  .portal-topbar__ulb {
    height: 30px;
  }
}

/* -------------------------------------------------- accueil sans contenu public */

/* Cet etat n'est pas une erreur : il dit qu'aucun contenu n'a encore ete publie.
   Il porte donc la couleur de la page, jamais celle d'un avertissement — et
   surtout une SUITE, pour que la page cesse d'etre un cul-de-sac. */
.portal-blank {
  padding: 2rem 1.5rem;
  text-align: center;
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
  box-shadow: var(--admin-shadow-soft, 0 1px 2px rgba(31, 41, 51, 0.06));
}

.portal-blank__title {
  margin: 0 0 0.5rem;
  font-weight: 600;
  color: var(--admin-text, #1f2933);
}

.portal-blank__hint {
  margin: 0 auto;
  color: var(--admin-muted, #6b7280);
}

/* Le bouton central (.portal-blank__action / __cta) a ete retire le 2026-09-07 :
   l'invitation a se connecter est un lien dans la phrase, comme dans les branches
   « aucun resultat » et « resultats ». Motif complet dans la vue. */

/* -------------------------------------------------------------- résultats */

.portal-group {
  margin-bottom: 2rem;
}

.portal-group__title {
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--admin-muted, #6b7280);
  margin: 0 0 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--admin-border, #d8dde3);
}

.portal-list {
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.portal-item {
  padding: 1.25rem 1.5rem;
  margin: 0;
}

.portal-item + .portal-item { border-top: 1px solid var(--admin-border, #d8dde3); }

.portal-item__link {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--admin-primary, #004D95);
  text-decoration: none;
}

.portal-item__link:hover {
  text-decoration: underline;
}

.portal-item__details {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
  margin: .75rem 0 0;
  font-size: 0.8125rem;
}

.portal-item__details > div { display: flex; align-items: center; gap: 0.5rem; }
.portal-item__details dt { display: flex; align-items: center; gap: 0.375rem; color: var(--admin-muted, #596575); font-weight: 400; }
.portal-item__details dd { margin: 0; color: var(--admin-text, #283747); }
.portal-icon { width: 1.125rem; height: 1.125rem; flex: 0 0 auto; }
.portal-item__source dd { font-weight: 600; }
.portal-item__type dd { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.625rem; border-radius: 5px; font-weight: 600; background: var(--admin-primary-soft, #e8f2fb); color: var(--admin-primary, #004D95); }
.portal-item__type--book dd { background: var(--portal-book-bg, #edf5ef); color: var(--portal-book-text, #286041); }
.portal-item__type--video dd { background: var(--portal-video-bg, #f2edf8); color: var(--portal-video-text, #69418b); }
.portal-item__type--link dd { background: var(--admin-warning-soft, #fff3e3); color: var(--portal-link-text, #805014); }
.portal-item__details .portal-item__categories { flex-basis: 100%; align-items: baseline; padding-top: 0.25rem; }
.portal-item__categories dd { line-height: 1.6; overflow-wrap: anywhere; }
.portal-item__link { display: inline-block; line-height: 1.45; }
.portal-item__link:focus-visible { outline: 2px solid var(--admin-primary, #004D95); outline-offset: 4px; }

@media (max-width: 560px) {
  .portal-item__details { gap: 0.75rem; }
  .portal-item__details > div { flex-basis: 100%; flex-wrap: wrap; }
  .portal-item__details .portal-item__categories { display: block; }
  .portal-item__categories dt { margin-bottom: 0.25rem; }
}

/* .portal-item__excerpt retire le 2026-09-07 : la liste ne rend plus d'extrait, le
   portail aiguille vers la fiche. Le champ `excerpt` reste dans l'index, ou la
   recherche continue de le lire. */

/* --------------------------------------------------------- réponse vide */

.portal-empty {
  padding: 2rem 1rem;
  text-align: center;
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
}

.portal-empty__title {
  margin: 0 0 0.5rem;
  font-weight: 600;
  color: var(--admin-text, #1f2933);
}

.portal-empty__hint {
  margin: 0;
  color: var(--admin-muted, #6b7280);
}

/* ---------------------------------------------------------- services */

.portal-services__title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
  color: var(--admin-text, #1f2933);
}

.portal-services__hint {
  font-size: .9rem;
  margin: 0 0 1rem;
  color: var(--admin-muted, #6b7280);
}

.portal-services__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.portal-service {
  min-height: 44px;
  font-size: .9rem;
  padding: 0.5rem 0.875rem;
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
}

.portal-service__name {
  font-weight: 600;
  color: var(--admin-text, #1f2933);
}

/* ------------------------------------------------------------- mobile */

@media (max-width: 560px) {
  /* UN SEUL RETRAIT POUR TOUTE LA PAGE. Mesure du 2026-09-05 a 375 px : la coque
     passait a 1 rem tandis que la barre haute et le pied de page restaient a
     1,5 rem — trois blocs, deux verticales, 8 px d'ecart. C'est peu, et c'est
     exactement ce qui se voit : le regard suit un bord, pas une valeur. */
  .portal-shell {
    padding: 2rem 1rem 3rem;
  }

  .portal-topbar {
    padding: 1rem 1rem 0;
  }

  .portal-search__row {
    flex-direction: column;
  }

  .portal-search__submit {
  min-height: 48px;
    width: 100%;
  }
}

/* ------------------------------------------------------------ session */

/* DEUX « Se connecter » COEXISTENT, et c'est voulu : celui de la barre haute est un
   acces PERMANENT, celui de la carte est l'action du MOMENT quand il n'y a rien a
   chercher. Ce qui genait, c'est qu'ils avaient le meme poids visuel et se
   concurrencaient. L'acces permanent s'efface donc — meme discretion que le
   selecteur de langue, a cote duquel il vit. */
.portal-session__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  /* Le gris attenue tombait a 4,36:1 sur le fond de page, sous le minimum de 4,5.
     La discretion vient donc du POIDS et de l'ABSENCE de couleur de marque, pas
     d'un gris trop clair : le bleu signale l'action, le neutre la navigation. */
  color: var(--admin-text, #1f2933);
  font-weight: 500;
  text-decoration: none;
}

.portal-session__link:hover,
.portal-session__link:focus-visible {
  color: var(--admin-primary, #004D95);
  text-decoration: underline;
}

/* Dans une notice, en revanche, le lien EST l'action proposee : il garde la couleur
   de marque.

   `nowrap` N'EST PAS COSMETIQUE ICI. Ces liens closent une phrase bornee a 58ch, et
   « Se connecter » tombait pile sur la fin de ligne : le rendu coupait le lien en
   deux, « Se » d'un cote et « connecter » centre sur la ligne suivante. Mesure du
   2026-09-07 a 1440 px, invisible en relisant la feuille. Le lien passe donc a la
   ligne d'un seul bloc plutot que d'etre scinde. Sans risque pour les deux libelles
   qui portent cette classe — « Se connecter » et « Tous les services » sont courts ;
   a reexaminer si un libelle long la recevait un jour. */
.portal-notice__link {
  color: var(--admin-primary, #004D95);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.portal-notice__link:hover {
  text-decoration: underline;
}

/* -------------------------------------------------- recherches fréquentes */

.portal-frequent {
  margin-bottom: 2rem;
}

.portal-frequent__title {
  font-size: 1.125rem;
  font-weight: 700;
  margin: 0 0 0.75rem;
  color: var(--admin-text, #1f2933);
}

.portal-frequent__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.portal-frequent__link {
  display: inline-block;
  padding: 0.375rem 0.875rem;
  font-size: 0.9375rem;
  color: var(--admin-primary-dark, #003A70);
  background: var(--admin-primary-soft, #e8f2fb);
  border-radius: var(--admin-radius, 10px);
  text-decoration: none;
}

.portal-frequent__link:hover {
  background: var(--admin-primary, #004D95);
  color: #ffffff;
}

/* ------------------------------------------------------- services cliquables */

.portal-service {
  min-height: 44px;
  font-size: .9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.875rem;
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.portal-service:hover {
  border-color: var(--admin-primary, #004D95);
  box-shadow: var(--admin-shadow-soft, 0 1px 3px rgba(15, 23, 42, 0.08));
}

.portal-service .portal-icon {
  color: var(--admin-primary, #004D95);
}

.portal-service__count {
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.0625rem 0.4375rem;
  color: var(--admin-muted, #6b7280);
  background: var(--admin-surface-soft, #eef1f5);
  border-radius: var(--admin-radius-sm, 6px);
}

.portal-service:hover .portal-service__count {
  color: var(--admin-primary-dark, #003A70);
  background: var(--admin-primary-soft, #e8f2fb);
}

/* ----------------------------------------------------------- pied de page */

/* Style propre au portail : .footer-slim vit dans layout.css, que cette page ne
   charge pas. Le reprendre par la classe ne produirait aucun style. */
/* Bandeau institutionnel, sur le modele du pied de page de l'Universite : langues
   et mention legale a gauche, reseaux a droite. Fond de marque plutot que blanc —
   il ferme la page au lieu de la prolonger. */
.portal-footer {
  flex: 0 0 auto;
  /* Le retrait horizontal est porte par __inner, pas ici : sinon le bandeau, qui
     occupe toute la largeur, decalait son contenu de 24 px vers l'exterieur par
     rapport au texte de la page. Mesure : bord a 200 px contre 224 px pour la
     coque. Un ecart de cet ordre ne se voit pas isolement, mais il casse la
     verticale que l'oeil suit d'un bloc a l'autre. */
  padding: 1.25rem 0;
  font-size: 0.875rem;
  color: #ffffff;
  background: var(--admin-primary, #004D95);
}

/* Meme largeur ET meme retrait que .portal-shell : le texte du pied de page tombe
   exactement sous celui de la page. */
.portal-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

.portal-footer__left {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.portal-footer__legal {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  opacity: 0.9;
}

.portal-footer__social {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.portal-footer__follow {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 0.75rem;
}

.portal-footer__networks {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 36 px de cible tactile : en deca, ces icones deviennent difficiles a viser au
   pouce, et elles vivent au bas d'une page que l'on consulte souvent sur mobile. */
.portal-footer__network {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  color: #ffffff;
  border-radius: var(--admin-radius-sm, 6px);
}

/* Survol : un ton plus fonce de la marque, jamais un voile blanc en dur — le
   garde-fou des tokens le refuse a juste titre, et le token suit le theme. */
.portal-footer__network:hover,
.portal-footer__network:focus-visible {
  background: var(--admin-primary-dark, #003A70);
}

/* ── MOBILE : empiler ne suffit pas, il faut un RYTHME ────────────────────────
   Mesure du 2026-09-05 a 375 px : les trois blocs tombaient a 5 px puis 15 px
   d'ecart. Deux valeurs proches et sans regle donnent l'impression d'un tas —
   l'oeil ne sait plus ce qui va ensemble.

   La regle appliquee : la mention legale d'un cote, les reseaux de l'autre,
   nettement detaches, avec un filet qui rend la separation explicite. Tout reste
   cale sur la meme verticale a gauche, comme en desktop — on ne change pas
   d'alignement en changeant de taille d'ecran.

   Le selecteur de langue faisait partie du groupe de gauche jusqu'au 2026-09-07 ;
   il ne vit plus qu'en barre haute. `.portal-footer__left` garde sa colonne : elle
   accueillerait d'eventuels liens institutionnels. */
@media (max-width: 560px) {
  /* Ce retrait doit vivre ICI et pas dans la media query du haut du fichier :
     `.portal-footer__inner` est defini plus bas qu'elle, et UNE MEDIA QUERY
     N'AJOUTE AUCUNE SPECIFICITE — a egalite, c'est la derniere regle du fichier
     qui gagne. Pose plus haut, ce padding etait simplement ignore (constate). */
  .portal-footer__inner {
    padding: 0 1rem;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .portal-footer__left {
    gap: 0.5rem;
  }

  .portal-footer__social {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
    /* Sous 340 px, « Suivez-nous » et cinq cibles de 36 px ne tiennent plus sur
       une ligne : le libelle passe au-dessus plutot que de comprimer les icones. */
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
  }
}

.portal-empty__members {
  margin: 1rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--admin-border, #d8dde3);
  color: var(--admin-muted, #6b7280);
}

/* Pagination et filtre : controles de navigation, sans dependance JavaScript. */
.portal-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--admin-primary, #004D95);
  background: var(--admin-primary-soft, #e8f2fb);
  margin: -1rem 0 1.5rem;
  color: var(--admin-text, #1f2933);
  overflow-wrap: anywhere;
}

/* La pagination arrive apres six ecrans de resultats : elle doit se DETACHER de la
   liste, sinon elle se lit comme une carte de plus. Un filet et de l'air au-dessus
   suffisent — c'est ce qui manquait pour qu'on la voie. */
.portal-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--admin-border, #d8dde3);
}

/* Le rang courant est l'information la plus utile de ce bloc : il se lit avant les
   deux fleches, donc il porte la graisse. */
.portal-pagination [aria-current="page"] {
  font-weight: 600;
  color: var(--admin-text, #1f2933);
}

.portal-pagination__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.5rem 1rem;
  color: var(--admin-primary, #004D95);
  background: var(--admin-surface, #ffffff);
  border: 1px solid var(--admin-border, #d8dde3);
  border-radius: var(--admin-radius, 10px);
  text-decoration: none;
}

.portal-pagination__link:hover {
  text-decoration: underline;
}

.portal-pagination__link:focus-visible {
  outline: 2px solid var(--admin-primary, #004D95);
  outline-offset: 2px;
}

/* Les resultats rapprochent la recherche de la liste sans changer l'accueil. */
.portal-shell--results { padding-top: 1.5rem; }
.portal-shell--results .portal-head { margin-bottom: 1.5rem; }
.portal-shell--results .portal-logo { height: 32px; margin-bottom: 0.5rem; }

/* Suggestions : une liste compacte, avec un repère clavier distinct du survol. */
.portal-suggestions { margin-top: .5rem; padding: .25rem; border: 1px solid var(--admin-border, #dce3ed); border-radius: 12px; background: var(--admin-surface, #fff); max-height: min(26rem, 55vh); overflow-y: auto; }
.portal-suggestions[hidden] { display: none; }
.portal-suggestions__item, .portal-suggestions__all { display: flex; flex-direction: column; justify-content: center; gap: .1rem; padding: .5rem .75rem; min-height: 44px; color: var(--admin-primary, #004D95); text-decoration: none; overflow-wrap: anywhere; border-radius: 4px; }
.portal-suggestions__item strong { font-size: .95rem; font-weight: 400; line-height: 1.4; color: var(--admin-text, #1f2937); }
.portal-suggestions__group + .portal-suggestions__group { border-top: 1px solid var(--admin-border-light, #edf0f4); }
.portal-suggestions__group { padding: .4rem 0; }
.portal-suggestions__heading { display: flex; align-items: center; gap: .5rem; margin: 0; padding: .45rem .85rem; font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--admin-text-muted, #64748b); }
.portal-suggestions__group .portal-suggestions__item { padding: .45rem 1rem .45rem 2.35rem; }
.portal-suggestions__item span { font-size: .75rem; line-height: 1.35; color: var(--admin-text-muted, #64748b); padding-left: 0; }
.portal-suggestions a:hover { background: var(--admin-primary-soft, #eaf3fb); }
.portal-suggestions a:focus-visible { background: var(--admin-primary-soft, #eaf3fb); outline: 1px solid var(--admin-primary, #004D95); outline-offset: -1px; }
.portal-suggestions__all { font-size: .8rem; font-weight: 600; position: sticky; bottom: 0; background: var(--admin-surface, #fff); border-top: 1px solid var(--admin-border, #dce3ed); border-radius: 0; }
.portal-suggestions__heading .portal-icon { width: 1rem; height: 1rem; flex-shrink: 0; }
.portal-suggest-status { color: var(--admin-text-muted, #64748b); font-size: .9rem; }
.portal-suggest-status:empty { display: none; }

.portal-home { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.portal-home:focus-visible { outline: 2px solid var(--admin-primary, #004D95); outline-offset: 4px; border-radius: 4px; }

@media (max-width: 560px) {
  .portal-topbar__actions { gap: .4rem; }
  .portal-langs--top { gap: .1rem; }
  .portal-item { padding: 1rem; }
  .portal-title { letter-spacing: -.02em; }
}

@media (max-width: 360px) {
  .portal-topbar { gap: .5rem; }
  .portal-topbar__ulb { height: 24px; }
  .portal-session__link { font-size: .8rem; white-space: nowrap; }
  .portal-lang { min-width: 28px; }
}
