/* Les polices de la charte, servies par nous comme sur le site : aucun appel
   à un hébergeur tiers, donc rien à déclarer dans une politique de
   confidentialité. Les fichiers sont les mêmes, copiés depuis public/fonts/. */
@font-face {
  font-family: 'Asap';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/asap-italic-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Asap';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/asap-normal-400_800.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spline Sans Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/spline-sans-mono-normal-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spline Sans Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/spline-sans-mono-normal-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spline Sans Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/spline-sans-mono-normal-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* La charte Blackbee, reprise telle quelle depuis src/styles/tokens.css du
   site. Les valeurs ne sont pas réinventées ici : le backoffice et le site
   doivent se ressembler, et deux jeux de couleurs qui dérivent l'un de l'autre
   finissent toujours par se contredire. */
:root {
  --rouge: #ED1C24;
  --rouge-survol: #C9151C;
  --miel: #E8A013;
  --noir: #0A0A0B;
  --panneau: #111113;
  --pied: #050506;
  --gris-900: #1A1A1D;
  --gris-800: #2A2A2E;
  --gris-700: #3F3F45;
  --gris-600: #57575E;
  --gris-500: #71717A;
  --gris-400: #9B9BA3;
  --gris-300: #C6C6CC;
  --gris-50: #F6F6F7;
  --blanc: #FFFFFF;
  --succes: #1D9E55;
  --erreur: #B42318;
  --sans: 'Asap', system-ui, 'Segoe UI', Calibri, sans-serif;
  --mono: 'Spline Sans Mono', ui-monospace, Consolas, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--noir);
  color: var(--gris-50);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1 { font-size: 26px; font-weight: 800; letter-spacing: -.02em; margin: 0; }
.point { color: var(--rouge); }

a { color: var(--gris-50); text-decoration: none; }
a:hover { color: var(--rouge); }
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 2px solid var(--rouge);
  outline-offset: 3px;
}

/* Le mono garde son emploi : repères, compteurs, codes. Pas les commandes. */
.etiquette {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gris-500);
}

/* ── La page de connexion ─────────────────────────────────────────────── */
.centre {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}

.carte-connexion {
  width: 100%;
  max-width: 400px;
  background: var(--panneau);
  border: 1px solid var(--gris-900);
  border-radius: 18px;
  padding: 34px 32px;
}

.marque {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -.02em;
  margin-bottom: 26px;
}

.explication, .apres-envoi p {
  font-size: 15px;
  color: var(--gris-400);
  margin: 10px 0 24px;
}

form { display: flex; flex-direction: column; gap: 18px; }
label { display: flex; flex-direction: column; gap: 7px; }

/* ⚠️ Cette règle ne visait que `input[type='email']` et `input[type='text']`.
   Un `<input name="q">` SANS attribut `type` n'était donc pas atteint, ni
   aucun `select`, ni aucun `textarea` : ils retombaient sur le style natif du
   navigateur, blanc sur blanc au milieu d'une interface noire. Sur l'écran
   des photos, le champ de recherche et la liste des destinations sortaient
   ainsi en blanc. On cible désormais les éléments, pas quelques types. */
input:not([type='checkbox']):not([type='radio']),
select,
textarea {
  background: var(--noir);
  border: 1px solid var(--gris-800);
  border-radius: 10px;
  /* 48 px de haut : une cible tactile confortable, y compris au téléphone. */
  padding: 14px 15px;
  font-family: var(--sans);
  font-size: 15.5px;
  color: var(--gris-50);
  /* Sans cela, macOS impose son propre fond aux listes déroulantes et le
     réglage ci-dessus reste sans effet. */
  appearance: none;
  -webkit-appearance: none;
  max-width: 100%;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--gris-600);
}

/* Une liste déroulante sans chevron ne se distingue plus d'un champ de texte :
   on redessine le repère que `appearance: none` vient d'enlever. */
select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gris-500) 50%),
    linear-gradient(135deg, var(--gris-500) 50%, transparent 50%);
  background-position: calc(100% - 17px) center, calc(100% - 12px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}

input::placeholder, textarea::placeholder { color: var(--gris-600); }

/* ⚠️ Les boutons étaient en Spline Sans Mono, 10,5 px, MAJUSCULES, lettres
   espacées. La charte réserve ce traitement aux ÉTIQUETTES TECHNIQUES — un
   libellé qu'on lit une fois pour se repérer. Une commande qu'on lit cinquante
   fois par jour demande l'inverse : la police de texte, une taille normale, la
   casse ordinaire. « ENREGISTRER LES NOMS » en capitales espacées se déchiffre ;
   « Enregistrer les noms » se lit.
   Le mono reste sur les compteurs, les codes de langue et les horodatages,
   c'est-à-dire là où il sert. */
