/*
// NOWOTCH.COM
// DESCRIPTION : design system / styles intranet
// Harmonisation des LISTES DEROULANTES : le raccourci `background` de .field / .btn / :disabled ecrasait le background-image du chevron pose sur `select` (specificite plus forte) -> passage a background-COLOR dans ces 4 regles, le chevron survit et TOUS les selects du panel ont le meme rendu (fond var(--paper) + chevron + MAJUSCULES).
// Selecteur de TRI de la toolbar (.toolbar .sortsel) : margin-left auto -> 0. La toolbar etant en flex-wrap, ce selecteur passe a la ligne sous la recherche sur la page Utilisateurs ; comme .sortsel ET .right portaient tous deux margin-left:auto, l'espace libre se repartissait entre eux et le selecteur se retrouvait AU MILIEU de sa ligne. Il est desormais colle a gauche, .right restant a l'extreme droite. Aucune autre page concernee (.sortsel n'existe que si sortOptions est fourni a NW_TABLE, ce que seule pages-users.js fait).
// AJOUT ADDITIF (2026/08/08) : deux variantes de grille 3 colonnes non equilibrees, .frow.n3 (1re colonne etroite) et .frow.w3 (1re colonne large), pour les zones Identite / Contact / Adresse du formulaire de contact WHOIS. Classes NOUVELLES : aucune regle existante n'est modifiee, aucun ecran qui ne les emploie pas n'est affecte.
// BOUTONS DESACTIVES — le DS n'en avait AUCUN style : un <button class="btn" disabled> etait bien non cliquable (l'attribut natif suffit) mais RIGOUREUSEMENT identique a un bouton actif, meme fond, meme bordure, meme contraste. On ne le decouvrait eteint qu'en cliquant sans effet, ce qui se lit comme une panne et non comme un refus. Seuls input/select/textarea:disabled et .pager button:disabled etaient traites. Regle GLOBALE (opacity .45 + cursor not-allowed) : tous les ecrans posent des boutons desactives, un meme etat doit se reconnaitre partout a la meme apparence. ⚠️ PAS de pointer-events:none — cela empecherait cursor:not-allowed de s'appliquer et rendrait la zone transparente au survol, or c'est le survol qui porte le motif du refus (title).
// ⚠️ `:not(:disabled)` ajoute a TOUS les survols de bouton (.btn, -primary, -accent, -ghost, -danger) : le survol ne doit rien promettre a un bouton eteint. Exclure ainsi plutot que reaffirmer les couleurs dans une regle `:disabled:hover` — cette derniere aurait une specificite SUPERIEURE aux variantes et aurait repeint un bouton primaire desactive en blanc au survol, soit un bug de plus et non un correctif.
// LIBELLES EN MAJUSCULES DANS LE POPUP D'EDITION D'UN DOMAINE : `#dom-form .lab` en text-transform, plutot que 12 libelles reecrits en capitales dans le source. La casse est une decision d'AFFICHAGE ; figee dans le texte, elle suivrait le libelle partout ou on le reutiliserait (erreurs, infobulles, futur fichier de langue) et il faudrait la defaire a chaque emprunt. Portee a #dom-form SEUL : `.lab` sert aussi a la FICHE (#dom-fiche), dont les libelles restent en casse-phrase — l'un se remplit, l'autre se lit.
// AJOUT ADDITIF (2026/08/15) : .frow.c4 (grille 4 colonnes) pour la ligne CNAME de l'editeur DNS — Nom | Destination | TTL | Proxy. Classe NOUVELLE, repli en 1 colonne sous 760px comme .c2/.c3 ; aucune regle existante n'est modifiee.
// AJOUT ADDITIF (2026/08/16) : `.tbl tbody tr.dns-mail-hl > td` — les lignes de la table DNS qui portent la messagerie reprennent le fond de la carte « Serveurs de mail (MX) » (var(--accent-soft), cf. .box-mail-hl), pour que la meme idee ait la meme couleur d'un ecran a l'autre. Pose sur les CELLULES : `.tbl tbody tr:hover` repeint la ligne entiere et ecraserait la mise en valeur au survol. Et `@media(max-width:760px) #dns-fields .frow` : l'editeur DNS compose ses colonnes en `style=` en ligne (largeurs INEGALES par champ), un repli a une colonne ne peut donc reprendre la main qu'avec `!important` — portee au seul #dns-fields.
// AJUSTEMENT (2026/08/16) : `.tbl tbody tr.dns-mail-hl > td` passe de var(--accent-soft) PLEIN a la meme teinte DILUEE A 45 % (color-mix vers `transparent`). Une carte se repere par son fond ; des lignes de tableau se comptent par dizaines et se lisent en colonne — le meme orange y devenait un aplat qui prenait toute l'attention la ou l'on cherchait un simple repere. La dilution vers `transparent` plutot qu'une couleur plus claire ecrite en dur : la teinte reste juste dans les trois themes (clair, sombre, gris) sans redeclaration par theme, et le survol de ligne transparait au lieu d'etre masque.
// UI-HOVER (2026/08/23) : `.tbl tbody tr:hover` passe de var(--paper-2) a var(--paper-3), un cran de plus, deja decline dans les trois themes. --paper-2 se distinguait a peine du papier en theme clair. ⚠️ AUCUNE couleur de texte n'est posee au survol : forcer var(--ink) sur les cellules ecraserait les valeurs volontairement discretes (.muted) et les couleurs semantiques des badges. ⚠️ `.tbl tbody tr.dns-mail-hl > td` reste INCHANGE : la mise en valeur de la messagerie est posee sur les CELLULES precisement pour survivre au survol de la ligne.
// COUCHE DE NOTIFICATION (2026/08/24, CONTRATS-12 partie B) : `.toast-wrap` passe de z-index 100 a 2000000. ⚠️ CE N'EST PAS UN CORRECTIF DU MODULE CONTRATS, c'est un correctif du PANEL, et c'est voulu : toute notification levee pendant qu'une modale est ouverte etait rendue DERRIERE elle et son fond flou, il fallait fermer la modale pour lire le message. Domaines, Candidats, Utilisateurs et Leads notifient aussi depuis des modales — ils etaient tous atteints, le defaut n'avait ete CONSTATE que sur contrats.
// ⚠️ Une notification est la seule surface qui ne doit JAMAIS pouvoir etre couverte : elle ne prend pas le focus, ne bloque rien, et si on ne la voit pas elle n'existe pas. Elle est donc, par definition, la couche du dessus. Le detail du choix de la valeur est ecrit a la regle elle-meme, pas ici.
// SOCLE-CRUMBS (2026/08/29) : les 3 regles `.crumbs` / `.crumbs .sep` / `.crumbs .here` (l.398-411) ne sont PAS modifiees — elles decrivent l'apparence du fil d'Ariane et elles sont justes. Ce qui manquait etait leur HOTE : `#crumbs` n'existait dans aucun balisage, NW_CRUMBS etait donc un no-op dans tout le panel. Deux regles sont AJOUTEES a la suite, et rien d'autre : `#crumbs` (placement, aligne sur la colonne de `.page`) et `#crumbs:empty` (repli).
// ⚠️ La separation classe/id est volontaire : `.crumbs` porte l'APPARENCE (heritee de l'ancienne topbar, intouchee), `#crumbs` porte le PLACEMENT (pose par ce lot). Personne n'a a relire l'une pour comprendre l'autre.
// ⚠️ `#crumbs:empty { display:none }` n'est pas cosmetique : `render()` vide le fil a chaque rendu et 6 des 27 routes n'appellent jamais NW_CRUMBS — sans ce repli, ces 6 ecrans porteraient une bande vide au-dessus de leur titre.
// ⚠️ Le placement est ecrit en px et non en jetons : le design system n'a PAS de jeton d'espacement (seul `--radius` existe). `.page` et `.foot-in` ecrivent leurs marges en px ; un jeton invente ici serait le seul de son espece. Les valeurs reprennent celles de `.page` (max-width 1480, 28px lateraux) pour que le fil s'aligne sur le titre qu'il surplombe.
// ⚠️ NON TOUCHES par ce lot, et inscrits au REGISTRE-suppressions.md comme candidats : `.topbar`, `.top-search`, `.top-actions`, `.side-foot`, `.sidebar` et les `grid-area` de `.app`. Toute la section commentee Topbar decrit une mise en page remplacee par la barre `.nav` ; aucune de ces classes n'existe dans un balisage. Condition inscrite au registre : apres validation visuelle du fil d'Ariane retabli.
// 🔴 REGLE DE TENUE DE CE FICHIER — UNE NOTE DE LOT NE CITE JAMAIS UN DELIMITEUR DE COMMENTAIRE.
// Le CSS n'a PAS de commentaires imbriques : une sequence de fermeture ecrite a l'interieur de
// cet en-tete le FERME sur place. Tout ce qui suit est alors parse comme du CSS, la reprise
// d'erreur du navigateur avale les regles suivantes, et le premier bloc `:root` disparait de la
// feuille appliquee. C'est arrive le 2026/08/29 (note SOCLE-CRUMBS, l.20) : le panel a tourne
// jusqu'au 2026/08/30 SANS typographie, SANS rayons et SANS ombres — les jetons declares
// uniquement dans `:root`. Les COULEURS, elles, continuaient de fonctionner parce que
// [data-theme="dark"] les redeclare : c'est ce qui a rendu la panne invisible pendant deux jours.
// ⚠️ Pour designer une section commentee, ecrire son NOM (« la section Topbar »), jamais ses
// delimiteurs. ⚠️ Et un compte global d'ouvertures et de fermetures NE PROUVE RIEN : il etait
// equilibre (88/88) pendant toute la panne. Ce qui se verifie, c'est l'APPARIEMENT DANS L'ORDRE.
// v 1.54.20260830.02
// CREATION : 2026/07/08
// MISE A JOUR : 2026/08/30
//
// Tous droits réservés.
// https://nowotch.com/legal/copyright
*/
/* =========================================================
   Nowotch Intranet — Design system
   Warm corporate. Cream paper, ink, deep blue, copper.
   ========================================================= */

