  :root {
    --bleu-fonce: #11285F;
    --bleu-moyen: #184093;
    --bleu-clair: #005EAA;
    --vert: #5EB245;
    --vert-fonce: #2B6A1F;
    --ambre: #E8A317;
    --texte: #1D1D18;
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0; padding: 0;
    font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    color: var(--texte);
    background: #F4F6FA;
  }
  /* Fond du document bleu EMV (2026-10-24, « un seul accès au hub ») : seulement
     dans un onglet Chrome ordinaire, où la barre ◀ ● ■ d'Android suit le fond de la
     page, et au rebond. L'icône installée suit, elle, le background_color du
     manifeste. body garde le fond clair et couvre tout l'écran. */
  html { background: var(--bleu-fonce); }
  /* Colonne pleine hauteur pour que la vue ?vue=repertoire (issue #405) puisse
     donner à son contenu exactement la hauteur restante sous l'en-tête, en CSS
     pur (flex:1 plus bas), sans mesurer quoi que ce soit en JS. */
  body { display: flex; flex-direction: column; min-height: 100vh; }
  /* Un composant cache/affiche toujours via l'attribut hidden natif : sans
     cette règle, une classe qui pose display:flex/block sur ce même élément
     gagnerait sur le [hidden] du navigateur et le rendrait visible quand même. */
  [hidden] { display: none !important; }
  header {
    background: var(--bleu-fonce);
    color: #fff;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 20px;
    flex: none;
  }
  .bouton-retour {
    flex: none;
    width: 44px;
    height: 44px;
    line-height: 44px;
    text-align: center;
    border-radius: 10px;
    color: #fff;
    text-decoration: none;
    font-size: 22px;
    background: rgba(255, 255, 255, 0.14);
  }
