/* =====================================================================
   SignaFlow — CHARTE GRAPHIQUE ProcessFlow (surcouche globale)
   ---------------------------------------------------------------------
   Source de vérité : _work_claude/Graphisme/CHARTE.md
   Ce fichier est chargé EN DERNIER : il pose les tokens officiels,
   re-mappe les anciens tokens (--sf-*, Bootstrap) dessus, et reskinne
   le shell + les composants globaux SANS toucher aux vues existantes.
   Rollback = retirer une seule balise <link>.
   ===================================================================== */

/* ---------- 1. Tokens officiels (CHARTE §2) ---------- */
:root {
  /* surfaces */
  --bg: #eef0f4;
  --bg-2: #e7e9ef;
  --surface: #ffffff;
  --surface-2: #f4f5f8;
  --surface-3: #eef0f5;
  --surface-hover: #e9ebf1;
  /* texte */
  --text: #1d1d1f;
  --text-2: #5c5c66;
  --text-3: #9296a1;
  /* accents */
  --accent: #0a84ff;
  --accent-2: #3aa0ff;
  --accent-press: #0060df;
  --accent-soft: rgba(10, 132, 255, .12);
  --row-zebra: var(--accent-a4,rgba(10, 132, 255, .045)); /* voile d'accent du zebrage des tableaux */
  --accent-ring: rgba(10, 132, 255, .30);
  --purple: #7c5cff;
  --purple-soft: rgba(124, 92, 255, .14);
  --green: #34c759;
  --green-deep: #248a3d;
  --green-soft: rgba(52, 199, 89, .16);
  --gray-soft: rgba(120, 120, 128, .14);
  /* bordures */
  --border: rgba(60, 60, 67, .12);
  --border-2: rgba(60, 60, 67, .20);
  /* rayons */
  --r-xl: 22px;
  --r-lg: 18px;
  --r-md: 14px;
  --r-sm: 11px;
  --r-xs: 9px;
  --r-pill: 980px;
  /* ombres */
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 1px rgba(16, 24, 40, .04);
  --shadow-md: 0 6px 20px rgba(16, 24, 40, .07), 0 1px 3px rgba(16, 24, 40, .05);
  --shadow-lg: 0 18px 44px rgba(16, 24, 40, .14), 0 4px 12px rgba(16, 24, 40, .07);
  --shadow-accent: 0 8px 22px rgba(10, 132, 255, .34);
  /* animations */
  --ease: cubic-bezier(.32, .72, 0, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  /* police officielle */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ---------- 2. Pont vers l'ancien système (--sf-*) ----------
   Tout le CSS existant (style.css, design-system.css) glisse vers la
   charte sans être réécrit : zéro couture entre écrans. */
:root {
  --sf-accent: var(--accent);
  --sf-accent-dark: var(--accent-press);
  --sf-accent-soft: #d9ecff;             /* équivalent opaque de --accent-soft */
  --sf-body-bg: var(--bg);
  --sf-card-bg: var(--surface);
  --sf-surface-low: var(--surface-2);
  --sf-surface: var(--surface-3);
  --sf-text: var(--text);
  --sf-text-muted: var(--text-2);
  --sf-border: var(--border);
  --sf-outline: var(--border-2);
  --sf-radius: var(--r-md);
  --sf-radius-lg: var(--r-lg);
  --sf-shadow: var(--shadow-md);
  --sf-shadow-lg: var(--shadow-lg);
  --sf-glass: rgba(255, 255, 255, .82);
  --sf-font: var(--font);
  /* la sidebar devient une carte claire (plus de charbon) */
  --sf-sidebar-bg: var(--surface);
  --sf-sidebar-hover: var(--surface-2);
}

/* ---------- 3. Base ---------- */
body {
  font-family: var(--font);
  color: var(--text);
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: var(--bg);
  /* halos radiaux très légers (profondeur, CHARTE §2.1) */
  background-image:
    radial-gradient(900px 520px at 8% -4%, var(--accent-a7,rgba(10, 132, 255, .07)), transparent 60%),
    radial-gradient(820px 500px at 96% -6%, rgba(124, 92, 255, .06), transparent 60%);
  background-attachment: fixed;
}

/* scrollbars discrètes façon macOS */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: rgba(60, 60, 67, .22); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background-color: rgba(60, 60, 67, .38); }
::-webkit-scrollbar-track { background: transparent; }

/* ---------- 4. App shell : rail et topbar plein bord, sans gouttière ----------
   Le rail part du bord gauche et va de haut en bas ; la topbar part du bord
   droit du rail et file jusqu'au bord droit de l'écran. Les deux se touchent :
   aucune marge, aucun rayon, aucune ombre entre eux. La topbar ne passe jamais
   au-dessus du rail (CHARTE §4). */
.app-shell { background: transparent; }

/* Rail de navigation : bande gris clair pleine hauteur, collée à gauche.
   Teinte = jeton --bg-2 (#e7e9ef), un cran sous le fond de l'application : le
   rail se lit comme un plan a part sans jamais assombrir l'écran, et la page
   courante peut ressortir en pastille blanche posée dessus, exactement comme
   une carte de contenu. Un filet d'un demi-pixel marque la jonction. */
.app-sidebar {
  --rail-ico: var(--text-2);
  --rail-ico-on: var(--text);
  --rail-ico-off: var(--text-3);
  --rail-hover: var(--surface-3);
  inset: 0 auto 0 0;
  height: auto;
  width: var(--sf-sidebar-w);
  background: var(--surface);
  border: 0;
  border-right: 0.5px solid var(--border);
  border-radius: 0;
  box-shadow: none;
  color: var(--rail-ico);
  overflow: hidden;
  transition: width .34s var(--ease);
}

/* Bouton 3 barres : déploie le rail pour montrer le titre de chaque page.
   Il remplace la pastille de marque, qui ne servait qu'à revenir à l'accueil
   (le tableau de bord est déjà la première entrée du menu). */
/* v755c : la ligne du haut — les 3 barres, puis le logo quand le rail est deploye */
.sidebar-top { flex: none; width: 100%; display: flex; align-items: center; justify-content: center; gap: 10px; margin: 14px 0 6px; box-sizing: border-box; }
.app-shell.is-nav-open .sidebar-top { justify-content: flex-start; padding: 0 12px; }
.sidebar-burger {
  width: 46px; height: 46px; flex: none;
  margin: 0;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--rail-ico);
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease), transform .12s var(--spring);
}
.sidebar-burger svg { width: 21px; height: 21px; }
.sidebar-burger:hover { background: var(--rail-hover); color: var(--rail-ico-on); }
.sidebar-burger:active { transform: scale(.92); }
.sidebar-burger:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* v755c : la marque, en petit, sur la ligne des 3 barres — rail deploye seulement.
   Logo s'il y en a un ; sinon les initiales et le nom. */