button {
  min-height: 42px;
  padding: 0 18px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  background: var(--rouge);
  color: var(--blanc);
  border: none;
  border-radius: 999px;
  cursor: pointer;
  /* Un bouton ne s'étire pas pour remplir la ligne : « Chercher » occupait
     toute la largeur sous son champ, ce qui lui donnait l'importance d'une
     action principale alors qu'il n'accompagne qu'une recherche. */
  flex: none;
  white-space: nowrap;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
button:hover { background: var(--rouge-survol); }
@media (prefers-reduced-motion: reduce) { button { transition: none; } }

.lien-discret {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gris-400);
  border-bottom: 1px solid var(--gris-700);
  padding-bottom: 3px;
}

.avis {
  font-size: 14px;
  border-radius: 10px;
  padding: 12px 14px;
  margin: 0 0 20px;
}
.avis-attention {
  color: var(--miel);
  background: color-mix(in srgb, var(--miel) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--miel) 30%, transparent);
}

/* Le piège à robots. Il doit rester dans le flux pour qu'un automate le
   remplisse, mais invisible et inatteignable au clavier pour un humain :
   `display:none` seul serait repéré par les robots un peu sérieux. */
.piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── Le cadre ─────────────────────────────────────────────────────────── */
.cadre { display: flex; min-height: 100vh; }

.rail {
  width: 232px;
  flex: none;
  background: var(--pied);
  border-right: 1px solid var(--gris-900);
  padding: 22px 0;
  display: flex;
  flex-direction: column;
}

.marque-rail {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 20px 26px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.02em;
}
.marque-rail:hover { color: var(--gris-50); }

.rubriques { display: flex; flex-direction: column; gap: 2px; padding: 0 12px; }
.bloc-bas { margin: 20px 12px 0; padding-top: 16px; border-top: 1px solid var(--gris-900); }

.rubrique {
  padding: 12px;
  border-radius: 9px;
  font-size: 14.5px;
  color: var(--gris-400);
}
.rubrique:hover { background: var(--gris-900); color: var(--gris-50); }
.rubrique.courante { background: var(--gris-900); color: var(--blanc); font-weight: 600; }

.pied-rail { margin-top: auto; padding: 0 20px; display: flex; flex-direction: column; gap: 10px; }

.carte-personne {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  background: var(--panneau);
  border: 1px solid var(--gris-900);
  border-radius: 11px;
}
.initiales {
  width: 30px; height: 30px; flex: none;
  border-radius: 999px;
  background: var(--gris-800);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 800;
}
.qui { display: flex; flex-direction: column; line-height: 1.25; }
.nom { font-size: 13px; font-weight: 600; }

.bouton-discret {
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  width: 100%;
  min-height: 40px;
  background: transparent;
  color: var(--gris-500);
  border: 1px solid var(--gris-900);
  font-size: 9.5px;
}
.bouton-discret:hover { background: transparent; color: var(--gris-300); border-color: var(--gris-700); }

.page { flex: 1; min-width: 0; padding: 30px 34px 60px; }

/* Sous 900 px le rail passe en bandeau : la place manque pour une colonne
   fixe, et le backoffice doit rester utilisable depuis une tablette. */
@media (max-width: 900px) {
  .cadre { flex-direction: column; }
  .rail {
    width: 100%;
    flex-direction: row;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-right: none;
    border-bottom: 1px solid var(--gris-900);
    overflow-x: auto;
    /* Le rail suit le défilement : sept rubriques ne tiennent pas dans la
       largeur d'un téléphone, et remonter en haut de page pour changer
       d'écran est le genre de détail qui fait renoncer. */
    position: sticky; top: 0; z-index: 10;
    /* Le bord droit s'estompe quand il reste des rubriques à faire défiler.
       Sans cet indice, rien ne dit qu'il y a autre chose à droite. */
    mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent);
    scrollbar-width: none;
  }
  .rail::-webkit-scrollbar { display: none; }
  .rubrique { white-space: nowrap; }
  .marque-rail { padding: 0; }
  .rubriques { flex-direction: row; padding: 0; flex: none; }
  .bloc-bas { margin: 0; padding-top: 0; border-top: none; }
  .pied-rail { margin: 0 0 0 auto; flex-direction: row; align-items: center; padding: 0; }

  /* ⚠️ « Fermer la session » était masqué sur téléphone : on ne pouvait plus
     se déconnecter depuis le terrain, précisément là où un appareil se perd
     ou se prête. Le bouton reste, réduit à son minimum. */
  .pied-rail form button { padding: 0 11px; font-size: 12px; white-space: nowrap; }
  .carte-personne .qui { display: none; }
  .page { padding: 22px 18px 48px; }
}

/* ── Les listes ───────────────────────────────────────────────────────── */
.tete-page { display: flex; align-items: baseline; gap: 14px; margin-bottom: 18px; }

