/* =========================================================================
 * BAZA-S301 — ERGONOMIE MOBILE : barre d'onglets, listes, séparateurs.
 *
 * POURQUOI CETTE FEUILLE VIT DANS `public/` (et pas dans `src/index.css`)
 * ---------------------------------------------------------------------
 * `apps/app/src/index.css` est la COQUE GELÉE S141 : son empreinte SHA-256
 * est épinglée par la porte `check:app-s141-real-only-no-global-demo`. Une
 * feuille servie depuis `public/` et liée par `<link>` n'est PAS fusionnée
 * par Vite dans `assets/index-*.css` : l'empreinte gelée reste donc intacte
 * (méthode S300 déjà éprouvée).
 *
 * CONSÉQUENCE DE CASCADE — LA RÈGLE À NE JAMAIS OUBLIER ICI
 * --------------------------------------------------------
 * Dans `index.html`, les feuilles `public/` sont liées AVANT le bundle : sur
 * le live, `assets/index-*.css` (la coque gelée) charge EN DERNIER. À
 * spécificité ÉGALE, c'est donc la coque qui gagne, jamais cette feuille.
 * Toute règle ci-dessous doit donc l'emporter par SPÉCIFICITÉ, jamais par
 * l'ordre des sources. C'est la raison des sélecteurs volontairement longs
 * (`ul.real-demo-samples > li.real-nearby-item`, `.tabbar .tab .tab-icon`…).
 * Corollaire : `@media` n'ajoute AUCUNE spécificité — chaque comportement
 * d'écran étroit est RE-DÉCLARÉ explicitement, jamais supposé hérité.
 *
 * MESURES DE DÉPART (harnais `scripts/mesure-app-s301-listes-navigation.ts`,
 * relevé `docs/visual-evidence/s301/mesures-baseline.json`, moteur Chromium,
 * 8 largeurs) — chaque augmentation ci-dessous part d'un CHIFFRE MESURÉ :
 *   · cible tactile d'un onglet ....... 32,88 px de haut  (exigence ≥ 48)
 *   · icône d'onglet (visuel) ......... 21,6 × 19,8 px    (cible ~28-30)
 *   · libellé d'onglet ................ 10,88 px
 *   · vignette des trois listes ....... 48 × 48 px        (cible ~60-64)
 *   · heure de conversation ........... 13 px
 *   · badge de type ................... 12 px
 *   · séparateur ...................... bord à bord, il traverse la photo
 *
 * AUCUNE identité visuelle tierce n'est reprise : ni composant, ni icône, ni
 * couleur, ni animation. Les icônes restent les DESSINS CSS historiques de
 * Baza, simplement agrandis ; les couleurs restent les variables du thème.
 * ========================================================================= */

/* =========================================================================
 * §3 — BARRE D'ONGLETS (Profils / Messages / Groupes / Moi)
 * =========================================================================
 * La compaction venait de la coque elle-même : S170 (`padding: 3px 4px 1px`)
 * puis S172 (`padding: 2px 4px 0; gap: 0; font-size: 0.68rem` et
 * `.tab-icon { transform: scale(0.9) }`). Ces règles NE SONT PAS modifiées :
 * elles sont surclassées ici.
 *
 * `.tabbar` n'est PAS touchée : son `padding-bottom: env(safe-area-inset-bottom)`
 * (S129) reste l'unique gestion de l'encoche, donc rien à re-prouver de ce côté.
 */

/* Cible tactile : 52 px de haut × (largeur d'écran / 4) — ≥ 48 × 48 partout,
   y compris à 320 px de large (80 px par onglet). Le calcul de la hauteur :
   8 (haut) + 22 (boîte d'icône) + 3 (gouttière) + ~12,5 (libellé) + 6 (bas)
   ≈ 51,5 ⇒ `min-height: 52px` borne la cible sans gonfler la barre (53 px
   avec le filet, contre 33,88 px mesurés — une barre native reste autour de
   49-56 px : elle n'est donc pas « inutilement haute »). */
.tabbar .tab {
  min-height: 52px;
  gap: 3px;
  padding: 8px 4px 6px;
  font-size: 0.78rem; /* 12,48 px — libellé lisible (avant : 10,88 px) */
  /* Contraste du libellé INACTIF : `--text-faint` (#8a978d) sur le fond gris
     #f0f2f5 de la barre plafonne à ~3,0:1. Ce gris-vert plus dense monte à
     ~6,3:1 (AA large et AA texte normal) sans changer l'identité de Baza. */
  color: #4f5b52;
}

