/* Charte graphique — voir design.md à la racine. Mobile-first. */
:root {
  --olive: #6b7a4f;
  --olive-fonce: #4a5738;
  --fond: #faf9f5;
  --carte: #ffffff;
  --accent: #d4a373;
  --texte: #2c2c2c;

  --texte-doux: #6b6459;
  --bordure: #e5e0d5;
  --olive-clair: #edf0e6;

  --statut-ok: #7fa650;
  --statut-bientot: #e8a855;
  --statut-urgent: #d66b5c;

  --statut-ok-texte: #5e7b3b;
  --statut-bientot-texte: #906835;
  --statut-urgent-texte: #af584b;

  --statut-ok-fond: #e4ead7;
  --statut-bientot-fond: #f7ead8;
  --statut-urgent-fond: #f4dfd9;

  --rayon-petit: 8px;
  --rayon: 12px;
  --rayon-grand: 20px;
  --rayon-photo: 16px;

  /* --- Les bords de l'écran (encoche, île dynamique, barre d'accueil) ---
     Dans un navigateur ordinaire, ces quatre valeurs sont NULLES : la barre
     d'adresse occupe déjà le haut de l'écran, et le site ne change donc pas
     d'un pixel. Elles ne deviennent non nulles que lorsque la page occupe
     l'écran ENTIER — application installée depuis l'écran d'accueil, ou
     application des boutiques —, cas où l'en-tête passerait sous l'encoche.

     Elles vivent ici, en variables, pour trois raisons : une seule source
     plutôt qu'une dizaine d'appels à env() qui divergeraient (la même règle
     que pour les menus construits à deux endroits) ; un repli explicite à
     0px pour les navigateurs qui ignorent l'un des quatre noms ; et la
     possibilité de PROUVER la mise en page en leur donnant une valeur au
     banc, sans avoir à tenir un iPhone. */
  --zone-sure-haut: env(safe-area-inset-top, 0px);
  --zone-sure-bas: env(safe-area-inset-bottom, 0px);
  --zone-sure-gauche: env(safe-area-inset-left, 0px);
  --zone-sure-droite: env(safe-area-inset-right, 0px);

  --ombre-carte: 0 1px 2px rgba(44, 44, 44, 0.04), 0 2px 8px rgba(44, 44, 44, 0.04);
  --ombre-relief: 0 4px 16px rgba(44, 44, 44, 0.08);
}

* {
  box-sizing: border-box;
}

/* L'attribut hidden vaut display:none, mais toute règle .classe { display: ... }
   le neutralise silencieusement. Cette règle rétablit la priorité attendue. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  background: var(--fond);
  color: var(--texte);
  font-size: 15px;
  line-height: 1.5;
  /* Place pour la barre de navigation basse (mobile). Mesurée avec le badge
     d'alertes affiché : 76px la faisaient passer PAR-DESSUS les derniers
     éléments — filtres et fins de liste devenaient intouchables. La barre
     grandit de la hauteur de la barre d'accueil de l'iPhone : la place
     réservée dessous doit grandir d'autant, sinon on retrouve exactement le
     défaut qu'on avait mesuré. */
  padding-bottom: calc(112px + var(--zone-sure-bas));
}

/* --- En-tête --- */
.entete {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--fond);
  border-bottom: 1px solid var(--bordure);
  /* En plein écran, l'en-tête commence AU BORD de l'écran : sans cette marge,
     le logo et le commutateur passent sous l'encoche. Comme le fond de
     l'en-tête est celui de la page, la bande ainsi dégagée se confond avec
     elle — on ne voit pas une barre en plus, on voit l'en-tête à sa place.
     Les côtés servent au mode paysage, où l'encoche mord un bord latéral. */
  padding: calc(16px + var(--zone-sure-haut)) calc(20px + var(--zone-sure-droite)) 16px
    calc(20px + var(--zone-sure-gauche));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.entete-titre {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--olive-fonce);
}

.entete-action {
  background: none;
  border: none;
  font-family: inherit;
  font-size: 14px;
  color: var(--texte-doux);
  cursor: pointer;
  text-decoration: underline;
  padding: 8px;
  min-height: 44px;
}

.contenu {
  padding: 20px calc(20px + var(--zone-sure-droite)) 20px calc(20px + var(--zone-sure-gauche));
  max-width: 1100px;
  margin: 0 auto;
}

h1 {
  font-size: 28px;
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 4px;
}

h2 {
  font-size: 21px;
  font-weight: 600;
  line-height: 1.25;
  margin: 32px 0 12px;
}

h2:first-child {
  margin-top: 0;
}

h3 {
  font-size: 17px;
  font-weight: 600;
  margin: 0;
}

.sous-titre {
  color: var(--texte-doux);
  margin: 0 0 24px;
}

.aide {
  color: var(--texte-doux);
  font-size: 13px;
  margin: 6px 0 0;
}

/* --- Formulaires --- */
label {
  display: block;
  margin: 18px 0 6px;
  font-weight: 500;
  font-size: 14px;
}

input,
select,
textarea {
  width: 100%;
  min-height: 44px;
  /* 16px minimum : en dessous, iOS zoome automatiquement au focus */
  font-size: 16px;
  padding: 11px 13px;
  font-family: inherit;
  color: var(--texte);
  background: var(--carte);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-petit);
}

input:focus,
select:focus,
textarea:focus {
  outline: 2px solid var(--olive);
  outline-offset: 1px;
}

.obligatoire {
  font-weight: 400;
  font-size: 13px;
  color: var(--texte-doux);
  margin-left: 5px;
}

/* --- Boutons --- */
.bouton,
.bouton-secondaire,
.bouton-danger {
  min-height: 44px;
  padding: 12px 20px;
  font-size: 15px;
  font-family: inherit;
  font-weight: 500;
  border-radius: var(--rayon-petit);
  cursor: pointer;
  border: 1px solid transparent;
}

.bouton {
  background: var(--olive);
  color: #fff;
}

.bouton:hover:not(:disabled) {
  background: var(--olive-fonce);
}

.bouton:disabled {
  background: #c9c4b8;
  cursor: not-allowed;
}

.bouton-secondaire {
  background: var(--carte);
  color: var(--texte);
  border-color: var(--bordure);
}