.rappels { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 22px; }
.rappel {
  font-size: 13px;
  color: var(--gris-400);
  background: var(--panneau);
  border: 1px solid var(--gris-900);
  border-radius: 999px;
  padding: 8px 15px;
}
.rappel b { color: var(--gris-50); font-weight: 700; }
.rappel.attention { border-color: color-mix(in srgb, var(--miel) 40%, transparent); }
.rappel.attention b { color: var(--miel); }

.liste { display: flex; flex-direction: column; gap: 1px; background: var(--gris-900);
         border: 1px solid var(--gris-900); border-radius: 12px; overflow: hidden; }

.ligne {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 17px;
  background: var(--noir);
  color: var(--gris-50);
  /* 52 px : confortable à viser, y compris sur une tablette en atelier. */
  min-height: 52px;
}
.ligne:hover { background: var(--panneau); color: var(--gris-50); }

.pastille-statut { width: 7px; height: 7px; border-radius: 999px; flex: none; background: var(--gris-700); }
.pastille-statut.publie { background: var(--succes); }
/* Brouillon en rouge : ce n'est pas en ligne, et cela doit se voir d'un coup
   d'œil dans une liste. Le miel disait « attention », le rouge dit « pas
   encore publié », ce qui est l'information utile. */
.pastille-statut.brouillon { background: var(--rouge); }

.ligne-titre { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.ligne-client { font-size: 14.5px; font-weight: 600; }
.ligne-detail { font-size: 12.5px; color: var(--gris-500); }

.col-pole { width: 110px; flex: none; }
.col-langues { display: flex; gap: 5px; width: 132px; flex: none; }
.col-photos { width: 96px; flex: none; text-align: right; }

.jeton {
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 4px 9px;
  border: 1px solid var(--gris-800);
  color: var(--gris-500);
}
/* En ligne, fait, présent : vert. Brouillon, manquant, à faire : rouge.
   Une seule convention sur tout l'atelier, pour qu'une couleur veuille dire
   la même chose d'un écran à l'autre. */
.jeton.bon { color: var(--succes); border-color: color-mix(in srgb, var(--succes) 45%, transparent); }
.jeton.manque { color: var(--rouge); border-color: color-mix(in srgb, var(--rouge) 45%, transparent); }
.jeton.avant { color: var(--miel); border-color: color-mix(in srgb, var(--miel) 45%, transparent); }

@media (max-width: 900px) {
  .col-pole, .col-photos { display: none; }
  .col-langues { width: auto; }
}

/* ── La fiche chantier ────────────────────────────────────────────────── */
.formulaire-chantier { display: flex; flex-direction: column; gap: 22px; }
.retour { font-size: 20px; color: var(--gris-500); line-height: 1; }
.actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.actions button { padding: 0 22px; min-height: 44px; }

.bouton-second {
  background: transparent; color: var(--gris-300); border: 1px solid var(--gris-800);
  min-height: 40px; padding: 0 16px;
}
.bouton-second:hover { background: transparent; border-color: var(--gris-600); color: var(--gris-50); }

.colonnes-chantier { display: flex; gap: 20px; align-items: flex-start; }
.langues { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

.colonne-langue {
  background: var(--panneau);
  border: 1px solid var(--gris-900);
  border-radius: 13px;
  padding: 15px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.colonne-langue.reference { border-color: var(--gris-800); }
/* Le miel signale une langue à faire : le rouge est réservé au signal fort. */
.colonne-langue.afaire { border-color: color-mix(in srgb, var(--miel) 50%, transparent); }

.tete-langue { display: flex; align-items: center; gap: 9px; }
.code-langue {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
  background: var(--gris-800); border-radius: 5px; padding: 4px 8px;
}

.champ-langue { display: flex; flex-direction: column; gap: 5px; }
.champ-langue input, .champ-langue textarea, .champ-langue select {
  background: var(--noir);
  border: 1px solid var(--gris-800);
  border-radius: 9px;
  padding: 11px 13px;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--gris-50);
  width: 100%;
  resize: vertical;
}

.lateral-chantier {
  width: 280px; flex: none;
  display: flex; flex-direction: column; gap: 16px;
  background: var(--pied);
  border: 1px solid var(--gris-900);
  border-radius: 13px;
  padding: 18px;
}
.bloc-lateral { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; border-top: 1px solid var(--gris-900); }
.bascule { flex-direction: row; align-items: center; gap: 11px; font-size: 14px; min-height: 30px; cursor: pointer; }
.bascule input { width: 18px; height: 18px; accent-color: var(--rouge); }

.avis-succes {
  color: var(--succes);
  background: color-mix(in srgb, var(--succes) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--succes) 30%, transparent);
}

@media (max-width: 1100px) {
  /* `align-items: flex-start` sert à empêcher le panneau latéral de s'étirer
     sur toute la hauteur quand les colonnes sont côte à côte. Une fois
     empilées, il fait l'inverse de ce qu'on veut : il empêche les blocs de
     prendre toute la LARGEUR, et les trois langues se retrouvaient dans une
     colonne de 240 px. */
  .colonnes-chantier { flex-direction: column; align-items: stretch; }
  .lateral-chantier { width: 100%; }
  .langues { grid-template-columns: 1fr; width: 100%; }
}

/* ------------------------------------------------------------------ */
/* Les photos                                                          */
/* ------------------------------------------------------------------ */

.onglets { display: flex; gap: 2px; margin-bottom: 20px; border-bottom: 1px solid var(--gris-900); }
.onglet {
  padding: 9px 18px; font-size: 14px; color: var(--gris-400); text-decoration: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.onglet:hover { color: var(--gris-50); }
.onglet.courant { color: var(--blanc); font-weight: 600; border-bottom-color: var(--rouge); }

.colonnes-photos { display: flex; gap: 22px; align-items: flex-start; }

.arbre {
  width: 244px; flex: none; display: flex; flex-direction: column; gap: 1px;
  background: var(--panneau); border: 1px solid var(--gris-900);
  border-radius: 10px; padding: 12px 10px; position: sticky; top: 20px;
  max-height: calc(100vh - 60px); overflow-y: auto;
}
.titre-lateral {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gris-500); padding: 0 8px 8px;
}
.noeud {
  display: flex; align-items: center; gap: 8px; padding: 6px 9px; border-radius: 7px;
  font-size: 13.5px; color: var(--gris-300); text-decoration: none;
}
.noeud span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.noeud em { font-style: normal; font-family: var(--mono); font-size: 11px; color: var(--gris-600); }
.noeud:hover { background: var(--gris-900); color: var(--gris-50); }
.noeud.courant { background: var(--gris-900); color: var(--blanc); font-weight: 600; }
.noeud.racine { font-weight: 600; color: var(--gris-50); margin-top: 6px; }
.noeud.enfant { padding-left: 20px; font-size: 12.5px; }

.ajout-dossier { display: flex; gap: 6px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--gris-900); }
.ajout-dossier input { flex: 1; min-width: 0; font-size: 12.5px; padding: 7px 9px; }
.ajout-dossier button { padding: 0 11px; font-size: 12.5px; min-height: 32px; }

