/* ══════════════════════════════════════════════════════════════════
   ROARY — s'adapter à la fenêtre, quelle qu'elle soit

   Le site était réglé pour quelques largeurs prévues : téléphone,
   tablette, grand écran. Entre ces largeurs — et c'est là qu'on se
   trouve dès qu'on redimensionne une fenêtre Chrome à la main — rien
   ne garantissait que le contenu tienne.

   Ce fichier ne redessine rien. Il retire les causes structurelles de
   débordement, celles qui produisent une barre de défilement
   horizontale ou une colonne coupée :

   1. En CSS Grid et en Flexbox, un enfant refuse par défaut de
      descendre sous la largeur de son contenu (`min-width:auto`). Un
      nom long, une adresse, un tableau : et toute la page s'élargit
      au-delà de la fenêtre. C'est de loin la cause la plus fréquente,
      et la plus invisible.

   2. Les grilles à nombre de colonnes fixe ne se replient pas. Trois
      colonnes dans 400 pixels donnent trois colonnes de 130 pixels.

   3. `100vh` ne correspond pas à la hauteur visible quand une barre
      d'outils apparaît ou disparaît.

   Il se charge en dernier, après toutes les autres feuilles.
   ══════════════════════════════════════════════════════════════════ */


/* ── 1. Rien ne dépasse la fenêtre ─────────────────────────────── */

html{
  /* La place de la barre de défilement est réservée en permanence :
     sans cela, la page se décale latéralement dès qu'elle devient
     assez longue pour la faire apparaître. */
  scrollbar-gutter: stable;
}

body{
  overflow-x: clip;   /* `clip` et non `hidden` : ne crée pas de contexte de défilement */
  max-width: 100%;
}

/* Un mot sans espace — une adresse, un identifiant, un nom composé —
   ne doit jamais élargir son conteneur. */
p, li, td, th, h1, h2, h3, h4, dd, dt,
.comment-text, .txt, .meta, .quoi, .detail{
  overflow-wrap: anywhere;
}

/* Les menus sont exclus de la règle précédente. Un libellé de
   navigation doit rester lisible d'un coup d'œil ; coupé en syllabes
   ou en lettres, il cesse d'être un repère et devient une énigme. */
.rail *, .pp-nav *, nav *, .navlinks *{
  overflow-wrap: normal;
}

img, svg, video, canvas, iframe{ max-width: 100%; }
img, video{ height: auto; }

table{ max-width: 100%; }
pre, code{ overflow-x: auto; max-width: 100%; }


/* ── 2. Les enfants de grille et de flex peuvent rétrécir ───────── */

/* La règle décisive. Sans elle, tout ce qui suit est inutile : un seul
   enfant récalcitrant suffit à élargir la page entière. */
.app > *,
.cols > *,
.col > *,
.main > *,
.panel > *,
.sec-h > *,
.stats-grid > *,
.member-grid > *,
.estab-grid > *,
.fav-grid > *,
.card-metrics > *,
.member-metrics > *,
.member-tags > *,
.erow > *,
.member-erow > *{
  min-width: 0;
}

/* Les zones de texte et les champs débordent volontiers de leur
   colonne : ils ont une largeur intrinsèque par défaut. */
input, select, textarea{ max-width: 100%; }


/* ── 3. Le rail suit la fenêtre ─────────────────────────────────
   Deux cent trente-six pixels fixes, c'est confortable à 1400 et
   étouffant à 950 — là où la colonne de travail n'a plus que 700
   pixels pour deux colonnes de contenu. */

/* Le rail a trois formes selon la largeur :
     — sous 768 px  : masqué, remplacé par la barre et le tiroir mobiles ;
     — 768 à 1024   : colonne d'icônes étroite, libellé sous l'icône ;
     — au-delà      : rail complet, libellé à côté de l'icône.

   Les libellés débordaient parce qu'ils étaient posés en texte nu dans
   une entrée en flex : le navigateur en fait un « élément anonyme »,
   une boîte que le CSS ne peut ni nommer ni contraindre. Elle gardait
   donc la largeur de son mot le plus long. Chaque libellé est
   désormais enveloppé dans `.rail-lbl`, et tout se pilote d'ici. */


/* ── Ce qui vaut pour toutes les largeurs ── */