/* Un geste secondaire qui a l'air d'un lien : il ne doit jamais concurrencer
   du regard le bouton d'à côté. Zone tactile de 44 px tenue quand même. */
.bouton-lien {
  background: none;
  border: none;
  padding: 0 4px;
  cursor: pointer;
  text-decoration: underline;
  color: inherit;
  font: inherit;
  min-height: 44px;
}

/* Les gestes de la carte « visite du vétérinaire sanitaire ». En colonne
   sous 380 px : deux boutons côte à côte y deviennent illisibles. */
.actions-visite {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-top: 12px;
}

.bouton-danger {
  background: var(--carte);
  color: var(--statut-urgent-texte);
  border-color: var(--bordure);
}

.bouton-large {
  width: 100%;
  margin-top: 24px;
}

/* --- Cartes --- */
.carte {
  background: var(--carte);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-carte);
  padding: 20px;
  margin-bottom: 16px;
}

/* Échéances réglementaires nationales (2027, 2029) : un filet terracotta à
   gauche pour les distinguer des rappels qui portent sur VOS animaux — ce
   sont des dates de texte, pas un calcul sur vos données. */
.carte-echeance-reglementaire {
  border-left: 4px solid var(--accent);
}

.grille {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

/* --- Photo d'animal : élément central des fiches --- */
.photo-animal {
  width: 100%;
  height: 220px;
  object-fit: cover;
  border-radius: var(--rayon-photo);
  display: block;
  background: var(--olive-clair);
}

/* Sans photo : jamais de cadre vide (design.md §7). Un bloc de 220 px occupé
   par une seule initiale EST un cadre vide — on passe donc à une pastille
   compacte, la fiche se réduisant alors à sa hauteur de texte. */
.photo-absente {
  width: 72px;
  height: 72px;
  border-radius: var(--rayon-photo);
  background: var(--olive-clair);
  color: var(--olive-fonce);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: 600;
}

.vignette {
  width: 64px;
  height: 64px;
  border-radius: var(--rayon-photo);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--olive-clair);
}

.vignette-absente {
  width: 64px;
  height: 64px;
  border-radius: var(--rayon-photo);
  background: var(--olive-clair);
  color: var(--olive-fonce);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  font-weight: 600;
  flex-shrink: 0;
}

.carte-animal {
  display: flex;
  gap: 16px;
  align-items: center;
  cursor: pointer;
  width: 100%;
  text-align: left;
  border: none;
  font-family: inherit;
  font-size: 15px;
  color: inherit;
}

.carte-animal-infos {
  min-width: 0;
  flex: 1;
}

.carte-animal-detail {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--texte-doux);
}

/* --- Pastilles de statut (texte gras ≥ 13px, cf. design.md §2) --- */
.pastille {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.pastille::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.pastille-ok {
  background: var(--statut-ok-fond);
  color: var(--statut-ok-texte);
}

.pastille-bientot {
  background: var(--statut-bientot-fond);
  color: var(--statut-bientot-texte);
}

.pastille-urgent {
  background: var(--statut-urgent-fond);
  color: var(--statut-urgent-texte);
}

.pastille-neutre {
  background: var(--olive-clair);
  color: var(--olive-fonce);
}

/* --- Filtres par catégorie --- */
.filtres {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 8px;
  margin-bottom: 16px;
  /* Le conteneur défile, jamais la page */
  scrollbar-width: thin;
}

.filtre {
  flex-shrink: 0;
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--bordure);
  background: var(--carte);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--texte-doux);
  cursor: pointer;
  min-height: 44px;
}

.filtre.actif {
  background: var(--olive);
  border-color: var(--olive);
  color: #fff;
}

/* --- Documents --- */
.ligne-document {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--bordure);
}

.ligne-document:last-child {
  border-bottom: none;
}

.doc-infos {
  min-width: 0;
}

.doc-titre {
  margin: 0;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.doc-date {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--texte-doux);
}

/* --- Messages --- */
.message {
  padding: 12px 14px;
  border-radius: var(--rayon-petit);
  font-size: 14px;
  margin: 16px 0;
  background: var(--statut-ok-fond);
  color: var(--statut-ok-texte);
}

.message-erreur {
  background: var(--statut-urgent-fond);
  color: var(--statut-urgent-texte);
}

.message-attention {
  background: var(--statut-bientot-fond);
  color: var(--statut-bientot-texte);
}

.etat-vide {
  padding: 40px 24px;
  text-align: center;
  color: var(--texte-doux);
  background: var(--carte);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-carte);
}

/* Consentement marketing (décision n°28). La case d'inscription : une ligne
   discrète, jamais pré-cochée, cliquable sur toute sa surface. */
.ligne-consentement {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 14px 0 6px;
  font-size: 13px;
  font-weight: 400;
  color: var(--texte-doux);
  cursor: pointer;
}

.ligne-consentement input {
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  flex-shrink: 0;
  accent-color: var(--olive);
}

/* La relance « moment en or » : une ligne douce, pas une bannière — elle se
   refuse d'un clic et ne revient jamais. */
.relance-marketing {
  background: var(--olive-clair);
  border-radius: var(--rayon);
  padding: 14px 18px;
  margin-bottom: 16px;
  font-size: 14px;
}

.relance-marketing p {
  margin: 0 0 10px;
  color: var(--olive-fonce);
}

.relance-marketing-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* Bloc « Prochainement » (décision n°26) : un aparté, pas une annonce — filet
   terracotta à gauche, fond neutre, jamais en travers de l'usage principal.
   Le retour à la ligne du texte saisi au backoffice est respecté (pre-line). */
.bloc-prochainement {
  margin-top: 32px;
  padding: 14px 18px;
  border-left: 3px solid var(--accent);
  background: var(--carte);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  box-shadow: var(--ombre-carte);
}

.bloc-prochainement-etiquette {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-fonce, #b07d4f);
}

.bloc-prochainement p:last-child {
  margin: 0;
  font-size: 15px;
  color: var(--texte-doux);
  white-space: pre-line;
}

/* Les deux casquettes professionnelles (élevage, clinique). Même dessin que
   « Prochainement » mais liseré OLIVE et non terracotta : le terracotta est
   réservé à ce qui demande une action ou avertit, l'olive à ce qu'on propose.
   Le cadre existe pour une seule raison : en petit gris au milieu des
   réglages de compte, ces deux portes étaient introuvables. */