.contenu-photos { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 22px; }

.explication-vue { font-size: 13.5px; color: var(--gris-400); line-height: 1.55; max-width: 78ch; }
.explication-vue b { color: var(--gris-50); font-weight: 600; }
.rien { font-size: 14px; color: var(--gris-500); padding: 30px 0; }

.groupe {
  background: var(--panneau); border: 1px solid var(--gris-900);
  border-radius: 12px; padding: 15px 17px 18px;
  display: flex; flex-direction: column; gap: 14px;
}
.groupe.muet { border-color: color-mix(in srgb, var(--miel) 30%, transparent); }

.tete-groupe {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  padding-bottom: 13px; border-bottom: 1px solid var(--gris-900);
}
.tete-groupe b { font-size: 15px; }
.nom-groupe {
  flex: 1; min-width: 190px; font-size: 15px; font-weight: 600;
  padding: 10px 13px;
  /* Le nom est ce qu'on vient corriger : il se lit comme un titre, et le
     cadre ne se montre qu'au survol. */
  background: transparent;
  border-color: transparent;
}
.nom-groupe:hover { border-color: var(--gris-800); background: var(--noir); }
.nom-groupe:focus { border-color: var(--gris-600); background: var(--noir); }
.compte-groupe { font-family: var(--mono); font-size: 11px; color: var(--gris-500); }
.choix-parent { font-size: 12.5px; padding: 8px 10px; max-width: 200px; }
/* ⚠️ « Un seul bouton rouge par vue » (charte). Le rangement affiche un
   groupe par chantier : cinq groupes faisaient cinq boutons rouges empilés,
   et le rouge cessait d'être un signal pour devenir un fond.
   Ils passent en second plan ; le rouge se manifeste au survol, au moment où
   l'on vise vraiment le bouton. */
.tete-groupe button {
  min-height: 38px; padding: 0 18px;
  font-size: 10.5px;
  background: transparent;
  color: var(--gris-300);
  border: 1px solid var(--gris-700);
}
.tete-groupe button:hover {
  background: var(--rouge);
  border-color: var(--rouge);
  color: var(--blanc);
}

/* La barre d'action reste au-dessus des vignettes quand on fait défiler :
   choisir vingt photos puis remonter chercher le bouton est le genre de
   va-et-vient qui fait renoncer à ranger. */
.barre-selection {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 5;
  padding: 11px 13px; margin-bottom: 2px;
  background: var(--panneau);
  border: 1px solid var(--gris-900); border-radius: 10px;
}
.barre-selection select { font-size: 13px; padding: 9px 32px 9px 11px; min-width: 230px; flex: 1; max-width: 340px; }
.barre-selection button { min-height: 38px; padding: 0 15px; }
/* Le compte des photos vient en premier et ne se laisse pas écraser. */
.barre-selection .compte-groupe { font-size: 12px; flex: none; }

