:root{
  --brown:#7c4d2a; --brown-d:#5d3a20; --cream:#f7f1e8; --paper:#fffdf9;
  --ink:#2b2118; --muted:#6c6152; --line:#e6dcce;
  --green:#2e7d4f; --green-d:#226039; --green-bg:#e6f4ec; --red:#c0392b; --red-bg:#fbeae8;
  --amber:#b5791b; --amber-bg:#fbf1de; --blue:#2c6e8f; --blue-bg:#e6f0f5;
  --shadow:0 1px 3px rgba(60,40,20,.12);
  --radius:12px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--cream); color:var(--ink); font-size:15px; line-height:1.45;
  -webkit-text-size-adjust:100%;
}
a{color:var(--brown);text-decoration:none}
a:hover{text-decoration:underline}
h1{font-size:1.45rem;margin:.2rem 0 1rem}
h2{font-size:1.15rem;margin:1.4rem 0 .7rem}
h3{font-size:1rem;margin:1rem 0 .5rem}
.muted{color:var(--muted)}
small{color:var(--muted)}

/* ---- Top bar ---- */
/* La barre supérieure ne déborde JAMAIS : elle rétrécit d'abord (le nom de
   l'association se tronque), puis passe à la ligne. Sans `flex-wrap`, ses dix
   éléments — retour, marque, recherche, raccourcis, cloche, e-mails, profil,
   bascule de profil, « Quitter », hamburger — mesuraient une trentaine de
   pixels de plus que l'écran d'un téléphone, et TOUTE page de l'application
   débordait horizontalement, grilles comprises. C'est ce défaut de gabarit qui
   masquait les vrais débordements de contenu (cf. `npm run captures`). */
/* Zone sûre — l'en-tête du document déclare `viewport-fit=cover`, donc la page
   s'étend SOUS l'encoche et sous les coins arrondis. En mode installé
   (`display:standalone`) il n'y a plus de barre d'URL au-dessus : sans ces
   `env(...)`, l'heure et la batterie de l'iPhone se superposent au 🐾 et à la
   cloche. Les retraits valent 0 partout ailleurs (navigateur de bureau, Android
   sans découpe), la règle est donc sans effet visible hors de ce cas.
   Le rembourrage passe par des variables pour que la déclinaison sous 620 px
   n'ait qu'à changer les valeurs de base : redéclarer `padding` en raccourci
   là-bas écraserait silencieusement le calcul de zone sûre. */
.topbar{
  --topbar-pad-y:.55rem;--topbar-pad-x:.9rem;
  position:sticky;top:0;z-index:30;display:flex;align-items:center;justify-content:space-between;
  background:var(--brown);color:#fff;box-shadow:var(--shadow);
  padding:calc(var(--topbar-pad-y) + env(safe-area-inset-top))
          calc(var(--topbar-pad-x) + env(safe-area-inset-right))
          var(--topbar-pad-y)
          calc(var(--topbar-pad-x) + env(safe-area-inset-left));
  gap:.4rem;flex-wrap:wrap;row-gap:.35rem;
}
/* Hors production (e-mails non réellement envoyés) : bandeau vert — cf. config.IS_PRODUCTION.
   --green-d et non --green : ce dernier est trop clair pour garder le texte #f3e3d2
   (.who, .brand-txt small) au-dessus du seuil AA. */
.topbar.env-test{background:var(--green-d)}
/* La topbar reste collée en haut (position:sticky) : sans cette marge, une
   ancre (#section) atterrit avec son titre masqué sous la topbar. */