.bloc-professionnel {
  margin-top: 28px;
  padding: 14px 18px;
  border-left: 3px solid var(--olive);
  background: var(--carte);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  box-shadow: var(--ombre-carte);
}

/* Les rappels sur ce téléphone (application des boutiques). Liseré OLIVE :
   c'est une PROPOSITION, pas un avertissement — le terracotta reste réservé à
   ce qui alerte. Même dessin que les deux blocs voisins pour que la colonne
   reste lisible : trois cartes de familles différentes se liraient mal. */
.bloc-notifications {
  margin-top: 28px;
  padding: 14px 18px;
  border-left: 3px solid var(--olive);
  background: var(--carte);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  box-shadow: var(--ombre-carte);
}

.bloc-notifications-etiquette {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--olive-fonce);
}

.bloc-notifications .actions-visite {
  margin-top: 12px;
}

.bloc-professionnel-etiquette {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--olive-fonce);
}

/* Les lignes gardent leur allure de texte doux : la carte porte le poids
   visuel, pas les liens — sinon on aurait trois boutons empilés. */
.bloc-professionnel .aide {
  margin: 0;
  text-align: left;
}

/* MES IDENTIFIANTS — la valeur d'un côté, le geste de l'autre.
   PAS de passage en colonne au-dessous d'une largeur donnée : `wrap` suffit et
   fait mieux. Un email court reste sur la même rangée que son bouton ; un
   email long le pousse à la ligne, tout seul, au moment exact où il gêne.
   Une media query aurait décroché le bouton même quand rien ne l'exigeait,
   et cette carte serait devenue deux fois plus haute pour rien. */
.ligne-identifiant {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 12px;
  margin: 8px 0 0;
}

.ligne-identifiant strong {
  /* Un email ne se coupe pas aux espaces : sans cela il élargit la carte et
     fait défiler la page en travers — sur l'écran où l'on vient justement
     relire une adresse. */
  overflow-wrap: anywhere;
}

#zone-identifiant {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--bordure, #e6e2d8);
}

/* Terracotta : celui-ci AVERTIT, et la charte réserve cette couleur à ce qui
   demande de s'arrêter une seconde. */
.avertissement-identifiant {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--accent);
  background: #faf3ec;
  border-radius: 0 var(--rayon) var(--rayon) 0;
  font-size: 14px;
  line-height: 1.45;
}

/* Le garde-fou de titularité conditionne l'accès aux documents : tant qu'il
   se fondait dans le décor, on cherchait ses documents sans comprendre.
   Liseré terracotta : c'est une demande d'action, pas une carte parmi d'autres. */
#bloc-titularite {
  border: 2px solid var(--accent);
  background: #faf3ec;
}

/* Le doublon d'identification (étape 1 du dossier partagé) : même langage
   visuel que le garde-fou de titularité — une demande d'action, liseré
   terracotta — car tant qu'il dure, la puce ne sert plus de pivot. */
.bandeau-attention {
  margin: 14px 0 0;
  padding: 12px 16px;
  border: 2px solid var(--accent);
  background: #faf3ec;
  border-radius: var(--rayon);
}

/* --- Fiche animal --- */

/* La carte d'un animal s'ouvre au toucher : le curseur et l'ombre au survol
   doivent le laisser deviner sans qu'on l'explique. */
.carte-cliquable {
  cursor: pointer;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.carte-cliquable:hover,
.carte-cliquable:focus-visible {
  box-shadow: 0 4px 16px rgba(44, 44, 44, 0.12);
  transform: translateY(-2px);
}

.fiche-tete {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 10px 0 26px;
}

/* --- Navigation basse (mobile : accessible au pouce) --- */
.navigation-basse {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--carte);
  border-top: 1px solid var(--bordure);
  display: flex;
  padding: 6px calc(4px + var(--zone-sure-droite)) calc(6px + var(--zone-sure-bas))
    calc(4px + var(--zone-sure-gauche));
  z-index: 20;
}

.nav-item {
  flex: 1;
  min-height: 56px;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--texte-doux);
  cursor: pointer;
  border-radius: var(--rayon-petit);
  padding: 6px 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
}

.nav-item.actif {
  color: var(--olive-fonce);
  background: var(--olive-clair);
}

.nav-badge {
  background: var(--statut-urgent);
  color: #fff;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 6px;
  min-width: 18px;
}

/* --- Courbe de poids (couche 2) --- */
.courbe {
  width: 100%;
  height: auto;
  display: block;
}

.legende-poids {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--texte-doux);
  margin-top: 8px;
}

/* Mesure isolée : la valeur remplace la courbe (voir dessinerCourbe) */
.poids-unique {
  font-size: 32px;
  font-weight: 600;
  color: var(--olive-fonce);
  margin-bottom: 4px;
}

/* --- Tableau de valeurs d'analyse : défile dans son conteneur --- */
.conteneur-tableau {
  overflow-x: auto;
  margin-top: 12px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 460px;
}

th,
td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--bordure);
}

th {
  font-weight: 600;
  color: var(--texte-doux);
  font-size: 13px;
}

tr.anomalie td {
  background: var(--statut-urgent-fond);
}

/* --- Écran de connexion --- */
.centre {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  /* L'écran de connexion est centré, donc rarement gêné — sauf sur un petit
     écran où la boîte occupe presque toute la hauteur : elle toucherait alors
     l'encoche en haut et la barre d'accueil en bas. */
  padding: calc(24px + var(--zone-sure-haut)) calc(24px + var(--zone-sure-droite))
    calc(24px + var(--zone-sure-bas)) calc(24px + var(--zone-sure-gauche));
}

.boite-connexion {
  width: 100%;
  max-width: 400px;
  background: var(--carte);
  border-radius: var(--rayon-grand);
  box-shadow: var(--ombre-relief);
  padding: 32px 28px;
}

/* ===========================================================
   Tablette — 2 colonnes
   =========================================================== */