.barre-recherche { display: flex; gap: 8px; align-items: center; }
.barre-recherche input { flex: 1; max-width: 380px; padding: 10px 13px; font-size: 14px; }
.barre-recherche button { min-height: 40px; padding: 0 16px; }
.barre-recherche select { flex: 1; max-width: 340px; padding: 10px 32px 10px 13px; font-size: 14px; }

.grille {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
}
.grille.serree { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }

.vignette {
  display: flex; flex-direction: column; gap: 5px; position: relative; cursor: pointer;
  border: 1px solid var(--gris-900); border-radius: 9px; padding: 7px; background: var(--noir);
}
.vignette:hover { border-color: var(--gris-700); }
.vignette.sans-choix { cursor: default; }
.vignette img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px;
  background: var(--gris-900); display: block;
}
.vignette input[type="checkbox"] {
  position: absolute; top: 13px; left: 13px; width: 19px; height: 19px;
  /* Le rouge est un signal, pas une couleur d'état. Vingt photos cochées
     faisaient vingt taches rouges là où la charte en tolère une par vue. */
  accent-color: var(--gris-300);
  cursor: pointer;
}
/* La case doit rester lisible sur une photo claire comme sur une sombre. */
.vignette input[type="checkbox"]::before {
  content: ''; position: absolute; inset: -3px; border-radius: 5px;
  background: color-mix(in srgb, var(--noir) 55%, transparent); z-index: -1;
}
/* Une photo choisie se distingue par sa clarté, pas par un cadre rouge : la
   bordure s'éclaircit et le fond se relève d'un cran. */
.vignette:has(input:checked) {
  border-color: var(--gris-500);
  background: var(--gris-900);
}

.sous-vignette {
  font-size: 11.5px; color: var(--gris-300); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; align-items: center; gap: 6px;
}
.detail-vignette { font-family: var(--mono); font-size: 10px; color: var(--gris-600); }
.protege {
  font-style: normal; font-family: var(--mono); font-size: 9px; flex: none;
  padding: 1px 5px; border-radius: 999px; color: var(--succes);
  border: 1px solid color-mix(in srgb, var(--succes) 40%, transparent);
}
.pas-image {
  width: 100%; aspect-ratio: 4 / 3; border-radius: 6px; background: var(--gris-900);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 10px; color: var(--gris-500); text-align: center; padding: 6px;
}

.souci { display: flex; flex-direction: column; gap: 9px; padding-top: 10px; }
.libelle-souci { font-size: 13.5px; color: var(--miel); }

@media (max-width: 900px) {
  .colonnes-photos { flex-direction: column; align-items: stretch; }
  .arbre { width: 100%; position: static; max-height: 260px; }
}

.nom-photo {
  width: 100%; font-size: 11.5px; padding: 5px 7px; border-radius: 5px;
  background: var(--gris-900); border: 1px solid transparent; color: var(--gris-50);
}
.nom-photo:hover { border-color: var(--gris-800); }
.nom-photo:focus { border-color: var(--gris-600); background: var(--noir); }
button.protege { cursor: pointer; background: transparent; }
button.protege:hover { color: var(--miel); border-color: color-mix(in srgb, var(--miel) 50%, transparent); }

/* ------------------------------------------------------------------ */
/* L'administration                                                    */
/* ------------------------------------------------------------------ */

.bloc-admin { display: flex; flex-direction: column; gap: 14px; margin-bottom: 40px; }
.bloc-admin h2 {
  font-size: 17px; font-weight: 800; letter-spacing: -.02em;
  padding-bottom: 9px; border-bottom: 1px solid var(--gris-900);
}

.ligne-compte { gap: 12px; }
.ligne-compte.suspendu { opacity: .5; }
.en-ligne { display: flex; align-items: center; gap: 6px; flex: none; }
.en-ligne.large { flex: 1; min-width: 0; }
.en-ligne select { font-size: 12.5px; padding: 6px 8px; min-width: 150px; }
.en-ligne button { min-height: 32px; padding: 0 12px; font-size: 12.5px; }

.ajout-compte {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  padding: 14px; border: 1px dashed var(--gris-800); border-radius: 10px;
}
.ajout-compte input { flex: 1; min-width: 170px; padding: 9px 11px; font-size: 13.5px; }
.ajout-compte select { padding: 9px 11px; font-size: 13.5px; }
.ajout-compte button { min-height: 38px; padding: 0 18px; }