/* Icône : la boîte `.tab-icon` fait 24 × 22 px, mais le glyphe est dessiné en
   pixels FIXES par ses `::before`/`::after`. Agrandir la boîte n'agrandirait
   donc PAS le dessin : le seul levier correct est l'échelle. 24 × 22 × 1,28
   ⇒ 30,72 × 28,16 px de visuel (mesuré par `getBoundingClientRect`, qui tient
   compte des transformations — la mesure de départ 21,6 × 19,8 valait bien
   24 × 22 × 0,9). La boîte de mise en page reste 24 × 22 : aucune secousse de
   gabarit au changement d'onglet.

   POURQUOI 1,28 ET NON 1,25. La boîte n'est pas carrée. À 1,25 la LARGEUR
   atteignait bien 30 px, mais la HAUTEUR plafonnait à 27,5 px — sous les 28 px
   demandés. La porte S301 (contrôle H2) mesure les DEUX côtés et refusait :
   1,28 amène le petit côté à 28,16 px, la fourchette « ~28-30 » du mandat étant
   ainsi tenue sur les deux axes. La hauteur de barre est INCHANGÉE : une
   transformation ne modifie pas la mise en page. */
.tabbar .tab .tab-icon {
  margin: 0; /* annule le `margin: -1px 0` de compaction S172 */
  transform: scale(1.28);
}

/* État actif IMMÉDIATEMENT identifiable et JAMAIS porté par la seule couleur :
   accent supérieur élargi + libellé en gras + `aria-current` côté composant. */
.tabbar .tab.is-active {
  color: var(--green);
}
.tabbar .tab.is-active .tab-label {
  font-weight: 800;
}
.tabbar .tab.is-active::before {
  width: 34px;
  height: 4px;
}

/* Badge de non-lus : recalé sur le coin haut-droit de l'icône AGRANDIE
   (demi-largeur 15 px au lieu de 10,8) — il effleure le bord, jamais le
   centre du dessin. */
.tabbar .tab .tab-badge {
  top: 4px;
  margin-left: 9px;
}

/* Écrans étroits (≤ 360 px : 80 px par onglet, 72 px utiles). RE-DÉCLARÉ
   explicitement — une media query n'ajoute aucune spécificité et ne saurait
   « hériter » du bloc ci-dessus face à la coque gelée. Libellé à 12 px et
   gouttières resserrées : « Messages », le plus long des quatre, mesure alors
   ~66 px pour 76 px utiles ⇒ aucun mot coupé, aucune ellipse. */
@media (max-width: 360px) {
  .tabbar .tab {
    min-height: 52px;
    gap: 3px;
    padding: 8px 2px 6px;
    font-size: 0.75rem; /* 12 px */
    color: #4f5b52;
  }
  .tabbar .tab.is-active {
    color: var(--green);
  }
}

/* =========================================================================
 * §4 — LES TROIS LISTES (Profils / Messages / Groupes)
 * =========================================================================
 * Harmonisées SANS être rendues identiques : la vignette, la typographie et
 * le séparateur suivent la même grammaire ; la composition de chaque ligne
 * (distance et âge en Profils, heure et aperçu en Messages, rôle et membres
 * en Groupes) reste celle de sa liste.
 */

/* --- Vignettes : 48 → 60 px (bas de la fourchette ~60-64 visée) ----------
   Le ratio est structurellement préservé : la vignette est un CARRÉ arrondi
   en cercle, la photo est peinte en `object-fit: cover` (`.avatar-photo-img`)
   ⇒ recadrage propre, jamais d'étirement. Le repli initiales est centré par
   le flex historique et sa police suit la taille du disque. */
.real-nearby-item .avatar,
li.conversation .avatar,
.group-row .avatar {
  width: 60px;
  height: 60px;
  font-size: 1.3rem; /* 20,8 px — initiales lisibles sur un disque de 60 px */
}
/* Avatar de GROUPE : sa police propre (0,95rem) doit suivre le même saut. */
.group-row .avatar.group-avatar {
  font-size: 1.15rem;
}
/* Pastille de présence : elle grandit avec le disque et reste sur le liseré
   bas-droit — elle ne couvre jamais le centre (le visage). */
.real-nearby-item .avatar-presence,
li.conversation .avatar-presence,
.group-row .avatar-presence {
  width: 15px;
  height: 15px;
  right: 2px;
  bottom: 2px;
}

/* --- Typographie : hausse LÉGÈRE, hiérarchie préservée -------------------
   Mesuré avant : pseudo 20 px > aperçu 19 px > distance/âge 14 px > heure
   13 px > badge 12 px. La hiérarchie pseudo/aperçu ne tenait qu'à 1 px : le
   pseudo passe à 21 px et l'aperçu reste à 19 px (déjà confortable), ce qui
   REND la hiérarchie lisible au lieu de l'aplatir. Les métadonnées, elles,
   étaient les plus faibles : elles montent d'un cran. */