@media (min-width: 640px) {
  .grille {
    grid-template-columns: repeat(2, 1fr);
  }

  .contenu {
    /* Cette largeur est celle d'un téléphone EN PAYSAGE autant que celle d'une
       tablette : la marge latérale doit y survivre, sinon le texte passe sous
       l'encoche dès qu'on tourne l'appareil. */
    padding: 32px calc(32px + var(--zone-sure-droite)) 32px calc(32px + var(--zone-sure-gauche));
  }
}

/* ===========================================================
   Desktop — 3 colonnes, navigation latérale, plus de barre basse
   =========================================================== */
@media (min-width: 1024px) {
  body {
    padding-bottom: 0;
    display: grid;
    grid-template-columns: 230px 1fr;
    grid-template-rows: auto 1fr;
    /* Zones NOMMÉES et non placement automatique : celui-ci suivait l'ordre
       du HTML (contenu avant navigation) et posait donc le contenu dans la
       colonne étroite… et la navigation par-dessus le reste. C'était le grand
       chevauchement visible en largeur bureau. */
    grid-template-areas:
      'entete entete'
      'nav    contenu';
    /* Coquille d'application : l'en-tête et la barre latérale ne bougent
       jamais, seul le contenu défile. Sans ça, le défilement les emportait
       et l'en-tête « flottait » au milieu de la page. */
    height: 100vh;
    overflow: hidden;
  }

  .entete {
    grid-area: entete;
  }

  .contenu {
    grid-area: contenu;
    overflow-y: auto;
    max-width: none;
    /* Ici le contenu défile dans sa propre boîte, et plus dans la page : la
       réserve du bas que portait <body> ne s'applique plus. Sur une tablette
       à barre d'accueil, la dernière ligne passerait dessous. */
    padding-bottom: calc(32px + var(--zone-sure-bas));
  }

  .contenu > * {
    max-width: 1100px;
  }

  /* L'écran de connexion, lui, occupe tout : pas de barre latérale avant
     d'être entré. Défilable, pour les petits écrans en hauteur. */
  #ecran-connexion {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
    overflow-y: auto;
  }

  .navigation-basse {
    grid-area: nav;
    position: static;
    flex-direction: column;
    border-top: none;
    border-right: 1px solid var(--bordure);
    /* Devenue colonne de gauche, elle touche le bord gauche et le bas. */
    padding: 20px 12px calc(20px + var(--zone-sure-bas)) calc(12px + var(--zone-sure-gauche));
    gap: 4px;
    align-items: stretch;
    overflow-y: auto;
  }

  .nav-item {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    font-size: 14px;
    min-height: 44px;
    padding: 10px 12px;
  }

  .grille {
    grid-template-columns: repeat(3, 1fr);
  }

  .photo-animal {
    height: 280px;
  }
}

/* --- Logo --- */
/* Sur l'écran de connexion, la marque est ce qu'on voit avant tout le reste :
   elle prend de la place et de l'air. Dans l'en-tête de l'application, elle
   s'efface au profit du contenu — on ne rappelle pas sa marque à quelqu'un
   qui est déjà entré. */
.logo-connexion {
  display: block;
  margin: 4px auto 18px;
  filter: drop-shadow(0 4px 10px rgba(107, 122, 79, 0.18));
}

.entete-titre {
  display: flex;
  align-items: center;
  gap: 9px;
}

.entete-titre img {
  display: block;
  flex-shrink: 0;
}

/* --- Photo de l'animal (9 août 2026) --- */
/* La photo remplit le même cadre que l'initiale — jamais de cadre vide :
   sans photo, l'initiale reste (design.md §7). */
.photo-remplie {
  background-size: cover;
  background-position: center;
  color: transparent; /* l'initiale s'efface sous l'image */
}

/* --- Pastille d'origine d'un document (évolution décision n°2) --- */
/* Discrète mais lisible : elle dit « ceci vient de vous », sans crier.
   Les documents des cliniques n'ont pas de pastille — l'absence EST le
   label d'origine vétérinaire. */
.pastille-origine {
  display: inline-block;
  padding: 1px 8px;
  margin-top: 4px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  font-size: 11px;
  color: var(--texte-doux);
  background: transparent;
}

/* --- L'âge à côté de la photo (remontée du 9 août) --- */
/* Une pastille accrochée au coin de la photo : l'âge se lit d'un coup
   d'œil, sans chercher la ligne de détail. */
.photo-animal-bloc {
  position: relative;
  display: inline-block;
}

.badge-age {
  position: absolute;
  bottom: -6px;
  right: -8px;
  padding: 1px 8px;
  border: 1px solid var(--bordure);
  border-radius: 999px;
  background: var(--carte);
  font-size: 11px;
  font-weight: 600;
  color: var(--olive-fonce);
  white-space: nowrap;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

/* La tête de carte animal (correction du 9 août) : photo à GAUCHE, nom et
   âge à CÔTÉ — l'âge se lit contre la photo, en toutes lettres. */
.carte-animal-tete {
  display: flex;
  align-items: center;
  gap: 14px;
}

.carte-animal-tete h3 {
  margin: 0;
}

.age-photo {
  margin: 3px 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--olive-fonce);
}

/* ---------------------------------------------------------------------------
   Campagne de retours + canal de signalement (9 août 2026)
   --------------------------------------------------------------------------- */

/* Le bandeau de retours : la charte du bloc « Prochainement » (filet
   terracotta), en tête d'écran — visible sans être criard, refermable. */
.bandeau-retours {
  margin: 0 0 20px;
  padding: 14px 18px;
  border-left: 3px solid var(--accent);
  background: var(--carte);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  box-shadow: var(--ombre-carte);
}

.bandeau-retours p {
  margin: 0 0 10px;
}

.bandeau-retours-actions {
  display: flex;
  flex-wrap: wrap; /* deux boutons côte à côte sont illisibles sous 380 px */
  gap: 10px;
  align-items: center;
}

/* Le bouton permanent « Signaler » : posé au-dessus de la barre de
   navigation mobile (fixed elle aussi), jamais par-dessus un geste. */
.bouton-signaler-flottant {
  position: fixed;
  right: calc(14px + var(--zone-sure-droite));
  bottom: calc(74px + var(--zone-sure-bas)); /* la barre fait ~68 px */
  z-index: 19; /* sous la navigation (20) : elle garde le dernier mot */
  padding: 10px 16px;
  min-height: 44px;
  border: 1px solid var(--bordure);
  border-radius: 22px;
  background: var(--carte);
  color: var(--olive-fonce);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  box-shadow: var(--ombre-carte);
}