.sidebar-marque { display: none; align-items: center; min-width: 0; flex: 1 1 auto; }
.app-shell.is-nav-open .sidebar-marque { display: flex; }
.sidebar-marque [hidden] { display: none !important; }
.sidebar-marque__logo { display: block; width: auto; height: auto; max-width: 132px; max-height: 30px; object-fit: contain; border-radius: 6px; }
.sidebar-marque__repli { display: flex; align-items: center; gap: 9px; min-width: 0; }
.sidebar-marque__mono {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  border-radius: 8px;
  color: #fff;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  font-size: 12px; font-weight: 700; letter-spacing: -0.01em; line-height: 1;
}
.sidebar-marque__nom {
  min-width: 0;
  font-size: 13.5px; font-weight: 700; letter-spacing: -0.02em;
  color: var(--rail-ico-on);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.app-sidebar .nav-item {
  color: var(--rail-ico);
  border-radius: var(--r-sm);
  transition: background .2s var(--ease), color .2s var(--ease), transform .12s var(--spring);
}
.app-sidebar .nav-item i { opacity: 1; }
/* Jeu d'icones unique de l'application : trait de 1.6, bouts arrondis, grille
   de 24. Le rail, la barre du haut et les panneaux utilisent le meme trace. */
.sf-ico { width: 21px; height: 21px; flex: none; display: block; }
.app-sidebar .nav-item .sf-ico { width: 21px; height: 21px; }
/* Les anciennes icones de police se dimensionnaient par font-size ; un trace
   SVG demande une taille explicite. Chaque emplacement recoit donc la sienne,
   pour que le meme jeu d'icones garde partout le poids visuel d'avant. */
.search-box .sf-ico {
  position: absolute;
  left: 13px;
  top: 50%;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  color: var(--text-3);
}
.sf-ico.cat-chev { width: 14px; height: 14px; }
.cat-act .sf-ico { width: 15px; height: 15px; }
.btn-plus__ic .sf-ico { width: 13px; height: 13px; stroke-width: 2.2; }
/* Une icone posee au fil du texte (bouton, onglet, ligne de tableau) doit rester
   sur la meme ligne que son libelle : le trace SVG est donc remis en ligne, et
   cale sur la ligne de base du texte. */
.btn > .sf-ico, .app-tabs .nav-link .sf-ico, .sf-ico-xs { display: inline-block; vertical-align: -3px; }
.btn-sf-ghost > .sf-ico { width: 16px; height: 16px; color: var(--text-3); }
.btn-outline-danger > .sf-ico, .btn-outline-secondary > .sf-ico { width: 16px; height: 16px; }
.btn-sf-ghost:hover > .sf-ico { color: var(--text-2); }
.app-tabs .nav-link .sf-ico { width: 16px; height: 16px; }
.sf-ico-xs { width: 12px; height: 12px; vertical-align: -2px; }
.sf-ico-xl { width: 34px; height: 34px; }
.pager .btn > .sf-ico { width: 15px; height: 15px; vertical-align: -3px; }
.sf-ico.user-caret { width: 13px; height: 13px; }
.gs-type .sf-ico { width: 17px; height: 17px; }
.sf-help .sf-ico { width: 15px; height: 15px; }
.sf-lightbox-close .sf-ico { width: 20px; height: 20px; }
/* Un produit, un seul cube. Les pages deja passees au SVG le dessinent au
   trait ; celles encore en Font Awesome gardent leur balise <i class="fas
   fa-cube">, mais le glyphe plein est remplace par ce meme trace. La taille
   suit le texte (em), comme le faisait la police : rien ne bouge autour.
   Ce pont disparaitra le jour ou la derniere page passera a sf-ico. */
.fa-cube::before { content: ""; }
.fa-cube {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -.22em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.5 7.5a1.6 1.6 0 0 0-.8-1.4l-6.9-3.9a1.6 1.6 0 0 0-1.6 0L4.3 6.1a1.6 1.6 0 0 0-.8 1.4v9a1.6 1.6 0 0 0 .8 1.4l6.9 3.9a1.6 1.6 0 0 0 1.6 0l6.9-3.9a1.6 1.6 0 0 0 .8-1.4z'/%3E%3Cpath d='m3.8 6.6 8.2 4.7 8.2-4.7'/%3E%3Cpath d='M12 21.6v-10.3'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.5 7.5a1.6 1.6 0 0 0-.8-1.4l-6.9-3.9a1.6 1.6 0 0 0-1.6 0L4.3 6.1a1.6 1.6 0 0 0-.8 1.4v9a1.6 1.6 0 0 0 .8 1.4l6.9 3.9a1.6 1.6 0 0 0 1.6 0l6.9-3.9a1.6 1.6 0 0 0 .8-1.4z'/%3E%3Cpath d='m3.8 6.6 8.2 4.7 8.2-4.7'/%3E%3Cpath d='M12 21.6v-10.3'/%3E%3C/svg%3E") no-repeat center / contain;
}
.app-sidebar .nav-item:hover { background: var(--rail-hover); color: var(--rail-ico-on); }
.app-sidebar .nav-item:active { transform: scale(.94); }

/* Page courante : pastille blanche posée sur le gris du rail, avec l'ombre
   courte et le filet des cartes de contenu. L'icône seule porte l'accent :
   un aplat bleu plein serait trop lourd sur un rail clair. */
.app-sidebar .nav-item.active {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: none;
}
.app-sidebar .nav-item.active:hover { background: var(--accent-soft); color: var(--accent); }
.app-sidebar .nav-item.active i,
.app-sidebar .nav-item.active .sf-ico { color: var(--accent); }
.app-sidebar .nav-item.active .nav-label { font-weight: 600; }
.app-sidebar .nav-item.disabled { color: var(--rail-ico-off); opacity: 1; }
.app-sidebar .nav-item.disabled:hover { background: transparent; color: var(--rail-ico-off); }
.app-sidebar .nav-sep { background: var(--border); height: 1px; opacity: 1; }
.app-sidebar .sidebar-footer { border-top: 1px solid var(--border); }
.app-sidebar .sidebar-footer .version-badge { color: var(--text-3); }
.app-sidebar .sidebar-footer .version-badge strong { color: var(--text-2); }

/* Libellés des pages : masqués tant que le rail est replié. */
.app-sidebar .nav-label {
  display: none;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.008em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* État déployé : le rail s'élargit, les entrées passent en ligne
   icône + titre, et le contenu suit sans à-coup. */
.app-shell.is-nav-open { --sf-sidebar-w: 236px; }
.app-shell.is-nav-open .app-sidebar { align-items: stretch; }
.app-shell.is-nav-open .sidebar-nav { align-items: stretch; }
.app-shell.is-nav-open .sidebar-nav .nav-item {
  width: auto;
  height: 42px;
  padding: 0 11px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
}
.app-shell.is-nav-open .sidebar-nav .nav-item i { width: 20px; flex: none; text-align: center; }
.app-shell.is-nav-open .sidebar-nav .nav-item .sf-ico { width: 21px; height: 21px; }
.app-shell.is-nav-open .app-sidebar .nav-label { display: block; }
.app-shell.is-nav-open .app-sidebar .nav-sep { width: auto; margin: 10px 11px; }

/* Décalage du contenu : exactement la largeur du rail, rien de plus. */
.app-main {
  margin-left: var(--sf-sidebar-w);
  padding-right: 0;
  transition: margin-left .34s var(--ease);
}

/* Topbar : bandeau « verre dépoli » (CHARTE §5.1) collé en haut, sur toute
   la largeur restante. Plus de rayon ni de marge : seul un filet le sépare du
   contenu. */
.app-topbar {
  top: 0;
  margin: 0;
  border-radius: 0;
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0;
  border-bottom: 0.5px solid var(--border);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar, .app-main { transition: none; }
  .sidebar-burger, .sidebar-burger:active { transition: none; transform: none; }
}

/* Gouttières du contenu : valeur unique, exposée en jetons. Les fonds qui
   doivent déborder jusqu'aux bords de la zone de contenu (voile coloré de la
   page dossier) les annulent au pixel près au lieu de les recopier en dur. */
:root { --sf-content-px: 22px; --sf-content-pt: 16px; }
.app-content { padding: var(--sf-content-pt) var(--sf-content-px) 22px; }
@media (max-width: 991.98px) { :root { --sf-content-px: 14px; --sf-content-pt: 14px; } }
@media (max-width: 575.98px) { :root { --sf-content-px: 12px; } }
.topbar-title { color: var(--text); font-weight: 700; font-size: 15px; letter-spacing: -0.011em; }
.topbar-title i { color: var(--accent); }
#page-title-icon { display: inline-flex; align-items: center; color: var(--accent); }
#page-title-icon .sf-ico { width: 19px; height: 19px; }

/* Recherche globale : pilule + highlight de focus obligatoire (§6.1) */
.gs-input {
  background: var(--surface-2);
  border: 0.5px solid var(--border);
  border-radius: var(--r-pill);
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.gs-input:focus-within {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3.5px var(--accent-ring);
}
.gs-input .kbd {
  background: var(--surface);
  border: 0.5px solid var(--border-2);
  border-radius: 7px;
  color: var(--text-3);
  font-size: 11px;
}
.gs-results {
  border-radius: var(--r-md);
  border: 0.5px solid var(--border);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.gs-item { transition: background .15s var(--ease); }
.gs-item:hover { background: var(--surface-2); }

/* Chip utilisateur */
.topbar-user .user-chip { border-radius: var(--r-pill); transition: background .2s var(--ease), border-color .2s var(--ease), transform .12s var(--spring); }
.topbar-user .user-chip:hover { background: var(--surface-2); border-color: var(--border); }
.topbar-user .user-chip:active { transform: scale(.97); }
.user-avatar {
  background: linear-gradient(135deg, var(--purple), var(--accent));
  color: #fff;
  border: none;
}

/* ---------- 5. Boutons (CHARTE §5.10) ---------- */
.btn {
  border-radius: var(--r-sm);
  font-weight: 600;
  letter-spacing: -0.011em;
  transition: transform .12s var(--spring), box-shadow .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease), filter .2s var(--ease);
}
.btn:active { transform: scale(.96); }
.btn-primary, .btn-primary:focus {
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  border: none;
  box-shadow: var(--shadow-accent), inset 0 1px 0 rgba(255, 255, 255, .35);
  color: #fff;
}
.btn-primary:hover { background: linear-gradient(180deg, var(--accent-2), var(--accent)); filter: brightness(1.06); box-shadow: var(--shadow-accent); }
.btn-primary:active { background: var(--accent-press); filter: none; }
.btn-outline-primary { color: var(--accent); border-color: var(--border-2); background: var(--surface); box-shadow: var(--shadow-sm); }
.btn-outline-primary:hover { background: var(--accent-soft); border-color: var(--accent-a35,rgba(10, 132, 255, .35)); color: var(--accent); }
.btn-outline-secondary { border-color: var(--border-2); color: var(--text-2); background: var(--surface); box-shadow: var(--shadow-sm); }
.btn-outline-secondary:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-2); }
.btn-light { background: var(--surface-2); border-color: transparent; color: var(--text-2); }
.btn-light:hover { background: var(--surface-hover); color: var(--text); }
.btn-success { background: linear-gradient(180deg, #46d165, var(--green)); border: none; box-shadow: 0 8px 22px rgba(52, 199, 89, .30); }
.btn-danger:active, .btn-success:active, .btn-secondary:active { transform: scale(.96); }

/* ---------- 6. Champs : highlight de focus OBLIGATOIRE (§6.1) ---------- */
.form-control, .form-select {
  border-radius: var(--r-sm);
  border: 0.5px solid var(--border-2);
  background-color: var(--surface);
  color: var(--text);
  transition: border-color .2s, box-shadow .2s, background .2s;
}
.form-control::placeholder { color: var(--text-3); }
.form-control:focus, .form-select:focus {
  background-color: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3.5px var(--accent-ring);
}
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.form-check-input:indeterminate { background-color: var(--accent); border-color: var(--accent); }
.form-check-input:focus { box-shadow: 0 0 0 3.5px var(--accent-ring); border-color: var(--accent); }
.form-switch .form-check-input { transition: background-position .2s var(--ease), background-color .2s var(--ease); }

/* ---------- 7. Cartes, modals, dropdowns ---------- */
.card { border: 0.5px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-sm); }
.modal-content {
  border: 0.5px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}
.modal-backdrop.show { opacity: .35; }
.modal.fade .modal-dialog { transition: transform .3s var(--ease), opacity .3s var(--ease); transform: translateY(10px) scale(.985); }
.modal.show .modal-dialog { transform: none; }
.dropdown-menu {
  border: 0.5px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.dropdown-item { transition: background .15s var(--ease); font-size: 13px; }
.dropdown-item:hover { background: var(--surface-2); }

/* ---------- 8. Badges & statuts (règle statut → couleur, §2.3) ---------- */
.badge-status {
  border-radius: var(--r-pill);
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0;
}
.badge-status.st-termine { background: var(--green-soft); color: var(--green-deep); }
.badge-status.st-encours { background: var(--accent-soft); color: var(--accent); }
.badge-status.st-afaire { background: var(--gray-soft); color: var(--text-2); }
.badge-status.st-amodif { background: rgba(255, 59, 48, .12); color: #d70015; }

/* ---------- 9. Tables ---------- */
/* Densite : un tableau sert a comparer, donc a en voir le plus possible d'un
   seul coup d'oeil. Les hauteurs de ligne et les corps de texte sont resserres,
   et les selecteurs passent par > pour l'emporter sur design-system.css, qui
   impose un rembourrage plus large a specificite egale. */
.app-table thead th, .table thead th {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-3);
}
.app-table > thead > tr > th {
  padding: 9px 14px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.app-table > tbody > tr > td {
  padding: 8px 14px;
  font-size: 12.5px;
  border-color: var(--border);
}
.app-table > tbody > tr > td .row-link { font-size: 13px; }
.app-table > tbody > tr > td .small { font-size: 11px; }
.app-table .badge-etape { font-size: 10.5px; padding: 3px 9px; }

/* Zebrage et survol : Bootstrap 5.3 peint un fond opaque sur chaque cellule
   (.table > * > * > * recoit background-color: var(--bs-table-bg), soit du
   blanc). Toute couleur posee sur le <tr> passe donc dessous et reste
   invisible : le zebrage comme le survol doivent viser les <td> eux-memes. */
.app-table > tbody > tr:nth-child(even) > td { background-color: var(--row-zebra-c, var(--row-zebra)); }

/* Survol : il porte sur la ligne entiere, donc sur chacune de ses cellules. Il
   se distingue nettement du zebrage, d'ou le voile d'accent plus franc, double
   d'un lisere a gauche pose sur la premiere cellule. Le !important repond a
   celui de design-system.css, qui imposait sinon son propre bleu. */
/* Le lisere est declare des l'etat de repos, transparent, et a la geometrie
   exacte qu'il aura au survol. Sans cela l'animation partait de l'ombre interne
   de Bootstrap (inset 0 0 0 9999px) : l'etalement se resorbait en fondu et la
   premiere cellule virait au bleu plein pendant un instant. Seule la couleur
   change desormais, donc le fondu est propre a l'aller comme au retour. */
.app-table > tbody > tr > td:first-child { box-shadow: inset 3px 0 0 transparent; }
.app-table > tbody > tr.row-clickable > td { transition: background-color .16s var(--ease), box-shadow .16s var(--ease), color .16s var(--ease); }
.app-table > tbody > tr.row-clickable > td .row-link { transition: color .16s var(--ease); }

/* Les variables --row-*-c sont posees a l'execution par la fiche du dossier, a
   partir de la couleur choisie pour ce dossier : le survol, le zebrage et le
   lisere reprennent ainsi sa teinte. Hors de ce contexte, les jetons de la
   charte prennent le relais.

   Selection : la ligne cochee reste teintee, mais s'efface devant le survol,
   qui garde la main. */
.app-table > tbody > tr.row-picked > td { background-color: var(--row-pick-c, var(--accent-soft)); }
.app-table > tbody > tr.row-picked > td:first-child { box-shadow: inset 3px 0 0 var(--row-bar-c, var(--accent-2)); }

.app-table > tbody > tr.row-clickable:hover > td,
.app-table > tbody > tr.row-clickable:active > td { background-color: var(--row-tint-c, var(--accent-soft)) !important; }
.app-table > tbody > tr.row-clickable:hover > td:first-child,
.app-table > tbody > tr.row-clickable:active > td:first-child { box-shadow: inset 3px 0 0 var(--row-bar-c, var(--accent)) !important; }
.app-table > tbody > tr.row-clickable:hover .row-link { color: var(--row-ink-c, var(--accent-press)); }

/* Colonne de selection : etroite, la case centree sur la hauteur de la ligne. */
.app-table .col-pick { width: 42px; padding-right: 0; text-align: center; }
.app-table .col-pick .form-check-input { width: 16px; height: 16px; margin: 0; vertical-align: middle; cursor: pointer; float: none; }
.app-table thead .col-pick { padding-right: 0; }

/* Coins : le cadre d'un tableau porte un rayon moyen, moins arrondi que les
   cartes, pour que les lignes ne semblent pas rognees aux extremites. */
.card.panel.panel-table, .card.panel:has(> .table-responsive) { border-radius: var(--r-md) !important; }
.card.panel.panel-table .table-responsive, .card.panel:has(> .table-responsive) > .table-responsive { border-radius: 0; }

/* Hauteur : la page ne doit pas s'allonger indefiniment sous le tableau. Le
   cadre garde une hauteur maximale et c'est l'interieur qui defile, la ligne
   d'en-tete restant collee en haut. Le filet sous cette ligne passe par une
   ombre interne : une bordure de cellule est abandonnee par position: sticky et
   disparaitrait des le premier defilement. */
.sf-tbl-scroll { max-height: min(58vh, 620px); overflow-y: auto; overscroll-behavior: contain; }
.sf-tbl-scroll > .app-table > thead > tr > th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface-2);
  border-bottom: 0;
  box-shadow: inset 0 -1px 0 var(--border);
}
/* Ascenseur discret, dans l'esprit du systeme. */
.sf-tbl-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
.sf-tbl-scroll::-webkit-scrollbar-track { background: transparent; }
.sf-tbl-scroll::-webkit-scrollbar-thumb { background: var(--border-2); background-clip: content-box; border: 3px solid transparent; border-radius: var(--r-pill); }
.sf-tbl-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-3); background-clip: content-box; border: 3px solid transparent; }