:root {
  /* Palette — light : orange nowotch + olive (harmonisée) */
  --paper: #faf8f4;
  --paper-2: #f2efe8;
  --paper-3: #e8e2d5;
  --line: #ddd6c7;
  --line-soft: #e8e2d5;
  --ink: #1c1b19;
  --ink-2: #57544e;
  --ink-3: #847f75;
  --ink-4: #a8a396;
  --accent: #ef8b1e;
  --accent-soft: #fdeddb;
  --accent-ink: #8a4e08;
  --accent-hover: #d9770c;
  --copper: #9e5a29;
  --copper-soft: #f3e5d4;
  --copper-ink: #77421c;
  --green: #66702f;
  --green-soft: #edf0dc;
  --red: #c23b32;
  --red-soft: #f7e0dc;
  --amber: #b8801a;
  --amber-soft: #f6ecc9;

  /* Type */
  --font-sans: "Inter Tight", "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
  --font-serif: "Newsreader", Georgia, serif;

  /* Sizing */
  --radius: 8px;
  --radius-lg: 12px;
  --side-w: 232px;
  --top-h: 56px;

  /* Shadows */
  --shadow-1: 0 1px 0 rgba(26, 26, 26, 0.04), 0 1px 2px rgba(26, 26, 26, 0.04);
  --shadow-2:
    0 4px 14px rgba(26, 26, 26, 0.08), 0 1px 3px rgba(26, 26, 26, 0.06);
  --shadow-pop:
    0 12px 40px rgba(26, 26, 26, 0.18), 0 2px 6px rgba(26, 26, 26, 0.08);
}

[data-theme="dark"] {
  --paper: #141517;
  --paper-2: #1c1e21;
  --paper-3: #25272c;
  --line: #2c2f34;
  --line-soft: #232529;
  --ink: #ecebe6;
  --ink-2: #bdbab2;
  --ink-3: #8a877e;
  --ink-4: #5e5c55;
  --accent: #f39c12;
  --accent-soft: #2a2117;
  --accent-ink: #fcd8a3;
  --accent-hover: #ffab2e;
  --copper: #cf8a63;
  --copper-soft: #3a2918;
  --copper-ink: #e8aa72;
  --green: #a0ad63;
  --green-soft: #21260f;
  --red: #d96961;
  --red-soft: #3a1d1a;
  --amber: #d9aa3e;
  --amber-soft: #332811;
  --shadow-1: 0 1px 0 rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 4px 14px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.3);
  --shadow-pop: 0 12px 40px rgba(0, 0, 0, 0.6), 0 2px 6px rgba(0, 0, 0, 0.4);
}

[data-theme="grey"] {
  --paper: #2b2e33;
  --paper-2: #33373d;
  --paper-3: #3d424a;
  --line: #474d55;
  --line-soft: #3a3f47;
  --ink: #eef0f2;
  --ink-2: #c4c8ce;
  --ink-3: #949aa2;
  --ink-4: #6c727b;
  --accent: #f39c12;
  --accent-soft: #3d3220;
  --accent-ink: #fcd8a3;
  --accent-hover: #ffab2e;
  --copper: #d0906a;
  --copper-soft: #42321f;
  --copper-ink: #e8aa72;
  --green: #a3b066;
  --green-soft: #313a1d;
  --red: #e0796f;
  --red-soft: #452824;
  --amber: #dcae44;
  --amber-soft: #3d3116;
  --shadow-1: 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.2);
  --shadow-2: 0 4px 14px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
  --shadow-pop: 0 12px 40px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35);
}

* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
}
svg.ic {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  display: inline-block;
  vertical-align: middle;
}
.btn > svg.ic {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
}
body {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01", "cv11";
}
a {
  color: var(--accent);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
button {
  font-family: inherit;
  cursor: pointer;
}
/* Base THÉMÉE des champs d'édition (corrige les champs blancs hors .field dans tous les thèmes).
   `:not(...)` en LISTE unique = spécificité (0,1,1) volontairement BASSE : les composants à
   style propre (.toolbar .search input, .nsearch input, .otp .otp-box, chat…) gardent leur rendu
   via une spécificité ≥ ou l'ordre source. checkbox/radio/range sont exclus (styles natifs). */
input:not([type=checkbox], [type=radio], [type=range]),
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 7px 10px;
  outline: none;
}
input:not([type=checkbox], [type=radio], [type=range]):focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Les recherches (pilule transparente sans bordure) ne prennent pas la bague de focus. */
.toolbar .search input:focus,
.nsearch input:focus {
  box-shadow: none;
  border-color: transparent;
}
input::placeholder,
textarea::placeholder {
  color: var(--ink-4);
  opacity: 1;
}
/* SELECT : on force le rendu custom, sinon le contrôle natif garde un fond BLANC
   (texte invisible en dark/grey). + chevron SVG inline. */
select {
  -webkit-appearance: none;
  appearance: none;
  background-color: var(--paper);
  color: var(--ink);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23847f75' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}
/* Listes déroulantes du panel en MAJUSCULES (règle globale). Le rendu en LECTURE (libellés via
   reseauShow/sourceShow…) n'est pas concerné : il n'utilise pas <select>. */
select, select option { text-transform: uppercase; }
/* Champs désactivés : lisibles dans tous les thèmes (plus de fond blanc / texte fantôme).
   ⚠️ background-COLOR et non le raccourci `background` : ce dernier remet background-image à
   `none` et effacerait le chevron SVG posé sur `select` ci-dessus (règle de spécificité plus
   faible). Même précaution partout où une règle plus spécifique repeint un select. */
input:disabled,
select:disabled,
textarea:disabled {
  background-color: var(--paper-2);
  color: var(--ink-3);
  cursor: not-allowed;
}
/* Champs d'édition de la fiche (.form-group) : taille compacte alignée sur le panel (.field). */
.form-group input,
.form-group select,
.form-group textarea {
  font-size: 13.5px;
}

/* =========================================================
   App layout
   ========================================================= */
.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.sidebar {
  grid-area: side;
  border-right: 1px solid var(--line);
  background: var(--paper-2);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.topbar {
  grid-area: top;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 5;
}
.main {
  flex: 1;
  min-height: 0;
}

/* Sidebar */
.brand {
  padding: 16px 18px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--line-soft);
}
.brand-mark {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--ink);
  color: var(--paper);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -0.02em;
  font-family: var(--font-serif);
  position: relative;
  overflow: hidden;
}
.brand-mark::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at 70% 30%,
    var(--copper) 0%,
    transparent 55%
  );
  opacity: 0.55;
}
.brand-mark span {
  position: relative;
  z-index: 1;
}
.brand-name {
  font-weight: 600;
  letter-spacing: -0.01em;
  font-size: 15px;
}
.brand-sub {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 1px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

.side-nav {
  padding: 10px 8px;
  flex: 1;
  overflow: auto;
}
.side-section {
  padding: 12px 10px 6px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-4);
  font-weight: 600;
}
.side-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--radius);
  color: var(--ink-2);
  font-size: 13.5px;
  cursor: pointer;
  user-select: none;
  position: relative;
}
.side-link:hover {
  background: var(--paper-3);
  color: var(--ink);
}
.side-link.active {
  background: var(--ink);
  color: var(--paper);
}
[data-theme="dark"] .side-link.active {
  background: var(--paper-3);
  color: var(--ink);
}
.side-link .ic {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  opacity: 0.85;
}
.side-link .badge {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10.5px;
  background: var(--copper-soft);
  color: var(--copper-ink);
  padding: 1px 6px;
  border-radius: 99px;
  font-weight: 600;
}
.side-link.active .badge {
  background: var(--copper);
  color: white;
}
.side-foot {
  padding: 10px 12px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--ink-3);
}
.side-foot .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px var(--green-soft);
}

/* Topbar */
.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-3);
  font-size: 13px;
}
.crumbs .sep {
  color: var(--ink-4);
}
.crumbs .here {
  color: var(--ink);
  font-weight: 500;
}