/* En largeur bureau la navigation passe à gauche : le bouton descend
   dans le coin, plus rien à enjamber. */
@media (min-width: 900px) {
  .bouton-signaler-flottant {
    bottom: 20px;
    right: 20px;
  }
}

/* La confirmation d'envoi : une carte calme, la référence en évidence. */
.signalement-merci {
  border-left: 3px solid var(--accent);
}

.signalement-merci #signalement-reference {
  font-size: 18px;
  letter-spacing: 1px;
}

/* ---------------------------------------------------------------------------
   Informations vitales et accès urgence (9 août 2026)
   --------------------------------------------------------------------------- */

/* Le bloc lu en premier quand ça va mal : filet rouge, en tête de fiche. */
.bloc-vitales {
  background: var(--carte);
  border: 1px solid var(--bordure);
  border-left: 3px solid #a8332e;
  border-radius: 0 var(--rayon) var(--rayon) 0;
  padding: 14px 18px;
  margin: 20px 0;
  box-shadow: var(--ombre-carte);
}

.vitale-ligne {
  margin: 8px 0;
  display: flex;
  flex-wrap: wrap; /* sous 380 px, l'étiquette passe au-dessus de la valeur */
  align-items: baseline;
  gap: 4px 10px;
}

.vitale-etiquette {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--texte-doux, #6b6459);
  min-width: 150px;
}

.vitale-sang {
  color: #a8332e;
  font-size: 19px;
}

/* Absent ≠ vide : on écrit « Non renseigné » en gris plutôt que de laisser un
   blanc, qu'un lecteur pressé prendrait pour une donnée fiable. */
.vitale-absente {
  font-weight: 400;
  color: var(--texte-doux, #6b6459);
}

.vitale-provenance {
  font-size: 13px;
  color: var(--texte-doux, #6b6459);
  flex-basis: 100%;
}

.vitale-declaratif {
  color: #8a5a12;
  font-weight: 600;
}

/* Le lien d'urgence : long, il doit pouvoir se couper n'importe où plutôt
   que de faire déborder la page en 375 px. */
.urgence-lien {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  word-break: break-all;
  background: var(--fond);
  border: 1px solid var(--bordure);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0 0 10px;
}

/* Le QR de la fiche d'urgence : une étiquette à découper. */
.urgence-qr-carte {
  background: #fff;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: 16px;
  margin: 0 0 12px;
  text-align: center;
  max-width: 320px;
}

/* Le SVG arrive sans dimensions imposées : on le contraint ici pour qu'il
   remplisse la carte sans la faire déborder en 375 px. */
.urgence-qr svg {
  width: 100%;
  max-width: 240px;
  height: auto;
}

.urgence-qr-titre {
  margin: 10px 0 2px;
  font-weight: 600;
}

.urgence-qr-aide {
  margin: 0;
  font-size: 12.5px;
  color: var(--texte-doux, #6b6459);
}

/* Impression : on ne sort QUE l'étiquette. Le reste du carnet — en-tête,
   navigation, documents — n'a rien à faire sur une feuille destinée à être
   découpée et glissée dans un carnet de santé papier. */
@media print {
  body.impression-qr > *:not(#contenu-app),
  body.impression-qr #contenu-app > *:not(#vue-fiche),
  body.impression-qr #vue-fiche > *:not(#bloc-urgence),
  body.impression-qr #bloc-urgence > *:not(#urgence-lien-zone),
  body.impression-qr #urgence-lien-zone > *:not(.urgence-qr-carte) {
    display: none !important;
  }

  body.impression-qr .urgence-qr-carte {
    border: 1px dashed #999; /* le trait de découpe */
    margin: 0 auto;
    box-shadow: none;
  }
}

/* ---------------------------------------------------------------------------
   Le commutateur d'espace (application installable, étape 1)
   Remplace les deux portes qui vivaient dans l'en-tête : le lien « Espace
   cabinet » et le bouton « 🐾 Mon élevage ». Un seul geste, au même endroit.
   --------------------------------------------------------------------------- */

.commutateur {
  position: relative;
}

/* Un bouton lisible, pas un lien souligné : c'est un choix d'espace, pas une
   navigation de plus. Le nom de l'espace courant y est écrit en toutes
   lettres — jamais deviné par une couleur (règle n°2). */
.commutateur-bouton {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--bordure);
  border-radius: 22px;
  background: var(--carte);
  color: var(--olive-fonce);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
}

.commutateur-fleche {
  font-size: 11px;
  color: var(--texte-doux);
}

.commutateur-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30; /* au-dessus de l'en-tête collant (10) et de la navigation (20) */
  min-width: 190px;
  display: flex;
  flex-direction: column;
  padding: 6px;
  border: 1px solid var(--bordure);
  border-radius: 12px;
  background: var(--carte);
  box-shadow: var(--ombre-carte);
}

.commutateur-choix {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--texte);
  font: inherit;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
}

.commutateur-choix:hover {
  background: var(--olive-clair);
}

.commutateur-choix.actif {
  color: var(--olive-fonce);
  font-weight: 600;
}

.commutateur-coche {
  color: var(--olive);
}

/* ---------------------------------------------------------------------------
   L'invitation à installer l'application
   ÉTEINTE par défaut (pwa.js, INVITATION_INSTALLATION_ACTIVE) : le service
   worker part en silence, l'invitation ne s'affichera que sur décision.
   --------------------------------------------------------------------------- */

.invitation-installation {
  position: fixed;
  left: calc(12px + var(--zone-sure-gauche));
  right: calc(12px + var(--zone-sure-droite));
  /* Au-dessus de la barre de navigation du carnet (~68 px), comme le bouton
     flottant de signalement. Sur l'espace véto, qui n'a pas cette barre, la
     marge supplémentaire ne gêne rien. */
  bottom: calc(74px + env(safe-area-inset-bottom));
  z-index: 21; /* juste au-dessus de la navigation (20) */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--bordure);
  border-left: 3px solid var(--accent);
  border-radius: 12px;
  background: var(--carte);
  box-shadow: var(--ombre-carte);
}