.grille-roles { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.carte-role {
  background: var(--panneau); border: 1px solid var(--gris-900); border-radius: 10px;
  padding: 14px; display: flex; flex-direction: column; gap: 12px;
}
/* Un rôle figé se distingue au premier coup d'œil : ses cases sont grisées,
   mais rien ne le dirait sans cette bordure. */
.carte-role.fige { border-color: var(--gris-800); background: var(--noir); }

.tete-role { display: flex; flex-direction: column; gap: 6px; }
.tete-role b { font-size: 15px; }
.nom-role { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; padding: 7px 9px; }

.liste-droits { display: flex; flex-direction: column; gap: 3px; }
.liste-droits .bascule { font-size: 13px; min-height: 26px; }
.liste-droits .bascule input { width: 16px; height: 16px; }
.liste-droits .bascule input:disabled { opacity: .4; cursor: not-allowed; }
.liste-droits button { margin-top: 8px; align-self: flex-start; min-height: 34px; padding: 0 14px; font-size: 12.5px; }

.note-role {
  margin-top: 8px; font-size: 11.5px; color: var(--gris-500); line-height: 1.5;
  padding-left: 10px; border-left: 2px solid var(--gris-800);
}

.ligne-trace { gap: 12px; align-items: baseline; }
.quand {
  font-family: var(--mono); font-size: 10.5px; color: var(--gris-600);
  width: 108px; flex: none;
}

/* ------------------------------------------------------------------ */
/* Avis et logos                                                       */
/* ------------------------------------------------------------------ */

.carte-avis {
  background: var(--panneau); border: 1px solid var(--gris-900); border-radius: 10px;
  padding: 15px; display: flex; flex-direction: column; gap: 12px; margin-bottom: 14px;
}
.carte-avis.neuve { border-style: dashed; border-color: var(--gris-800); background: transparent; }

.tete-avis { display: flex; gap: 8px; flex-wrap: wrap; }
.nom-avis { flex: 1; min-width: 170px; font-size: 14.5px; font-weight: 600; padding: 8px 11px; }
.societe-avis { flex: 1; min-width: 150px; font-size: 13.5px; padding: 8px 11px; }
.provenance-avis {
  width: 150px; font-family: var(--mono); font-size: 11.5px; padding: 8px 11px;
}

.langues-avis { display: grid; gap: 10px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.langues-avis textarea { resize: vertical; min-height: 78px; line-height: 1.5; }

.pied-avis { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pied-avis button { min-height: 38px; padding: 0 20px; }
.pied-avis .bascule { flex: 1; min-width: 210px; }

.grille-logos { display: grid; gap: 13px; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); }
.carte-logo {
  background: var(--panneau); border: 1px solid var(--gris-900); border-radius: 10px;
  padding: 11px; display: flex; flex-direction: column; gap: 7px;
}
.carte-logo.neuve { border-style: dashed; border-color: var(--gris-800); background: transparent; }
/* Fond clair sous le logo : la plupart sont dessinés pour du blanc et
   disparaîtraient sur le noir de l'interface. */
.cadre-logo {
  background: var(--gris-50); border-radius: 7px; padding: 9px;
  display: flex; align-items: center; justify-content: center; min-height: 82px;
}
.cadre-logo img { max-width: 100%; height: auto; max-height: 74px; object-fit: contain; }
.cadre-logo .pas-image { background: transparent; color: var(--gris-500); aspect-ratio: auto; min-height: 64px; }
.pied-logo { display: flex; gap: 6px; align-items: center; margin-top: 3px; }
.pied-logo select { flex: 1; min-width: 0; }
.pied-logo button { min-height: 32px; padding: 0 12px; font-size: 12.5px; flex: none; }

@media (max-width: 900px) {
  .langues-avis { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ */
/* Le tableau de bord                                                  */
/* ------------------------------------------------------------------ */

.compte-tache {
  font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--miel);
  width: 42px; flex: none; text-align: right;
}

.graphique {
  display: flex; align-items: flex-end; gap: 5px; height: 148px;
  padding: 14px 12px 0; background: var(--panneau);
  border: 1px solid var(--gris-900); border-radius: 10px;
}
.colonne-jour { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; }
/* La barre occupe la place restante au-dessus de son étiquette : sans ce
   conteneur en flex, un `height` en pourcentage n'a aucun parent à mesurer. */
.colonne-jour { justify-content: flex-end; }
.barre {
  width: 100%; max-width: 34px; background: var(--rouge); border-radius: 3px 3px 0 0;
  min-height: 2px; transition: background .15s;
}
.colonne-jour:hover .barre { background: var(--rouge-survol); }
.etiquette-jour {
  font-family: var(--mono); font-size: 9.5px; color: var(--gris-600);
  white-space: nowrap; flex: none;
}

.deux-colonnes { display: grid; gap: 18px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.deux-colonnes .titre-lateral { padding-left: 0; }
.ligne-page { gap: 12px; }

@media (max-width: 900px) {
  .deux-colonnes { grid-template-columns: 1fr; }
  .etiquette-jour { display: none; }
}

/* ------------------------------------------------------------------ */
/* L'étoile qui décolle, une fois le lien parti                        */
/* ------------------------------------------------------------------ */

/* Première version jetée : une étoile générique à branches fines montait en
   traînant un trait de crayon. Ça ressemblait à un clipart qui glisse.
   Celle-ci est l'étoile du logo — même tracé, même proportion (1,051) — et
   elle prend son élan avant de partir : c'est l'accroupissement qui fait lire
   un décollage, pas la montée. */

/* Le logo reste au premier plan : l'étoile lui passe DERRIÈRE en montant.
   Sans cela elle le traverse, et deux étoiles rouges se chevauchent une
   demi-seconde — celle du logo et celle qui décolle. */
.marque { position: relative; z-index: 4; }

.rampe {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  perspective: 700px;
  perspective-origin: 50% 82%;
  margin-bottom: 4px;
  animation: refermerLaRampe 3.1s cubic-bezier(.4, 0, .2, 1) forwards;
}

@keyframes refermerLaRampe {
  0%, 78% { height: 148px; }
  100%    { height: 10px; }
}

.etoile-fusee {
  fill: var(--rouge);
  transform-style: preserve-3d;
  transform-origin: 50% 62%;
  animation: decoller 3.1s cubic-bezier(.42, 0, .72, .3) forwards;
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--rouge) 70%, transparent));
  position: relative;
  z-index: 2;
}

/* Cinq temps : elle s'accroupit, elle s'arrache, elle vire, elle s'éloigne,
   elle sort. Le `translateZ` négatif la fait rapetisser DANS la perspective,
   ce qui se lit comme de l'éloignement et non comme un rétrécissement. */
@keyframes decoller {
  0%   { transform: translateY(0) translateZ(0) rotate(0deg) scale(1, 1); opacity: 1; }
  12%  { transform: translateY(10px) translateZ(0) rotate(0deg) scale(1.14, .84); opacity: 1; }
  20%  { transform: translateY(-4px) translateZ(0) rotate(-6deg) scale(.9, 1.2); opacity: 1; }
  38%  { transform: translateY(-72px) translateZ(-30px) rotate(34deg) scale(1, 1); opacity: 1; }
  62%  { transform: translateY(-176px) translateZ(-210px) rotate(148deg) scale(1, 1); opacity: .95; }
  82%  { transform: translateY(-268px) translateZ(-450px) rotate(268deg) scale(1, 1); opacity: .5; }
  100% { transform: translateY(-360px) translateZ(-700px) rotate(400deg) scale(1, 1); opacity: 0; }
}

/* La lueur au sol : ce que la poussée éclaire juste avant le départ. */
.lueur {
  position: absolute;
  bottom: 2px;
  width: 96px;
  height: 26px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    color-mix(in srgb, var(--miel) 55%, transparent),
    transparent 70%);
  animation: lueurAuSol 3.1s ease-out forwards;
}