/* `overflow-x: hidden` sur le rail rognerait la pastille de complétude
   posée sur l'avatar. Le rail défile déjà verticalement ; l'horizontal
   n'a plus lieu d'être maintenant que les libellés tiennent. */
.rail{ min-width: 0; }
.rail nav{ min-width: 0; }
.rail a.it{ min-width: 0; }
.rail a.it .ic{ flex-shrink: 0; }

/* Le libellé prend toute la place que l'icône lui laisse.

   `display: block` est essentiel. Ma version précédente utilisait
   `-webkit-box` avec `-webkit-line-clamp` pour limiter le nombre de
   lignes — et c'est ce qui écrasait le menu : la largeur naturelle
   d'une boîte `-webkit-box` verticale est considérée comme nulle par
   le navigateur. Placée dans une ligne en flex, elle se réduisait donc
   à deux caractères, quelle que soit la place disponible.

   On laisse le texte revenir à la ligne normalement. Deux lignes pour
   « Trouver mon établissement » ne gênent personne, et rien n'a de
   hauteur fixe dans ce menu. */
.rail a.it .rail-lbl{
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.25;
  overflow-wrap: normal;   /* jamais de coupure au milieu d'un mot */
  word-break: keep-all;
  hyphens: none;
}

/* Le compte en pied de rail. */
.rail .me{ min-width: 0; }
.rail .me > div{ min-width: 0; }
.rail .me .n{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* ── Deux formes, plus trois ──

   Le rail compact en colonne d'icônes était une fausse bonne idée : à
   quatre-vingts pixels, un libellé de deux mots ne tient pas, et tout
   ce qu'on gagne en surface on le perd en lisibilité. On l'abandonne.

   Il ne reste donc que deux états, tranchés :
     — jusqu'à 1024 px : le hamburger et son tiroir, déjà là et déjà
       éprouvés, qui affichent les libellés en entier ;
     — à partir de 1025 : le rail complet.

   Une seule frontière, aucune zone intermédiaire à régler. */

@media (max-width: 1024px){
  .app{ grid-template-columns: 1fr !important; }
  .rail{ display: none !important; }
  .mobile-bar{ display: flex !important; }
}


/* ── Rail complet, à partir de 1025 px ──
   Sa largeur suit la fenêtre, avec un plancher qui garantit qu'un
   libellé de deux mots tient sans se couper. */

@media (min-width: 1025px){
  .app{ grid-template-columns: clamp(198px, 16vw, 240px) 1fr; }
  .mobile-bar{ display: none !important; }

  /* L'entrée passe en grille plutôt qu'en flex.

     C'est une décision de fiabilité, pas de goût. En flex, la largeur
     d'un enfant se déduit de son contenu, et cette déduction dépend de
     propriétés qui interagissent mal — c'est ce qui a réduit les
     libellés à deux caractères. En grille, `auto 1fr` est un ordre :
     l'icône prend ce qu'il lui faut, le libellé prend tout le reste.
     Aucun calcul de largeur naturelle n'intervient. */
  .rail a.it{
    display: grid;
    /* Trois colonnes : l'icône, le libellé, la pastille. La troisième
       ne coûte rien quand elle est vide — mais sans elle, la pastille
       de notifications passerait à la ligne suivante, sous le texte. */
    grid-template-columns: auto 1fr auto;
    align-items: start;
    column-gap: 12px;
  }
  .rail a.it .ic{ margin-top: 2px; }
  .rail a.it .rail-lbl{ min-width: 0; }
  .rail a.it .badge{ margin: 2px 0 0; align-self: start; }
}


/* ── Le tiroir mobile ──
   Même enveloppe, mêmes garanties. */

.pp-nav a.pp-i{ min-width: 0; }
.pp-nav a.pp-i .rail-lbl{
  display: block; flex: 1 1 auto; min-width: 0; overflow-wrap: normal;
}


/* ── 4. Les grilles de cartes suivent la place disponible ───────
   Prudence délibérée ici : les autres grilles du site ont déjà leurs
   propres points de rupture, réfléchis page par page. Les écraser
   depuis une feuille chargée en dernier reviendrait à défaire des
   décisions prises en connaissance de cause — et c'est comme cela
   qu'on répare une largeur en cassant les trois autres.

   Seules les grilles de cartes sont reprises, parce qu'elles ont un
   plancher de 280 pixels : dans une fenêtre de 640, elles n'affichent
   que deux cartes en laissant du vide à droite. Le `min()` permet à la
   cellule de descendre sous le plancher quand la fenêtre l'exige,
   plutôt que de déborder. */

.member-grid,
.estab-grid{
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}

/* ── 5. La hauteur suit la fenêtre ──────────────────────────────
   `100vh` ignore les barres d'outils qui apparaissent et
   disparaissent. `dvh` suit la hauteur réellement visible ; la règle
   précédente reste comme repli pour les navigateurs anciens. */

@supports (height: 100dvh){
  .app{ min-height: 100dvh; }
  .rail{ height: 100dvh; }
  .hero{ height: 100dvh; }
}

/* Une fenêtre basse ne doit pas écraser le bandeau d'accueil au point
   de superposer le nom et la phrase. */
@media (max-height: 620px){
  /* Le hero est un conteneur flex en ligne : rendre le bas statique
     sans changer de direction le placerait à côté du nom, pas dessous.
     C'est le genre de détail qui transforme une correction en dégât. */
  .hero{
    height: auto; min-height: 560px; padding: 96px 0 72px;
    flex-direction: column; justify-content: center;
  }
  .hero-bas{ position: static; margin-top: 40px; width: 100%; }
  .scroll-cue{ display: none; }
}


/* ── 6. Les modales tiennent dans la fenêtre ────────────────────
   Une fenêtre courte transformait la fenêtre de dialogue en piège :
   son bas, boutons compris, passait sous le bord de l'écran. */

.score-modal,
.rc-boite,
.ri-boite,
.signal-modal{
  max-height: min(86dvh, 86vh);
  overflow-y: auto;
}


/* ── 7. Zone intermédiaire : rail présent, place comptée ────────
   De 901 à 1180 pixels, le rail occupe déjà sa largeur et la colonne
   de travail se partage en deux. On lui rend un peu d'air. */

@media (min-width: 901px) and (max-width: 1180px){
  .main{ padding-left: clamp(16px, 2.4vw, 32px); padding-right: clamp(16px, 2.4vw, 32px); }
  .cols{ gap: 12px; }
  .panel{ padding: 20px 18px 18px; }
}


/* ── 8. La carte d'identité tient dans sa largeur ───────────────
   Elle aligne l'avatar, l'identité et la colonne d'actions sur une
   ligne. Le repli existe déjà (`flex-wrap`), mais le bloc d'identité
   réclame 220 pixels au minimum : sous 620 pixels de colonne utile,
   les trois éléments ne peuvent plus cohabiter et la colonne
   d'actions se retrouve écrasée contre le bord. */

@media (max-width: 1024px){
  .idcard .body{ padding: 24px 22px 22px; gap: 18px; }
  .idcard .who{ min-width: 180px; }
}

@media (max-width: 760px){
  .idcard .body{ padding: 20px 18px 18px; gap: 14px; }
  .idcard .who{ min-width: 100%; }
  /* Les sélecteurs de statut et de contrat prennent toute la largeur
     plutôt que de se serrer dans une colonne de quatre-vingts pixels. */
  .idcard .actions{ width: 100%; }
  .idcard .actions .status-badge{ width: 100%; }
  .idcard .actions select{ width: 100%; }
}


/* ── 9. Les en-têtes de section respirent ───────────────────────
   `sec-h` porte un titre et parfois une note à droite. Sur une
   colonne étroite, la note passe dessous au lieu de comprimer le
   titre jusqu'à le couper. */

@media (max-width: 900px){
  .sec-h{ flex-wrap: wrap; gap: 6px; }
  .sec-note{ flex-basis: 100%; }
  .pk{ flex-wrap: wrap; gap: 8px; }
}


/* ── 10. Les barres de commandes se replient ────────────────────
   Filtres de recherche, actions de carte, lignes de formulaire :
   partout où des éléments sont posés en ligne sans autorisation de
   passer à la ligne, une fenêtre étroite produit un débordement. */

.filters, .filters-more, .card-actions, .chip-add-row,
.mission-actions, .tagline-actions, .fav-actions{
  flex-wrap: wrap;
}

@media (max-width: 560px){
  .card-actions{ gap: 8px; }
  .card-actions .member-go,
  .card-actions .estab-go{ flex: 1 1 100%; }
  .chip-add-row input{ flex: 1 1 100%; }
}