/* SOCLE-CRUMBS (2026/08/29) : les 3 regles ci-dessus sont celles de l'ancienne topbar.
   Elles sont reprises TELLES QUELLES — elles decrivent l'APPARENCE du fil d'Ariane et
   restent justes. Ce qui a disparu, c'est leur hote : `.topbar` n'existe plus dans aucun
   balisage. Le conteneur revit en `#crumbs`, pose au-dessus de `#main` et HORS de lui.
   ⚠️ La separation est volontaire : `.crumbs` porte l'apparence (intouchee), `#crumbs`
   porte le PLACEMENT (ajoute ici). Personne n'a a relire l'une pour comprendre l'autre.
   Les valeurs reprennent celles de `.page` (max-width 1480 / 28px lateraux) pour que le
   fil s'aligne sur le titre qu'il surplombe. ⚠️ Ce sont des px et non des jetons : le
   design system n'a PAS de jeton d'espacement — `.page`, `.foot-in` et toute la feuille
   ecrivent leurs marges en px. Un jeton invente ici serait le seul de son espece. */
#crumbs {
  max-width: 1480px;
  margin: 0 auto;
  padding: 14px 28px 0;
}
/* ⚠️ INDISPENSABLE, pas cosmetique : `render()` vide le fil a chaque rendu, et 6 des 27
   routes du panel n'appellent jamais NW_CRUMBS (soon_notifs, soon_profil, soon_reglages,
   candidats, profile, tests). Sans ce repli, ces 6 ecrans afficheraient
   une bande vide de 14px au-dessus de leur titre. Un conteneur vide ne doit pas occuper
   de place : il n'a rien a dire. */
#crumbs:empty {
  display: none;
}
.top-search {
  margin-left: 24px;
  flex: 1;
  max-width: 420px;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 6px 10px;
  color: var(--ink-3);
}
.top-search input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--ink);
}
.top-search kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--ink-3);
  background: var(--paper);
}
.top-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  /* background-COLOR : un <select class="btn"> (ex. sélecteur de zone DNS) doit garder le
     chevron du style global `select` — le raccourci `background` l'effacerait. */
  background-color: var(--paper);
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .02em;
  transition:
    background 0.12s,
    border-color 0.12s;
}
/* ⚠️ `:not(:disabled)` sur TOUS les survols de bouton. Le survol ne doit rien promettre à un
   bouton éteint : sans cette exclusion, passer la souris sur un bouton désactivé lui repeignait
   le fond et lui rendait l'air cliquable au moment précis où l'on essaie de cliquer.
   Exclure ici plutôt que réaffirmer les couleurs dans une règle `:disabled:hover` : cette
   derniere aurait une spécificité SUPÉRIEURE aux variantes (.btn-primary, .btn-accent…) et aurait
   repeint un bouton primaire désactivé en blanc au survol — un bug de plus, pas un correctif. */
.btn:not(:disabled):hover {
  background-color: var(--paper-2);   /* idem : ne pas effacer le chevron d'un select.btn */
  border-color: var(--ink-4);
}
/* BOUTONS DÉSACTIVÉS — le design system n'en avait AUCUN style. Un <button class="btn" disabled>
   était bien non cliquable (l'attribut natif suffit à cela) mais RIGOUREUSEMENT identique à un
   bouton actif : même fond, même bordure, même contraste. On ne pouvait le découvrir éteint qu'en
   cliquant dessus sans effet, ce qui se lit comme une panne, pas comme un refus. Seuls
   input/select/textarea:disabled et .pager button:disabled étaient traités.
   Règle GLOBALE et non locale au module Domaines : tous les écrans du panel posent des boutons
   désactivés, et un même état doit se reconnaître partout à la même apparence.
   ⚠️ PAS de `pointer-events:none` — essayé, RETIRÉ. Un <button disabled> natif n'est déjà pas
   cliquable : la propriété n'ajoutait aucune protection et coûtait deux choses. Un élément sans
   pointer-events n'est plus une cible de survol, donc elle annulait le `cursor:not-allowed` de
   cette règle même, et elle rendait définitivement invisibles les infobulles des boutons
   désactivés — précisément là où le motif du refus est l'information utile (bouton EPP,
   « Déverrouiller » réservé aux administrateurs). L'opacité grise, le curseur avertit, l'attribut
   natif bloque : chacun son rôle, aucun n'a besoin d'un quatrième. */
.btn:disabled,
.btn[disabled] {
  opacity: .45;
  cursor: not-allowed;
}
.btn-primary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.btn-primary:not(:disabled):hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}
.btn-accent {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
}
.btn-accent:not(:disabled):hover {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
}
.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ink-2);
}
.btn-ghost:not(:disabled):hover {
  background: var(--paper-2);
  color: var(--ink);
}
.btn-danger{background:var(--red);color:#fff;border-color:var(--red)}
.btn-danger:not(:disabled):hover{background:color-mix(in oklab,var(--red) 84%,black);border-color:color-mix(in oklab,var(--red) 84%,black);color:#fff}
.btn-sm {
  padding: 4px 8px;
  font-size: 12px;
}
.btn-icon {
  padding: 6px;
}
.btn .ic {
  width: 14px;
  height: 14px;
}

/* Avatar */
.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 600;
  font-size: 11px;
  flex: 0 0 28px;
  font-family: var(--font-mono);
  letter-spacing: -0.02em;
  /* Une image de logo est toujours rognee au cercle (cf. .avatar > img). */
  overflow: hidden;
}
/* Logo/photo dans un avatar : remplit tout le cercle, recadre au centre (style FB/Insta). */
.avatar > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.avatar.sm {
  width: 22px;
  height: 22px;
  font-size: 9.5px;
  /* flex-basis alignee sur la taille, sinon la base 28px l'emporte en conteneur flex. */
  flex: 0 0 22px;
}
.avatar.lg {
  width: 44px;
  height: 44px;
  font-size: 15px;
  /* Idem : sans ca, .avatar.lg rendait un ovale 28x44 dans les en-tetes de fiche (flex row). */
  flex: 0 0 44px;
}
/* Variante XL : apercu de logo dans la carte d'upload (taille fixe = rendu constant). */
.avatar.xl {
  width: 72px;
  height: 72px;
  font-size: 22px;
  flex: 0 0 72px;
}
.avatar.copper {
  background: var(--copper-soft);
  color: var(--copper-ink);
}
.avatar.green {
  background: var(--green-soft);
  color: var(--green);
}
.avatar.amber {
  background: var(--amber-soft);
  color: var(--amber);
}
.avatar.red {
  background: var(--red-soft);
  color: var(--red);
}

/* Page chrome */
.page {
  padding: 24px 28px 80px;
  max-width: 1480px;
  margin: 0 auto;
}
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.page-head .h1 {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 0;
}
.page-head .sub {
  color: var(--ink-3);
  font-size: 13.5px;
  margin-top: 2px;
}
.page-head .actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* Cards */
.card {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.card-head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: 12px;
}
.card-head .title {
  font-weight: 600;
  font-size: 14px;
}
.card-head .sub {
  color: var(--ink-3);
  font-size: 12.5px;
}
.card-head .actions {
  margin-left: auto;
  display: flex;
  gap: 6px;
}
.card-body {
  padding: 18px;
}
.card-body.flush {
  padding: 0;
}

/* Stats */
.stat-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(4, 1fr);
}
/* Première cellule du stat-grid scindée en deux demi-cartes côte à côte
   (ex. Clients nowotch / Clients Talfaza), même style .stat que les autres. */
.stat-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.stat {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  position: relative;
  overflow: hidden;
}
.stat .label {
  font-size: 11.5px;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.stat .value {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 4px;
  font-feature-settings: "tnum";
}
.stat .delta {
  font-size: 12px;
  margin-top: 2px;
  color: var(--ink-3);
  display: flex;
  align-items: center;
  gap: 4px;
}
.stat .delta.up {
  color: var(--green);
}
.stat .delta.down {
  color: var(--red);
}
.stat .spark {
  position: absolute;
  right: 14px;
  bottom: 12px;
  opacity: 0.85;
}

/* Tables */
.tbl-wrap {
  overflow: auto;
}
table.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.tbl thead th {
  text-align: left;
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--paper-2);
  position: sticky;
  top: 0;
  white-space: nowrap;
  user-select: none;
  cursor: pointer;
}
.tbl thead th .sort-ind {
  display: inline-block;
  margin-left: 4px;
  opacity: 0.4;
  font-family: var(--font-mono);
  font-size: 10px;
}
.tbl thead th.sort-asc .sort-ind,
.tbl thead th.sort-desc .sort-ind {
  opacity: 1;
  color: var(--ink);
}
.tbl tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.tbl tbody tr:hover {
  background: var(--paper-3);
}
.tbl tbody tr.clickable {
  cursor: pointer;
}
.tbl .num {
  font-family: var(--font-mono);
  font-feature-settings: "tnum";
  text-align: right;
}
.tbl .mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
}
.tbl-foot {
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  border-top: 1px solid var(--line-soft);
  font-size: 12.5px;
  color: var(--ink-3);
}
.pager {
  margin-left: auto;
  display: flex;
  gap: 4px;
  align-items: center;
}
.pager button {
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-2);
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-family: var(--font-mono);
}
.pager button.cur {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.pager button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* Pills */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 99px;
  font-size: 11.5px;
  font-weight: 500;
  background: var(--paper-3);
  color: var(--ink-2);
  white-space: nowrap;
}
.pill .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.pill.green {
  background: var(--green-soft);
  color: var(--green);
}
.pill.red {
  background: var(--red-soft);
  color: var(--red);
}
.pill.amber {
  background: var(--amber-soft);
  color: var(--amber);
}
.pill.blue {
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.pill.copper {
  background: var(--copper-soft);
  color: var(--copper-ink);
}
.pill.ghost {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-3);
}