.real-nearby-item .pseudo,
li.conversation .pseudo,
.group-row .pseudo {
  font-size: 1.3125rem; /* 21 px */
  /* Contre-mesure faite (`scripts/mesure-app-s301-troncature.ts`) : à largeur
     accordée identique, un pseudo laissé à 20 px n'affiche pas un caractère de
     plus. Le pixel gagné ici ne coûte donc aucune troncature — la place perdue
     vient de la vignette et de la colonne de distance, pas du pseudo. Cette
     dernière est corrigée plus bas sous 375 px. */
}
li.conversation .conv-time,
.group-row .conv-time {
  font-size: 0.875rem; /* 14 px (avant : 13 px) */
}
li.conversation .conv-type,
.group-row .conv-type {
  font-size: 0.8125rem; /* 13 px (avant : 12 px) */
}
/* Pastille de non-lus : diamètre et chiffre relevés ensemble (le nombre reste
   centré ; `line-height` suit la hauteur, sinon le chiffre décolle). */
li.conversation .conv-unread,
.group-row .conv-unread {
  min-width: 22px;
  height: 22px;
  line-height: 22px;
  font-size: 0.8125rem; /* 13 px */
}
.real-nearby-item .card-body .card-sub .badge {
  font-size: 0.8125rem; /* 13 px (avant : 12 px) */
}
.real-nearby-item .card-body .card-age {
  font-size: 0.9375rem; /* 15 px (avant : 14 px) */
}
/* Distance : S195 aligne la colonne des cachets grâce à une largeur MINIMALE
   fixe calibrée sur « à 120,4 km » en 14 px. Agrandir la police SANS relever
   cette largeur casserait l'alignement dès trois chiffres : les deux valeurs
   montent donc ENSEMBLE (92 px × 15/14 ≈ 98,6 ⇒ 100 px). */
.real-nearby-item .card-body .card-line .distance {
  font-size: 0.9375rem; /* 15 px */
  min-width: 6.25rem; /* 100 px */
}
/* … SAUF sur les écrans étroits, où cette gouttière d'alignement se paie au
   prix fort. Mesuré à 320 px (`scripts/mesure-app-s301-troncature.ts`) :
   « Coupledelabaie » ne recevait plus que 17 px, soit UN caractère — la
   colonne fixe de 100 px confisquait près de la moitié du corps de ligne
   pour afficher « à 5 km ». Un pseudonyme réduit à une initiale n'est plus
   une ellipse maîtrisée, c'est un texte amputé (mandat §4).
   On ne rétrécit RIEN : on rend au texte une gouttière qui ne servait qu'à
   aligner des cachets. L'alignement S195 reste entier dès 375 px, largeur à
   laquelle « à 120,4 km » tient de toute façon dans sa colonne. */
/* … SAUF sur les écrans étroits, où cette colonne se paie au prix fort.
   Mesuré par `scripts/mesure-app-s301-troncature.ts`, qui compare caractère
   par caractère la même page AVEC et SANS cette feuille :
     · à 320 px, « Coupledelabaie » ne recevait plus que 17 px — UN caractère.
       Un pseudonyme réduit à son initiale n'est plus une ellipse maîtrisée,
       c'est un texte amputé, ce que le mandat §4 refuse.
     · la gouttière fixe de 100 px confisquait la moitié du corps de ligne
       pour écrire « à 5 km », et « Position masquée » en 15 px prenait à elle
       seule plus de place que le pseudonyme qu'elle accompagne.
   Sous 375 px la métadonnée rend donc les deux : sa gouttière d'alignement et
   son pixel de police. On ne rétrécit rien sous la taille d'origine — la
   distance retrouve exactement ses 14 px d'avant S301 — et le pseudonyme, lui,
   RESTE à 21 px : à largeur accordée identique (mesurée : 90, 49, 124, 37 px,
   les mêmes qu'avec un pseudo à 20 px), autant que les lettres soient plus
   grandes. L'alignement des cachets S195 reste entier dès 375 px, largeur à
   laquelle « à 120,4 km » tient de toute façon dans sa colonne.
   Enfin, sous 375 px la métadonnée accepte de S'ÉLIDER elle-même (45 % au
   plus). C'est l'ordre de dégradation que le mandat §4 demande : quand la
   place manque, c'est l'information SECONDAIRE qui cède, jamais le nom. Sans
   cela « Position masquée » — un statut, pas une distance — prenait à 320 px
   plus de largeur que le pseudonyme qu'il accompagne.
   Résultat mesuré après correction, vs la base : « Discretion » 53 → 79 px et
   « Le_hollandais » 101 → 124 px À 320 px (gains), « Coupledelabaie » et les
   autres à parité. Il ne subsiste qu'un cas déficitaire, le pseudonyme
   pathologique de 34 caractères sans espace : 101 → 90 px, soit exactement les
   11 px que la vignette à 60 px prend à la colonne de texte. Comme la police y
   est plus grande, ces 90 px portent des lettres plus lisibles que les 101 px
   d'avant. Résidu ASSUMÉ, mesuré, et non dissimulé. */