/* ---------- 9b. Pagination (catalogue #080) ---------- */
/* Le pied du tableau tient sur une ligne : les pastilles a gauche, le compte et
   le nombre de lignes chargees a droite. */
.pager { justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pager-left { flex: 1 1 0; min-width: 0; display: flex; align-items: center; }
.pager-side { flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.pager-info { font-size: 12px; color: var(--text-3); font-weight: 500; }

.sf-pager { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.sf-pager button {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  border: 0;
  background: transparent;
  border-radius: var(--r-sm);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease), transform .15s var(--spring);
}
.sf-pager button:hover { background-color: var(--surface-2); color: var(--text); }
.sf-pager button:active { transform: scale(.9); }
.sf-pager button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-pager button[disabled] { opacity: .3; cursor: default; background-color: transparent; color: var(--text-3); transform: none; }
/* Page courante : elle reprend la couleur du dossier, comme le reste du
   tableau ; hors de ce contexte l'accent de la charte prend le relais. */
.sf-pager button.is-on, .sf-pager button.is-on:hover { background-color: var(--row-bar-c, var(--accent)); color: #fff; box-shadow: var(--shadow-sm); }
.sf-pager .sf-pager-gap { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 32px; color: var(--text-3); font-size: 13px; font-weight: 600; -webkit-user-select: none; user-select: none; }
.sf-pager .sf-ico { width: 16px; height: 16px; }
/* Apparition en cascade a chaque changement de page ; le decalage est pose par
   SFPager, faute de pouvoir viser un rang variable en CSS. */
.sf-pager > * { animation: sfPopIn .22s var(--spring) backwards; }

/* Nombre de lignes par page : le champ « select » de la charte, chevron compris. */
.sf-perpage {
  -webkit-appearance: none;
  appearance: none;
  height: 32px;
  padding: 0 30px 0 11px;
  background-color: var(--surface-2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239296a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 14px;
  border: .5px solid var(--border);
  border-radius: var(--r-sm);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  transition: background-color .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.sf-perpage:hover { background-color: var(--surface-hover); }
.sf-perpage:focus { outline: none; background-color: var(--surface); border-color: var(--accent); box-shadow: 0 0 0 3.5px var(--accent-ring); }

@media (prefers-reduced-motion: reduce) {
  .sf-pager > * { animation: none; }
  .sf-pager button { transition: none; }
  .sf-pager button:active { transform: none; }
}

/* ---------- 9c. Pied de tableau : repartition et selection ---------- */
/* Les deux zones occupent la meme place a gauche du pied, l'une remplacant
   l'autre. La regle [hidden] est necessaire : display: flex l'emporterait
   autrement sur la feuille par defaut du navigateur. */
.sf-repart { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sf-repart[hidden], .sf-selbar[hidden] { display: none; }

.sf-repart__p {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 8px;
  border: 0; background-color: transparent; border-radius: var(--r-xs);
  font-family: var(--font); font-size: 11px; font-weight: 600; color: var(--text-3);
  cursor: pointer; white-space: nowrap;
  transition: background-color .2s var(--ease), color .2s var(--ease), transform .15s var(--spring);
}
.sf-repart__p .chip-dot { width: 6px; height: 6px; flex: none; }
.sf-repart__p b { font-weight: 700; color: var(--text-2); font-variant-numeric: tabular-nums; }
.sf-repart__p:hover { background-color: var(--surface-2); color: var(--text-2); }
.sf-repart__p:active { transform: scale(.94); }
.sf-repart__p:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-repart__p.is-on { background-color: var(--accent-soft); color: var(--accent); }
.sf-repart__p.is-on b { color: var(--accent); }

/* Deux etapes n'avaient pas encore de pastille de couleur : les teintes sont
   celles deja portees par les badges d'etape du tableau. */
.d-validation { background: #7c3aed; }
.d-termine { background: #16a34a; }

.sf-selbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; animation: sfPopIn .22s var(--spring); }
.sf-selbar__n { font-size: 12px; font-weight: 700; color: var(--text); white-space: nowrap; }
.sf-selbar__b {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px;
  border: .5px solid var(--border); background-color: var(--surface-2); border-radius: var(--r-sm);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-2);
  cursor: pointer; white-space: nowrap;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), transform .15s var(--spring);
}
.sf-selbar__b .sf-ico { width: 14px; height: 14px; }
.sf-selbar__b:hover { background-color: var(--surface-hover); color: var(--text); }
.sf-selbar__b:active { transform: scale(.94); }
.sf-selbar__b:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-selbar__b--danger { color: #ff3b30; }
.sf-selbar__b--danger:hover { background-color: rgba(255, 59, 48, .12); border-color: rgba(255, 59, 48, .22); color: #ff3b30; }

/* Ecran etroit : chaque zone prend sa ligne, la pagination reste au centre. */
@media (max-width: 900px) {
  .pager-left, .pager-side, .sf-pager { flex: 1 1 100%; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .sf-selbar { animation: none; }
  .sf-repart__p, .sf-selbar__b { transition: none; }
  .sf-repart__p:active, .sf-selbar__b:active { transform: none; }
}

/* ---------- 10. Tooltips ---------- */
.tooltip .tooltip-inner {
  background: rgba(29, 29, 31, .92);
  border-radius: 8px;
  font-size: 11.5px;
  font-family: var(--font);
  padding: 5px 10px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* ---------- 11. Toasts / lightbox ---------- */
/* Visionneuse : voile opaque sans flou (le flou derriere une fenetre est
   proscrit dans l'application ; le verre depoli reste reserve aux barres). */

/* ---------- 12. Apparitions (catalogue §6) ---------- */
@keyframes sfFadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes sfPopIn { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: scale(1); } }
@keyframes sfSceneIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
/* apparition douce du contenu de page — `backwards` (jamais both/forwards, cf. piège §1) */
.app-content > main > * { animation: sfSceneIn .5s var(--ease) backwards; }

/* ---------- 12b. Page SITE : le gabarit « index.html » de la charte ----------
   .site-shell = shell · .site-col-left = sidebar (aperçu + activités)
   .site-header = topbar · .stepper = modules · dessous = détail            */
.site-shell { background: transparent; }
.site-header {
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 0.5px solid var(--border);
  box-shadow: var(--shadow-sm);
}

/* Cartes module (CHARTE §5.6 + §6.2) : lévitation, ressort, sélection animée */
.step-card {
  background: var(--surface);
  border: 0.5px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform .24s var(--spring), box-shadow .24s var(--ease),
              border-color .2s var(--ease), background .2s var(--ease);
}
.step-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.step-card:active { transform: translateY(-1px) scale(.98); }
.step-card.active, .step-card.s-current {
  box-shadow: 0 0 0 2px var(--accent), var(--shadow-md);
  background: linear-gradient(180deg, var(--accent-a5,rgba(10, 132, 255, .05)), var(--accent-a2,rgba(10, 132, 255, .02)));
  transform: translateY(-2px);
  border-color: transparent;
}
.step-card .step-icon, .step-card i { transition: transform .26s var(--spring); }
.step-card:hover .step-icon, .step-card:hover > i { transform: scale(1.09) rotate(-3deg); }

/* Sidebar site (aperçu + fil d'activité) : cartes charte */
.site-col-left > .card { border-radius: var(--r-lg); border: 0.5px solid var(--border); box-shadow: var(--shadow-sm); }

/* ---------- 12c. Boutons d'ouverture importants (CHARTE §5.8) ----------
   Langage commun : fond bleu plein dégradé + glow, contenu blanc, tuile
   d'icône translucide, reflet + sheen au survol, pastille flèche « → »,
   label + sous-titre, ressort au clic. Appliqué à .vt-open-btn
   (« Ouvrir la VT », « Éditer la maquette »). */
@keyframes sfSheen { 0% { left: -60%; opacity: 0; } 18% { opacity: 1; } 100% { left: 135%; opacity: 0; } }
@keyframes sfPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(.7); } }

.vt-open-btn {
  position: relative; overflow: hidden;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
  color: #fff;
  box-shadow: var(--shadow-accent);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  text-align: center; text-decoration: none;
  transition: transform .24s var(--spring), box-shadow .26s var(--ease), filter .2s var(--ease);
}
.vt-open-btn::before {           /* reflet (gloss) */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, .28), transparent 46%);
  pointer-events: none;
}
.vt-open-btn::after {            /* balayage lumineux (sheen) */
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 42%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .5), transparent);
  transform: skewX(-18deg); pointer-events: none; opacity: 0;
}
@media (hover:hover) and (pointer:fine){.vt-open-btn:hover{ filter: brightness(1.05); transform: translateY(-3px); box-shadow: 0 14px 32px var(--accent-a45,rgba(10, 132, 255, .45)); color: #fff; } }
@media (hover:hover) and (pointer:fine){.vt-open-btn:hover::after{ animation: sfSheen .8s var(--ease); } }
.vt-open-btn:active { transform: translateY(-1px) scale(.98); transition-duration: .1s; }
.vt-open-btn .vt-open-icon {
  background: rgba(255, 255, 255, .2);
  color: #fff;
  border-radius: 16px;
  display: grid; place-items: center;
  box-shadow: none;
  transition: transform .32s var(--spring);
}
@media (hover:hover) and (pointer:fine){.vt-open-btn:hover .vt-open-icon{ transform: scale(1.08) rotate(-3deg); } }
.vt-open-btn .vt-open-icon svg { width: 26px; height: 26px; }
.vt-open-label { font-size: 15px; font-weight: 700; line-height: 1.25; letter-spacing: -0.011em; }
.vt-open-sub { font-size: 12px; font-weight: 500; color: rgba(255, 255, 255, .85); line-height: 1.3; }
.vt-open-go {
  position: absolute; top: 11px; right: 11px;
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .22); color: #fff;
  transition: transform .3s var(--spring);
}
.vt-open-go svg { width: 15px; height: 15px; transition: transform .3s var(--spring); }
@media (hover:hover) and (pointer:fine){.vt-open-btn:hover .vt-open-go{ transform: scale(1.12); } }
@media (hover:hover) and (pointer:fine){.vt-open-btn:hover .vt-open-go svg{ transform: translateX(1.5px); } }

/* Pilules teintées pour documents annexes (CHARTE §5.13 .pillbtn) :
   Récap VT = bleu · Formulaire VT = violet */
.vt-act-btn {
  border: none; border-radius: var(--r-sm);
  font-size: 12.5px; font-weight: 600;
  transition: transform .16s var(--spring), background .2s var(--ease), color .2s var(--ease);
}
.vt-act-btn:active { transform: scale(.96); }
.vt-act-btn.vt-act-recap { background: var(--accent-soft); color: var(--accent); }
@media (hover:hover) and (pointer:fine){.vt-act-btn.vt-act-recap:hover{ background: var(--accent-a18,rgba(10, 132, 255, .18)); color: var(--accent); } }
.vt-act-btn.vt-act-form { background: var(--purple-soft); color: var(--purple); }
@media (hover:hover) and (pointer:fine){.vt-act-btn.vt-act-form:hover{ background: rgba(124, 92, 255, .22); color: var(--purple); } }

/* Badges : pastille ronde animée (vert / bleu pulsent, gris fixe — §5.11) */
.badge-status { display: inline-flex; align-items: center; gap: 6px; }
.badge-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.badge-status.st-termine::before, .badge-status.st-encours::before { animation: sfPulse 2s infinite; }

/* ---------- 12d. Typo compacte (CHARTE §3) — plafond 16px ---------- */
.page-header h1, .page-title, .content-title h1 { font-size: 16px; font-weight: 700; letter-spacing: -0.02em; }
.panel-title { font-size: 16px; font-weight: 700; letter-spacing: -0.02em; }
/* Sous-titre de page : texte courant, donc bien sous le plafond (CHARTE §3). */
.page-subtitle { font-size: 12.5px; line-height: 1.5; }
.step-title { font-size: 13px; font-weight: 600; }
.step-status { font-size: 11.5px; font-weight: 600; }
.vt-info-txt small, .vt-field-label { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); }

/* ---------- 12e. Slideover : supprime le flash au changement de vue ----------
   Cause : .sf-slideover a transform:translateX(105%) + transition:transform ;
   au (re)montage de la vue (routing SPA App Connect) la transition rejoue
   depuis le centre → il « apparaît puis glisse dehors ». On garde le panneau
   invisible au repos : même si une frame le rend à translateX(0), rien ne
   clignote. L'ouverture (.open) reste fluide. */
.sf-slideover {
  visibility: hidden;
  transition: transform .28s var(--ease), visibility 0s linear .28s;
}
.sf-slideover.open {
  visibility: visible;
  transition: transform .28s var(--ease), visibility 0s;
}

/* ---------- 12f. Vue SITE : gabarit « index.html » (100vh, cartes, gouttières) ----------
   Reproduit l'app shell documenté : page plein écran sans scroll, colonnes en
   cartes séparées par des gouttières de 14px, modules qui s'enroulent, SEULE la
   zone de détail défile. Scopé via :has(.site-shell) → n'affecte ni la carte VT
   (.vt-module-container) ni la maquette. */
.app-shell.fullscreen-vt:has(.site-shell) .app-content {
  padding: 14px !important;
  height: 100vh;
  min-height: 0;
  overflow: hidden;
  background: transparent;
}
/* le <main is="dmx-view"> intermédiaire doit relayer la hauteur, sinon
   .site-shell height:100% se calcule contre un parent auto et s'effondre */
.app-shell.fullscreen-vt:has(.site-shell) .app-content > main {
  height: 100%;
  min-height: 0;
  display: block;
}
.site-shell {
  display: grid;
  grid-template-columns: 384px minmax(0, 1fr);
  gap: 14px;
  height: 100%;
  align-items: stretch;
}
/* Colonne gauche : aperçu (fixe) + activités ; la colonne défile en entier
   (chaîne flex du feed conservée telle quelle → aucun risque de coupure) */
.site-shell .site-col-left {
  width: auto; flex: none; grid-column: 1;
  display: flex; flex-direction: column; gap: 14px;
  height: 100%; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding-right: 3px;
}
.site-shell .site-col-left > * + * { margin-top: 0; }
.site-shell .site-col-left > .card.panel:last-child { flex: 1 0 auto; min-height: 0; }
/* Colonne droite : header + stepper fixes, le panneau de détail défile seul */
.site-shell .site-col-right {
  grid-column: 2; min-width: 0;
  display: flex; flex-direction: column; gap: 14px;
  height: 100%; min-height: 0; overflow: hidden; padding-right: 0;
}
.site-shell .site-col-right > * + * { margin-top: 0; }
.site-shell .site-header, .site-shell .stepper { flex: none; }
.site-shell .site-col-right > .card.panel {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  animation: sfSceneIn .42s var(--ease);   /* « entre » à chaque changement de module */
}
/* En-tête = carte verre dépoli avec un vrai padding */
.site-shell .site-header {
  border-radius: var(--r-lg);
  padding: 14px 18px;
  border: 0.5px solid var(--border);
  box-shadow: var(--shadow-sm);
}
/* Stepper (modules) : grille qui s'enroule, aucun scroll (CHARTE §4) */
.site-shell .stepper {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 12px;
}
.site-shell .stepper .step-card { animation: sfPopIn .4s var(--ease) backwards; }
.site-shell .stepper .step-card:nth-child(2) { animation-delay: .04s; }
.site-shell .stepper .step-card:nth-child(3) { animation-delay: .08s; }
.site-shell .stepper .step-card:nth-child(4) { animation-delay: .12s; }
.site-shell .stepper .step-card:nth-child(5) { animation-delay: .16s; }
.site-shell .stepper .step-card:nth-child(6) { animation-delay: .20s; }
/* Fil d'activité : apparition en cascade */
.site-shell .feed .feed-item { animation: sfFadeUp .5s var(--ease) backwards; }
.site-shell .feed .feed-item:nth-child(2) { animation-delay: .05s; }
.site-shell .feed .feed-item:nth-child(3) { animation-delay: .10s; }
.site-shell .feed .feed-item:nth-child(4) { animation-delay: .15s; }
.site-shell .feed .feed-item:nth-child(n+5) { animation-delay: .19s; }
/* Boutons d'ouverture VT / Maquette : taille STRICTEMENT identique (règle 📐 §5.8) */
.site-shell .vt-main-row .vt-open-btn,
.site-shell .mq-site-card .vt-open-btn {
  flex: 0 0 168px; width: 168px; height: 154px;
  margin-bottom: 0; padding: 16px;
}
/* ≥1700px : on aère un peu (CHARTE §8) sans grossir le texte */
@media (min-width: 1700px) {
  .app-shell.fullscreen-vt:has(.site-shell) .app-content { padding: 18px !important; }
  .site-shell { grid-template-columns: 420px minmax(0, 1fr); gap: 18px; }
  .site-shell .site-col-left, .site-shell .site-col-right { gap: 18px; }
}
/* ≤900px : la charte impose le passage en colonne, page qui défile verticalement */
@media (max-width: 900px) {
  .app-shell.fullscreen-vt:has(.site-shell) .app-content { height: auto; overflow: visible; }
  .site-shell { grid-template-columns: 1fr; height: auto; }
  .site-shell .site-col-left, .site-shell .site-col-right { height: auto; overflow: visible; }
  .site-shell .site-col-right > .card.panel { overflow: visible; }
}

/* ---------- 12g. Champ couleur : selecteur + pastilles de raccourci ----------
   Choisir la couleur d'un dossier doit tenir en un geste. La rangee de
   pastilles couvre les teintes courantes, le selecteur natif reste disponible
   a cote pour tout le reste. Les huit teintes sont une gamme pastel autonome,
   volontairement reguliere entre elle : elles colorent une carte entiere, ce
   que les accents de la charte (§2) ne savent pas faire sans ecraser le texte.
   ------------------------------------------------------------------------- */
.sf-color-field {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.sf-color-field input[type="color"].form-control-color {
  flex: 0 0 auto;
  width: 46px;
  height: 34px;
  padding: 3px;
  border-radius: var(--r-xs);
  border: 1px solid var(--border-2);
  background: var(--surface);
  cursor: pointer;
}
.sf-swatches {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  min-width: 0;
}
.sf-swatch {
  position: relative;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--border-2);
  border-radius: 50%;
  background: var(--sw, #fff);
  cursor: pointer;
  transition: transform .22s var(--spring), box-shadow .18s var(--ease);
}
.sf-swatch:hover { transform: scale(1.14); box-shadow: var(--shadow-sm); }
.sf-swatch:active { transform: scale(.94); transition-duration: .1s; }
.sf-swatch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Pastille retenue : un anneau accent detache du disque, pour rester lisible
   quelle que soit la teinte posee dessous. */
.sf-swatch.is-on {
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
}
.sf-swatch.is-on::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 9px;
  height: 5px;
  border-left: 1.8px solid var(--text);
  border-bottom: 1.8px solid var(--text);
  transform: rotate(-45deg) translate(1px, -1px);
}

/* ---------- 12h. Menu « ... » d'une carte de dossier ----------
   Le menu est ouvert par le script de la page, sans Popper : il ne recoit donc
   aucune position calculee et doit la tenir de la feuille de style. Il s'ancre
   sous le bouton, aligne a droite, et porte la rangee de teintes sous les
   actions, dans la meme gamme que le panneau de modification (12g).
   ------------------------------------------------------------------------- */
.client-card .dropdown { position: relative; }
.client-card .dropdown-menu {
  position: absolute;
  top: 100%;
  right: 0;
  left: auto;
  margin-top: 6px;
  min-width: 208px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
}
.client-card .dropdown-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--r-xs);
}
.client-card .dropdown-menu .dropdown-item .sf-ico {
  width: 17px;
  height: 17px;
  color: var(--text-3);
}
.client-card .dropdown-menu .dropdown-item:hover { background: var(--surface-hover); }
.client-card .dropdown-menu .dropdown-item:hover .sf-ico { color: var(--text-2); }
.client-card .dropdown-menu .dropdown-item.text-danger .sf-ico { color: inherit; }
.card-menu .sf-ico { width: 19px; height: 19px; }
.card-menu-colors { padding: 8px 10px 6px; }
.card-menu-colors-lab {
  display: block;
  margin-bottom: 7px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
}
.card-menu-colors .sf-swatches { gap: 6px; max-width: 186px; }
.card-menu-colors .sf-swatch { width: 22px; height: 22px; }
.card-menu-colors .sf-swatch.is-on::after {
  width: 7px;
  height: 4px;
  border-left-width: 1.6px;
  border-bottom-width: 1.6px;
}