/* Forms */
.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.field label {
  font-size: 12px;
  color: var(--ink-3);
  font-weight: 500;
}
/* ⚠️ CAUSE HISTORIQUE des selects « sans chevron » : le raccourci `background` utilisé ici
   (spécificité 0,1,1) écrasait le background-image du style global `select` (0,0,1) — tout
   select posé dans une .field perdait donc sa flèche, alors que ceux des lignes répétables
   (.cz-row : langues, téléphones…) la gardaient. D'où le rendu incohérent d'une zone à l'autre.
   background-COLOR ne touche pas background-image : le chevron survit. */
.field input,
.field select,
.field textarea {
  background-color: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 7px 10px;
  font-size: 13.5px;
  outline: none;
  transition:
    border-color 0.12s,
    box-shadow 0.12s;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Toolbar above tables */
.toolbar {
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.toolbar .search {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 5px 10px;
  flex: 1;
  max-width: 320px;
}
.toolbar .search input {
  background: transparent;
  border: 0;
  outline: 0;
  flex: 1;
}
.toolbar .filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 99px;
  font-size: 12px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-3);
  cursor: pointer;
}
.toolbar .filter-chip:hover {
  background: var(--paper-2);
}
.toolbar .filter-chip.on {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
/* Sélecteur de tri (Trier : …) dans la toolbar */
/* ⚠️ `margin-left: auto` RETIRÉ (il valait `auto`). `.toolbar` est un flex en `flex-wrap: wrap` :
   sur la page Utilisateurs, la recherche + les chips de poste remplissent la 1re ligne et le
   sélecteur de tri passe à la ligne suivante. Là, `.sortsel` ET `.right` portaient tous deux
   `margin-left: auto` -> l'espace libre se répartissait ENTRE les deux et le sélecteur se
   retrouvait au MILIEU de sa ligne. À `0`, il est collé à gauche ; `.right` garde son `auto` et
   reste donc à l'extrême droite. Seul l'alignement horizontal change.
   Portée : `.sortsel` n'est émis par NW_TABLE que si `sortOptions` est fourni, et seule
   `pages-users.js` en fournit — aucune autre page n'est touchée. */
.toolbar .sortsel {
  margin-left: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-3);
}
.toolbar .sortsel select {
  padding: 5px 8px;
  font-size: 12.5px;
}
.toolbar .right {
  margin-left: auto;
  display: flex;
  gap: 8px;
  align-items: center;
}

/* Drawer / modal */
.drawer-back {
  position: fixed;
  inset: 0;
  background: rgba(20, 18, 12, 0.45);
  z-index: 50;
  display: none;
}
.drawer-back.on {
  display: block;
  animation: fade 0.15s ease both;
}
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(620px, 92vw);
  background: var(--paper);
  border-left: 1px solid var(--line);
  z-index: 51;
  transform: translateX(100%);
  transition: transform 0.25s ease;
  display: flex;
  flex-direction: column;
}
.drawer.on {
  transform: translateX(0);
}
.drawer-head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: 12px;
}
.drawer-body {
  flex: 1;
  overflow: auto;
  padding: 18px;
}
.drawer-foot {
  padding: 12px 18px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Toast / session-loss alert */
/* z-index 2000000 — LA COUCHE DU DESSUS, et voici pourquoi cette valeur precise.
   A 100, toute notification levee depuis une modale etait rendue DERRIERE elle : il fallait
   fermer la modale pour lire le message qui expliquait pourquoi elle refusait de se fermer.
   ⚠️ Relever le z-index sur la seule foi des valeurs de CE fichier n'aurait rien repare.
   L'echelle declaree ici plafonne a 1200 (#dom-confirm), mais les modales construites en
   JavaScript posent leur z-index EN LIGNE, hors de toute echelle : 9999 (huit occurrences,
   dont la modale des types de documents — celle-la meme ou le defaut a ete constate), 10000 et
   10001 (Leads), 99999 (confirmation de suppression d'un type), et 999999 pour un toast local
   que le module contrats s'est ecrit a lui-meme. Une valeur de 1300, parfaitement defendable au
   vu du seul CSS, aurait laisse le bug intact exactement la ou il avait ete signale.
   2000000 = le DOUBLE du plus haut z-index du panel (999999), et non 999999+1 : une marge d'une
   unite se referme au premier module qui reprend l'habitude du gros nombre rond. Il reste de la
   place sous le maximum CSS (2147483647) pour une couche superieure qui resterait a inventer.
   ⚠️ Ces z-index en ligne violent la regle ecrite plus bas (§ ECHELLE D'EMPILEMENT) : toute
   surface empilee se declare dans le CSS, jamais en `style=`. Les resorber est un lot a part —
   ici on ne fait que passer AU-DESSUS d'eux. */
.toast-wrap {
  position: fixed;
  bottom: 16px;
  right: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 2000000;
}
.toast {
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius);
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: var(--shadow-pop);
  font-size: 13px;
  max-width: 380px;
  animation: slidein 0.25s ease both;
}
.toast.warn {
  background: var(--red);
}
.toast button {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: inherit;
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
}
@keyframes slidein {
  from {
    transform: translateY(20px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* Misc */
.kpi-row {
  display: grid;
  gap: 12px;
  grid-template-columns: 2fr 1fr;
}
.two-col {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr;
}
.three-col {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr 1fr 1fr;
}
.divider {
  height: 1px;
  background: var(--line-soft);
  margin: 14px 0;
}
.muted {
  color: var(--ink-3);
}
.tiny {
  font-size: 11.5px;
  text-transform: none;
}
.mono {
  font-family: var(--font-mono);
  text-transform: none;
}
/* Champ en erreur (validation front) : bordure rouge + halo. */
.err,
.field.err input,
.field.err select,
input.err,
select.err,
textarea.err {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-soft);
}
/* Message d'erreur sous un champ (validation au blur). Vide/masque par defaut. */
.ferr {
  display: none;
  color: var(--red);
  font-size: 11.5px;
  text-transform: none;
  margin-top: 4px;
}
.ferr.on {
  display: block;
}
.tnum {
  font-feature-settings: "tnum";
}
.right {
  text-align: right;
}
.center {
  text-align: center;
}
.flex {
  display: flex;
}
.flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.gap-8 {
  gap: 8px;
}
.gap-12 {
  gap: 12px;
}
.gap-16 {
  gap: 16px;
}
.spacer {
  flex: 1;
}

/* List items in cards */
.list-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.list-item:last-child {
  border-bottom: 0;
}
.list-item .meta {
  color: var(--ink-3);
  font-size: 12px;
}
.list-item .title {
  font-weight: 500;
  font-size: 13.5px;
}

/* Sparkline placeholder */
.spark-bar {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 24px;
}
.spark-bar i {
  display: block;
  width: 4px;
  background: var(--accent);
  border-radius: 2px;
  opacity: 0.55;
}
.spark-bar i:last-child {
  opacity: 1;
}

/* Login */
.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: var(--paper);
  background-image:
    radial-gradient(circle at 20% 0%, var(--copper-soft) 0%, transparent 40%),
    radial-gradient(circle at 80% 100%, var(--accent-soft) 0%, transparent 45%);
  padding: 40px 20px;
}
.login-card {
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 32px;
  box-shadow: var(--shadow-2);
}
.login-card .brand {
  padding: 0 0 20px;
  border: 0;
}
.login-card h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 4px;
}
.login-card p.lead {
  color: var(--ink-3);
  margin: 0 0 22px;
  font-size: 13.5px;
}
/* Saisie du code OTP en 6 cases (login.php #code-form).
   Les .otp-box sont dans un .field -> on scope en `.otp .otp-box` (0,2,0) pour
   BATTRE la règle globale `.field input` (0,1,1) qui imposerait sinon
   font-size 13.5px + padding et casserait la rangée. Force rangée + taille réduite. */
.otp{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;justify-content:center;gap:8px;margin:8px 0 4px}
.otp .otp-box{flex:0 0 auto;width:40px;height:48px;text-align:center;font-size:20px;font-weight:600;font-family:var(--font-mono);color:var(--ink);background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);outline:none;padding:0;transition:border-color .12s,box-shadow .12s}
.otp .otp-box:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.otp-dash{color:var(--ink-3);font-weight:600;flex:0 0 auto}
@media(max-width:420px){.otp .otp-box{width:34px;height:42px;font-size:18px}.otp{gap:6px}}