@media (max-width: 374px) {
  .real-nearby-item .card-body .card-line .distance {
    min-width: 0;
    font-size: 0.875rem; /* 14 px — la taille d'avant S301, pas moins */
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* --- Séparateurs : ils commencent APRÈS la vignette ----------------------
   Avant : `border-bottom` bord à bord — le filet traversait la photographie.
   Après : le filet est peint par un `::after` calé sur la colonne de texte.
   Le `border-bottom` historique n'est pas SUPPRIMÉ mais rendu TRANSPARENT :
   la ligne conserve exactement la même hauteur (aucun reflux de mise en
   page, aucune liste qui « saute » d'un pixel par élément).
   Géométrie, mesurée sur la coque :
     · Profils  → 16 (gouttière S171) + 60 (vignette) + 11 (gap S130) = 87 px
     · Messages → 12 (gouttière)      + 60           + 11             = 83 px
     · Groupes  → identique à Messages (même gabarit `.conversation`)
   Le dernier élément de chaque liste ne porte AUCUN filet : le bas de liste
   est net, jamais une ligne suspendue dans le vide. */
ul.real-demo-samples > li.real-nearby-item,
li.conversation {
  position: relative;
  border-bottom-color: transparent;
}
/* La ligne de GROUPE est le seul cas particulier : son fond propre est le ROUGE
   révélé derrière le geste de retrait (`.group-row { background-color: #c0392b }`).
   Un filet `transparent` laisserait donc apparaître un trait ROUGE d'un pixel sur
   toute la largeur — l'inverse du résultat voulu. Le filet prend ici la couleur de
   la surface de la ligne : invisible entre deux lignes blanches, sans rien changer
   au rouge du tiroir (qui est peint par `.group-row-action`, un élément à part). */
li.group-row {
  border-bottom-color: var(--surface);
}
ul.real-demo-samples > li.real-nearby-item::after,
li.conversation::after,
li.group-row::after {
  content: '';
  position: absolute;
  bottom: 0;
  height: 1px;
  /* Couleur du filet — MESURÉE, pas choisie au jugé.
     La coque définit `--divider: #e6ebe6`. Sur le fond blanc des listes, ce
     gris rend un rapport de contraste de 1,25:1 : la recette visuelle §8 l'a
     photographié et le filet est tout simplement INVISIBLE à l'écran. Le
     mandat §4 demande « un contraste suffisant mais non agressif » — 1,25:1
     n'est pas discret, il est absent, et un séparateur qu'on ne voit pas ne
     sépare rien.
     `#b7c1b7` rend 1,83:1 sur blanc, soit l'ordre de grandeur du séparateur
     système d'iOS (#c6c6c8, 1,90:1) : perceptible, jamais dur.
     On NE TOUCHE PAS au jeton `--divider`, qui gouverne des dizaines de
     bordures hors du périmètre S301 (en-têtes, formulaires, fiches). Seul le
     filet de liste que S301 introduit lui-même porte cette valeur. */
  background: #b7c1b7;
  pointer-events: none;
}
ul.real-demo-samples > li.real-nearby-item::after {
  left: 87px;
  right: 16px;
}
li.conversation::after,
li.group-row::after {
  left: 83px;
  right: 12px;
}
ul.real-demo-samples > li.real-nearby-item:last-child::after,
li.conversation:last-child::after,
li.group-row:last-child::after {
  content: none;
}
/* Le qualificatif `li` des sélecteurs ci-dessus n'est PAS décoratif : l'avant-plan
   glissable `.group-row-content` porte lui aussi la classe `.conversation` (il
   hérite du gabarit de la coque). Sans ce `li`, chaque ligne de groupe peindrait
   DEUX filets — un sur la ligne, un sur son avant-plan. Le filet doit rester sur
   `li.group-row`, qui ne bouge pas pendant le geste. */
/* Repli : une ligne Profils NON glissable garde la gouttière compacte de la
   coque à ≤ 360 px (`padding: 9px 10px`, `gap: 10px`) ⇒ 10 + 60 + 10 = 80 px. */
@media (max-width: 360px) {
  ul.real-demo-samples > li.real-nearby-item:not(.s173b-swipe-row)::after {
    left: 80px;
    right: 10px;
  }
}