/* ---------- 12i. Menu « ... » en fin de ligne de tableau ---------- */
/* Le tableau defile dans un cadre a debordement masque : le menu est donc pose
   en position fixe par le script, qui lui donne top et left. Tout le reste de
   son habillage est ici. */
.sf-rowmenu { position: relative; display: inline-block; }
.sf-rowmenu .dropdown-menu {
  min-width: 194px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 1080;
}
.sf-rowmenu .dropdown-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--r-xs);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
}
.sf-rowmenu .dropdown-menu .dropdown-item .sf-ico { width: 17px; height: 17px; }
.sf-rowmenu .dropdown-menu .dropdown-item:hover { background: var(--surface-hover); }
.sf-rowmenu .dropdown-menu .dropdown-item.text-danger:hover { background: rgba(255, 59, 48, .12); }
.app-table .row-menu { color: var(--text-3); display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); }
.app-table .row-menu > .sf-ico { width: 17px; height: 17px; display: block; vertical-align: 0; }
.app-table .row-menu:hover, .app-table .row-menu[aria-expanded="true"] { color: var(--text); background: var(--surface); border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* ---------- 13. Accessibilité : garde-fou obligatoire ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- 14. Mode impression (maquette + dossier mairie) : la charte ne touche pas au PDF ---------- */
body.mq-print { background: #fff !important; background-image: none !important; }
body.mq-print .app-content > main > *,
body.mr-print .app-content > main > * { animation: none !important; }
/* Pourquoi les deux : §12 anime le contenu de page avec `backwards`, donc tant
   que l'animation n'a pas demarre l'element tient l'etat `from`
   (translateY(12px)). Chrome ne demarre pas les animations d'un onglet en
   arriere-plan : le shell reste alors decale de 12 px et le document mesure
   3977 px au lieu de 3965. Puppeteer, lui, laisse l'animation finir — la regle
   ne change donc pas le PDF aujourd'hui (fichier identique a l'octet pres
   avant/apres). On la pose quand meme, pour la meme raison que `mq-print` :
   aucune animation ne doit pouvoir se figer dans un document imprime, et le
   jour ou l'attente de Puppeteer se raccourcira ce serait une page decalee
   sans explication. Couper l'animation est la seule reponse propre — `fill:
   none` casserait l'effet a l'ecran, un `transform: none` global casserait les
   transforms legitimes des visuels. */


/* ─────────────────────────────────────────────────────────────────────────
   VT — icônes SVG des outils : taille & épaisseur homogènes avec le reste
   (les boutons dimensionnaient les anciennes icônes FA via font-size ; nos SVG
   inline sont en 1em → on force une taille lisible et un trait plus marqué).
   ───────────────────────────────────────────────────────────────────────── */
.vt-module-container .vt-side-act svg,
.vt-module-container .rep-acts button svg,
.vt-module-container .repere-surf-ic svg,
.vt-module-container .vt-surf-tab svg,
.vt-module-container .vt-surface-del svg,
.vt-module-container .marker-tb-actions button svg,
.vt-module-container .marker-tb-close svg,
.vt-module-container .vt-mapbtn svg,
.vt-module-container .leaflet-bar a svg { stroke-width: 2.2; }

.vt-module-container .vt-side-act svg { width: 18px !important; height: 18px !important; }
.vt-module-container .rep-acts button svg,
.vt-module-container .repere-surf-ic svg { width: 17px !important; height: 17px !important; }
.vt-module-container .vt-mapbtn svg,
.vt-module-container .leaflet-bar a svg { width: 21px !important; height: 21px !important; }
.vt-module-container .vt-surf-tab svg { width: 17px !important; height: 17px !important; }
.vt-module-container .vt-surface-del svg { width: 13px !important; height: 13px !important; }
.vt-module-container .marker-tb-actions button svg { width: 18px !important; height: 18px !important; }
.vt-module-container .marker-tb-close svg { width: 15px !important; height: 15px !important; }


/* ============================================================================
   15. Recherche avancee : declencheur de la barre du haut et palette
   ----------------------------------------------------------------------------
   Vocabulaire repris du catalogue Graphisme :
     #250 entree de fenetre  -> opacity + scale(.9 -> 1) en .38s var(--spring)
     #245 apparition cascade -> fadeUp .5s avec delais echelonnes
     #244 ressort au clic    -> :active { scale } avec var(--spring)
     #248 balayage lumineux  -> keyframes sfSheen (deja defini plus haut)
     #251 icone vivante      -> hover scale(1.1) rotate(-6deg)
   Aucune couleur hors des tokens : violet = dossier, bleu = projet,
   vert = catalogue produits, gris = fichiers.
   ============================================================================ */

/* ---------- 15a. Declencheur ---------- */
.sf-strig {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 9px;
  width: 100%; height: 38px; padding: 0 6px 0 13px;
  border: .5px solid var(--border); border-radius: var(--r-pill);
  background-color: var(--surface-2);
  font-family: var(--font); font-size: 13px; font-weight: 500; color: var(--text-3);
  text-align: left; cursor: pointer;
  transition: background-color .24s var(--ease), border-color .24s var(--ease), box-shadow .24s var(--ease), color .24s var(--ease), transform .15s var(--spring);
}
.sf-strig > .sf-ico { width: 17px; height: 17px; flex: none; vertical-align: 0; transition: color .24s var(--ease), transform .28s var(--spring); }
.sf-strig__t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-strig__k {
  flex: none; display: inline-flex; align-items: center; height: 22px; padding: 0 8px;
  border: .5px solid var(--border); border-radius: var(--r-xs);
  background-color: var(--surface);
  font-size: 11px; font-weight: 600; color: var(--text-3); white-space: nowrap;
  transition: color .24s var(--ease), border-color .24s var(--ease);
}
.sf-strig:hover { background-color: var(--surface); border-color: var(--border-2); box-shadow: var(--shadow-sm); color: var(--text-2); }
.sf-strig:hover > .sf-ico { color: var(--accent); transform: scale(1.1) rotate(-6deg); }
.sf-strig:hover .sf-strig__k { color: var(--text-2); border-color: var(--border-2); }
.sf-strig:active { transform: scale(.985); transition-duration: .1s; }
.sf-strig:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-strig::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 42%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .95), transparent);
  transform: skewX(-18deg); pointer-events: none; opacity: 0;
}
.sf-strig:hover::after { animation: sfSheen .8s var(--ease); }