/* ===== Module Utilisateurs — mini-lignes de résumé (dernières connexions / derniers inscrits) ===== */
.mini{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12.5px;border-top:1px solid var(--line-soft)}
.mini:first-of-type{border-top:0;margin-top:6px}
.mini .mininame{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mini .m{color:var(--ink-3);margin-left:auto;font-size:11px;flex:0 0 auto;padding-left:6px}

/* ===== Modal centré (design system, tokens only) — ex. popup création utilisateur ===== */
.modal-back{position:fixed;inset:0;background:rgba(20,18,12,.5);display:none;align-items:center;justify-content:center;z-index:1000;padding:20px}
[data-theme="dark"] .modal-back,[data-theme="grey"] .modal-back{background:rgba(0,0,0,.6)}
.modal-back.on{display:flex}
/* ÉCHELLE D'EMPILEMENT DES SURFACES MODALES — à tenir à jour, c'est la seule vue d'ensemble.
     1000  fiche domaine (#dom-fiche), formulaire d'édition (#dom-form) : la couche de base ;
     1100  éditeur d'enregistrement DNS (#dns-record-modal), qui s'ouvre PAR-DESSUS la fiche ;
     1200  confirmations et messages (#dom-confirm, #dom-alert, #nw-confirm), sommet des
           surfaces MODALES. SOCLE-CONFIRM (30/08) : #nw-confirm est le composant PARTAGE
           du panel (window.NW_CONFIRM, app.js). Il est declare ici, avec les deux autres,
           parce que c'est ce que la regle du bas de cette note demande — et parce qu'une
           confirmation qui s'ouvre derriere ce qu'elle interroge est bloquante ET
           invisible. #dom-confirm et #dom-alert sont les implementations LOCALES de
           domaines : elles migreront sur le composant partage, ce n'est pas fait ici ;
   2000000  couche de NOTIFICATION (.toast-wrap) — au-dessus de tout, y compris des z-index poses
            en ligne par les modales JavaScript (jusqu'a 999999). Motif detaille a la regle.
   ⚠️ Les confirmations DOIVENT dépasser 1100. Elles vivaient à 1000, ce qui suffisait tant que
   rien ne s'empilait au-dessus de la fiche : depuis que l'éditeur DNS le fait, une confirmation
   déclenchée DEPUIS cet éditeur (branche « warning » de l'enregistrement) se serait ouverte
   DERRIÈRE lui — visible nulle part, et bloquante, puisqu'elle attend une réponse. C'est
   exactement le défaut qui a fait renoncer au tiroir NW_DRAWER (z-index 51 sous une fiche à
   1000) ; le reproduire un étage plus haut n'aurait rien réglé.
   Toute nouvelle surface empilée se déclare ICI, jamais en `style="z-index:…"` isolé : un ordre
   d'empilement dispersé entre plusieurs fichiers ne se vérifie plus. */
#dns-record-modal{z-index:1100}
#dom-confirm,
#dom-alert,
#nw-confirm{z-index:1200}
.modal{width:100%;max-width:460px;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-pop)}
.modal-head{padding:16px 20px;border-bottom:1px solid var(--line-soft)}
.modal-head h3{margin:0;font-size:17px;font-weight:600}
.modal-head p{margin:4px 0 0;font-size:13px;color:var(--ink-3)}
.modal-body{padding:18px 20px;display:flex;flex-direction:column;gap:14px}
.modal-foot{padding:14px 20px;border-top:1px solid var(--line-soft);display:flex;gap:8px;justify-content:flex-end}
.mail-line{display:flex;gap:8px}
.mail-line input{flex:1}
.mail-line select{flex:0 0 auto}
.field .hint{font-size:11.5px;color:var(--ink-3)}
.field .preview{font-size:12.5px;color:var(--ink-2);background:var(--paper-2);border:1px solid var(--line-soft);border-radius:var(--radius);padding:7px 10px;font-family:var(--font-mono)}

/* Tweaks panel positioning override */
#tweaks-root {
  position: fixed;
  bottom: 16px;
  left: 16px;
  z-index: 200;
}

/* Empty state */
.empty {
  padding: 40px 24px;
  text-align: center;
  color: var(--ink-3);
}
.empty .ico {
  font-size: 22px;
  margin-bottom: 6px;
  opacity: 0.5;
  font-family: var(--font-mono);
}

/* Two-pane (clients detail, kb, etc) */
.split {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 16px;
}
.split-3 {
  display: grid;
  grid-template-columns: 240px 1fr 280px;
  gap: 16px;
}
@media (max-width: 1100px) {
  .split,
  .split-3 {
    grid-template-columns: 1fr;
  }
  .stat-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .kpi-row,
  .two-col,
  .three-col {
    grid-template-columns: 1fr;
  }
}

/* Chat */
.chat {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--top-h) - 70px);
  min-height: 420px;
}
.chat-stream {
  flex: 1;
  overflow: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.msg {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  max-width: 80%;
}
.msg.me {
  align-self: flex-end;
  flex-direction: row-reverse;
}
.msg .bubble {
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  padding: 8px 12px;
  font-size: 13.5px;
}
.msg.me .bubble {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.msg .who {
  font-size: 11px;
  color: var(--ink-3);
  margin-bottom: 2px;
}
.chat-compose {
  border-top: 1px solid var(--line-soft);
  padding: 10px 12px;
  display: flex;
  gap: 8px;
  align-items: center;
}
.chat-compose textarea {
  flex: 1;
  resize: none;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 8px 10px;
  min-height: 36px;
  max-height: 120px;
  outline: none;
}

/* DNS rows */
.dns-row td {
  font-family: var(--font-mono);
  font-size: 12.5px;
}
.dns-type {
  display: inline-block;
  min-width: 40px;
  text-align: center;
  padding: 1px 6px;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  background: var(--paper-3);
  color: var(--ink-2);
}
.dns-type.A {
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.dns-type.MX {
  background: var(--copper-soft);
  color: var(--copper-ink);
}
.dns-type.CNAME {
  background: var(--green-soft);
  color: var(--green);
}
.dns-type.TXT {
  background: var(--amber-soft);
  color: var(--amber);
}
.dns-type.NS {
  background: var(--red-soft);
  color: var(--red);
}

/* Invoice preview */
.invoice-preview {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  padding: 28px;
  font-family: var(--font-serif);
  color: var(--ink);
}
.invoice-preview h2 {
  font-size: 20px;
  margin: 0;
  letter-spacing: -0.01em;
}
.invoice-preview .meta-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 18px 0 22px;
  font-family: var(--font-sans);
  font-size: 13px;
}
.invoice-preview table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-sans);
  font-size: 13px;
}
.invoice-preview th {
  text-align: left;
  font-weight: 600;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
}
.invoice-preview td {
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}
.invoice-preview .totals {
  margin-top: 14px;
  display: flex;
  justify-content: flex-end;
}
.invoice-preview .totals table {
  width: 280px;
}

/* Login history bar */
.history-bar {
  display: flex;
  gap: 2px;
  height: 22px;
}
.history-bar i {
  flex: 1;
  border-radius: 2px;
  background: var(--green);
  opacity: 0.85;
}
.history-bar i.fail {
  background: var(--red);
}
.history-bar i.warn {
  background: var(--amber);
}