:target{scroll-margin-top:76px}
.brand{display:flex;align-items:center;gap:.5rem;color:#fff;font-weight:700;margin-right:auto;min-width:0}
.brand:hover{text-decoration:none}
.brand .paw{font-size:1.3rem}
.brand-txt{display:flex;flex-direction:column;line-height:1;min-width:0;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis}
.brand-txt small{color:#f3e3d2;font-weight:500;font-size:.62rem}
.topbar-actions{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;justify-content:flex-end}
/* Sous 620 px, le libellé de la marque cède la place : le 🐾 reste le lien
   d'accueil, c'est le TEXTE qui part, jamais la cible. */
@media(max-width:620px){
  .brand-txt{display:none}
  /* Seules les valeurs de base changent : le calcul de zone sûre déclaré sur
     .topbar reste en vigueur (cf. le commentaire là-bas). */
  .topbar{--topbar-pad-y:.5rem;--topbar-pad-x:.6rem;gap:.3rem}
  .topbar-actions{gap:.4rem}
}
.who{color:#f3e3d2;font-size:.85rem}
.bell{position:relative;color:#fff;font-size:1.15rem;background:none;border:0;padding:0;cursor:pointer}
.bell .dot{position:absolute;top:-6px;right:-9px;background:var(--red);color:#fff;border-radius:10px;
  font-size:.62rem;padding:1px 5px;font-weight:700}
.bell-ic{width:1em;height:1em;display:inline-block;vertical-align:middle}
/* Panneau de la cloche de rappels (déplié par [data-notif-toggle], cf. app.js).
   Ancré à droite de la cloche ; sur mobile il s'étale plutôt que de déborder
   hors de l'écran (right:0 le garderait sous le bord droit du viewport). */
.notif{position:relative;display:flex;align-items:center}
.notif-panel{position:absolute;top:calc(100% + .5rem);right:0;z-index:60;width:min(24rem,calc(100vw - 1.5rem));
  max-height:min(28rem,70vh);overflow-y:auto;background:var(--paper);color:var(--ink);
  border:1px solid var(--line);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.18);padding:.6rem}
.notif-head{display:flex;justify-content:space-between;align-items:baseline;gap:.5rem;
  padding:.1rem .2rem .45rem;border-bottom:1px solid var(--line);font-size:.9rem}
.notif-list{list-style:none;margin:0;padding:0}
.notif-item{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  padding:.5rem .2rem;border-bottom:1px solid var(--line)}
.notif-item:last-child{border-bottom:0}
.notif-titre{flex:1 1 11rem;display:flex;flex-direction:column;line-height:1.25;font-size:.86rem}
.notif-titre .muted{font-size:.76rem}
.notif-actions{display:flex;gap:.25rem;margin-left:auto}
.notif-actions form{display:inline}
.notif-more{padding:.4rem .2rem 0;font-size:.8rem}
.notif-foot{padding-top:.5rem;margin-top:.3rem;border-top:1px solid var(--line);text-align:right;font-size:.85rem}
.quicklink{display:flex;align-items:center;justify-content:center;width:30px;height:30px;
  border-radius:8px;color:#fff;font-size:1.05rem}
.quicklink:hover{background:rgba(255,255,255,.18);text-decoration:none}
@media(max-width:620px){.quicklink{display:none}}
/* Horloge de simulation décalée (hors production, cf. lib/simulation.js) : fond
   ambre pour trancher sur le vert de la topbar hors-prod — c'est un avertissement,
   pas un raccourci de plus. Le libellé disparaît sur petit écran, l'icône reste. */
.simclock{display:flex;align-items:center;gap:.3rem;padding:.15rem .5rem;border-radius:20px;
  background:var(--amber);color:#fff;font-size:.78rem;font-weight:700;white-space:nowrap}
.simclock:hover{background:#8f5f14;color:#fff;text-decoration:none}
@media(max-width:620px){.simclock .lbl{display:none}}
.btn-ghost{color:#fff;border:1px solid rgba(255,255,255,.5);padding:.25rem .6rem;border-radius:8px;font-size:.8rem}
.btn-ghost:hover{background:rgba(255,255,255,.15);text-decoration:none}

/* ---- Back button ---- */
.topback{background:rgba(255,255,255,.15);color:#fff;border:1px solid rgba(255,255,255,.4);
  width:30px;height:30px;border-radius:8px;font-size:1.05rem;cursor:pointer;flex:0 0 auto;line-height:1}
.topback:hover{background:rgba(255,255,255,.28)}

/* ---- Main nav ----
   La barre de navigation (groupes) est désormais une navbar Bootstrap
   (offcanvas en mobile) — balisage dans partials/header.ejs, thème brun/crème
   dans public/css/brand-bootstrap.css. */

/* ---- Layout ---- */
.container{width:100%;margin:0 auto;padding:1rem 1.2rem 3rem}
/* Pendant bas de la zone sûre de la topbar : en mode installé, la barre de
   gestes de l'iPhone recouvrirait la dernière ligne du pied de page. */
.appfoot{width:100%;margin:0 auto;display:flex;flex-direction:column;gap:.2rem;
  padding:1.2rem calc(1.2rem + env(safe-area-inset-right))
          calc(1.2rem + env(safe-area-inset-bottom)) calc(1.2rem + env(safe-area-inset-left));
  color:var(--muted);font-size:.78rem;border-top:1px solid var(--line)}
/* Bouton qui a l'apparence d'un lien. C'est bien un <button> et non un <a> :
   il n'ouvre pas une adresse, il déclenche une action de la page (ici la modale
   du cache). Un <a href="#"> conviendrait visuellement mais serait annoncé
   comme un lien par un lecteur d'écran, et suivi par le clavier comme tel. */
.lienlike{background:none;border:0;padding:0;font:inherit;color:var(--brown);
  text-decoration:underline;cursor:pointer}
.lienlike:hover{color:var(--brown-d)}

/* ---- Cards & grid ---- */
.card{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);
  padding:1rem;box-shadow:var(--shadow);margin-bottom:1rem}
.card h2:first-child,.card h3:first-child{margin-top:0}
.grid{display:grid;gap:1rem}
.grid.cols-2{grid-template-columns:repeat(2,1fr)}
.grid.cols-3{grid-template-columns:repeat(3,1fr)}
.grid.cols-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:760px){
  .grid.cols-2,.grid.cols-3,.grid.cols-4{grid-template-columns:1fr 1fr}
}
@media(max-width:480px){
  .grid.cols-2{grid-template-columns:1fr}
  .grid.cols-3,.grid.cols-4{grid-template-columns:1fr 1fr}
}
/* Deux sections côte à côte sur desktop (dashboard : Sous responsabilité / Par FA),
   empilées sur mobile — indépendant de .grid.cols-2 dont le seuil (480px) est trop bas ici. */
.dash-split{display:grid;grid-template-columns:1fr 1fr;gap:1rem;align-items:start;margin-bottom:1.75rem}
@media(max-width:760px){.dash-split{grid-template-columns:1fr}}

/* ---- Zone « À traiter » (dashboard) : résumé priorisé en tête ---- */
.triage{background:var(--paper);border:1px solid var(--line);border-left:4px solid var(--red);
  border-radius:var(--radius);padding:.85rem 1rem;margin-bottom:1.5rem;box-shadow:var(--shadow)}
.triage.ok{border-left-color:var(--green)}
.triage-h{font-weight:700;font-size:1.05rem;display:flex;align-items:center;gap:.5rem}
.triage-chips{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.6rem}
.triage-chip{display:inline-flex;align-items:center;gap:.4rem;background:var(--cream);
  border:1px solid var(--line);border-radius:100px;padding:.3rem .75rem;font-size:.85rem;
  color:var(--ink);font-weight:600;transition:border-color .12s}
.triage-chip:hover{text-decoration:none;border-color:var(--brown)}
.triage-chip .tc-n{font-weight:800;font-variant-numeric:tabular-nums}
.triage-chip.lvl-danger .tc-n{color:var(--red)}
.triage-chip.lvl-warn .tc-n{color:var(--amber)}

/* ---- Stat tiles ---- */
.tile{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);padding:.9rem;
  box-shadow:var(--shadow)}
.tile .n{font-size:1.7rem;font-weight:800;color:var(--brown-d);line-height:1.1}
.tile .l{color:var(--muted);font-size:.78rem;text-transform:uppercase;letter-spacing:.03em}
.tile.alert-tile{border-left:4px solid var(--amber)}
.tile.danger-tile{border-left:4px solid var(--red)}
/* Tuiles cliquables : chaque chiffre renvoie à l'écran filtré correspondant. */
a.tile{color:inherit;text-decoration:none;transition:border-color .12s,box-shadow .12s,transform .12s}
a.tile:hover{border-color:var(--brown-d);box-shadow:0 3px 10px rgba(0,0,0,.12);transform:translateY(-1px)}
.tile .n a{color:inherit;text-decoration:none;border-bottom:1px dashed transparent}
.tile .n a:hover{border-bottom-color:currentColor}

/* ---- Badges ---- */
.badge{display:inline-block;padding:.12rem .5rem;border-radius:20px;font-size:.74rem;font-weight:600;
  border:1px solid transparent;white-space:nowrap;max-width:100%}
/* Sur téléphone, un badge long (« Indispo. dans 20 j (27/08/2026) ») pousse la
   page plutôt que de se couper : mieux vaut deux lignes qu'un défilement latéral. */
@media(max-width:640px){.badge{white-space:normal}}
.c-neutral{background:#efe9df;color:#6b5d4c}
.c-info{background:var(--blue-bg);color:var(--blue)}
.c-success,.c-done{background:var(--green-bg);color:var(--green)}
.c-warn{background:var(--amber-bg);color:var(--amber)}
.c-danger{background:var(--red-bg);color:var(--red)}
.c-muted{background:#e7ded0;color:#6a5f4e}
.pill{display:inline-block;background:var(--cream);border:1px solid var(--line);border-radius:20px;
  padding:.1rem .55rem;font-size:.74rem;margin:0 .15rem .15rem 0}

/* ---- Tables ---- */
.table-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:.88rem}
th,td{text-align:left;padding:.5rem .55rem;border-bottom:1px solid var(--line);vertical-align:top}
th{color:var(--muted);font-weight:600;font-size:.76rem;text-transform:uppercase;letter-spacing:.02em}
tr:hover td{background:#fbf7f0}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}

/* ---- Forms ---- */
form .field{margin-bottom:.8rem}
label{display:block;font-size:.8rem;color:var(--brown-d);font-weight:600;margin-bottom:.25rem}
label .req{color:var(--red)}
input,select,textarea{
  width:100%;padding:.55rem .6rem;border:1px solid var(--line);border-radius:9px;background:#fff;
  font-size:1rem;color:var(--ink);font-family:inherit;
}
input:focus,select:focus,textarea:focus{outline:2px solid #d8b48f;border-color:#c89a6e}
textarea{min-height:80px;resize:vertical}
.field-row{display:flex;gap:.7rem;flex-wrap:wrap}
.field-row .field{flex:1;min-width:160px}
.check{display:flex;align-items:center;gap:.5rem}
.check input{width:auto}
.hint{font-size:.76rem;color:var(--muted);margin-top:.2rem}

/* ---- Buttons ---- */
.btn{display:inline-flex;align-items:center;gap:.4rem;background:var(--brown);color:#fff;border:none;
  padding:.55rem .95rem;border-radius:9px;font-size:.9rem;font-weight:600;cursor:pointer}
.btn:hover{background:var(--brown-d);text-decoration:none}
.btn.sec{background:#fff;color:var(--brown);border:1px solid var(--brown)}
.btn.sec:hover{background:var(--cream)}
.btn.sm{padding:.32rem .6rem;font-size:.8rem}
.btn.danger{background:var(--red)}
.btn.danger:hover{background:#9c2b1f}
/* Tertiaire (faible emphase) : « Passer sans CEC », remises à zéro… — auparavant
   rendu comme un bouton primaire brun faute de style .btn.ghost. */
.btn.ghost{background:transparent;color:var(--brown);border:1px solid transparent}
.btn.ghost:hover{background:var(--cream);text-decoration:none}
/* Destructif subtil : bordure/texte rouges sur fond clair, pour les suppressions
   discrètes en ligne (note, soin, pesée) sans le poids d'un aplat rouge plein. */
.btn.sec.danger{background:#fff;color:var(--red);border:1px solid var(--red)}
.btn.sec.danger:hover{background:var(--red-bg)}
.btn.ok{background:var(--green)}
/* État désactivé : un bouton bloqué (garde-fous du tunnel d'adoption, etc.) doit
   se distinguer d'un bouton actif. Le hover est neutralisé pour ne pas « répondre ». */
.btn:disabled,.btn[disabled]{opacity:.5;cursor:not-allowed;box-shadow:none}
.btn:disabled:hover,.btn[disabled]:hover{background:var(--brown)}
.btn.sec:disabled:hover,.btn.sec[disabled]:hover{background:#fff}
.btn-row{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
/* Menu déroulant léger (sans JS) : <details class="menu"> + summary .btn + .menu-list.
   Utilisé pour regrouper des actions secondaires (ex. exports du registre). */
.menu{position:relative;display:inline-block}
.menu>summary{list-style:none;cursor:pointer}
.menu>summary::-webkit-details-marker{display:none}
.menu-list{position:absolute;right:0;top:calc(100% + 4px);z-index:40;background:var(--paper);
  border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);min-width:210px;
  padding:.3rem;display:flex;flex-direction:column;gap:.05rem}
.menu-list a{padding:.42rem .55rem;border-radius:7px;color:var(--ink);font-size:.85rem;white-space:nowrap}
.menu-list a:hover{background:var(--cream);text-decoration:none}

/* Focus clavier visible sur TOUT élément interactif (WCAG 2.4.7). Les champs de
   formulaire gardent leur propre anneau (:focus plus haut) ; ceci couvre boutons,
   liens, onglets, résumés de <details>, et les éléments focusables (.tip, pickers). */
:focus-visible{outline:2px solid var(--brown-d);outline-offset:2px;border-radius:6px}
.topbar :focus-visible{outline-color:#fff}

/* ---- Alerts ---- */
.alert{padding:.6rem .8rem;border-radius:9px;margin-bottom:.8rem;font-size:.88rem;border:1px solid}
.alert.ok{background:var(--green-bg);border-color:#bfe0cd;color:var(--green)}
.alert.err{background:var(--red-bg);border-color:#f0c4be;color:var(--red)}
.alert.info{background:var(--blue-bg);border-color:#bcd9e6;color:var(--blue)}
.alert.warn{background:var(--amber-bg);border-color:#ecd6a8;color:var(--amber)}

/* ---- Page header ---- */
.page-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:.6rem}
.page-head h1{margin:0}
.toolbar{display:flex;gap:.5rem;flex-wrap:wrap;align-items:end;margin-bottom:1rem}
/* Les champs se partagent la largeur et passent à la ligne proprement : sans
   base de flex, six filtres (registre) se tassaient jusqu'à l'illisible avant de
   se replier. Sous 640 px, un champ par ligne.
   `:not([type=checkbox])` n'est pas décoratif : une case à cocher étirée à 100 %
   de son conteneur mesure deux cents pixels et pousse la page à elle seule
   (constaté sur /acces/journal). */
.toolbar .field{margin:0;flex:1 1 12rem;min-width:0}
.toolbar .field input:not([type=checkbox]):not([type=radio]),
.toolbar .field select{width:100%}

/* ---- Kanban ---- */
.kanban{display:flex;gap:.7rem;overflow-x:auto;padding-bottom:.6rem}
.kcol{min-width:230px;flex:0 0 230px;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius)}
.kcol h3{margin:0;padding:.6rem .7rem;border-bottom:1px solid var(--line);font-size:.82rem;
  display:flex;justify-content:space-between;align-items:center}
.kcol .kbody{padding:.5rem;display:flex;flex-direction:column;gap:.5rem;min-height:40px}
.kcard{background:#fff;border:1px solid var(--line);border-radius:9px;padding:.55rem;font-size:.85rem;box-shadow:var(--shadow)}
.kcard a{font-weight:600}
.kcard .meta{color:var(--muted);font-size:.75rem;margin-top:.2rem}
.list-section{margin:1.1rem 0 .6rem;font-size:1.05rem;display:flex;align-items:center;gap:.5rem}
.list-clotures>summary{cursor:pointer;font-weight:600;font-size:.95rem;display:flex;align-items:center;gap:.5rem;list-style:none}
.list-clotures>summary::-webkit-details-marker{display:none}
.list-clotures>summary::before{content:'▸';color:var(--muted);font-size:.8rem}
.list-clotures[open]>summary::before{content:'▾'}

/* ---- Timeline ---- */
.timeline{list-style:none;margin:0;padding:0}
.timeline li{position:relative;padding:.1rem 0 .9rem 1.2rem;border-left:2px solid var(--line);margin-left:.4rem}
.timeline li:before{content:"";position:absolute;left:-6px;top:.35rem;width:10px;height:10px;border-radius:50%;
  background:var(--brown)}
.timeline .when{font-size:.76rem;color:var(--muted)}

/* ---- Tabs ---- */
.tabs{display:flex;gap:.3rem;border-bottom:1px solid var(--line);margin-bottom:1rem;overflow-x:auto}
.tabs a{padding:.5rem .8rem;border-bottom:2px solid transparent;white-space:nowrap;color:var(--ink)}
.tabs a.active{border-color:var(--brown);color:var(--brown);font-weight:600}

/* ---- Definition list ---- */
.dl{display:grid;grid-template-columns:max-content 1fr;gap:.3rem .9rem;font-size:.9rem}
.dl dt{color:var(--muted)}
.dl dd{margin:0}
@media(max-width:480px){.dl{grid-template-columns:1fr}.dl dt{margin-top:.4rem}}

/* ---- Login ---- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:1.5rem;
  background:linear-gradient(160deg,#7c4d2a,#a9713f)}
/* Hors production : même signal vert que la topbar (cf. .topbar.env-test). Ces pages
   (login, forgot) n'ont pas de topbar — c'est le fond plein écran qui porte le signal. */
.login-wrap.env-test{background:linear-gradient(160deg,#226039,#2e8d56)}
.login-card{background:var(--paper);border-radius:16px;padding:1.8rem;width:100%;max-width:380px;box-shadow:0 10px 40px rgba(0,0,0,.25)}
.login-card .logo{text-align:center;font-size:2.4rem}
.login-card h1{text-align:center;font-size:1.2rem;margin:.2rem 0 .2rem}
.login-card .sub{text-align:center;color:var(--muted);font-size:.82rem;margin-bottom:1.3rem}
.login-card .btn{width:100%;justify-content:center;margin-top:.4rem}
.login-card .demo{margin-top:1rem;font-size:.78rem;background:var(--cream);border-radius:9px;padding:.6rem;color:var(--brown-d)}

/* ---- Conformity bloc ---- */
.conform{border-left:4px solid var(--blue);background:var(--blue-bg);padding:.7rem .9rem;border-radius:9px}
.conform.block{border-color:var(--red);background:var(--red-bg)}
.conform.ok{border-color:var(--green);background:var(--green-bg)}
.conform.warn{border-color:var(--amber);background:var(--amber-bg)}
.conform ul{margin:.4rem 0 0;padding-left:1.1rem}

/* ---- Misc ---- */
.empty{color:var(--muted);text-align:center;padding:1.5rem;font-style:italic}
/* État vide actionnable des grilles Tabulator (placeholder). */
.grid-empty{text-align:center;padding:1.6rem 1rem;color:var(--muted)}
.grid-empty-title{font-weight:700;color:var(--ink);font-size:1rem}
.grid-empty-sub{margin:.25rem 0 .9rem;font-size:.88rem}
.grid-empty-actions{display:flex;gap:.5rem;justify-content:center;flex-wrap:wrap}
.chart-legend{display:flex;gap:1rem;flex-wrap:wrap;font-size:.78rem;color:var(--muted);margin-top:.4rem;justify-content:center}
.chart-legend span{display:flex;align-items:center;gap:.3rem}
.chart-legend i{width:11px;height:11px;border-radius:3px;display:inline-block}
.bar{height:9px;border-radius:6px;background:var(--brown);min-width:2px}
.bartrack{background:var(--line);border-radius:6px;overflow:hidden;width:100%}
.right{text-align:right}
.nowrap{white-space:nowrap}
/* Contenu réservé aux lecteurs d'écran (visuellement masqué mais annoncé). */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
.flag{display:inline-block;background:var(--red-bg);color:var(--red);font-size:.72rem;padding:.05rem .4rem;border-radius:6px;margin:0 .2rem .2rem 0}
.flag.warn{background:var(--amber-bg);color:var(--amber)}
.doc-thumb{display:inline-block;width:96px;border:1px solid var(--line);border-radius:9px;overflow:hidden;
  background:#fff;text-align:center;margin:0 .4rem .4rem 0;vertical-align:top}
.doc-thumb .preview{display:block;height:64px;text-decoration:none}
.doc-thumb img{width:100%;height:64px;object-fit:cover;display:block}
.doc-thumb .fileicon{display:flex;flex-direction:column;align-items:center;justify-content:center;height:64px;background:var(--cream)}
.doc-thumb .fileicon .emoji{font-size:1.7rem;line-height:1}
.doc-thumb .fileicon .ext{font-size:.56rem;font-weight:700;color:var(--brown-d);margin-top:3px;letter-spacing:.03em}
.doc-thumb .cap{font-size:.62rem;padding:2px 3px;color:var(--muted);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.doc-thumb .doc-actions{display:flex;justify-content:center;gap:.2rem;padding:0 0 3px}
.doc-thumb .doc-actions form{margin:0}
.doc-thumb .doc-actions a,.doc-thumb .doc-actions button{display:inline-block;font-size:.72rem;line-height:1.3;
  padding:0 .35rem;color:var(--brown-d);text-decoration:none;background:#fff;border:1px solid var(--line);border-radius:5px;cursor:pointer}
.doc-thumb .doc-actions a:hover,.doc-thumb .doc-actions button:hover{background:var(--cream)}
.doc-thumb .doc-actions .doc-x:hover{border-color:var(--red);color:var(--red);background:var(--red-bg)}
.doc-thumb .doc-actions .doc-star:hover{border-color:var(--amber);color:var(--amber);background:var(--amber-bg)}
.doc-main-badge{display:block;font-size:.6rem;font-weight:700;color:var(--amber);padding:1px 3px;letter-spacing:.02em}
/* ---- Lien « ouvrir l'élément rattaché » (↗) ----
   Icône seule, discrète au repos et franche au survol : elle apparaît dans des
   listes denses (grille des rappels, tableau de bord, cloche, onglets de fiche)
   où elle ne doit pas concurrencer le titre de la ligne. Toujours accompagnée
   d'un title/aria-label côté gabarit — une flèche seule n'est pas un libellé. */
.lien-fiche{display:inline-block;text-decoration:none;color:var(--muted);line-height:1;
  padding:0 .18rem;border-radius:4px;opacity:.75}
.lien-fiche:hover,.lien-fiche:focus-visible{color:var(--brown-d);background:var(--cream);opacity:1}
.printable{max-width:780px;margin:0 auto;background:#fff;padding:2rem}
@media print{.topbar,.navbar,.offcanvas,.appfoot,.no-print{display:none!important}.container{padding:0}}

/* ---- Infobulles (aide contextuelle des champs) ---- */
.tip{
  display:inline-block;position:relative;width:1rem;height:1rem;line-height:1rem;text-align:center;
  border-radius:50%;background:var(--line);color:var(--brown-d);font-size:.68rem;font-weight:700;
  cursor:help;vertical-align:text-top;margin-left:.25rem;user-select:none;
}
/* `visibility:hidden` masque la bulle mais la LAISSE occuper sa place : 250 px
   posés à droite d'un « ? » proche du bord poussaient la page entière (tous les
   formulaires débordaient horizontalement sur téléphone). L'écraser à l'échelle
   zéro (`scale(0)`) la réduit à un point, sans rien coûter à l'animation. */
.tip::after{
  content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 7px);transform:translateX(-50%) scale(0);
  background:var(--brown-d);color:#fff;padding:.45rem .6rem;border-radius:8px;
  font-size:.74rem;font-weight:400;line-height:1.35;width:max-content;max-width:min(250px,80vw);
  white-space:normal;text-align:left;opacity:0;visibility:hidden;
  transition:opacity .12s,transform .12s;
  z-index:60;pointer-events:none;box-shadow:0 2px 8px rgba(60,40,20,.3);
}
/* Près du bord gauche d'une carte, ancrer la bulle à gauche plutôt que centrée. */
.tip.tip-left::after{transform:scale(0);transform-origin:left bottom;left:0}
.tip::before{
  content:'';position:absolute;left:50%;bottom:calc(100% + 2px);transform:translateX(-50%);
  border:5px solid transparent;border-top-color:var(--brown-d);
  opacity:0;visibility:hidden;transition:opacity .12s;z-index:60;pointer-events:none;
}
.tip:hover::after,.tip:focus::after,.tip:hover::before,.tip:focus::before{opacity:1;visibility:visible}
.tip:hover::after,.tip:focus::after{transform:translateX(-50%) scale(1)}
.tip.tip-left:hover::after,.tip.tip-left:focus::after{transform:scale(1)}

/* ---- Référence courte (identifiant apparent, cliquer = copier) ---- */
.ref{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.76rem;
  background:var(--cream);border:1px solid var(--line);border-radius:6px;
  padding:.06rem .35rem;color:var(--muted);white-space:nowrap;
}
.ref[data-id]{cursor:copy}
.ref[data-id]:hover{border-color:var(--brown);color:var(--brown)}
.ref.copied{background:var(--green-bg);border-color:var(--green);color:var(--green)}
.ref.copied::after{content:' copié ✓'}
.ref.copyfail{background:var(--red-bg);border-color:var(--red);color:var(--red)}
.ref.copyfail::after{content:' ⌘/Ctrl+C'}

/* ---- Déclencheur de recherche (top bar) ---- */
.topsearch{display:flex;align-items:center;gap:.4rem;background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.32);color:#f3e3d2;border-radius:9px;
  padding:.3rem .55rem;font-size:.82rem;cursor:pointer;font-family:inherit;line-height:1}
.topsearch:hover{background:rgba(255,255,255,.24)}
.topsearch .ic{font-size:.9rem;filter:grayscale(.2)}
.topsearch .lbl{max-width:120px}
.topsearch .kbd-hint{background:rgba(0,0,0,.18);border:1px solid rgba(255,255,255,.28);border-radius:6px;
  padding:.02rem .32rem;font-size:.72rem;font-family:inherit;color:#fff}
.topsearch .kbd-hint .mod{font-size:.8rem}
@media(max-width:620px){.topsearch .lbl,.topsearch .kbd-hint{display:none}
  .topsearch{padding:.32rem .5rem}}

/* ---- Palette de recherche globale (Ctrl/⌘+K) ---- */
body.cmdk-lock{overflow:hidden}
.cmdk{position:fixed;inset:0;z-index:100;display:flex;align-items:flex-start;justify-content:center;
  padding:10vh 1rem 1rem}
.cmdk[hidden]{display:none}
.cmdk-backdrop{position:absolute;inset:0;background:rgba(43,33,24,.45);backdrop-filter:blur(2px)}
.cmdk-panel{position:relative;width:100%;max-width:600px;background:var(--paper);border:1px solid var(--line);
  border-radius:14px;box-shadow:0 20px 60px rgba(43,33,24,.35);overflow:hidden;
  display:flex;flex-direction:column;max-height:76vh;animation:cmdk-in .12s ease-out}
@keyframes cmdk-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.cmdk-inputwrap{display:flex;align-items:center;gap:.5rem;padding:.6rem .8rem;border-bottom:1px solid var(--line)}
.cmdk-ic{font-size:1.05rem;opacity:.7}
.cmdk-input{flex:1;border:none;padding:.35rem .1rem;font-size:1.05rem;background:transparent}
.cmdk-input:focus{outline:none}
.cmdk-close{background:var(--cream);border:1px solid var(--line);color:var(--muted);border-radius:7px;
  padding:.15rem .45rem;font-size:.72rem;cursor:pointer;font-family:inherit;white-space:nowrap}
.cmdk-close:hover{border-color:var(--brown);color:var(--brown)}
.cmdk-results{overflow-y:auto;padding:.35rem}
.cmdk-hint{color:var(--muted);text-align:center;padding:1.6rem 1rem;font-size:.9rem}
.cmdk-group+.cmdk-group{margin-top:.25rem}
.cmdk-group-h{font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
  font-weight:700;padding:.45rem .6rem .25rem}
.cmdk-item{display:flex;align-items:center;gap:.6rem;padding:.5rem .6rem;border-radius:9px;
  color:var(--ink);cursor:pointer}
.cmdk-item:hover{text-decoration:none}
.cmdk-item.active{background:var(--cream)}
.cmdk-item-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:.05rem}
.cmdk-item-title{font-weight:600;font-size:.92rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-item-sub{color:var(--muted);font-size:.78rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-foot{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;padding:.5rem .8rem;
  border-top:1px solid var(--line);color:var(--muted);font-size:.76rem;background:var(--cream)}
.cmdk-foot .cmdk-all{margin-left:auto;font-weight:600}
.cmdk-foot kbd,.cmdk-hint kbd{display:inline-block;background:var(--paper);border:1px solid var(--line);
  border-radius:5px;padding:0 .3rem;font-size:.72rem;font-family:inherit;margin:0 .05rem;color:var(--brown-d)}
@media(max-width:480px){.cmdk{padding:6vh .5rem 1rem}.cmdk-foot span{display:none}.cmdk-foot .cmdk-all{margin-left:0}}

/* ---- En-têtes de colonne triables ---- */
a.th-sort{display:inline-flex;align-items:center;gap:.25rem;color:var(--muted);font-weight:600;
  text-transform:uppercase;font-size:.76rem;letter-spacing:.02em}
a.th-sort:hover{color:var(--brown);text-decoration:none}
a.th-sort.active{color:var(--brown-d)}
a.th-sort .th-arrow{font-size:.7rem;opacity:.45}
a.th-sort.active .th-arrow{opacity:1}

/* ---- Autocomplétion de sélection d'entité (entity_picker) ---- */
.field.ac{position:relative}
.ac-input{width:100%}
.ac-menu{position:absolute;left:0;right:0;top:100%;z-index:40;margin-top:2px;background:var(--paper);
  border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);max-height:260px;overflow-y:auto;padding:.25rem}
.ac-menu[hidden]{display:none}
.ac-item{display:flex;flex-direction:column;gap:.05rem;padding:.4rem .55rem;border-radius:8px;cursor:pointer}
.ac-item.active,.ac-item:hover{background:var(--cream)}
.ac-item-t{font-weight:600;font-size:.9rem}
.ac-item-s{color:var(--muted);font-size:.76rem}
.field.ac.ac-chosen .ac-input{border-color:var(--green);background:var(--green-bg)}
.field.ac.ac-invalid .ac-input{border-color:var(--red);background:var(--red-bg)}

/* ---- Modale générique (pop-in « tunnel »), dérivée de .cmdk ---- */
.modal{position:fixed;inset:0;z-index:100;display:flex;align-items:flex-start;justify-content:center;padding:8vh 1rem 1rem}
.modal[hidden]{display:none}
/* z-index explicites : les classes .modal-backdrop / .modal-panel entrent en
   collision avec Bootstrap, qui pose z-index:1050 sur .modal-backdrop. Sans les
   fixer ici, le fond flouté passerait AU-DESSUS du panneau (popin illisible, clics
   captés par le fond qui ferme la modale). On les rétablit dans le contexte
   d'empilement local de .modal (panneau > fond). */
.modal-backdrop{position:absolute;inset:0;z-index:0;background:rgba(43,33,24,.45);backdrop-filter:blur(2px)}
.modal-panel{position:relative;z-index:1;width:100%;max-width:560px;background:var(--paper);border:1px solid var(--line);
  border-radius:14px;box-shadow:0 20px 60px rgba(43,33,24,.35);max-height:86vh;overflow-y:auto;animation:cmdk-in .12s ease-out}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.8rem 1rem;border-bottom:1px solid var(--line)}
.modal-head h3{margin:0}
.modal-body{padding:1rem}
.modal-x{background:var(--cream);border:1px solid var(--line);color:var(--muted);border-radius:7px;
  padding:.15rem .5rem;font-size:.8rem;cursor:pointer;font-family:inherit}
.modal-x:hover{border-color:var(--brown);color:var(--brown)}

/* ---- Frise de statut (fiche animal) ---- */
.statusflow{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center;margin:.2rem 0}
.statusflow .sf-step{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .7rem;border-radius:20px;
  border:1px solid var(--line);background:var(--paper);color:var(--muted);font-size:.8rem;font-weight:600}
.statusflow .sf-step.done{background:var(--green-bg);color:var(--green);border-color:transparent}
.statusflow .sf-step.current{background:var(--brown);color:#fff;border-color:transparent;box-shadow:var(--shadow)}
.statusflow .sf-sep{color:var(--muted);opacity:.5}

/* ---- Bandeau « prochaine action » du tunnel d'adoption ---- */
.tunnel-next{display:flex;flex-wrap:wrap;align-items:baseline;gap:.35rem 1rem;
  background:var(--cream);border:1px solid var(--line);border-left:4px solid var(--brown);
  border-radius:var(--radius);padding:.7rem .9rem;margin-bottom:1rem}
.tunnel-next .tn-step{font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;
  color:var(--brown-d);font-weight:700;white-space:nowrap}
.tunnel-next .tn-action{font-size:.95rem;color:var(--ink)}
.tunnel-next .tn-arrow{color:var(--brown);font-weight:700;margin-right:.15rem}

/* ---- Étapes de l'assistant d'adoption (wizard) ---- */
.wsteps{display:flex;flex-wrap:wrap;gap:.35rem;margin:.4rem 0 1rem}
.wstep{display:inline-flex;align-items:center;gap:.4rem;padding:.35rem .75rem;border-radius:9px;
  border:1px solid var(--line);font-size:.82rem;font-weight:600;color:var(--muted);background:var(--paper)}
.wstep .n{display:inline-flex;align-items:center;justify-content:center;width:1.35rem;height:1.35rem;
  border-radius:50%;background:var(--cream);font-size:.72rem}
.wstep.done{color:var(--green);border-color:transparent;background:var(--green-bg)}
.wstep.done .n{background:var(--green);color:#fff}
.wstep.current{color:#fff;background:var(--brown);border-color:transparent}
.wstep.current .n{background:rgba(255,255,255,.25);color:#fff}
/* Fil d'Ariane vertical cliquable : les étapes franchies sont des boutons de retour. */
.wsteps.vertical{flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:.3rem;max-width:22rem}
.wsteps.vertical .wstep-form{display:block;margin:0}
.wsteps.vertical .wstep{width:100%;justify-content:flex-start}
.wsteps.vertical button.wstep{cursor:pointer;text-align:left;font:inherit;font-weight:600}
.wsteps.vertical button.wstep.done:hover{background:var(--brown);color:#fff}
/* Pastille du numéro sur une étape survolée : #90684a = --brown + 15 % de blanc,
   posé en dur plutôt qu'en rgba() blanc translucide — le blanc sur 25 % de blanc
   ne tient pas le rapport de contraste AA (3,9:1), alors que ce ton donne 4,9:1. */
.wsteps.vertical button.wstep.done:hover .n{background:#90684a;color:#fff}
.wstep .wstep-back{margin-left:auto;opacity:.6;font-weight:400}

/* ---- Sous-étapes du tunnel d'adoption (F24) : grisées puis dégrisées ------ */
.substep{border:1px solid var(--line);border-radius:11px;padding:.7rem .85rem;margin:.5rem 0;background:var(--paper);transition:opacity .15s}
.substep-head{display:flex;align-items:center;gap:.5rem;font-weight:600;font-size:.9rem;margin:0 0 .1rem}
.substep-head .n{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;height:1.5rem;
  border-radius:50%;background:var(--cream);color:var(--muted);font-size:.75rem;font-weight:700}
.substep-head .st{margin-left:auto;font-size:.72rem;font-weight:600;color:var(--muted)}
.substep.done{border-color:transparent;background:var(--green-bg)}
.substep.done .n{background:var(--green);color:#fff}
.substep.done .st{color:var(--green)}
.substep.current{border-color:var(--brown);box-shadow:0 0 0 1px var(--brown) inset}
.substep.current .n{background:var(--brown);color:#fff}
.substep.locked{opacity:.5;filter:grayscale(.4)}
.substep.locked .substep-body{pointer-events:none}
.substep.locked .st{color:var(--muted)}
.step-card.locked{opacity:.55;filter:grayscale(.3)}
.step-card.locked .step-body{pointer-events:none}

/* ---- Ligne de registre annulée (F24/B1) : barrée, atténuée --------------- */
tr.row-annulee td{color:var(--muted);text-decoration:line-through;text-decoration-color:var(--red);opacity:.7}
tr.row-annulee td:last-child{text-decoration:none}
tr.row-annulee a{color:var(--muted)}

/* ---- Bandeau de fiche/onglet verrouillé (verrou d'édition par statut) ---- */
.tab-locked{border:1px dashed var(--amber);background:var(--amber-bg);color:var(--amber);
  border-radius:var(--radius);padding:.7rem .9rem;font-size:.85rem;font-weight:600;margin-bottom:1rem}

/* F16 — zone de glisser-déposer pour l'upload de documents (amélioration progressive).
   L'input natif recouvre toute la zone (opacity 0) : la surface cliquable/tactile
   est donc la carte entière, pas un simple <input type=file> — plus fiable au doigt. */
.dropzone { position: relative; display: flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 92px; border: 2px dashed var(--line); border-radius: var(--radius, 12px);
  padding: .9rem 1rem; background: linear-gradient(180deg, var(--paper), var(--cream));
  text-align: center; cursor: pointer; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }
.dropzone input[type=file] { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer; }
.dropzone:hover, .dropzone:focus-within { border-color: var(--brown); background: var(--amber-bg); }
.dropzone.dragover { border-color: var(--brown); background: var(--amber-bg); box-shadow: 0 0 0 4px rgba(124,77,42,.14); }
.dropzone.has-file { border-style: solid; border-color: var(--green); background: var(--green-bg); }
.dz-content { display: flex; flex-direction: column; align-items: center; gap: .3rem; pointer-events: none; }
.dz-icon { width: 26px; height: 26px; color: var(--muted); transition: color .16s ease, transform .16s ease; }
.dropzone:hover .dz-icon, .dropzone.dragover .dz-icon, .dropzone:focus-within .dz-icon { color: var(--brown); transform: translateY(-2px); }
.dz-text { font-size: .82rem; color: var(--ink); line-height: 1.3; }
.dz-text strong { color: var(--brown-d); }
.dz-sub { display: block; font-size: .74rem; color: var(--muted); margin-top: .1rem; }
.dz-file { display: none; align-items: center; gap: .45rem; font-size: .82rem; pointer-events: none; }
.dropzone.has-file .dz-content { display: none; }
.dropzone.has-file .dz-file { display: flex; }
.dz-file-icon { font-size: 1.1rem; }
.dz-file-name { font-weight: 700; color: var(--green); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dz-file-size { color: var(--muted); font-size: .76rem; }
.dz-remove { position: relative; z-index: 2; pointer-events: auto; width: 24px; height: 24px; flex: none;
  border: 1px solid var(--line); border-radius: 50%; background: #fff; color: var(--muted);
  font-size: .78rem; line-height: 1; cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.dz-remove:hover { background: var(--red-bg); color: var(--red); border-color: var(--red); }
/* Variante compacte : ligne unique, pour un dépôt inline dans un espace restreint (ex. pièce d'un soin). */
.dropzone.compact { display: inline-flex; min-height: unset; max-width: 280px; padding: .4rem .6rem; border-radius: 9px; gap: .4rem; }
.dropzone.compact .dz-content { flex-direction: row; gap: .4rem; }
.dropzone.compact .dz-icon { width: 18px; height: 18px; }
.dropzone.compact .dz-text { font-size: .74rem; text-align: left; }
.dropzone.compact .dz-file { font-size: .74rem; }
.dropzone.compact .dz-file-name { max-width: 130px; }

/* ============================================================================
   Dynamique (grilles Tabulator, toasts, formulaires AJAX, graphiques Chart.js)
   ========================================================================== */

/* --- Toasts (coin haut-droit) : réutilisent le style .alert --- */
.toast-stack{position:fixed;top:.7rem;right:.7rem;z-index:60;display:flex;flex-direction:column;
  gap:.5rem;max-width:min(360px,90vw);pointer-events:none}
.toast-stack .alert{margin:0;box-shadow:var(--shadow);pointer-events:auto;
  animation:toast-in .18s ease}
.toast-stack .alert.toast-out{opacity:0;transform:translateY(-6px);transition:opacity .3s ease,transform .3s ease}
@keyframes toast-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

/* --- Champs en erreur (formulaires AJAX, convention fieldErrors) --- */
.field-invalid input,.field-invalid select,.field-invalid textarea,
input.field-invalid,select.field-invalid,textarea.field-invalid{
  border-color:var(--red)!important;background:var(--red-bg)}
.field-msg{color:var(--red);font-size:.85rem;margin-top:.25rem}
.form-errors:empty{display:none}
.form-errors .alert{margin-bottom:1rem}

/* --- Barre de progression d'upload (XHR, progression réelle via .upload.onprogress) --- */
.up-progress{display:flex;align-items:center;gap:.55rem;margin-top:.4rem}
.up-progress-track{flex:1;height:8px;border-radius:6px;background:var(--cream);overflow:hidden;position:relative}
.up-progress-fill{position:relative;height:100%;width:0;border-radius:6px;overflow:hidden;
  background:linear-gradient(90deg,var(--brown),var(--amber));transition:width .2s ease}
.up-progress-fill::after{content:'';position:absolute;inset:0;
  background-image:linear-gradient(135deg,rgba(255,255,255,.28) 25%,transparent 25%,transparent 50%,
    rgba(255,255,255,.28) 50%,rgba(255,255,255,.28) 75%,transparent 75%,transparent);
  background-size:22px 22px;animation:up-stripes 1s linear infinite}
@keyframes up-stripes{from{background-position:0 0}to{background-position:22px 0}}
.up-progress-pct{min-width:2.6em;text-align:right;font-size:.74rem;font-weight:700;
  color:var(--brown-d);font-variant-numeric:tabular-nums}
.up-progress.done .up-progress-fill{background:var(--green)}
.up-progress.done .up-progress-fill::after{animation:none;background-image:none}
.up-progress.done .up-progress-pct{color:var(--green)}

/* --- Graphiques Chart.js --- */
.chart-box{position:relative;height:260px;width:100%}
.stats-tabs{display:flex;gap:.3rem;flex-wrap:wrap;margin-bottom:1rem;border-bottom:1px solid var(--line)}
.stats-tabs a{padding:.45rem .9rem;border-radius:8px 8px 0 0;color:var(--muted);font-weight:600;font-size:.9rem}
.stats-tabs a:hover{background:var(--cream);text-decoration:none}
.stats-tabs a.active{color:var(--brown);background:var(--paper);border:1px solid var(--line);border-bottom-color:var(--paper);margin-bottom:-1px}
.dot-unread{color:var(--red);font-size:.7rem}

/* --- Grilles Tabulator : ré-habillage aux couleurs de l'app --- */
.tabulator{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);
  font-size:.9rem;overflow:hidden}
.tabulator .tabulator-header{background:var(--cream);border-bottom:2px solid var(--line)}
.tabulator .tabulator-header .tabulator-col{background:var(--cream);border-right:none;
  color:var(--brown-d)}
.tabulator .tabulator-header .tabulator-col .tabulator-col-title{font-weight:700;font-size:.82rem}
.tabulator-row{border-bottom:1px solid var(--line);cursor:pointer}
.tabulator-row.tabulator-row-even{background:var(--paper)}
.tabulator-row:hover{background:var(--cream)!important}
.tabulator-row .tabulator-cell{border-right:none;padding:.5rem .6rem}
.tabulator .tabulator-footer{background:var(--cream);border-top:1px solid var(--line);color:var(--ink)}
.tabulator .tabulator-footer .tabulator-page{border-radius:8px;border:1px solid var(--line);
  background:#fff;color:var(--brown);min-height:44px;min-width:44px;padding:.45rem .7rem;
  font-size:.9rem;line-height:1.2}
.tabulator .tabulator-footer .tabulator-page.active{background:var(--brown);color:#fff;border-color:var(--brown)}
.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}
.tabulator .tabulator-footer .tabulator-page-size{border-radius:8px;border:1px solid var(--line);padding:.1rem .3rem;min-height:44px}
.tabulator-row .tabulator-cell .ref{cursor:pointer}
.tabulator .tabulator-col.tabulator-sortable:hover{background:var(--amber-bg)}
.tabulator-row.row-annulee .tabulator-cell{color:var(--muted);text-decoration:line-through;text-decoration-color:var(--red);opacity:.75}
.tabulator-row.row-annulee .tabulator-cell:last-child{text-decoration:none}
/* Ligne dépliable des colonnes repliées sur mobile (responsiveLayout:'collapse'). */
.tabulator .tabulator-responsive-collapse{border-top:1px solid var(--line);padding:.4rem .6rem;background:var(--cream)}
.tabulator .tabulator-responsive-collapse td{border:none;padding:.15rem .3rem;font-size:.85rem}
.tabulator .tabulator-responsive-collapse td:first-child{color:var(--muted);font-weight:600;padding-right:.6rem}
.tabulator .tabulator-responsive-collapse-toggle{background:var(--brown);border-radius:5px}

/* --- Pied de grille : pagination utilisable au doigt ---------------------
   Les boutons portent des libellés explicites (« ‹ Précédente » / « Suivante ›»,
   cf. le bloc FR de public/js/grids.js) : il leur faut de la place, et le pied
   doit passer à la ligne au lieu de déborder. Cible tactile 44 px (WCAG 2.5.8).
   Le `.tabulator` est en `overflow:hidden` : sans retour à la ligne, les boutons
   de pagination sortaient tout simplement de la boîte sur un écran de 360 px. */
.tabulator .tabulator-footer .tabulator-footer-contents{flex-wrap:wrap;gap:.4rem;row-gap:.5rem}
.tabulator .tabulator-footer .tabulator-paginator{display:flex;flex-wrap:wrap;gap:.35rem;
  align-items:center;justify-content:center}
.tabulator .tabulator-footer .tabulator-page-counter{width:100%;text-align:center;font-size:.85rem}
/* Filet de sécurité : si les colonnes prioritaires ne tiennent tout de même pas
   (écran très étroit), le tableau DÉFILE dans sa boîte au lieu d'être coupé. */
.tabulator .tabulator-tableholder{overflow-x:auto}

@media (max-width:640px){
  /* Sur un écran de 360 px, les marges de confort d'un écran large coûtent
     soixante-dix pixels — soit, dans une grille, une colonne entière. Elles se
     resserrent : c'est la place que la colonne d'actions du registre réclamait. */
  .container{padding:.8rem .6rem 2.5rem}
  .card{padding:.7rem}
  /* Densité réduite : à 360 px, le confort de lecture prime sur le nombre de
     colonnes visibles — celles qui ne tiennent pas sont de toute façon dans le
     dépliant « + », sauf les prioritaires (responsive:0). */
  .tabulator{font-size:.85rem}
  .tabulator-row .tabulator-cell{padding:.45rem .4rem}
  .tabulator .tabulator-header .tabulator-col .tabulator-col-title{font-size:.78rem}
  .tabulator .tabulator-footer .tabulator-page{padding:.45rem .55rem}
  .toolbar .field{flex:1 1 100%}
}

/* Respect de la préférence système « animations réduites » (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* Note : l'app est volontairement en thème clair uniquement. Un thème sombre
   (prefers-color-scheme) a été tenté puis retiré — il nécessite un découpage des
   jetons de couleur (fond plein vs texte) à valider à l'écran. À reprendre plus tard. */