/* ---------- 15b. Fenetre de la palette ---------- */
.sf-pal { position: fixed; inset: 0; z-index: 1090; display: none; }
.sf-pal.is-open { display: block; }
.sf-pal__scrim {
  position: absolute; inset: 0;
  background-color: rgba(29, 29, 31, .28);
  -webkit-backdrop-filter: saturate(140%) blur(3px); backdrop-filter: saturate(140%) blur(3px);
  animation: sfPalScrim .38s var(--ease) backwards;
}
@keyframes sfPalScrim { from { opacity: 0; } to { opacity: 1; } }
.sf-pal__win {
  position: absolute; left: 50%; top: 11vh; transform: translateX(-50%);
  width: min(680px, calc(100vw - 32px));
  display: flex; flex-direction: column; max-height: min(78vh, 700px);
  background-color: var(--surface); border: .5px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg); overflow: hidden;
  animation: sfPalIn .38s var(--spring) backwards;
}
@keyframes sfPalIn {
  from { opacity: 0; transform: translateX(-50%) scale(.9); }
  to { opacity: 1; transform: translateX(-50%) scale(1); }
}

/* ---------- 15c. Champ de saisie ---------- */
.sf-pal__head { flex: none; display: flex; align-items: center; gap: 10px; padding: 14px 14px 14px 18px; box-shadow: inset 0 -1px 0 var(--border); }
.sf-pal__loupe { width: 19px; height: 19px; flex: none; color: var(--text-3); vertical-align: 0; }
.sf-pal__in {
  flex: 1 1 auto; min-width: 0; border: 0; padding: 0; background: transparent; outline: none;
  font-family: var(--font); font-size: 16px; font-weight: 500; color: var(--text);
}
.sf-pal__in::placeholder { color: var(--text-3); font-weight: 400; }
.sf-pal__spin { flex: none; width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--accent-soft); border-top-color: var(--accent); animation: sfPalSpin .7s linear infinite; }
.sf-pal__spin[hidden] { display: none; }
@keyframes sfPalSpin { to { transform: rotate(360deg); } }
.sf-pal__esc {
  flex: none; height: 24px; padding: 0 9px;
  border: .5px solid var(--border); border-radius: var(--r-xs); background-color: var(--surface-2);
  font-family: var(--font); font-size: 11px; font-weight: 600; color: var(--text-3); cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), transform .15s var(--spring);
}
.sf-pal__esc:hover { background-color: var(--surface-hover); color: var(--text-2); }
.sf-pal__esc:active { transform: scale(.94); }
.sf-pal__esc:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }

/* ---------- 15c bis. Ligne de filtres ----------
   Une famille a la fois : les puces se comportent comme des onglets, la
   selection est exclusive. Le nombre n'apparait qu'une fois une recherche
   faite : compter des resultats qui n'existent pas encore n'apprend rien. */
.sf-pal__filtres {
  flex: none; display: flex; align-items: center; gap: 6px;
  padding: 9px 12px; overflow-x: auto; scrollbar-width: none;
  box-shadow: inset 0 -1px 0 var(--border);
}
.sf-pal__filtres::-webkit-scrollbar { display: none; }
.sf-pal__f {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 12px;
  border: .5px solid var(--border); border-radius: var(--r-pill);
  background-color: var(--surface); cursor: pointer;
  font-family: var(--font); font-size: 12.5px; font-weight: 600; color: var(--text-2);
  white-space: nowrap;
  transition: background-color .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .15s var(--spring);
}
.sf-pal__f:hover { background-color: var(--surface-2); color: var(--text); }
.sf-pal__f:active { transform: scale(.96); }
.sf-pal__f:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-pal__f b {
  display: inline-grid; place-items: center; min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: var(--r-pill); background-color: var(--gray-soft);
  font-size: 10.5px; font-weight: 700; color: var(--text-3);
}
.sf-pal__f.is-on { background-color: var(--accent); border-color: transparent; color: #fff; }
.sf-pal__f.is-on b { background-color: rgba(255, 255, 255, .26); color: #fff; }
.sf-pal__f.is-vide:not(.is-on) { opacity: .45; }
.sf-pal.is-note .sf-pal__filtres { display: none; }

/* ---------- 15d. Resultats ---------- */
.sf-pal__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px; }
.sf-pal__body::-webkit-scrollbar { width: 10px; }
.sf-pal__body::-webkit-scrollbar-track { background: transparent; }
.sf-pal__body::-webkit-scrollbar-thumb { background: var(--border-2); background-clip: content-box; border: 3px solid transparent; border-radius: var(--r-pill); }
.sf-pal__sec { padding: 11px 10px 5px; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); animation: sfPalUp .46s var(--ease) backwards; }
.sf-pal__it {
  display: flex; align-items: center; gap: 11px; width: 100%; padding: 8px 10px;
  border: 0; background-color: transparent; border-radius: var(--r-sm);
  font-family: var(--font); text-align: left; cursor: pointer;
  transition: background-color .2s var(--ease), transform .15s var(--spring);
  animation: sfPalUp .46s var(--ease) backwards;
}
@keyframes sfPalUp {
  from { opacity: 0; transform: translateY(9px) scale(.985); filter: blur(4px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
.sf-pal__it:hover { background-color: var(--surface-2); }
.sf-pal__it.is-on { background-color: var(--accent-soft); }
.sf-pal__it:active { transform: scale(.985); transition-duration: .1s; }
.sf-pal__it:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-pal__tile {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: var(--r-xs); background-color: var(--gray-soft); color: var(--text-2);
  transition: transform .28s var(--spring);
}
.sf-pal__tile .sf-ico { width: 17px; height: 17px; display: block; vertical-align: 0; }
.sf-pal__it:hover .sf-pal__tile, .sf-pal__it.is-on .sf-pal__tile { transform: scale(1.08) rotate(-5deg); }
.sf-pal-a .sf-pal__tile, .sf-pal-s .sf-pal__tile { background-color: var(--accent-soft); color: var(--accent); }
.sf-pal-c .sf-pal__tile { background-color: var(--purple-soft); color: var(--purple); }
.sf-pal-p .sf-pal__tile, .sf-pal-b .sf-pal__tile { background-color: var(--green-soft); color: var(--green-deep); }
.sf-pal__txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.sf-pal__n { font-size: 14px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-pal__n mark { background-color: var(--accent-soft); color: var(--accent); border-radius: 3px; padding: 0 1px; }
.sf-pal__s { font-size: 12px; font-weight: 500; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-pal__tag {
  flex: none; display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  border-radius: var(--r-pill); background-color: var(--surface-2);
  font-size: 11px; font-weight: 600; color: var(--text-3); white-space: nowrap;
}
.sf-pal__go { flex: none; width: 18px; color: var(--text-3); opacity: 0; transform: translateX(-4px); transition: opacity .2s var(--ease), transform .2s var(--ease), color .2s var(--ease); }
.sf-pal__go .sf-ico { width: 16px; height: 16px; display: block; vertical-align: 0; }
.sf-pal__it:hover .sf-pal__go, .sf-pal__it.is-on .sf-pal__go { opacity: 1; transform: translateX(0); }
.sf-pal__it.is-on .sf-pal__go { color: var(--accent); }
/* Cartes : un produit montre son visuel et ses valeurs, un document sa sorte,
   son poids et sa date. Les valeurs absentes disparaissent, une carte ne
   montre jamais un champ vide. */
.sf-pal__it.is-fiche { align-items: flex-start; padding: 9px 10px; }
.sf-pal__it.is-fiche .sf-pal__tile, .sf-pal__it.is-fiche .sf-pal__vign { margin-top: 1px; }
.sf-pal__it.is-fiche .sf-pal__tag, .sf-pal__it.is-fiche .sf-pal__go { margin-top: 9px; }
.sf-pal__vign {
  flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 3px;
  border: .5px solid var(--border); border-radius: var(--r-xs);
  background-color: var(--surface-2); overflow: hidden;
  transition: transform .28s var(--spring);
}
.sf-pal__vign img { max-width: 100%; max-height: 100%; display: block; object-fit: contain; }
.sf-pal__it:hover .sf-pal__vign, .sf-pal__it.is-on .sf-pal__vign { transform: scale(1.06); }
.sf-pal__pil { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.sf-pal__pil b {
  display: inline-flex; align-items: center; height: 18px; padding: 0 7px;
  border-radius: var(--r-pill); background-color: var(--surface-2);
  font-size: 11px; font-weight: 600; color: var(--text-2); white-space: nowrap;
}
.sf-pal__it.is-on .sf-pal__pil b { background-color: rgba(255, 255, 255, .72); }

.sf-pal__vide { display: flex; flex-direction: column; align-items: center; gap: 9px; padding: 40px 20px; color: var(--text-3); text-align: center; animation: sfPalUp .46s var(--ease) backwards; }
.sf-pal__vide .sf-ico { width: 26px; height: 26px; opacity: .5; vertical-align: 0; }
.sf-pal__vide p { margin: 0; font-size: 13px; font-weight: 500; }
.sf-pal__vide b { color: var(--text-2); }

/* ---------- 15e. Pied ---------- */
.sf-pal__foot { flex: none; display: flex; align-items: center; gap: 14px; padding: 9px 16px; box-shadow: inset 0 1px 0 var(--border); background-color: var(--surface-2); font-size: 11px; font-weight: 500; color: var(--text-3); }
.sf-pal__h { display: inline-flex; align-items: center; gap: 4px; }
.sf-pal__h b { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 4px; border: .5px solid var(--border); border-radius: 5px; background-color: var(--surface); font-size: 10px; font-weight: 600; color: var(--text-2); }
.sf-pal__brand { margin-left: auto; font-weight: 600; }

/* ---------- 15g. Bloc notes ----------
   La bande vit sous les resultats, au-dessus du pied. Chaque carte porte sa
   teinte via --nc, prise dans la palette des dossiers (aucune couleur nouvelle).
   L'editeur remplace le corps de la palette et reutilise .sf-rte.
   ------------------------------------------------------------------------- */
.sf-note {
  flex: none; display: flex; flex-direction: column; gap: 7px;
  padding: 9px 12px 11px;
  box-shadow: inset 0 1px 0 var(--border);
  background-color: var(--surface-2);
}
.sf-note[hidden] { display: none; }
.sf-note__h { display: flex; align-items: center; gap: 7px; }
.sf-note__hi { flex: none; width: 15px; height: 15px; color: var(--text-3); vertical-align: 0; }
.sf-note__ht { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); }
.sf-note__nb {
  display: inline-grid; place-items: center; min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: var(--r-pill); background-color: var(--gray-soft);
  font-size: 10px; font-weight: 700; color: var(--text-2);
}
.sf-note__new {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 11px;
  border: 0; border-radius: var(--r-pill); background-color: var(--accent-soft);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--accent); cursor: pointer;
  transition: background-color .2s var(--ease), transform .18s var(--spring), box-shadow .2s var(--ease);
}
.sf-note__new .sf-ico { width: 14px; height: 14px; display: block; vertical-align: 0; }
.sf-note__new:hover { background-color: var(--accent); color: #fff; transform: translateY(-1px); box-shadow: var(--shadow-accent); }
.sf-note__new:active { transform: scale(.98); transition-duration: .1s; }
.sf-note__new:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note__vide { margin: 0; padding: 4px 1px 3px; font-size: 12px; font-weight: 500; color: var(--text-3); }
.sf-note__row {
  display: flex; gap: 8px; overflow-x: auto; overscroll-behavior-x: contain;
  padding: 2px 1px 5px; scroll-snap-type: x proximity;
}
.sf-note__row::-webkit-scrollbar { height: 8px; }
.sf-note__row::-webkit-scrollbar-track { background: transparent; }
.sf-note__row::-webkit-scrollbar-thumb { background: var(--border-2); background-clip: content-box; border: 2px solid transparent; border-radius: var(--r-pill); }
.sf-note__k {
  position: relative; flex: none; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 3px;
  width: 152px; min-height: 92px; padding: 9px 10px 7px;
  border: .5px solid var(--border-2); border-radius: var(--r-md);
  background-color: var(--nc, var(--surface));
  cursor: pointer; text-align: left;
  transition: transform .22s var(--spring), box-shadow .2s var(--ease), border-color .2s var(--ease);
  animation: sfPalUp .46s var(--ease) backwards;
}
.sf-note__k:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border); }
.sf-note__k:active { transform: scale(.98); transition-duration: .1s; }
.sf-note__k:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note__ep { position: absolute; top: 7px; right: 8px; color: var(--accent); }
.sf-note__ep .sf-ico { width: 13px; height: 13px; display: block; vertical-align: 0; }
.sf-note__t {
  padding-right: 14px; font-size: 12.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sf-note__p {
  font-size: 11.5px; font-weight: 500; line-height: 1.35; color: var(--text-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-note__f { margin-top: auto; padding-top: 5px; display: flex; align-items: center; gap: 6px; }
/* Compteur de cases a cocher : visible d'un coup d'oeil sur la carte, sans
   avoir a ouvrir la note. Il disparait quand la note n'a aucune case. */
.sf-note__ck {
  flex: none; padding: 1px 6px; border-radius: var(--r-pill);
  background-color: var(--gray-soft); font-size: 10px; font-weight: 600;
  color: var(--text-2); letter-spacing: .2px; white-space: nowrap;
}
.sf-note__ck.is-fini { background-color: var(--green-soft); color: var(--green-deep); }
.sf-note__d { flex: 1 1 auto; min-width: 0; font-size: 10.5px; font-weight: 500; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-note__cp {
  flex: none; display: grid; place-items: center; width: 24px; height: 24px;
  border: 0; border-radius: 50%; background-color: transparent; color: var(--accent); cursor: pointer;
  transition: background-color .2s var(--ease), transform .18s var(--spring);
}
.sf-note__cp .sf-ico { width: 14px; height: 14px; display: block; vertical-align: 0; }
.sf-note__cp:hover { background-color: var(--accent-soft); transform: translateY(-1px); }
.sf-note__cp:active { transform: scale(.9); transition-duration: .1s; }
.sf-note__cp:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }

/* Editeur d'une note : il occupe le corps, le champ de recherche s'efface. */
.sf-pal.is-note .sf-pal__head { display: none; }
.sf-pal.is-note .sf-pal__win { max-height: min(82vh, 700px); }
.sf-note-ed {
  display: flex; flex-direction: column; gap: 11px; padding: 12px 12px 4px;
  animation: sfPalUp .46s var(--ease) backwards;
}
.sf-note-ed__top { display: flex; align-items: center; gap: 6px; }
.sf-note-ed__b {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px;
  border: 0; border-radius: var(--r-xs); background-color: transparent; color: var(--text-3); cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), transform .18s var(--spring);
}
.sf-note-ed__b .sf-ico { width: 16px; height: 16px; display: block; vertical-align: 0; }
.sf-note-ed__b:hover { background-color: var(--surface-2); color: var(--text-2); }
.sf-note-ed__b:active { transform: scale(.92); transition-duration: .1s; }
.sf-note-ed__b:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note-ed__b.is-on { background-color: var(--accent-soft); color: var(--accent); }
.sf-note-ed__b.is-danger:hover { background-color: rgba(255, 59, 48, .12); color: #ff3b30; }
.sf-note-ed__t {
  flex: 1 1 auto; min-width: 0; border: 0; padding: 0 2px; background: transparent; outline: none;
  font-family: var(--font); font-size: 17px; font-weight: 700; color: var(--text);
}
.sf-note-ed__t::placeholder { color: var(--text-3); font-weight: 600; }
.sf-note-ed__st { flex: none; margin-left: 9px; font-size: 11px; font-weight: 500; color: var(--text-3); white-space: nowrap; }
.sf-note-ed__st.is-ko { color: #ff3b30; }
/* Compteur de longueur : muet tant qu'on est loin du plafond, rouge une fois
   atteint. Chiffres a chasse fixe pour qu'il ne tremble pas en tapant. */
.sf-note-ed__cpt {
  flex: none; margin-left: 9px; font-size: 11px; font-weight: 500;
  color: var(--text-3); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.sf-note-ed__cpt.is-plein { color: #ff3b30; }
/* Ajout refuse : la zone se souligne un instant, sans rien deplacer. */
.sf-rte.is-trop .sf-rte__editor {
  border-color: rgba(255, 59, 48, .45);
  box-shadow: 0 0 0 3px rgba(255, 59, 48, .14);
}
.sf-note-ed__rte .sf-rte__editor {
  min-height: 190px; max-height: 42vh; font-size: 13.5px;
  background-color: var(--nc, var(--surface));
  transition: background-color .32s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.sf-note-ed__rte .sf-rte__bar button .sf-ico { width: 15px; height: 15px; display: block; vertical-align: 0; }
.sf-note-ed__bas { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; padding: 1px 2px 4px; }
.sf-note-ed__col .sf-swatch { width: 23px; height: 23px; }
.sf-note-ed__col .sf-swatch.is-on::after { width: 8px; height: 4px; }
.sf-note-ed__fin {
  margin-left: auto; flex: none; height: 27px; padding: 0 15px;
  border: .5px solid var(--border); border-radius: var(--r-pill); background-color: var(--surface-2);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-2); cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), transform .18s var(--spring), box-shadow .2s var(--ease);
}
.sf-note-ed__fin:hover { background-color: var(--surface-hover); color: var(--text); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.sf-note-ed__fin:active { transform: scale(.98); transition-duration: .1s; }
.sf-note-ed__fin:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
/* Date de derniere modification : elle vit dans la barre du haut, juste avant
   l'etat d'enregistrement. */
.sf-note-ed__maj { flex: none; font-size: 11px; font-weight: 500; color: var(--text-3); white-space: nowrap; }

/* ---------- 15f. Ecrans etroits et mouvement reduit ---------- */
@media (max-width: 640px) {
  .sf-pal__win { top: 6vh; width: calc(100vw - 20px); max-height: 86vh; }
  .sf-pal__tag { display: none; }
  .sf-pal__foot .sf-pal__h { display: none; }
  .sf-strig__k { display: none; }
  .sf-note__k { width: 136px; min-height: 86px; }
  .sf-note-ed__rte .sf-rte__editor { min-height: 150px; }
  .sf-note-ed__maj { display: none; }
  .sf-note-ed__fin { height: 26px; padding: 0 13px; }
}

/* ---------- 15g. Reperes : une note posee a un endroit de l'application ----------
   La couche est fixe et transparente aux clics ; seules les pastilles les
   recoivent. Elle passe sous la barre du haut (1020) pour ne jamais la couvrir. */
/* Les pastilles de repere doivent passer PAR-DESSUS le decor de
   l'application : barre du haut (1020), rail lateral, panneaux lateraux
   (1035). A 1010 un repere pose sur la barre d'outils disparaissait derriere
   elle. On reste sous les fenetres modales et sous la palette. */
.sf-lieux { position: fixed; inset: 0; z-index: 1045; pointer-events: none; }
.sf-lieu {
  position: absolute; top: 0; left: 0; margin: -13px 0 0 -13px;
  width: 26px; height: 26px; padding: 0; border: 0;
  border-radius: var(--r-pill); background-color: var(--nc, var(--surface));
  color: var(--text-2); display: grid; place-items: center;
  cursor: pointer; pointer-events: auto;
  box-shadow: 0 0 0 1.5px #fff, 0 2px 8px rgba(0, 0, 0, .18);
  transition: box-shadow .2s var(--ease);
}
.sf-lieu .sf-ico { width: 14px; height: 14px; display: block; }
.sf-lieu:hover { box-shadow: 0 0 0 1.5px #fff, 0 4px 14px rgba(0, 0, 0, .24); }
.sf-lieu:focus-visible { outline: none; box-shadow: 0 0 0 1.5px #fff, 0 0 0 4px var(--accent-ring); }
.sf-lieu.is-parti { display: none; }
.sf-lieu.is-hop { animation: sf-lieu-hop 1.3s var(--ease); }
/* Un battement lent, pour reperer la pastille dans la page sans qu'elle
   n'accroche l'oeil en permanence. L'anneau est un element a part : il ne
   touche donc ni aux ombres du survol, ni au saut d'arrivee. */
.sf-lieu::after {
  content: ''; position: absolute; inset: 0;
  border-radius: var(--r-pill); pointer-events: none;
  box-shadow: 0 0 0 0 var(--accent-ring); opacity: 0;
  animation: sf-lieu-pouls 2.8s var(--ease) infinite;
}
@keyframes sf-lieu-pouls {
  0%   { box-shadow: 0 0 0 0 var(--accent-ring); opacity: .9; }
  60%  { box-shadow: 0 0 0 9px var(--accent-ring); opacity: 0; }
  100% { box-shadow: 0 0 0 9px var(--accent-ring); opacity: 0; }
}
/* Au survol et pendant le saut d'arrivee, le battement s'efface : deux
   signaux en meme temps au meme endroit, c'est un de trop. */
.sf-lieu:hover::after, .sf-lieu:focus-visible::after, .sf-lieu.is-hop::after {
  animation: none; opacity: 0;
}
@keyframes sf-lieu-hop {
  0%, 100% { box-shadow: 0 0 0 1.5px #fff, 0 0 0 0 var(--accent-a0,rgba(10, 132, 255, 0)), 0 2px 8px rgba(0, 0, 0, .18); }
  20%, 60% { box-shadow: 0 0 0 1.5px #fff, 0 0 0 11px var(--accent-soft), 0 2px 8px rgba(0, 0, 0, .18); }
  40%, 80% { box-shadow: 0 0 0 1.5px #fff, 0 0 0 0 var(--accent-a0,rgba(10, 132, 255, 0)), 0 2px 8px rgba(0, 0, 0, .18); }
}

/* Mode placement : la page entiere devient une cible, la barre reste cliquable. */
body.sf-viser, body.sf-viser * { cursor: crosshair !important; }
body.sf-viser .sf-viser-bar, body.sf-viser .sf-viser-bar * { cursor: default !important; }
body.sf-viser .sf-viser-bar__x { cursor: pointer !important; }
.sf-viser-bar {
  position: fixed; z-index: 5000; left: 50%; top: 18px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px;
  height: 38px; padding: 0 8px 0 16px;
  border: .5px solid var(--border); border-radius: var(--r-pill);
  background-color: rgba(255, 255, 255, .86);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, .14);
  font-family: var(--font); font-size: 13px; font-weight: 500; color: var(--text);
  white-space: nowrap;
}
.sf-viser-bar__x {
  height: 26px; padding: 0 12px; border: 0; border-radius: var(--r-pill);
  background-color: var(--gray-soft);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-2);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.sf-viser-bar__x:hover { background-color: var(--surface-hover); color: var(--text); }
.sf-viser-cadre {
  position: fixed; z-index: 4999; top: 0; left: 0; pointer-events: none;
  border: 1.5px solid var(--accent); border-radius: var(--r-xs);
  background-color: var(--accent-soft);
}

/* La ligne du repere dans l'editeur de note. */
.sf-note-ed__lieu { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 2px 0; }
.sf-note-ed__pose {
  display: inline-flex; align-items: center; gap: 6px;
  height: 27px; padding: 0 13px;
  border: .5px solid var(--border); border-radius: var(--r-pill);
  background-color: var(--surface-2);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-2);
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease), transform .18s var(--spring);
}
.sf-note-ed__pose:hover { background-color: var(--surface-hover); color: var(--text); transform: translateY(-1px); }
.sf-note-ed__pose:active { transform: scale(.98); transition-duration: .1s; }
.sf-note-ed__pose:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note-ed__lc {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0;
  height: 27px; padding: 0 12px; border-radius: var(--r-pill);
  background-color: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 600;
}
.sf-note-ed__lc > span { max-width: 210px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-note-ed__go {
  height: 27px; padding: 0 14px; border: 0; border-radius: var(--r-pill);
  background-color: var(--accent);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: #fff;
  cursor: pointer;
  transition: filter .2s var(--ease), transform .18s var(--spring);
}
.sf-note-ed__go:hover { filter: brightness(1.07); transform: translateY(-1px); }
.sf-note-ed__go:active { transform: scale(.98); transition-duration: .1s; }
.sf-note-ed__go:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note-ed__lx {
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: var(--r-pill);
  background-color: transparent; color: var(--text-3);
  display: grid; place-items: center; cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.sf-note-ed__lx:hover { background-color: var(--surface-hover); color: var(--text); }
.sf-note-ed__lx:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-note-ed__pose .sf-ico, .sf-note-ed__lc .sf-ico, .sf-note-ed__lx .sf-ico { width: 14px; height: 14px; display: block; }
/* Temoin sur la carte de la note. */
.sf-note__li { display: inline-flex; align-items: center; color: var(--text-3); }
.sf-note__li .sf-ico { width: 12px; height: 12px; display: block; }

@media (prefers-reduced-motion: reduce) {
  .sf-pal__scrim, .sf-pal__win, .sf-pal__it, .sf-pal__sec, .sf-pal__vide { animation: none; }
  .sf-note__k, .sf-note-ed { animation: none; }
  .sf-note__new, .sf-note__k, .sf-note__cp, .sf-note-ed__b, .sf-note-ed__fin { transition: none; }
  .sf-note-ed__rte .sf-rte__editor, .sf-rte.is-trop .sf-rte__editor { transition: none; }
  .sf-note__new:hover, .sf-note__k:hover, .sf-note__cp:hover, .sf-note-ed__fin:hover { transform: none; }
  .sf-note__new:active, .sf-note__k:active, .sf-note__cp:active, .sf-note-ed__b:active, .sf-note-ed__fin:active { transform: none; }
  .sf-pal__spin { animation: none; }
  .sf-lieu, .sf-note-ed__pose, .sf-note-ed__go, .sf-note-ed__lx, .sf-viser-bar__x { transition: none; }
  .sf-lieu.is-hop { animation: none; }
  .sf-lieu::after { animation: none; opacity: 0; }
  .sf-note-ed__pose:hover, .sf-note-ed__go:hover { transform: none; }
  .sf-note-ed__pose:active, .sf-note-ed__go:active { transform: none; }
  .sf-pal__f, .sf-pal__vign { transition: none; }
  .sf-strig, .sf-strig > .sf-ico, .sf-strig__k, .sf-pal__it, .sf-pal__tile, .sf-pal__go, .sf-pal__esc { transition: none; }
  .sf-strig:hover > .sf-ico, .sf-pal__it:hover .sf-pal__tile, .sf-pal__it.is-on .sf-pal__tile { transform: none; }
  .sf-strig:active, .sf-pal__it:active, .sf-pal__esc:active { transform: none; }
  .sf-pal__f:active { transform: none; }
  .sf-pal__it:hover .sf-pal__vign, .sf-pal__it.is-on .sf-pal__vign { transform: none; }
  .sf-strig:hover::after { animation: none; }
}