/* KB */
.kb-list .list-item {
  cursor: pointer;
}
.kb-list .list-item:hover {
  background: var(--paper-2);
}
.kb-cat {
  font-size: 11px;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Audit row */
.audit-diff {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  padding: 6px 8px;
  margin-top: 4px;
}
.audit-diff .before {
  color: var(--red);
}
.audit-diff .after {
  color: var(--green);
}

/* Tabs */
.tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 16px;
}
.tab {
  padding: 8px 14px;
  cursor: pointer;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab:hover {
  color: var(--ink);
}
.tab.on {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
/* Panneaux d'onglets (fiche utilisateur en onglets) : un seul visible à la fois. */
.pane {
  display: none;
}
.pane.on {
  display: block;
}
/* Disposition des formulaires de la fiche (cf. maquette ds-maquette-fiche-onglets) */
.frow{display:grid;gap:10px;margin-bottom:12px}
.frow.c2{grid-template-columns:1fr 1fr}
.frow.c3{grid-template-columns:1fr 1fr 1fr}
.frow.sal{grid-template-columns:2fr 1fr}
.frow:last-child{margin-bottom:0}
.frow .field>*{width:100%}
.lab{font-size:12px;color:var(--ink-3);font-weight:500;margin-bottom:5px;display:block}
/* POPUP D'ÉDITION D'UN DOMAINE (#dom-form) : libellés en MAJUSCULES.
   Par `text-transform` et non en réécrivant les 12 libellés : la casse est une décision
   d'affichage, elle n'a pas à être figée dans le texte source. Un libellé écrit en capitales dans
   le code se retrouverait tel quel partout où on le réutiliserait — messages d'erreur, infobulles,
   futur fichier de langue — et il faudrait le rétablir à la main à chaque emprunt.
   PORTÉE À #dom-form SEUL : `.lab` sert aussi à la FICHE (#dom-fiche), dont les libellés restent
   en casse-phrase. Les deux écrans ne se ressemblent pas par hasard — l'un se lit, l'autre se
   remplit. */
#dom-form .lab{text-transform:uppercase;letter-spacing:.03em}
.box{border:1px solid var(--line);border-radius:var(--radius);padding:13px;margin-bottom:12px;background:var(--paper-2)}
.box:last-child{margin-bottom:0}
.box-t{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-3);font-weight:700;margin-bottom:10px}
.docline{display:flex;align-items:center;gap:8px;padding:8px 0;font-size:13px;border-top:1px solid var(--line-soft);margin-top:4px}
.docline:first-of-type{border-top:0;margin-top:0}
.docline .a{margin-left:auto;display:flex;gap:6px;align-items:center}
.box-t .a{margin-left:auto;display:flex;gap:6px}
@media(max-width:760px){.frow.c2,.frow.c3,.frow.sal{grid-template-columns:1fr}}
/* AJOUT ADDITIF (2026/08/08) — deux variantes de grille 3 colonnes NON equilibrees, pour les zones
   du formulaire de contact WHOIS (maquette validee). Aucune regle existante n'est modifiee ; ces
   deux classes sont nouvelles, donc sans effet sur les ecrans qui ne les emploient pas.
   .n3 = 1re colonne ETROITE  (Civilite | Prenom | Nom  et  Code postal | Ville | Region)
   .w3 = 1re colonne LARGE    (Email | Indicatif | Telephone) */
.frow.n3{grid-template-columns:120px 1fr 1fr}
.frow.w3{grid-template-columns:2fr 120px 1fr}
@media(max-width:760px){.frow.n3,.frow.w3{grid-template-columns:1fr}}
/* AJOUT ADDITIF (2026/08/15) — grille 4 colonnes, pour la seule ligne de l'editeur DNS qui en
   porte quatre (CNAME : Nom | Destination | TTL | Proxy). Classe NOUVELLE, meme forme que .c2/.c3
   et meme repli en 1 colonne sous 760px : aucune regle existante n'est modifiee. */
.frow.c4{grid-template-columns:1fr 1fr 1fr 1fr}
@media(max-width:760px){.frow.c4{grid-template-columns:1fr}}
/* EDITEUR DNS — les lignes du formulaire portent des colonnes de largeurs INEGALES (une liste de
   TTL ne doit pas occuper la place d'une cle publique), calculees par champ et posees en `style=`
   sur chaque .frow. Sous 760px ces largeurs fixes ne tiennent plus : le repli a une colonne doit
   donc reprendre la main sur un style EN LIGNE, ce que seul `!important` permet. Portee au SEUL
   #dns-fields : aucune autre grille du panel n'est concernee. */
@media(max-width:760px){#dns-fields .frow{grid-template-columns:1fr !important}}
/* Fiche candidat (recrutement) — classes reprises de la maquette (jusqu'ici absentes du DS ;
   noms specifiques a la fiche, non utilises ailleurs -> ajout additif sans impact autres modules). */
.kv{display:grid;grid-template-columns:150px 1fr;gap:6px 12px;font-size:13.5px}
.kv .k{color:var(--ink-3)}
.tag-list{display:flex;gap:6px;flex-wrap:wrap}
.langbar{display:flex;align-items:center;gap:8px;font-size:12.5px;padding:5px 0}
.langbar .nm{width:90px}
.lb{flex:1;height:6px;border-radius:99px;background:var(--paper-3);overflow:hidden;max-width:180px}
.lb i{display:block;height:100%;background:var(--copper);border-radius:99px}
.consent{display:flex;align-items:center;gap:8px;font-size:12.5px;padding:4px 0}
.consent .ok{color:var(--green)}
.consent .no{color:var(--red)}
.scorewrap{display:flex;align-items:center;gap:8px}
.scorebar{width:64px;height:6px;border-radius:99px;background:var(--paper-3);overflow:hidden;flex:0 0 64px}
.scorebar i{display:block;height:100%;background:var(--accent);border-radius:99px}
.scoretxt{font-family:var(--font-mono);font-size:12px;color:var(--ink-2)}
.seg{display:inline-flex;border:1px solid var(--line);border-radius:99px;overflow:hidden;flex-wrap:wrap}
.seg button{border:0;background:transparent;color:var(--ink-3);padding:6px 12px;font:600 12px var(--font-sans);cursor:pointer}
.seg button.on{background:var(--accent);color:#fff}
.starrow{display:flex;gap:3px;color:var(--amber)}
/* Langues (fiche candidat) : Écrit/Parlé sur lignes séparées, barre colorée par niveau. */
.lang-block{padding:8px 0;border-top:1px solid var(--line-soft)}
.lang-block:first-of-type{border-top:0}
.lang-block .lname{font-weight:600;margin-bottom:4px}
.lmetric{display:flex;align-items:center;gap:10px;padding:2px 0;font-size:12.5px}
.lmetric .ll{width:46px;color:var(--ink-3)}
.lmetric .lval{font-family:var(--font-mono);color:var(--ink-2)}
.lbar{flex:1;max-width:200px;height:7px;border-radius:99px;background:var(--paper-3);overflow:hidden}
.lbar i{display:block;height:100%;border-radius:99px}
.c-grey{background:var(--ink-3)}.c-orange{background:var(--accent)}.c-green{background:var(--green)}
/* Fiche candidat : toutes les listes déroulantes affichées EN MAJUSCULES (valeurs stockées inchangées). */
#cand-fiche select,#cand-fiche select option{text-transform:uppercase}
/* Profil de la fiche candidat : espacement bas UNIFORME des rangées .two-col (12px des deux côtés,
   aligné sur les box pleine largeur contact/cv/expériences). La box de droite étant :last-child, sa
   marge basse valait 0 et collait la colonne droite -> on la neutralise et on porte l'espacement
   sur la rangée .two-col. */
#candp-profil .two-col{margin-bottom:12px}
#candp-profil .two-col>.box{margin-bottom:0}
/* Fiche candidat : TAILLE DE POLICE UNIFORME de tous les champs d'édition, quelle que soit la zone.
   Les lignes répétables (.cz-row : e-mails, téléphones, langues, réseaux) et les textareas de
   l'onglet RH posent leurs contrôles HORS .field — ils héritaient donc de la taille ambiante
   (règle globale `font-size:inherit` ligne 164), d'où l'écart visible avec les zones bâties sur
   .field (Identité, Poste, Expériences…, déjà en 13.5px). On aligne TOUT sur la taille standard
   du DS. Portée limitée au conteneur #cand-fiche : aucun autre module n'est touché. */
#cand-fiche input:not([type=checkbox]):not([type=radio]):not([type=range]),
#cand-fiche select,
#cand-fiche textarea{font-size:13.5px}
@media(max-width:760px){.kv{grid-template-columns:1fr}}
/* Tableau des droits d'accès (onglet Droits) — aligné sur la maquette. */
.perm {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.perm th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--paper-2);
  text-align: center;
}
.perm th:first-child {
  text-align: left;
}
.perm td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  text-align: center;
  vertical-align: middle;
}
.perm td:first-child {
  text-align: left;
}
.perm .mod {
  font-weight: 500;
}
.perm .code {
  font-size: 10.5px;
  color: var(--ink-3);
  font-family: var(--font-mono);
}

/* Role hint banner */
.role-hint {
  background: var(--amber-soft);
  color: var(--amber);
  border: 1px solid color-mix(in oklab, var(--amber) 30%, transparent);
  border-radius: var(--radius);
  padding: 6px 12px;
  font-size: 12.5px;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}

/* Profile row */
.role-switch {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 8px;
  border: 1px solid var(--line);
  border-radius: 99px;
  background: var(--paper-2);
  font-size: 12.5px;
  cursor: pointer;
}
.role-switch .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.role-switch .dot.copper {
  background: var(--copper);
}
.role-switch .dot.green {
  background: var(--green);
}
.role-switch .dot.gray {
  background: var(--ink-4);
}

/* Hover anim for cards */
.hov-pop {
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}
.hov-pop:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}

/* =========================================================
   Top-nav shell (Lot 3) — barre du haut + menus groupés + footer
   ========================================================= */