@keyframes lueurAuSol {
  0%   { opacity: 0; transform: scale(.3); }
  12%  { opacity: .9; transform: scale(1.1); }
  30%  { opacity: .5; transform: scale(1.6); }
  50%  { opacity: 0; transform: scale(2); }
  100% { opacity: 0; }
}

/* Les jets : trois, décalés, de largeurs différentes. Un seul faisait un
   trait ; trois font un souffle. */
.jet {
  position: absolute;
  bottom: 10px;
  border-radius: 999px;
  transform-origin: 50% 100%;
  background: linear-gradient(to top,
    transparent,
    color-mix(in srgb, var(--miel) 85%, transparent) 22%,
    color-mix(in srgb, var(--rouge) 70%, transparent) 62%,
    transparent);
}
.jet.j1 { width: 7px;   height: 96px; animation: souffler 3.1s cubic-bezier(.42, 0, .72, .3) forwards; }
.jet.j2 { width: 3.5px; height: 128px; margin-left: -13px;
          animation: souffler 3.1s cubic-bezier(.42, 0, .72, .3) .06s forwards; opacity: 0; }
.jet.j3 { width: 3.5px; height: 118px; margin-left: 13px;
          animation: souffler 3.1s cubic-bezier(.42, 0, .72, .3) .1s forwards; opacity: 0; }

@keyframes souffler {
  0%   { transform: scaleY(0) scaleX(.6); opacity: 0; }
  12%  { transform: scaleY(.18) scaleX(1.5); opacity: 1; }
  20%  { transform: scaleY(.5) scaleX(1.2) translateY(-6px); opacity: 1; }
  38%  { transform: scaleY(1) scaleX(.9) translateY(-66px); opacity: .85; }
  62%  { transform: scaleY(.72) scaleX(.55) translateY(-168px); opacity: .45; }
  82%  { transform: scaleY(.4) scaleX(.3) translateY(-256px); opacity: .18; }
  100% { transform: scaleY(.15) scaleX(.2) translateY(-340px); opacity: 0; }
}