header img.logo-emv { height: 40px; width: auto; flex: none; display: block; background: #fff; border-radius: 12px; padding: 5px 7px; }
  header h1 {
    margin: 0;
    font-size: 22px;
    font-weight: 800;
    letter-spacing: 0.02em;
  }
  .sous-titre {
    padding: 10px 20px;
    font-size: 13px;
    color: #5b5b55;
    background: #fff;
    border-bottom: 1px solid #e3e3de;
  }
  .bandeau-horsligne {
    background: var(--ambre);
    color: var(--texte);
    padding: 10px 20px;
    font-size: 13px;
    font-weight: 700;
    flex: none;
  }
  #ecran-tuiles, #vue-repertoire, #vue-acces { flex: 1 1 auto; min-height: 0; }
  .controles {
    max-width: 960px;
    margin: 0 auto;
    padding: 14px 20px 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
  }
  /* Rangée « Qui a quoi » (2026-10-12) : ce qui reste à faire (Rébecca) et à
     livrer (Jacques), retard + semaine en cours ; depuis le 2026-10-25, quatre
     cartes du chemin avec Anne-Marie (② et ④). Cibles ≥ 44px ; vert quand il ne
     reste rien. Jamais rouge. */
  .qui-a-quoi {
    max-width: 960px;
    margin: 0 auto;
    padding: 12px 20px 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  .qui-carte {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "nom n" "verbe n";
    align-items: center;
    gap: 2px 10px;
    min-height: 56px;
    padding: 10px 14px;
    background: #fff;
    border: 1px solid #c9cdd6;
    border-left: 5px solid var(--ambre);
    border-radius: 10px;
    font: inherit;
    color: var(--texte);
    text-align: left;
  }
  button.qui-carte { cursor: pointer; }
  button.qui-carte:active { background: #F4F6FA; }
  .qui-carte-ok { border-left-color: var(--vert); background: #F1F9EE; }
  .qui-nom { grid-area: nom; font-size: 13px; color: #5A6478; }
  .qui-n { grid-area: n; font-size: 26px; font-weight: 700; color: var(--bleu-fonce); line-height: 1; }
  .qui-carte-ok .qui-n { color: #2F7A1B; }
  .qui-verbe { grid-area: verbe; font-size: 13px; font-weight: 600; }
  /* 4 pastilles du chemin (2026-10-25) : remplies par colonne, Anne-Marie sous Rébecca (②) et
     sous Jacques (④). Même 2 × 2 au cellulaire et à l'ordinateur ; « – » quand l'étape est illisible. */
  .qui-a-quoi-chemin { grid-auto-flow: column; grid-template-rows: repeat(2, auto); }
  .qui-carte-inconnue { border-left-color: #c9cdd6; }
  .qui-carte-inconnue .qui-n { color: #5A6478; }
  @media (max-width: 700px) {
    .qui-a-quoi { padding: 12px 12px 0; gap: 8px; }
    .qui-carte { padding: 8px 10px; gap: 2px 6px; }
    .qui-n { font-size: 22px; }
  }
  .interrupteur {
    display: inline-flex;
    border: 1px solid #c9cdd6;
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
    flex: none;
  }
  .interrupteur .segment {
    border: none;
    background: #fff;
    color: var(--texte);
    padding: 10px 16px;
    min-height: 44px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .interrupteur .segment[aria-pressed="true"] { background: var(--bleu-fonce); color: #fff; }
  #recherche {
    flex: 1;
    min-width: 180px;
    min-height: 44px;
    border: 1px solid #c9cdd6;
    border-radius: 10px;
    padding: 0 14px;
    font-size: 14px;
    color: var(--texte);
  }
  main { padding: 20px; max-width: 960px; margin: 0 auto; }
  .grille {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 16px;
  }
  .tuile {
    position: relative;
    display: block;
    text-decoration: none;
    color: #1D1D18;
    background: #fff;
    border-radius: 12px;
    border: 1px solid #e3e3de;
    border-left: 4px solid var(--c2, var(--bleu-moyen));
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    padding: 16px 52px 16px 16px;
    min-height: 44px;
    min-width: 0;
    box-shadow: 0 1px 2px rgba(17, 40, 95, 0.08);
  }
  .tuile:hover { background: var(--halo, #F4F6FA); }
  .tuile .ligne { display: flex; align-items: center; gap: 10px; }
  .tuile .emoji {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px; height: 36px;
    border-radius: 50%;
    background: var(--c1, #e3e3de);
    font-size: 19px;
  }
  .tuile .nom { font-weight: 700; color: #1D1D18; }
  .tuile .aide { font-size: 13px; margin-top: 6px; color: #4a4a44; }
  .tuile .compteur {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    min-width: 0;
  }
  /* compteur.lignes (issue #464) : plusieurs lignes empilées sous le nom du
     module — la pastille reste unique, alignée sur la PREMIÈRE ligne, donc
     remontée en haut plutôt que centrée verticalement sur tout le bloc. */
  .tuile .compteur.multiligne { align-items: flex-start; }
  .tuile .compteur.multiligne .pastille { margin-top: 4px; }
  .tuile .compteur .pastille {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 50%;
  }
  .tuile .compteur .texte-compteur {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: #1D1D18;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Compteur figé (ex. « AppSheet ») pour une tuile sans clé au Worker :
     gris, jamais coloré comme un vrai compteur, pas de pastille. */
  .tuile .compteur .texte-compteur-fixe { color: #8a8a82; }
  .tuile .compteur-lignes {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .tuile .ligne-compteur {
    font-size: 13px;
    color: #1D1D18;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Lignes au-delà de la 3e : cachées tant que la tuile n'est pas dépliée
     (bouton « +N autres », voir compteur-plus plus bas). */
  .tuile .ligne-compteur-cachee { display: none; }
  .tuile .compteur.deplie .ligne-compteur-cachee { display: block; }
  .tuile .compteur-plus {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    border: none;
    background: transparent;
    color: var(--bleu-clair);
    font-size: 12px;
    font-weight: 700;
    padding: 0;
    cursor: pointer;
  }

  /* ---------- TUILE GÉNÉRIQUE (issue #479) ----------
     lignes/pastilles/alerte de la tuile { lignes, pastilles, alerte, lien }
     publiée par le hub (hub/Tuiles.js) et transportée telle quelle par le
     Worker (worker/src/index.js). Remplace, pour les tuiles qui la publient,
     le rendu compteur.texte/lignes ci-dessus (`.compteur.multiligne` etc.,
     conservé pour le bandeau de relais et les reprises directes de
     `compteur`) — une seule tuile (`.compteur.tuile-generique`) empile
     lignes puis pastilles puis alerte, toujours dans cet ordre. */
  .tuile .compteur.tuile-generique { flex-direction: column; align-items: stretch; gap: 4px; }
  .tuile-lignes { display: flex; flex-direction: column; gap: 2px; }
  .tuile-ligne { display: flex; align-items: center; gap: 6px; min-width: 0; }
  .tuile-ligne-point { flex: none; width: 8px; height: 8px; border-radius: 50%; }
  .tuile-ligne-texte {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: #1D1D18;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .tuile-ligne-bouton, .tuile-alerte-bouton {
    flex: none;
    min-height: 28px;
    padding: 0 8px;
    border: none;
    border-radius: 6px;
    background: var(--bleu-fonce);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
  }
  /* Pastilles 2×2 (issue #479) : jusqu'à 4, deux colonnes toujours — avec 2
     ou 3 pastilles la grille reste sur 2 colonnes (une case incomplète),
     jamais un réalignement qui ferait bouger la mise en page selon le
     compte. */
  .tuile-pastilles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 8px;
    margin-top: 2px;
  }
  .tuile-pastille {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 32px;
    padding: 2px 0;
    border: none;
    background: transparent;
    text-align: left;
    cursor: default;
  }
  button.tuile-pastille { cursor: pointer; }
  .tuile-pastille-valeur { font-size: 14px; font-weight: 800; color: var(--bleu-fonce); line-height: 1.2; }
  .tuile-pastille-etiquette {
    font-size: 11px;
    color: #6b6b64;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Alerte (issue #479) : le bouton qui la règle est collé à côté d'elle,
     jamais ailleurs sur la tuile (règle EMV, voir CLAUDE.md). */
  .tuile-alerte {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 2px;
    padding-top: 4px;
    border-top: 1px solid #e3e3de;
  }
  .tuile-alerte-texte { flex: 1; min-width: 0; font-size: 12px; font-weight: 700; }
  .tuile-alerte-rouge .tuile-alerte-texte { color: var(--rouge, #C62828); }
  .tuile-alerte-ambre .tuile-alerte-texte { color: #E8A317; }
  .tuile-alerte-vert .tuile-alerte-texte { color: #5EB245; }
  .tuile-alerte-neutre .tuile-alerte-texte { color: #1D1D18; }

  .etat-pied {
    max-width: 960px;
    margin: 8px auto 0;
    padding: 0 20px;
    font-size: 12px;
    color: #6b6b64;
  }
  .etoile {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 44px;
    height: 44px;
    border: none;
    background: transparent;
    color: var(--bleu-fonce);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .vide {
    background: #fff;
    border: 1px dashed #c9cdd6;
    border-radius: 12px;
    padding: 20px;
    font-size: 14px;
    color: #4a4a44;
  }
  .vide strong { color: var(--bleu-fonce); }

  /* ---------- BANDEAU DE RELAIS (issue #444) ----------
     Une ligne, au-dessus de la grille : où en est la tournée de la semaine.
     Lu dans ETAT.modules.relais (Worker /etat — même route que les autres
     compteurs), jamais un calcul côté coquille. Couleurs identiques à
     COULEURS_COMPTEUR (script plus bas) pour rester cohérent avec les
     pastilles de compteur déjà affichées sur les tuiles. Caché tant
     qu'aucun compteur.texte n'est disponible — même convention [hidden] que
     le reste de la coquille, jamais une ligne vide affichée. */
  .relais-bandeau {
    max-width: 960px;
    margin: 14px auto 0;
    padding: 10px 14px;
    border-radius: 10px;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.5;
  }
  @media (max-width: 700px) { .relais-bandeau { margin: 10px 12px 0; font-size: 12.5px; } }

  /* ---------- ONGLET « TOURNÉE » (issue #464, #491, #558) ----------
     Remplace la grille par les 5 étapes du circuit, empilées 1->5, quand cet
     onglet est actif. Étapes ①②③ recalculées côté coquille à partir des
     compteurs déjà publics de checklist/comptabilisation/trailer-jack (même
     correspondance vert/orange/rouge -> fait/en_cours/bloqué que
     relaisEtapeModule_, hub/Relais.js) : le Worker n'expose pas
     relais.etapes (voir docs/connaissances/worker.md). ④/⑤ restent
     toujours « — »/« à venir », comme côté hub — jamais un état deviné.
     Depuis #558, chaque étape montre la tuile générique complète
     (.tournee-tuile, même moteur que la grille) plutôt qu'une ligne
     compacte ; les numéros vivent sur une ligne de circuit dédiée
     (.tournee-etape-item::before), jamais superposés à la tuile. */
  .tournee { display: flex; flex-direction: column; gap: 14px; }
  .tournee-entete { margin: 0; font-weight: 800; color: var(--bleu-fonce); font-size: 15px; }
  .tournee-message { background: #fff; border: 1px dashed #c9cdd6; border-radius: 12px; padding: 16px; font-size: 14px; color: #4a4a44; }

  /* En-tête Sem/Sect modifiable (issue #558, bureau/admin seulement). */
  .tournee-entete-zone { background: #fff; border: 1px solid #e3e3de; border-radius: 12px; padding: 14px 16px; }
  .tournee-entete-ligne { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
  .tournee-entete-titre { font-weight: 800; color: var(--bleu-fonce); font-size: 17px; }
  .tournee-entete-modifier { font-weight: 700; }
  .tournee-entete-sous { margin: 4px 0 0; font-size: 12.5px; color: #6b6b64; }
  .tournee-entete-formulaire { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
  .tournee-entete-champs { display: flex; gap: 10px; flex-wrap: wrap; }
  .tournee-champ { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 120px; }
  .tournee-champ label { font-size: 12px; font-weight: 700; color: #4a4a44; }
  .tournee-champ input {
    min-height: 44px; border: 1px solid #c9cdd6; border-radius: 10px;
    padding: 0 12px; font-size: 14px; color: var(--texte);
  }
  .tournee-entete-boutons { display: flex; flex-direction: column; gap: 10px; }
  .tournee-entete-bouton-ligne { display: flex; flex-direction: column; gap: 2px; }
  .tournee-entete-bouton-ligne button {
    min-height: 44px; border: none; border-radius: 10px;
    font-weight: 700; font-size: 14px; cursor: pointer;
  }
  .tournee-entete-bouton-ligne .aide-bouton { margin: 0; font-size: 11.5px; color: #8a8a82; }
  #tournee-entete-enregistrer { background: var(--bleu-fonce); color: #fff; }
  #tournee-entete-revenir { background: #fff; border: 1px solid #c9cdd6; color: var(--texte); }
  .tournee-entete-annuler { align-self: flex-start; }
  .tournee-entete-erreur { color: #C62828; font-size: 13px; margin: 0; font-weight: 700; }

  /* Ligne de circuit + numéros gros, ENTRE les tuiles (issue #558). Rail
     toujours marine (var(--bleu-fonce)) : seul le cercle change de couleur
     selon l'état de l'étape (tourneeCouleurEtape_, tuiles.js). Constantes
     partagées avec le calc() du média desktop plus bas : cercle 48px, écart
     16px, tuile 480px max — si l'une bouge, ajuster l'autre. */
  .tournee-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
  .tournee-etape-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-bottom: 20px;
  }
  .tournee-etape-item:last-child { padding-bottom: 0; }
  .tournee-etape-item:not(:last-child)::before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 50%;
    width: 4px;
    background: var(--bleu-fonce);
    transform: translateX(-50%);
    z-index: 0;
  }
  .tournee-circuit-num {
    position: relative;
    z-index: 2;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin-bottom: 12px;
    border-radius: 50%;
    background: var(--bleu-fonce);
    color: #fff;
    font-size: 22px;
    font-weight: 800;
    box-shadow: 0 2px 6px rgba(17, 40, 95, 0.3);
  }
  .tournee-etape-item.tournee-etape-orange .tournee-circuit-num { background: var(--ambre); }
  .tournee-etape-item.tournee-etape-vert .tournee-circuit-num { background: var(--vert); }
  .tournee-etape-item.tournee-etape-rouge .tournee-circuit-num { background: #C62828; }
  .tournee-circuit-tuile { position: relative; z-index: 1; width: 100%; max-width: 480px; }
  .tournee-circuit-tuile .tournee-tuile { position: relative; width: 100%; }
  .tournee-etape-item.tournee-etape-orange .tournee-tuile {
    border-color: var(--ambre);
    box-shadow: 0 4px 12px rgba(232, 163, 23, 0.35);
  }
  /* Mise à jour du module (2026-10-14) : ligne lisible, jamais une cible tactile à part. */
  .maj-module {
    margin: 8px 0 0;
    padding-top: 6px;
    border-top: 1px dashed #D9DFEB;
    font-size: 13px;
    font-weight: 700;
    color: var(--vert-fonce, #2B6A1F);
    overflow-wrap: anywhere;
  }
  .maj-module-en-cours { color: #8A5A00; }
  /* Repli de la publication (2026-10-21) : code et « ce qui a changé », fermé par défaut. */
  .maj-module-repli summary { cursor: pointer; padding: 13px 0; }
  .maj-module-repli p { margin: 4px 0; font-weight: 600; color: #5B6478; }
  .maj-module-repli ul { margin: 2px 0 0; padding-left: 18px; font-weight: 500; color: #3A4256; }
  .maj-module-repli li { margin: 2px 0; }
  /* Parcours des tournées (option A) : un chiffre par tuile d'étape ; vert + halo quand rien à faire. */
  .chiffre-etape { display: flex; align-items: baseline; gap: 8px; margin: 8px 0 0; }
  .chiffre-etape b { font-size: 32px; line-height: 1; font-weight: 700; color: #B36F00; font-variant-numeric: tabular-nums; }
  .chiffre-etape span { font-size: 14px; font-weight: 600; color: #5B6478; }
  .chiffre-etape-fini b { color: #2E9E5B; }
  /* Détail Sem/Sect sous le chiffre d'étape (« Sem 42 · Sect 3 : 3 clients », 3 lignes au plus). */
  .detail-etape { list-style: none; margin: 6px 0 0; padding: 0; font-size: 13px; color: #5B6478; }
  .detail-etape li { margin: 2px 0; }
  .detail-etape-autres { font-style: italic; }
  .tuile.tuile-etape-fini, .tournee-tuile-vide.tuile-etape-fini {
    border-left-color: #2E9E5B;
    background: #E3F5EA;
    box-shadow: 0 0 0 3px rgba(46, 158, 91, 0.35);
  }
  .tuile.tuile-etape-travail, .tournee-tuile-vide.tuile-etape-travail { border-left-color: var(--ambre); }
  .tournee-responsable {
    display: inline-block;
    margin: 4px 0 0;
    padding: 2px 10px;
    border-radius: 999px;
    background: #EDEFF5;
    color: var(--bleu-fonce);
    font-size: 12px;
    font-weight: 700;
  }
  .tournee-ouvrir {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 0 12px;
    border-radius: 8px;
    background: var(--bleu-fonce);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
  }
  .tournee-tuile-vide {
    background: #fff;
    border: 1px solid #e3e3de;
    border-left: 4px solid var(--bleu-moyen);
    border-radius: 12px;
    padding: 16px;
    min-height: 44px;
  }
  .tournee-tuile-vide .nom { font-weight: 700; color: #1D1D18; }
  .tournee-tuile-vide .aide { font-size: 13px; margin-top: 6px; color: #4a4a44; }

  @media (max-width: 700px) {
    .tournee-circuit-num { width: 44px; height: 44px; font-size: 22px; margin-bottom: 10px; }
    .tournee-entete-champs { flex-direction: column; }
  }

  /* Ordinateur (issue #558, règle permanente) : les tuiles gardent leur
     largeur de grille, centrées ; la ligne de circuit passe à gauche
     plutôt qu'au-dessus de chaque tuile. Le décalage (-248px) est le calcul
     fixe du centre du cercle (48px) dans la rangée centrée num+écart+tuile
     (48 + 16 + 480 = 544px de large) : à recalculer si l'une des trois
     constantes ci-dessus change. */
  @media (min-width: 701px) {
    .tournee-etape-item {
      flex-direction: row;
      align-items: flex-start;
      justify-content: center;
      gap: 16px;
    }
    .tournee-etape-item:not(:last-child)::before {
      left: calc(50% - 248px);
      transform: none;
    }
    .tournee-circuit-num { margin-bottom: 0; }
  }

  /* Carte de recherche pour une tuile de circuit (issue #558) : un <button>
     habillé comme une tuile normale (même classe .tuile) mais qui renvoie
     vers l'onglet Tournée plutôt que d'ouvrir le module — resets propres au
     <button> (largeur, alignement, police) que .tuile n'a pas besoin de
     poser pour son cas <a> habituel. */
  button.tuile-circuit-trouve {
    display: block;
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
  }
  .pied-installation {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 20px 8px;
    font-size: 12px;
    color: #6b6b64;
  }
  .bouton-installer {
    min-height: 44px;
    padding: 8px 16px;
    border: 1px solid var(--bleu-fonce);
    border-radius: 8px;
    background: #fff;
    color: var(--bleu-fonce);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
  }

  /* Porte d'accès par passkey (issue #409). */
  .carte-porte {
    max-width: 420px;
    margin: 14px auto 0;
    padding: 16px;
    background: #fff;
    border: 1px solid #e3e3de;
    border-radius: 12px;
    text-align: center;
  }
  .carte-porte-titre { margin: 0 0 10px; font-weight: 800; color: var(--bleu-fonce); }
  .bouton-porte {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    width: 100%;
    padding: 0 16px;
    border: none;
    border-radius: 8px;
    background: var(--bleu-fonce);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
  }
  .carte-porte .eawrap { justify-content: center; margin-top: 10px; }
  .carte-porte-aide { font-size: 12px; color: #6b6b64; margin: 8px 0 0; }
  .carte-porte-erreur { color: #C62828; font-size: 13px; margin: 8px 0 0; }
  .acces-confirmation { max-width: 520px; margin: 0 auto 12px; padding: 10px 12px; border-radius: 8px; border-left: 4px solid var(--vert); background: #F1F9EE; color: var(--vert-fonce, #2B6A1F); font-size: 14px; font-weight: 600; }
  .carte-porte-suite { font-size: 12px; color: var(--bleu-fonce); margin: 6px 0 0; }
  .carte-porte-detail { margin: 8px 0 0; text-align: left; }
  .carte-porte-detail summary { font-size: 12px; color: #6b6b64; cursor: pointer; }
  .carte-porte-detail pre {
    white-space: pre-wrap;
    font-size: 11px;
    color: #6b6b64;
    background: #f4f4f0;
    border-radius: 6px;
    padding: 8px;
    margin: 6px 0 0;
  }
  .carte-porte-domaine { font-size: 13px; color: #6b6b64; margin: 4px 0 0; }

  /* Zone utilisateur (en-tête, en haut à droite) — issue #409. */
  .zone-utilisateur { margin-left: auto; position: relative; flex: none; }
  .bouton-utilisateur {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    min-height: 44px;
    padding: 4px 10px;
    border: none;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    font-size: 13px;
    cursor: pointer;
  }
  .utilisateur-role { font-size: 11px; opacity: 0.85; }
  .menu-utilisateur {
    position: absolute;
    top: 48px;
    right: 0;
    background: #fff;
    border: 1px solid #e3e3de;
    border-radius: 10px;
    box-shadow: 0 4px 14px rgba(17, 40, 95, 0.18);
    min-width: 200px;
    overflow: hidden;
    z-index: 5;
  }
  .menu-utilisateur button {
    display: block;
    width: 100%;
    min-height: 44px;
    padding: 0 16px;
    border: none;
    background: #fff;
    color: var(--texte);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
  }
  .menu-utilisateur button:hover { background: #F4F6FA; }

  /* Invitation (?inviter=) et vue Accès (?vue=acces) — issue #409. */
  .contenu-invitation { flex: 1 1 auto; display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px; }
  .carte-invitation { max-width: 420px; width: 100%; background: #fff; border: 1px solid #e3e3de; border-radius: 12px; padding: 20px; }
  .carte-invitation label, .panneau-acces label, .etiquette-champ { display: block; font-size: 13px; font-weight: 700; margin: 12px 0 4px; color: var(--texte); }
  .carte-invitation input[type="text"], .panneau-acces input[type="text"], .panneau-acces select {
    width: 100%;
    min-height: 44px;
    border: 1px solid #c9cdd6;
    border-radius: 8px;
    padding: 0 12px;
    font-size: 14px;
  }
  .panneau-acces { max-width: 520px; margin: 0 auto 16px; padding: 16px; background: #fff; border: 1px solid #e3e3de; border-radius: 12px; }
  .titre-panneau-acces { font-size: 15px; margin: 16px 0 8px; color: var(--bleu-fonce); }
  .cases-modules { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0; }
  .case-module { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; background: #F4F6FA; border-radius: 8px; padding: 6px 10px; min-height: 32px; }
  .ligne-boutons-acces { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
  .bouton-secondaire-acces, .bouton-action-acces {
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid var(--bleu-fonce);
    border-radius: 8px;
    background: #fff;
    color: var(--bleu-fonce);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
  }
  .carte-utilisateur .ligne-boutons-acces { margin-top: 10px; }

  /* Bande de confirmation rendue dans la page (issue #904) : remplace les
     confirm() natifs, bloqués silencieusement en PWA standalone. Toujours
     dépliée juste sous la ligne d'actions qui l'a ouverte. */
  .zone-confirmation-acces {
    margin-top: 10px;
    padding: 10px 12px;
    background: #F4F6FA;
    border: 1px solid #c9cdd6;
    border-radius: 8px;
  }
  .confirmation-acces-texte { margin: 0 0 8px; font-size: 13px; color: #2a2f3a; }
  .bouton-action-acces-danger {
    border-color: #C62828;
    background: #C62828;
    color: #fff;
  }
  /* Échec d'une action confirmée (issue #937) : le message reste dans la
     bande, jamais renvoyé en haut de la vue via afficherErreurAdmin_. */
  .confirmation-acces-erreur-bloc { margin-top: 4px; }
  .confirmation-acces-erreur { margin: 0 0 8px; font-size: 13px; color: #C62828; font-weight: 700; }

  /* Utilisateur révoqué (issue #937, complément avant fusion) : distinct
     d'un coup d'oeil d'un compte actif, tableau et cartes. */
  .ligne-utilisateur-revoque { opacity: 0.55; }

  /* Vue Accès compacte (issue #1007) : tableau ordinateur dense (une ligne
     ≈ 52px) et fiches cellulaire à 3 lignes, jamais la liste des modules au
     long dans une cellule. Toute cette structure (révoqués séparés, aide
     dépliable, sélecteur de tri mobile) est construite dynamiquement par
     web/js/vue-acces.js, sans changement à index.html. */
  #acces-tableau th, #acces-tableau td { padding: 10px 12px; vertical-align: middle; }
  #acces-admin { padding-bottom: 110px; }
  #acces-compteur { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; white-space: normal; }
  #acces-bouton-inviter { background: var(--vert); border-color: var(--vert); color: #fff; }
  #acces-bouton-inviter:hover { background: #4A8F38; border-color: #4A8F38; }

  .acces-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: 50%; flex: none;
    background: var(--bleu-fonce); color: #fff; font-weight: 800; font-size: 13px;
  }
  .acces-avatar-revoque { background: #b8bfcc; }
  .acces-ligne-nom { display: inline-flex; align-items: center; gap: 8px; }
  .acces-nom-texte { font-weight: 700; }

  .acces-badge { display: inline-flex; align-items: center; border-radius: 999px; padding: 3px 10px; font-size: 12px; font-weight: 700; white-space: nowrap; }
  .acces-badge-admin { color: #11285F; background: #e6ebf7; }
  .acces-badge-bureau { color: #005EAA; background: #e3f0fb; }
  .acces-badge-terrain { color: #3f7f2c; background: #e8f5e3; }
  .acces-badge-etat-actif { color: #2f7d32; background: #e6f4e6; }
  .acces-badge-etat-revoque { color: #5b6472; background: #e7e9ee; }
  .acces-badge-modules-tous { color: #11285F; background: #eef1fa; }
  .acces-badge-compteur { color: #3a3f4b; background: #F4F6FA; }

  .acces-modules-apercu { display: inline-flex; align-items: center; gap: 4px; flex-wrap: nowrap; }
  .acces-emoji-module { font-size: 15px; }
  .acces-modules-plus { font-size: 12px; color: #8a8a82; }
  .acces-lien-modules { border: none; background: transparent; color: var(--bleu-clair); font-size: 12px; font-weight: 700; cursor: pointer; padding: 0; margin-left: 2px; min-height: 24px; }

  .acces-fleche-tri { opacity: .35; font-size: 11px; margin-left: 2px; }
  .acces-fleche-tri-active { opacity: 1; }

  .acces-actions { display: flex; gap: 6px; flex-wrap: nowrap; justify-content: flex-end; }
  .acces-bouton-compact { min-height: 28px; padding: 0 10px; font-size: 12px; white-space: nowrap; }
  .acces-cellule-actions { text-align: right; }

  /* Ligne dépliée (issue #1007, point 3) : pleine largeur sous la personne,
     seul endroit qui affiche encore la liste au long des modules ET les
     boutons « Retirer <appareil> » individuels. */
  .acces-ligne-deplie > td { white-space: normal; background: #F8F9FC; padding: 12px 16px; }
  .acces-deplie { display: flex; flex-direction: column; gap: 10px; }
  .acces-deplie-modules, .acces-deplie-appareils { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
  .acces-deplie-modules li { background: #fff; border: 1px solid #e3e3de; border-radius: 8px; padding: 4px 10px; font-size: 13px; }
  .acces-appareil-item { display: flex; align-items: center; gap: 8px; background: #fff; border: 1px solid #e3e3de; border-radius: 8px; padding: 6px 10px; font-size: 13px; }
  .acces-appareil-item-vide { color: #8a8a82; border-style: dashed; }
  .carte-utilisateur .acces-deplie { margin-top: 10px; padding-top: 10px; border-top: 1px solid #e3e3de; }

  /* Révoqués séparés (point 4) et aide dépliable (point 6), repliés par
     défaut, sous le tableau/les fiches principales. */
  .acces-revoques-details, .acces-aide-details { margin: 14px 0; }
  .acces-revoques-details summary, .acces-aide-details summary { cursor: pointer; font-weight: 700; color: var(--bleu-fonce); padding: 8px 0; }
  .acces-revoques-details .repertoire-cartes, .acces-revoques-details .repertoire-tableau-conteneur { margin-top: 8px; }
  .acces-aide-details ul { margin: 8px 0 0; padding-left: 18px; font-size: 13px; color: #4a4a44; }
  .acces-aide-details li { margin: 4px 0; }

  /* Fiches cellulaire à 3 lignes (point « cellulaire », issue #1007). */
  .acces-carte-ligne1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .acces-carte-ligne2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: #6b6b64; margin-top: 6px; }
  .acces-carte-ligne3 { margin-top: 8px; }
  .acces-carte-ligne3 .acces-actions { justify-content: stretch; }
  .acces-carte-ligne3 .acces-bouton-compact { flex: 1; }

  /* Sélecteur de tri compact, cellulaire seulement (bascule dans le bloc
     @media (max-width: 700px) plus bas). */
  .acces-tri-mobile { display: none; margin: 0 0 10px; }
  .acces-tri-mobile select { width: 100%; min-height: 44px; border: 1px solid #c9cdd6; border-radius: 8px; padding: 0 12px; font-size: 14px; }

  /* Vue ?vue=repertoire (issue #405) : lecture native du répertoire clients
     via le Worker (AppSheet refuse l'affichage en iframe — issue #405),
     modification toujours par le bouton « Ouvrir dans AppSheet ↗ ». */
  .vue-cadre { display: flex; flex-direction: column; min-height: 0; }
  .barre-cadre {
    flex: none;
    display: flex;
    justify-content: flex-end;
    padding: 8px 12px;
    background: #fff;
    border-bottom: 1px solid #e3e3de;
  }
  .bouton-externe {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--bleu-fonce);
    border-radius: 8px;
    color: var(--bleu-fonce);
    text-decoration: none;
    font-size: 13px;
    font-weight: 700;
    background: #fff;
    cursor: pointer;
  }
  .chargement-cadre { flex: none; display: flex; justify-content: center; padding: 16px; }

  .contenu-repertoire { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 12px 20px; overflow-y: auto; overflow-x: hidden; }
  .barre-recherche-repertoire { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; flex: none; }
  .barre-recherche-repertoire input[type="search"] { flex: 1; min-width: 200px; min-height: 44px; border: 1px solid #c9cdd6; border-radius: 10px; padding: 0 14px; font-size: 14px; }
  .compteur-repertoire { font-size: 13px; color: #6b6b64; white-space: nowrap; }

  /* Déclencheur du panneau « Fiche client » (issue #1031) — commun table et
     cartes : bouton clairement distinct d'un lien Jira (issue #1199 — le
     style bleu souligné laissait croire à un vrai lien hypertexte), + petit
     lien secondaire optionnel vers Jira. */
  .declencheur-fiche { display: inline-flex; align-items: center; gap: 6px; }
  .bouton-fiche-client { border: none; background: transparent; padding: 0; margin: 0; font: inherit; font-weight: 700; color: var(--texte); text-decoration: none; cursor: pointer; }
  .lien-jira-secondaire { font-size: 11px; color: #6b6b64; text-decoration: none; white-space: nowrap; }
  /* Copie l'URL Jira réelle (issue #1048) — bouton, mêmes proportions que le
     lien secondaire ci-dessus, distingué par l'icône 🔗 du 📋 qui copie le
     numéro seul (rendreBoutonCopieJira_). */
  .bouton-copie-lien-jira { border: none; background: transparent; padding: 0; margin: 0; font: inherit; font-size: 11px; color: #6b6b64; cursor: pointer; white-space: nowrap; }

  /* Cellulaire (< 700px, règle générale issue #195) : cartes groupées par client. */
  .repertoire-cartes { display: none; }
  .groupe-client { padding: 10px 2px 4px; }
  .groupe-client-nom { font-weight: 800; color: var(--bleu-fonce); font-size: 15px; }
  .groupe-client-emplacement { font-size: 12px; color: #6b6b64; margin-top: 2px; }
  .groupe-client-jira-ligne { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
  .groupe-client-jira { font-size: 12px; color: var(--bleu-clair); text-decoration: none; }
  .groupe-client-jira-copie { display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; padding: 0; min-width: 44px; min-height: 44px; font-size: 14px; cursor: pointer; color: var(--bleu-clair); }
  .carte-contact { background: #fff; border: 1px solid #e3e3de; border-radius: 12px; padding: 12px; margin: 8px 0; }
  .carte-contact-nom { font-weight: 700; }
  .carte-contact-titre { font-size: 13px; color: #6b6b64; margin-top: 2px; }
  .bouton-carte-repertoire {
    display: block;
    width: 100%;
    min-height: 44px;
    line-height: 44px;
    text-align: center;
    margin-top: 8px;
    border: 1px solid var(--bleu-fonce);
    border-radius: 8px;
    color: var(--bleu-fonce);
    text-decoration: none;
    font-size: 14px;
    font-weight: 700;
  }

  /* Ordinateur (>= 700px) : tableau dense, triable, défilement propre au
     conteneur — jamais de défilement horizontal de la page (issue #195). */
  .repertoire-tableau-conteneur { display: block; overflow-x: auto; border: 1px solid #e3e3de; border-radius: 12px; }
  .repertoire-tableau { border-collapse: collapse; width: 100%; font-size: 13px; }
  .repertoire-tableau th, .repertoire-tableau td { padding: 8px 12px; border-bottom: 1px solid #e3e3de; text-align: left; white-space: nowrap; }
  .repertoire-tableau thead th { background: #F4F6FA; }
  .entete-tri { border: none; background: transparent; font-weight: 700; font-size: 13px; cursor: pointer; padding: 0; color: var(--texte); }
  .repertoire-tableau td a { color: var(--bleu-clair); }

  .pied-repertoire { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 14px; padding: 10px 20px; font-size: 12px; color: #6b6b64; border-top: 1px solid #e3e3de; background: #fff; }
  .lien-discret { border: none; background: transparent; color: var(--bleu-clair); font-size: 12px; cursor: pointer; padding: 8px 0; min-height: 44px; }

  /* Autolaveuse EMV — même composant visuel que drive/emv-taches-vue.html et
     drive/emv-livraisons-vue.html (issue #429, remplace l'ancien indicateur à personnage des
     issues #375/#380) : jamais un sablier ni un rond qui tourne sans rapport avec un vrai
     traitement (règle permanente EMV — voir
     docs/connaissances/hub.md). web/index.html est une page statique Cloudflare Pages, sans
     Apps Script : elle ne peut pas charger drive/emv-activite-client.js.txt à l'exécution,
     donc ce bloc est une copie fixe du même dessin (CSS/SVG pur, aucune image ni bibliothèque). */
  .eawrap { display: flex; align-items: center; gap: 7px; padding: 8px 4px; min-height: 44px; }
  .eascene { position: relative; width: 40px; height: 16px; flex: none; overflow: hidden; }
  .eapiste { position: absolute; left: 0; right: 0; bottom: 2px; height: 2px; border-radius: 2px; background: #dfe4ee; }
  .eamachine {
    position: absolute; bottom: 0; left: 0; width: 18px; height: 12px; border-radius: 3px 6px 6px 3px;
    background: var(--bleu-fonce); animation: earoule 1.6s ease-in-out infinite;
  }
  .eamachine::before, .eamachine::after {
    content: ''; position: absolute; bottom: -2px; width: 4px; height: 4px; border-radius: 50%; background: #11285F;
  }
  .eamachine::before { left: 2px; }
  .eamachine::after { right: 2px; }
  .eapoussiere {
    position: absolute; bottom: 1px; width: 3px; height: 3px; border-radius: 50%; background: #8a94a6;
    animation: eaavale 1.6s ease-in-out infinite;
  }
  .eapoussiere:nth-child(3) { left: 22px; }
  .eapoussiere:nth-child(4) { left: 28px; animation-delay: .15s; }
  .eapoussiere:nth-child(5) { left: 34px; animation-delay: .3s; }
  @keyframes earoule { 0%, 100% { left: 0; } 50% { left: 20px; } }
  @keyframes eaavale { 0%, 15% { opacity: 1; } 45%, 100% { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .eamachine, .eapoussiere { animation: none; } }

  /* Panneau « Fiche client » (issue #1031) — modale centrée sur ordinateur,
     feuille ancrée en bas sur cellulaire (règle du point de bascule commun
     @media (max-width: 700px) plus bas). */
  .fiche-client-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: rgba(17, 40, 95, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
  }
  .fiche-client-panneau {
    background: #fff;
    border-radius: 14px;
    width: 100%;
    max-width: 560px;
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    box-shadow: 0 12px 40px rgba(17, 40, 95, 0.35);
  }
  .fiche-client-barre {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    background: var(--bleu-fonce);
    color: #fff;
    border-radius: 14px 14px 0 0;
  }
  .fiche-client-titre { margin: 0; font-size: 16px; font-weight: 800; }
  .fiche-client-fermer {
    flex: none;
    min-width: 44px;
    min-height: 44px;
    border: none;
    background: transparent;
    color: #fff;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    border-radius: 8px;
  }
  .fiche-client-fermer:hover { background: rgba(255, 255, 255, 0.15); }
  .fiche-client-corps { flex: 1 1 auto; overflow-y: auto; padding: 16px 18px; }
  .fiche-client-entete { margin-bottom: 6px; }
  .fiche-client-adresse { font-size: 13px; color: #4a4a44; }
  .fiche-client-entete .lien-jira-secondaire { display: inline-block; margin-top: 4px; }
  .fiche-client-entete .bouton-copie-lien-jira { display: inline-block; margin-top: 4px; margin-left: 10px; }
  .fiche-client-section-titre { font-size: 13px; font-weight: 800; color: var(--bleu-fonce); margin: 16px 0 8px; }
  .fiche-client-champ { padding: 8px 0; border-bottom: 1px solid #f0f0ec; }
  .fiche-client-libelle { font-size: 12px; font-weight: 700; color: #6b6b64; }
  .fiche-client-valeur { font-size: 14px; white-space: pre-wrap; word-break: break-word; margin-top: 2px; }
  .fiche-client-tournee { padding: 8px 0; border-bottom: 1px solid #f0f0ec; font-size: 13px; }
  .fiche-client-tournee-cle { font-weight: 700; color: var(--bleu-fonce); }
  .fiche-client-tournee-meta { font-size: 12px; color: #6b6b64; margin-top: 2px; }
  .fiche-client-vide { color: #6b6b64; font-size: 13px; margin: 0; }
  /* Piste p126 : groupe « Plus » (tuiles non ouvertes depuis 30 jours, repliées,
     jamais retirées) et tuile « bientôt » (écran pas encore en ligne). */
  .groupe-plus { grid-column: 1 / -1; margin-top: 4px; }
  .groupe-plus > summary {
    cursor: pointer;
    min-height: 44px;
    display: flex;
    align-items: center;
    font-weight: 700;
    color: var(--bleu-moyen, #005EAA);
  }
  .groupe-plus > .grille-plus { margin-top: 8px; }
  .tuile.tuile-bientot { opacity: 0.6; cursor: default; }
  /* Marqueur de migration (js/tuiles.js, rendreMigration_) : sans couleur, en
     bas à droite (l'étoile garde le haut). « AS » = encore Apps Script, avec
     bordure pointillée ; « ◐ » = hybride. */
  .tuile.tuile-as { border-style: dashed dashed dashed solid; border-top-color: #9a9a92; border-right-color: #9a9a92; border-bottom-color: #9a9a92; }
  .tuile .migration {
    position: absolute;
    right: 8px;
    bottom: 6px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.04em;
    color: #4a4a44;
    padding: 2px 4px;
    border: 1px solid #c9c9c2;
    border-radius: 4px;
    background: #fff;
  }
  .tuile.tuile-hybride .migration { font-size: 14px; padding: 0 3px; }
  /* Onglet Tournée : « Ouvrir ↗ » occupe le bas à droite, le marqueur remonte. */
  .tuile.tournee-tuile .migration { bottom: auto; top: 48px; }
  .tuile.tuile-bientot:hover { background: #fff; }
  .fiche-client-erreur { color: #C62828; font-size: 14px; font-weight: 700; margin: 0 0 12px; }

  /* Sous 700px (issue #195) : une colonne, cartes, cibles tactiles ≥ 44px. */
  @media (max-width: 700px) {
    main { padding: 12px; }
    /* minmax(0, 1fr) et non 1fr : « 1fr » vaut minmax(auto, 1fr), donc une
       ligne de tuile en nowrap élargissait toute la colonne et le navigateur
       dézoomait la page (bogue du 2026-10-12). Ainsi la ligne se coupe avec « … ». */
    .grille { grid-template-columns: minmax(0, 1fr); }
    header h1 { font-size: 19px; }
    .controles { flex-direction: column; align-items: stretch; padding: 12px 12px 0; }
    .interrupteur .segment { flex: 1; }
    #recherche { width: 100%; }
    .pied-installation, .etat-pied { padding-left: 12px; padding-right: 12px; }
    .contenu-repertoire { padding: 12px; }
    .barre-recherche-repertoire { flex-direction: column; align-items: stretch; }
    .repertoire-cartes { display: block; }
    .repertoire-tableau-conteneur { display: none; }
    .acces-tri-mobile { display: block; }
    .pied-repertoire { padding: 10px 12px; }
    .carte-porte { margin: 12px 12px 0; }
    .contenu-invitation { padding: 16px 12px; }
    .panneau-acces { margin: 0 0 16px; }
    .bouton-utilisateur { padding: 4px 8px; font-size: 12px; }
    .menu-utilisateur { min-width: 180px; }
    .fiche-client-overlay { align-items: flex-end; padding: 0; }
    .fiche-client-panneau { max-width: none; max-height: 85vh; border-radius: 16px 16px 0 0; }
  }

  /* Bandeau « Nouvelle version disponible » (js/maj.js) : fixe en haut, tant que non mis à jour. */
  .bandeau-maj {
    position: sticky; top: 0; z-index: 1000;
    display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
    padding: 8px 12px; background: var(--bleu-clair); color: #fff; font-size: 14px; font-weight: 700;
  }
  .bandeau-maj[hidden] { display: none; }
  .bandeau-maj button {
    min-height: 44px; padding: 0 16px; border: 0; border-radius: 8px;
    background: #fff; color: var(--bleu-fonce); font-size: 14px; font-weight: 700; cursor: pointer;
  }