.nav{position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:8px;min-height:60px;padding:0 20px;background:color-mix(in srgb,var(--paper) 85%,transparent);backdrop-filter:saturate(1.4) blur(10px);border-bottom:1px solid var(--line)}
.nav .logo{display:flex;align-items:center;gap:10px;padding-right:6px;cursor:pointer;flex:0 0 auto}
.nav .nmark{width:32px;height:32px;border-radius:9px;background:linear-gradient(150deg,var(--accent),var(--accent-hover));display:grid;place-items:center;color:#fff;font-weight:700;font-size:17px;font-family:var(--font-serif);box-shadow:0 6px 16px -8px var(--accent)}
.menu{display:flex;align-items:center;gap:2px;flex:1;min-width:0;flex-wrap:wrap}
.mitem{position:relative}
.mitem>button,.mlink{display:inline-flex;align-items:center;gap:6px;height:38px;padding:0 11px;border:0;background:transparent;color:var(--ink-2);font-size:13.5px;font-weight:500;border-radius:var(--radius);white-space:nowrap;cursor:pointer;font-family:inherit;text-decoration:none}
.mitem>button:hover,.mlink:hover{background:var(--paper-2);color:var(--ink)}
.mitem>button .car{width:7px;height:7px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg);margin-top:-3px;opacity:.5;transition:transform .15s}
.mlink.active,.mitem.active>button{color:var(--ink);font-weight:600}
.mlink.active::after,.mitem.active>button::after{content:"";position:absolute;left:11px;right:11px;bottom:-1px;height:2px;background:var(--accent);border-radius:2px}
.mlink .badge{font-family:var(--font-mono);font-size:10px;background:var(--copper-soft);color:var(--copper-ink);padding:0 5px;border-radius:99px;font-weight:600}
.drop{position:absolute;top:calc(100% + 4px);left:0;min-width:250px;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-pop);padding:8px;opacity:0;transform:translateY(-6px);pointer-events:none;transition:opacity .13s,transform .13s;z-index:50}
.drop.right{left:auto;right:0}
.drophead{font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-4);font-weight:700;padding:8px 10px 4px}
.di{display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:var(--radius);cursor:pointer;color:var(--ink)}
.di:hover{background:var(--paper-2)}
.di .dico{width:30px;height:30px;border-radius:8px;background:var(--accent-soft);color:var(--accent-ink);display:grid;place-items:center;flex:0 0 30px}
.di .dico .ic{width:16px;height:16px}
.di .dt{font-size:13.5px;font-weight:500}
.di .dtag{margin-left:auto;font-family:var(--font-mono);font-size:10.5px;background:var(--copper-soft);color:var(--copper-ink);padding:1px 6px;border-radius:99px;font-weight:600}
.dsep{height:1px;background:var(--line-soft);margin:6px 4px}
.menu .mitem:hover>.drop{opacity:1;transform:translateY(0);pointer-events:auto}
.menu .mitem:hover>button{background:var(--paper-2);color:var(--ink)}
.menu .mitem:hover::after{content:"";position:absolute;left:0;right:0;top:100%;height:10px}
.nav-right{display:flex;align-items:center;gap:8px;margin-left:auto;flex:0 0 auto}
.nsearch{display:flex;align-items:center;gap:8px;background:var(--paper-2);border:1px solid var(--line-soft);border-radius:99px;padding:7px 12px;color:var(--ink-3);width:170px}
.nsearch .ic{width:15px;height:15px}
.nsearch input{flex:1;background:transparent;border:0;outline:0;color:var(--ink);min-width:0}
.nsearch kbd{font-family:var(--font-mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:1px 5px;color:var(--ink-3);background:var(--paper)}
.iconbtn{width:38px;height:38px;border-radius:50%;border:1px solid var(--line);background:var(--paper);color:var(--ink-2);display:grid;place-items:center;flex:0 0 38px;cursor:pointer}
.iconbtn:hover{background:var(--paper-2);color:var(--ink)}
.iconbtn .ic{width:17px;height:17px}
.userbtn{display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--paper);border-radius:99px;padding:4px 6px 4px 4px;cursor:pointer}
.userbtn:hover{background:var(--paper-2)}
.userbtn .car{width:7px;height:7px;border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);transform:rotate(45deg);margin:-3px 3px 0 0}
#userwrap.open>.drop{opacity:1;transform:translateY(0);pointer-events:auto}
.umenu{min-width:264px}
.uhead{display:flex;align-items:center;gap:12px;padding:8px 10px 10px}
.uhead .un{font-weight:600;font-size:14px}
.uhead .ue{font-size:12px;color:var(--ink-3)}
.urow{display:flex;align-items:center;justify-content:space-between;padding:9px 10px;border-radius:var(--radius);cursor:pointer;color:var(--ink);font-size:13.5px}
.urow:hover{background:var(--paper-2)}
.urow .l{display:flex;align-items:center;gap:10px}
.urow .l .ic{width:16px;height:16px;color:var(--ink-3)}
.themeseg{display:inline-flex;border:1px solid var(--line);border-radius:99px;overflow:hidden}
.themeseg button{border:0;background:transparent;color:var(--ink-3);padding:3px 8px;font:600 11px var(--font-sans);cursor:pointer}
.themeseg button.on{background:var(--ink);color:var(--paper)}
[data-theme="dark"] .themeseg button.on,[data-theme="grey"] .themeseg button.on{background:var(--paper-3);color:var(--ink)}
.burger{display:none;width:38px;height:38px;border-radius:var(--radius);border:1px solid var(--line);background:var(--paper);color:var(--ink);align-items:center;justify-content:center;flex:0 0 38px;cursor:pointer}
.burger .ic{width:18px;height:18px}
/* Footer */
.foot{border-top:1px solid var(--line);background:var(--paper-2)}
.foot-in{max-width:1480px;margin:0 auto;padding:18px 28px;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:16px}
.foot-left{display:flex;flex-direction:column;gap:3px}
.fbrand{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}
.fmark{width:22px;height:22px;border-radius:6px;background:linear-gradient(150deg,var(--accent),var(--accent-hover));display:grid;place-items:center;color:#fff;font-family:var(--font-serif);font-size:12px;font-weight:700}
.fcopy{color:var(--ink-3);font-size:12.5px}
.foot-sites{justify-self:center;display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.foot-sites a{color:var(--ink-2);font-size:13px;text-decoration:none}
.foot-sites a:hover{color:var(--accent)}
.foot-sep{color:var(--ink-4);margin:0 4px}
.foot-social{justify-self:end;margin-left:0;display:flex;align-items:center;gap:8px}
@media(max-width:660px){.foot-in{grid-template-columns:1fr;justify-items:start;gap:14px}.foot-sites,.foot-social{justify-self:start}}
.soc{width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:var(--paper);color:var(--ink-3);display:grid;place-items:center}
.soc:hover{color:#fff;background:var(--accent);border-color:var(--accent)}
.soc svg{width:16px;height:16px;fill:currentColor;stroke:none}
@media(max-width:1080px){
  .menu{position:fixed;top:66px;left:8px;right:auto;width:min(340px,calc(100vw - 16px));background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg);flex-direction:column;align-items:stretch;padding:8px;gap:2px;display:none;box-shadow:var(--shadow-pop);max-height:calc(100vh - 80px);overflow:auto;flex-wrap:nowrap;z-index:45}
  .menu.open{display:flex}
  .mitem>button,.mlink{width:100%;justify-content:space-between;height:44px}
  .drop{position:static;box-shadow:none;border:0;border-left:2px solid var(--line);border-radius:0;margin:2px 0 6px 14px;min-width:0;opacity:1;transform:none;pointer-events:auto;padding:2px 0;display:none}
  .menu .mitem:hover>.drop{opacity:1}
  .mitem.open .drop{display:block}
  .mlink.active::after,.mitem.active>button::after{display:none}
  .burger{display:inline-flex}
  .nsearch{display:none}
}

/* Barre d'actions rapide flottante (haut/bas/tâches/accueil) */
.quickrail{position:fixed;right:14px;top:50%;transform:translateY(-50%);z-index:35;display:flex;flex-direction:column;gap:6px;padding:6px;background:var(--accent);border:1px solid transparent;border-color:transparent;border-radius:99px;box-shadow:var(--shadow-2)}
.quickrail button{width:38px;height:38px;border-radius:50%;border:0;background:transparent;color:#fff;display:grid;place-items:center;cursor:pointer}
.quickrail button:hover{background:rgba(255,255,255,.18);color:#fff}
.quickrail .sep{height:1px;background:rgba(255,255,255,.35);margin:2px 6px}
.quickrail .ic{width:18px;height:18px}
@media(max-width:640px){.quickrail{right:8px}}

/* =========================================================
   Accueil Domaines — cartes de synthèse + carte flip
   ========================================================= */
.txt-red{color:var(--red)!important}
.txt-amber{color:var(--amber)!important}
.pager .pinfo{font-family:var(--font-mono);font-size:12px;color:var(--ink-3);padding:0 4px}
/* ⚠️ `auto-fit` et non `repeat(5,1fr)` depuis l'ajout de la 5e carte (Services). Un nombre de
   colonnes FIGÉ imposait de le rectifier à chaque carte ajoutée, et cinq colonnes forcées
   écrasaient les cartes sous 1200 px — un classement à trois entrées y devenait illisible.
   `minmax(215px,1fr)` fixe une largeur PLANCHER et laisse la grille décider du reste : autant de
   colonnes que la place en autorise, jamais de carte comprimée. Les deux paliers ci-dessous
   (2 puis 1 colonne) restent des garde-fous explicites pour les petits écrans. */
.dom-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:12px;margin-bottom:16px}
/* (Les règles .dc-svc d'un rendu maison pour la carte « Services » ont été RETIRÉES : la carte
   reprend désormais le markup .rank de « Top registrars » et « Top clients ». Trois cartes
   voisines qui classent trois choses doivent se lire de la même façon.) */
.dcard{background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);min-height:196px;display:flex;flex-direction:column}
.dcard .dc-h{display:flex;align-items:center;gap:8px;padding:12px 16px 8px}
.dcard .dc-h .t{font-size:11.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-3);font-weight:600}
.dcard .dc-h .ico{width:26px;height:26px;border-radius:7px;background:var(--accent-soft);color:var(--accent-ink);display:grid;place-items:center;flex:0 0 26px}
.dcard .dc-h .ico .ic{width:15px;height:15px}
.dc-body{padding:0 16px 14px;flex:1;display:flex;flex-direction:column}
.dc-count{align-items:flex-start;justify-content:center;gap:2px}
.dc-count .big{font-size:60px;font-weight:600;letter-spacing:-.02em;line-height:1;font-feature-settings:"tnum";white-space:nowrap}
.dc-count .cap{color:var(--ink-3);font-size:12.5px}
.dc-count .mini{margin-top:auto;display:flex;gap:6px;flex-wrap:wrap;padding-top:12px}
.rank{display:flex;flex-direction:column;gap:2px}
.rank .r{display:flex;align-items:center;gap:9px;padding:7px 0;border-top:1px solid var(--line-soft)}
.rank .r:first-child{border-top:0}
.rank .r .nm{flex:1;font-size:15px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rank .r .ct{font-family:var(--font-mono);font-size:12.5px;font-weight:600;background:var(--copper-soft);color:var(--copper-ink);padding:2px 9px;border-radius:99px}
.rank .r .bar{height:6px;border-radius:99px;background:var(--accent);opacity:.55;min-width:6px}
.flip{perspective:1200px;flex:1;display:flex}
.flip-inner{position:relative;flex:1;transition:transform .5s cubic-bezier(.4,.15,.2,1);transform-style:preserve-3d}
.flip.flipped .flip-inner{transform:rotateY(180deg)}
.flip-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;display:flex;flex-direction:column;background:var(--paper)}
.flip-face.back{transform:rotateY(180deg)}
.dcard.is-flip{cursor:pointer;position:relative}
.dcard.is-flip .dc-h .ico{position:relative}
.dcard.is-flip .dc-h .flag{margin-left:auto;font-size:10px;color:var(--ink-4);display:inline-flex;align-items:center;gap:4px}
.rlist{display:flex;flex-direction:column;overflow:auto}
.rlist .rl{display:flex;align-items:center;gap:8px;padding:5px 0;border-top:1px solid var(--line-soft);font-size:12.5px}
.rlist .rl:first-child{border-top:0}
.rlist .rl .d{font-family:var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rlist .rl .when{margin-left:auto;font-size:11px;flex:0 0 auto;font-weight:600}
.flip-empty{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;color:var(--ink-3);font-size:12.5px;padding:6px}
.flip-count{font-size:34px;font-weight:600;line-height:1;letter-spacing:-.02em}
.flip-sub{color:var(--ink-3);font-size:12px;margin-bottom:8px}
.flip-face.front{background:var(--amber-soft)}     /* recto = à renouveler < 1 mois (orange) */
.flip-face.back{background:var(--red-soft)}         /* verso = urgence < 15 j (rouge) */
.dcard.face-month{background:var(--amber-soft);border-color:color-mix(in oklab,var(--amber) 40%,var(--line))}
.dcard.face-urgent{background:var(--red-soft);border-color:color-mix(in oklab,var(--red) 45%,var(--line))}
.dcard.face-month .dc-h .ico{background:var(--amber-soft);color:var(--amber)}
.dcard.face-month .dc-h .t{color:var(--amber)}
.dcard.face-urgent .dc-h .ico{background:var(--red-soft);color:var(--red)}
.dcard.face-urgent .dc-h .t{color:var(--red)}
.dcard.face-urgent .dc-h .ico::after{content:"";position:absolute;inset:-4px;border-radius:10px;border:2px solid var(--red);opacity:.55;animation:prg 1.7s ease-out infinite}
@keyframes prg{0%{transform:scale(1);opacity:.55}100%{transform:scale(1.55);opacity:0}}
.dom-spin{display:inline-flex;animation:domspin .9s linear infinite}
@keyframes domspin{to{transform:rotate(360deg)}}
.box-mail-hl{background:var(--accent-soft);border-color:color-mix(in oklab,var(--accent) 35%,var(--line))}
.box-mail-hl .box-t{color:var(--accent-ink)}
/* MESSAGERIE — MEME TEINTE QU'AILLEURS, MAIS DILUEE. La zone « Serveurs de mail (MX) » de l'onglet
   EMAIL est peinte en var(--accent-soft) (.box-mail-hl ci-dessus) ; les lignes de la table DNS qui
   portent la messagerie reprennent CETTE MEME teinte, pour que la meme idee ait la meme couleur.
   ⚠️ MAIS A 45 % SEULEMENT, et non a pleine valeur. Une CARTE est un bloc isole qu'on repere par
   son fond ; des LIGNES de tableau, elles, se comptent par dizaines et se lisent en colonne — le
   meme orange y devient un aplat qui prend toute l'attention, alors qu'on cherchait un simple
   repere. Le fond est donc dilue par color-mix vers `transparent`, ce qui le rend translucide :
   la teinte reste identique dans les trois themes (clair, sombre, gris) sans avoir a redeclarer
   une couleur par theme, et le survol de ligne transparait au lieu d'etre masque.
   ⚠️ Pose sur les CELLULES et non sur le <tr> : `.tbl tbody tr:hover` repeint la ligne entiere et
   ecraserait la mise en valeur des qu'on passe la souris — c'est-a-dire au moment meme ou l'on
   s'apprete a cliquer dessus. Le fond d'une cellule se peint PAR-DESSUS celui de sa ligne : la
   couleur tient, et sa translucidite laisse simplement le survol se lire dessous. */
.tbl tbody tr.dns-mail-hl > td{background:color-mix(in oklab,var(--accent-soft) 45%,transparent)}
.menu-pop{position:absolute;top:calc(100% + 4px);right:0;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-pop);padding:6px;z-index:20;min-width:170px;display:none}
.open > .menu-pop{display:block}
.menu-pop button{display:block;width:100%;text-align:left;border:0;background:transparent;color:var(--ink);padding:7px 10px;border-radius:6px;font-size:13px;cursor:pointer}
.menu-pop button:hover{background:var(--paper-2)}
.pill.owner{background:var(--accent-soft);color:var(--accent-ink)}
.pill.admin{background:var(--copper-soft);color:var(--copper-ink)}
.pill.tech{background:var(--green-soft);color:var(--green)}
.pill.billing{background:var(--amber-soft);color:var(--amber)}
.add-slot{border:1px dashed var(--line);border-radius:var(--radius);padding:14px;text-align:center;margin-top:4px}
.add-slots{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.add-chip{display:inline-flex;align-items:center;gap:6px;border:1px dashed var(--line);background:transparent;color:var(--ink-2);border-radius:99px;padding:6px 12px;font-size:12.5px;cursor:pointer}
.add-chip:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}
.add-chip .ic{width:13px;height:13px}
@media(max-width:1100px){.dom-cards{grid-template-columns:1fr 1fr}}
@media(max-width:640px){.dom-cards{grid-template-columns:1fr}}

/* Version globale du panel (footer / pages login & inscription) */
.nw-version{font-family:var(--font-sans);font-weight:400;font-size:13px;color:var(--ink-2);text-align:center;letter-spacing:0;width:100%}

/* Composant « Bientot disponible » (routes soon_* sans entree de menu).
   Classes prefixees soon-* pour ne PAS entrer en collision avec .pill du DS. */
.nw-soon{max-width:520px;margin:0 auto;text-align:center;background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow-2);padding:44px 36px}
.nw-soon .soon-icon{width:64px;height:64px;margin:0 auto 20px;border-radius:16px;background:var(--accent-soft);color:var(--accent);display:flex;align-items:center;justify-content:center}
.nw-soon .soon-icon svg{width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.8}
.nw-soon .soon-pill{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--accent-ink);background:var(--accent-soft);border:1px solid var(--accent);border-radius:999px;padding:4px 12px;margin-bottom:16px}
.nw-soon h1{font-size:22px;font-weight:700;margin:0 0 10px;color:var(--ink)}
.nw-soon p{font-size:14.5px;line-height:1.6;color:var(--ink-2);margin:0 auto;max-width:400px}
.nw-soon .soon-sub{font-size:12.5px;color:var(--ink-3);margin-top:18px}
.soon-wrap{min-height:calc(100vh - var(--top-h) - 32px);display:flex;align-items:center;justify-content:center;padding:24px 16px}
@media (max-width:560px){.nw-soon{padding:32px 22px}.nw-soon h1{font-size:20px}}