/* Une animation qui traverse l'écran est exactement ce que ce réglage vise :
   l'étoile se pose, elle ne décolle pas. */
@media (prefers-reduced-motion: reduce) {
  .etoile-fusee { animation: none; }
  .jet, .lueur { display: none; }
  .rampe { height: 66px; align-items: center; animation: none; }
}

/* ------------------------------------------------------------------ */
/* L'étoile roule pendant qu'une action est en cours                   */
/* ------------------------------------------------------------------ */

/* Le logo officiel, jamais recomposé en texte ni décomposé pour être animé.
   C'est un actif de marque : il s'affiche, il ne se manipule pas. */
.logo-officiel { display: block; height: auto; width: 118px; }
.marque .logo-officiel { width: 152px; }

/* L'indicateur d'attente est une étoile SÉPARÉE, posée à côté du logo. Elle
   n'existe que pendant l'action : hors de là, elle ne prend même pas de place.
   `visibility` plutôt que `display` pour que l'apparition ne décale rien. */
.etoile-attente {
  transform-origin: 50% 55%;
  opacity: 0;
  visibility: hidden;
  margin-left: 9px;
  flex: none;
  transition: opacity .18s;
}

/* La roue : un tour par seconde, à vitesse constante. Une rotation qui
   accélère et ralentit suggère un mouvement qui se termine — or on ne sait
   pas combien de temps le serveur va prendre. */
body.en-cours .etoile-attente {
  opacity: 1;
  visibility: visible;
  animation: roulerEtoile .9s linear infinite;
}

@keyframes roulerEtoile {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Le logo se met en retrait pendant l'attente : l'œil va sur ce qui bouge. */
body.en-cours .logo-officiel { opacity: .5; transition: opacity .2s; }

/* Ce qu'on vient de cliquer n'est plus cliquable : deux envois valent deux
   liens de connexion, ou deux fois la même publication. */
body.en-cours button[type="submit"] { opacity: .6; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  /* La roue est remplacée par un battement : le signal reste, le mouvement
     part. Supprimer l'indication au lieu de l'adoucir rendrait l'attente
     muette pour ceux qui en ont le plus besoin. */
  body.en-cours .etoile-attente { animation: battreEtoile 1.1s ease-in-out infinite; }
  @keyframes battreEtoile {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
  }
}


/* ------------------------------------------------------------------ */
/* L'état se lit à la couleur : en ligne vert, brouillon rouge         */
/* ------------------------------------------------------------------ */

/* La liste de statut se colore selon ce qui y est choisi, sans un octet de
   JavaScript : `:has` regarde quelle option est retenue. Autrement, il faut
   lire le mot pour savoir si la fiche est publiée — or c'est justement ce
   qu'on veut savoir sans lire. */
select[name="statut"]:has(option[value="publie"]:checked),
select[name="statut"]:has(option[value="prete"]:checked) {
  color: var(--succes);
  border-color: color-mix(in srgb, var(--succes) 45%, transparent);
}
select[name="statut"]:has(option[value="brouillon"]:checked) {
  color: var(--rouge);
  border-color: color-mix(in srgb, var(--rouge) 45%, transparent);
}
select[name="statut"]:has(option[value="archive"]:checked) {
  color: var(--gris-500);
}

/* Le rappel du haut de page suit la même logique. */
.rappel.attention { border-color: color-mix(in srgb, var(--rouge) 40%, transparent); }
.rappel.attention b { color: var(--rouge); }

/* ------------------------------------------------------------------ */
/* L'arbre se replie : huit métiers, pas cinquante-cinq dossiers       */
/* ------------------------------------------------------------------ */

.pole { display: flex; flex-direction: column; gap: 1px; }
.pole > summary {
  list-style: none;
  cursor: pointer;
  /* Le chevron par défaut de Safari, qui ne se style pas. */
  -webkit-appearance: none;
}
.pole > summary::-webkit-details-marker { display: none; }

/* Un chevron dessiné, qui pivote à l'ouverture : sans lui, rien ne dit qu'un
   pôle contient des chantiers. */
.pole > summary::before {
  content: '';
  width: 0; height: 0;
  border-left: 4px solid var(--gris-600);
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
  margin-right: 2px;
  flex: none;
  transition: transform .15s ease;
}
.pole[open] > summary::before { transform: rotate(90deg); }
.pole > summary:hover::before { border-left-color: var(--gris-300); }

/* « hors chantier » : les photos posées dans le dossier de métier lui-même,
   celles qui n'appartiennent à aucun chantier. Le nom du dossier répété
   deux fois prêtait à confusion. */
.noeud.directement span { color: var(--gris-500); font-style: italic; }

@media (prefers-reduced-motion: reduce) {
  .pole > summary::before { transition: none; }
}