.invitation-texte {
  margin: 0;
  flex: 1 1 220px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--texte);
}

.invitation-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Le bouton flottant « Signaler un problème » occupe le même coin : il monte
   au-dessus de la bande tant qu'elle est affichée, plutôt que de disparaître
   dessous. */
body.invitation-visible .bouton-signaler-flottant {
  bottom: calc(158px + var(--zone-sure-bas));
}

@media (min-width: 720px) {
  .invitation-installation {
    left: auto;
    right: 20px;
    bottom: 20px;
    max-width: 420px;
  }

  body.invitation-visible .bouton-signaler-flottant {
    bottom: 104px;
  }
}

/* L'en-tête à trois éléments (logo, commutateur, déconnexion) déborde d'un
   téléphone étroit : mesuré à 401 px de contenu pour 375 px d'écran. Le mot
   « VetoDossier » s'efface le premier — le logo porte la marque et garde le
   retour à l'accueil, alors qu'aucun des deux autres n'est remplaçable. */
@media (max-width: 480px) {
  .entete-mot {
    display: none;
  }

  .commutateur-bouton {
    padding: 8px 10px;
  }
}

/* ---------------------------------------------------------------------------
   Le numéro de puce (10 août 2026) — la moitié des dossiers n'en portait pas,
   et sans lui aucune clinique ne peut demander l'accès : la demande part dans
   le vide et expire. Le rappel dit ce que le numéro DÉBLOQUE, jamais ce qui
   manque, et il ne bloque rien.
   --------------------------------------------------------------------------- */

.rappel-puce {
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--bordure);
  border-left: 3px solid var(--accent);
  border-radius: var(--rayon-petit, 10px);
  background: var(--carte);
  font-size: 14px;
  line-height: 1.5;
}

/* L'avis de plausibilité : une remarque, pas un refus. Il reste dans la ligne
   d'aide du champ et ne prend jamais la couleur d'une erreur — la saisie est
   acceptée dans tous les cas. */
.avis-puce {
  display: block;
  margin-top: 4px;
  color: var(--olive-fonce);
}

.avis-puce-doute {
  color: var(--texte-doux);
}

/* ---------------------------------------------------------------------------
   Le scan par appareil photo (10 août 2026) — la ligne qui compte les pages.

   Elle mêle une phrase de 13 px et deux gestes de 44 px : sans flex, les
   boutons dépassaient de la ligne de texte et l'ensemble avait l'air cassé.
   Le retour à la ligne est indispensable — à 375 px, « Retirer la dernière »
   et « Tout retirer » ne tiennent pas côte à côte après la phrase.
   `display: flex` ne masque pas la ligne au repos : la règle [hidden] du haut
   de fichier porte !important, exprès pour ce piège.
   --------------------------------------------------------------------------- */

.pages-scan {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 4px;
}

/* ---------------------------------------------------------------------------
   Le geste photo change de nom selon l'appareil (10 août 2026, arbitrage
   client).

   Le geste EXISTE partout — un éleveur peut vouloir réunir des photos reçues
   par mail ou déjà scannées, et l'assemblage en un seul PDF vaut sur un poste
   fixe comme sur un téléphone. Ce qui n'existe pas partout, c'est l'appareil
   photo : sur ordinateur, `capture` est ignoré et le sélecteur de fichiers
   s'ouvre. Promettre « photographier » là serait promettre une caméra qui ne
   s'ouvrira pas.

   D'où deux libellés pour un seul bouton, échangés par une classe posée au
   démarrage. Aucun clignotement possible : les deux vivent dans un formulaire
   replié, ouvert bien après le démarrage du script.

   POURQUOI PAS UNE MEDIA QUERY : `(hover: none) and (pointer: coarse)`, le
   test habituel du tactile, se trompe sur la cible même qu'on veut servir —
   un iPad muni de son clavier-trackpad annonce `hover: hover` et
   `pointer: fine`. Le nombre de points tactiles ne bouge pas, lui : 5 sur
   iPad avec ou sans clavier, 0 sur une tour.
   --------------------------------------------------------------------------- */

.geste-photo {
  display: inline-block;
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
   La liste des fichiers choisis (arbitrage client du 10 août : plusieurs
   fichiers d'un coup font plusieurs documents, chacun avec sa catégorie).

   Même forme que la liste d'envoi de l'espace clinique, mais ces classes-là
   vivent dans styles-veto.css, que le carnet ne charge pas : elles sont
   redéfinies ici plutôt qu'importées, faute de quoi la liste s'afficherait
   sans aucun style.
   --------------------------------------------------------------------------- */

.liste-depot {
  margin: 10px 0 4px;
}

.ligne-depot {
  padding: 10px 12px;
  margin-bottom: 8px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-petit, 10px);
  background: var(--carte);
}

.ligne-depot-tete {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Le nom d'un fichier peut être très long : il se coupe plutôt que de pousser
   la croix hors de l'écran. */
.ligne-depot-nom {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
}

.fichier-retirer {
  flex: none;
  width: 44px;
  min-height: 44px;
  border: none;
  background: none;
  color: var(--texte-doux);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.categorie-rapide,
.titre-rapide {
  margin-top: 8px;
  font-size: 14px;
}

/* Le choix qui suit « Ajouter un document » (demande client du 10 août : une
   porte d'entrée, puis le choix — deux boutons côte à côte pour le même geste
   encombrent). Il s'ouvre SOUS le bouton qui l'a demandé, en pleine largeur :
   à 375 px, deux options empilées se touchent mieux qu'accolées. */
.choix-depot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 10px 0 16px;
  padding: 12px;
  border: 1px solid var(--bordure);
  border-left: 3px solid var(--accent);
  border-radius: var(--rayon-petit, 10px);
  background: var(--carte);
}

/* Le bureau est le défaut : si le script ne tournait pas, c'est le libellé qui
   ne promet AUCUNE caméra qui resterait affiché. On se trompe du bon côté. */
.si-tactile {
  display: none;
}

html.appareil-tactile .si-tactile {
  display: inline;
}

html.appareil-tactile .si-bureau {
  display: none;
}

/* ---------------------------------------------------------------------------
   Le choix de portée d'un partage par lien (niveau 2).

   Une case et son explication : la zone tactile porte sur TOUTE la ligne, pas
   sur le seul rond de 20 px. Ce qu'on choisit ici décide si un dossier entier
   part ou seulement des informations vitales — le geste ne doit pas rater.
   --------------------------------------------------------------------------- */

.choix-portee {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  min-height: 44px;
  padding: 10px 12px;
  margin-bottom: 8px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-petit, 10px);
  background: var(--carte);
  cursor: pointer;
  font-weight: 400;
}

.choix-portee input {
  margin-top: 2px;
  width: auto;
  flex: none;
  accent-color: var(--olive);
}

.choix-portee .aide {
  margin-top: 2px;
}

/* ---------------------------------------------------------------------------
   Gestes sur une ligne de document (11 août 2026) : ouvrir, ranger, supprimer.
   EN COLONNE sous 375 px — un menu déroulant et deux boutons sur une même
   ligne se chevauchent, et le menu passe alors sous la barre des 44 px.
   --------------------------------------------------------------------------- */
.actions-document {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
}

.menu-rangement {
  min-height: 44px;
  max-width: 190px;
  padding: 6px 8px;
  font-size: 0.9rem;
}

/* La file « à ranger » : un filet terracotta, jamais un fond d'alerte. Ces
   documents ne sont pas en défaut, ils attendent un rayon. */
.carte-a-ranger {
  border-left: 3px solid var(--accent);
  margin-bottom: 14px;
}

/* Les fiches d'archive : présentes, lisibles, mais visiblement à part de
   l'effectif courant. Atténuées, jamais grisées au point d'être illisibles —
   ce sont des pièces de registre, pas des restes. */
.carte-archive {
  border-left: 3px solid var(--bordure);
  opacity: 0.85;
}

/* Sous 480 px, une ligne porteuse de gestes passe en colonne : titre sur toute
   la largeur, gestes dessous. À trois éléments à droite, un titre de facture
   se pliait sur trois lignes sur un téléphone de 375 px. */
@media (max-width: 480px) {
  .ligne-avec-gestes {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  .ligne-avec-gestes .actions-document {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
  }

  /* Le menu passe en PREMIER et sur toute la largeur : c'est un champ de
     formulaire, il se lit large. Les deux boutons se rangent dessous, côte à
     côte — deux rangées au lieu de trois. */
  .ligne-avec-gestes .menu-rangement {
    order: -1;
    flex: 1 1 100%;
    max-width: none;
  }
}

/* ---------------------------------------------------------------------------
   Fiche animal : deux rangées de gestes (11 août 2026).
   Déposer et retrouver un document en pleine taille ; régler la photo ou
   corriger l'identité en petit dessous. Ce sont des gestes qu'on fait une fois
   dans la vie de la fiche, pas à chaque visite.
   --------------------------------------------------------------------------- */
.gestes-fiche {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}

.gestes-fiche > .bouton,
.gestes-fiche > .bouton-secondaire {
  flex: 1 1 160px;
}

.bouton-mini {
  background: none;
  border: 1px solid var(--bordure);
  border-radius: 20px;
  padding: 8px 12px;
  font-size: 0.85rem;
  font-family: inherit;
  color: var(--texte-doux, #6b6558);
  cursor: pointer;
  /* 40 px et non 44 : ce sont les gestes secondaires, et les garder petits est
     précisément la demande. Ils restent au-dessus du seuil confortable. */
  min-height: 40px;
}

.bouton-mini:hover {
  border-color: var(--olive);
  color: var(--olive-fonce);
}

.gestes-fiche-mineurs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

/* ---------------------------------------------------------------------------
   « Mes documents » : les rayons dépliables.
   --------------------------------------------------------------------------- */
.rayon-documents {
  border-bottom: 1px solid var(--bordure);
}

.rayon-documents:last-child {
  border-bottom: none;
}

.rayon-entete {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 12px 0;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: inherit;
}

.rayon-nom {
  flex: 1;
  font-weight: 600;
}

/* La flèche : à DROITE, après le compte, et elle PIVOTE d'un quart de tour à
   l'ouverture. À gauche et immobile, elle se lisait comme une puce de liste et
   personne ne devinait qu'un rayon se replie (remontée client du 11 août). */
/* PAS DE ROTATION CSS ICI, ET C'EST DÉLIBÉRÉ. Une flèche qui pivote était le
   premier jet ; au banc, la classe était posée, la règle bien écrite, et la
   matrice calculée restait l'identité — impossible de PROUVER que le geste se
   voit. Un caractère qui change (▸ / ▾) se lit dans le DOM, se vérifie, et ne
   dépend d'aucun rendu. Sur un écran, le résultat est le même. */
.rayon-chevron {
  color: var(--accent);
  font-size: 1.05rem;
  line-height: 1;
  width: 14px;
  text-align: center;
}

/* Le compte répond déjà à la moitié des questions qu'on se pose en arrivant. */
.rayon-compte {
  background: var(--fond);
  border: 1px solid var(--bordure);
  border-radius: 12px;
  padding: 2px 10px;
  font-size: 0.85rem;
  color: var(--texte-doux, #6b6558);
}

.rayon-corps {
  padding-left: 24px;
  padding-bottom: 6px;
}

/* ---------------------------------------------------------------------------
   La pile « à ranger » : sélection multiple.
   Le bouton de suppression vit EN TÊTE du bloc — au bas d'une liste de dix, il
   serait hors de l'écran au moment où on le cherche.
   --------------------------------------------------------------------------- */
.entete-a-ranger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.bouton-danger {
  background: none;
  border: 1px solid #b4534a;
  color: #b4534a;
  border-radius: 22px;
  padding: 8px 16px;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  min-height: 44px;
}

.bouton-danger:hover {
  background: #b4534a;
  color: #fff;
}

.bouton-danger[disabled] {
  opacity: 0.5;
  cursor: default;
}

/* La case et son étiquette forment une cible de 44 px : cocher dix lignes à la
   suite sur un téléphone ne doit pas demander de viser. */
.case-document-enveloppe,
.case-tout {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
}

.case-document,
#a-ranger-tout {
  width: 22px;
  height: 22px;
  accent-color: var(--olive);
  cursor: pointer;
}

/* Une ligne cochable : la case À CÔTÉ du titre, jamais au-dessus. En colonne
   (le réglage mobile des lignes à gestes), elle prenait une rangée entière et
   la pile de six documents devenait interminable. La grille remet la case et
   le titre sur le même axe, les gestes passant dessous sur toute la largeur. */
.ligne-selectionnable {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    'case infos'
    'case actions';
  align-items: start;
  column-gap: 6px;
}

.ligne-selectionnable .case-document-enveloppe {
  grid-area: case;
  /* La case couvre deux rangées de la grille : sans cet ancrage elle se
     centrerait sur toute la hauteur de la ligne et se retrouverait à hauteur
     de la date, loin du titre qu'elle désigne. */
  align-self: start;
}

.ligne-selectionnable .doc-infos {
  grid-area: infos;
}

.ligne-selectionnable .actions-document {
  grid-area: actions;
}

/* ---------------------------------------------------------------------------
   PIED DE PAGE LÉGAL DES ESPACES CONNECTÉS (12 août 2026)

   Défaut trouvé par le client : une fois connecté, les CGU, la politique de
   confidentialité et les mentions légales n'étaient accessibles NULLE PART.
   Elles ne vivaient que sur l'écran de connexion, c'est-à-dire précisément là
   où l'on ne va plus. C'est une obligation, et chez nous elle porte deux
   choses de plus : l'adresse d'exercice des droits RGPD, et l'engagement que
   les cliniques ont accepté.

   LES DEUX DROITS Y ONT LEUR PLACE, PAS DANS LES RÉGLAGES (décision client) :
   l'export et la suppression sont des DROITS, pas des options. Au milieu de
   l'écran des réglages, la suppression était à portée de clic distrait ; ici
   on y vient exprès. Elle est en DERNIER, après un séparateur : le voisinage
   d'un lien anodin est ce qui rend un geste grave trop facile.
--------------------------------------------------------------------------- */
.pied-legal {
  margin-top: 48px;
  padding: 14px 0 6px;
  border-top: 1px solid var(--bordure, #e6e2d8);
  font-size: 12px;
  color: var(--texte-doux);
  /* Disposition souple plutôt qu'un texte avec des « · » écrits en dur : au
     premier retour à la ligne, ces points restaient ORPHELINS en fin de ligne
     (vu au banc en 375 px). Les entrées se répartissent, l'espacement suffit
     à les séparer, et rien ne peut plus pendre au bout d'une ligne. */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  column-gap: 14px;
}

/* inline-block + padding, et non un simple lien en ligne : un `<a>` en ligne
   ne fait que la hauteur de ses caractères — 14 px mesurés au banc, très
   au-dessous de la règle des 44 px, et le premier jet du 12 août prétendait
   le contraire sans l'avoir mesuré. Le rembourrage vertical porte la cible à
   44 px sans grossir le texte, ce qui garde le pied discret. */
.pied-legal a,
.pied-legal button {
  display: inline-block;
  color: inherit;
  font: inherit;
  background: none;
  border: none;
  padding: 15px 4px;
  cursor: pointer;
  text-decoration: underline;
}

.pied-legal a:hover,
.pied-legal button:hover {
  color: var(--olive-fonce);
}

/* Le groupe des droits personnels de l'espace clinique. `display: contents`
   pour que ses deux liens se rangent dans la même ligne souple que les autres
   plutôt que de former un bloc à part. Masqué, il disparaît quand même : la
   règle `[hidden] { display: none !important }` l'emporte — c'est justement
   pour ça qu'elle porte le !important. */
#pied-droits-personnels {
  display: contents;
}

/* --------------------------------------------------------------------------
   LES RÉSEAUX SOCIAUX DU PIED DE PAGE (20 août 2026)

   Les logos sont DESSINÉS DANS LA PAGE, jamais chargés chez Meta : la CSP du
   site interdit les ressources externes (script-src 'self'), et surtout une
   image appelée chez Facebook lui signalerait chaque visiteur de chaque page —
   exactement ce que la promesse « aucun cookie de suivi » exclut.

   La sélection double sert à reprendre la main sur `.pied-legal a`, qui pose
   un soulignement et un rembourrage pensés pour du texte : à spécificité
   égale, c'est l'ordre du fichier qui trancherait, et un jour quelqu'un
   déplacerait ce bloc.
   -------------------------------------------------------------------------- */
.reseaux {
  display: flex;
  align-items: center;
  gap: 2px;
}

.pied-legal .reseaux a,
.reseaux a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44 px : la règle du projet pour tout geste, tenue jusque dans un pied. */
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 10px;
  text-decoration: none;
  opacity: 0.92;
  transition: opacity 0.15s ease;
}

.pied-legal .reseaux a:hover,
.reseaux a:hover,
.reseaux a:focus-visible {
  opacity: 1;
}

/* Sans cela, la ligne de base du SVG laisse quelques pixels sous l'icône et
   les deux logos ne sont pas alignés avec le texte voisin. */
.reseaux svg {
  display: block;
}

/* Le lien « Accueil du site » des deux espaces (24 août 2026) : la porte de
   sortie des écrans de connexion. Discret mais à 44 px de haut, comme tout
   geste — c'est précisément quand on est perdu qu'une cible se rate. */
.lien-accueil-site {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.88rem;
  color: var(--texte-doux);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lien-accueil-site:hover { color: var(--olive-fonce); }

/* L'activation d'une structure (espace refuge, 10 septembre 2026) : le type
   se choisit d'abord, en trois cartes cliquables de 44 px ; la déclaration
   sur l'honneur est une case avec son texte complet à côté. */
.etiquette-champ { margin: 16px 0 6px; font-weight: 600; }
.choix-type-structure { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.choix-type {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 14px;
  border: 1px solid var(--bordure, #e2ded4); border-radius: 999px; background: #fff; cursor: pointer;
  font-weight: 500;
}
.choix-type:has(input:checked) { border-color: var(--olive); background: var(--olive-clair); }
.choix-type input { margin: 0; }
.case-declaration {
  display: flex; align-items: flex-start; gap: 10px; margin: 16px 0 12px; font-weight: 400; cursor: pointer;
  line-height: 1.4;
}
.case-declaration input { margin-top: 4px; width: 20px; height: 20px; flex: none; }
