/* ==========================================================================
   trouvailles — liens + vidéos
   Structure héritée de TubeNotes, palette bleu / violet / magenta pastel.
   Sommaire : 1 variables · 2 base · 3 aquarelle · 4 topbar · 5 onglets
   6 recherche · 7 filtres · 8 grille & cartes · 9 vidéos & notes
   10 formulaires (feuilles) · 11 connexion · 12 bannière d'installation
   13 bouton flottant · 14 divers
   ========================================================================== */

/* ---------- 1. Variables ---------- */
:root {
  --paper: #faf8fc;
  --card: #ffffff;
  --ink: #2e2a3d;
  --muted: #6b6478;
  /* --faint ne sert plus qu'aux icônes, aux croix et aux bordures : le
     seuil qui s'y applique est 3:1, pas 4,5. #a59cb3 valait 2,62 et
     échouait même à celui-là. #8d84a0 monte à 3,53 sur blanc, 3,35 sur le
     fond de page, et reste assez clair pour ne pas rejoindre --muted :
     la hiérarchie ink / muted / faint tient toujours à 13,86 / 5,65 / 3,53. */
  --faint: #8d84a0;
  --line: #e8e2f2;
  --line-soft: #f2eef9;

  --blue: #5588d6;      --blue-soft: #e2ebfb;
  --violet: #8862c9;    --violet-soft: #ebe2fa;
  --magenta: #cc4f96;   --magenta-soft: #fae0ef;
  /* Le magenta vif ne passe pas AA en texte : 4,10 sur blanc, il faut 4,5.
     Or c'est la couleur des messages d'ERREUR — « Envoi impossible »,
     « Mot de passe incorrect ». Le texte qu'on doit pouvoir lire est le seul
     qu'on n'arrivait pas à lire.

     Même parade que --orange-text et --ocre-text, créés hier pour ce motif
     exact : la teinte vive garde son rôle de signal (pastilles, bordures,
     où le seuil est 3), une variante foncée porte les mots. */
  --magenta-text: #c2437f;
  --pink: #c15c84;      --pink-soft: #fbe5ed;
  --vert: #3f9d8f;      --vert-soft: #ddf1ed;

  --note-bg: #f4effc;
  --note-edge: #c9b3ea;

  --grad: linear-gradient(135deg, var(--blue), var(--violet) 50%, var(--magenta));
  --radius: 12px;
  --shadow: 0 1px 2px rgba(46,42,61,0.05), 0 2px 8px rgba(46,42,61,0.06);
  --shadow-hover: 0 2px 4px rgba(46,42,61,0.07), 0 6px 18px rgba(46,42,61,0.09);
}

/* ---------- 2. Base ---------- */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; }
body {
  background: var(--paper); color: var(--ink);
  font-family: 'Karla', sans-serif; font-size: 16px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { font-family: 'Bricolage Grotesque', sans-serif; }
a { color: inherit; }
button, input, select, textarea { font-family: inherit; }
::selection { background: var(--violet-soft); }

.app { position: relative; z-index: 1; min-height: 100vh; padding: 14px clamp(12px, 3vw, 40px) 120px; max-width: 1500px; margin: 0 auto; }
.loading { display: grid; place-items: center; min-height: 70vh; color: var(--muted); }

/* ---------- 3. Voile aquarelle ---------- */
.watercolor { position: absolute; top: 0; left: 0; right: 0; height: 360px; overflow: hidden; z-index: 0; pointer-events: none; }
.watercolor span { position: absolute; border-radius: 50%; filter: blur(70px); opacity: 0.35; }
.wc1 { width: 300px; height: 300px; background: var(--blue); top: -80px; left: -70px; }
.wc2 { width: 260px; height: 260px; background: var(--magenta); top: -60px; right: -50px; }
.wc3 { width: 230px; height: 230px; background: var(--violet); top: 80px; left: 40%; }

/* ---------- 4. Barre du haut ---------- */
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark { width: 40px; height: 40px; border-radius: 11px; flex-shrink: 0; }
.brand h1 { font-size: 23px; font-weight: 800; margin: 0; letter-spacing: -0.4px; }
.brand .count { font-size: 13px; color: var(--muted); font-weight: 500; }
.topbar-right { display: flex; align-items: center; gap: 9px; }
.sync-wrap { display: flex; align-items: center; gap: 6px; border: none; background: none; cursor: pointer; padding: 4px; }
.sync-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); }
.sync-dot.synced { background: var(--violet); }
.sync-dot.syncing { background: var(--blue); animation: pulse 1s infinite ease-in-out; }
.sync-dot.error { background: var(--magenta); }
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.35} }
.sync-txt { font-size: 13px; color: var(--muted); font-weight: 600; }
@media (max-width: 430px) { .sync-txt { display: none; } }
.avatar {
  width: 38px; height: 38px; border-radius: 50%; background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Bricolage Grotesque', sans-serif; font-weight: 700; font-size: 15px;
  border: none; cursor: pointer; flex-shrink: 0;
}

/* ---------- 5. (les onglets de type sont descendus dans la barre du bas : voir plus bas) ---------- */

/* ---------- 6. Recherche ---------- */
/* Aucun fond, jamais : ni au repos, ni collée en haut. Seul le champ arrondi
   porte son fond blanc. Le champ étant opaque et pleine largeur, le contenu
   qui défile derrière ne transparaît que sur quelques pixels de marge. */
.searchbar { position: sticky; top: 0; z-index: 20; background: transparent; padding: 6px 0 10px; }
.searchbar .inner { position: relative; }
.search-input {
  width: 100%; padding: 13px 44px 13px 44px; font: inherit; font-size: 16px;
  color: var(--ink); background: var(--card);
  border: 1.5px solid var(--line); border-radius: 999px; outline: none;
  box-shadow: var(--shadow); transition: border-color 0.15s;
}
.search-input:focus { border-color: var(--violet); }
.search-input::placeholder { color: var(--faint); }
.search-icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--faint); pointer-events: none; }
.clear-btn {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border-radius: 50%; border: none;
  background: var(--line-soft); color: var(--muted); cursor: pointer; font-size: 14px;
}

/* ---------- 7. Filtres ---------- */
.filters { margin-bottom: 16px; }
.chip-row { display: flex; gap: 8px; align-items: center; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
.chip-row::-webkit-scrollbar { display: none; }
.chip {
  font: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
  padding: 8px 14px; min-height: 38px; border-radius: 999px;
  border: 1.5px solid var(--line); background: var(--card); color: var(--muted);
  white-space: nowrap; transition: all 0.15s; flex-shrink: 0;
}
.chip:hover { color: var(--ink); }
.chip.active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.chip.c-bleu { background: var(--blue-soft); border-color: transparent; color: var(--blue); }
.chip.c-bleu.active { background: var(--blue); color: #fff; }
.chip.c-violet { background: var(--violet-soft); border-color: transparent; color: var(--violet); }
.chip.c-violet.active { background: var(--violet); color: #fff; }
.chip.c-vert { background: var(--vert-soft); border-color: transparent; color: var(--vert); }
.chip.c-vert.active { background: var(--vert); color: #fff; }
.chip.c-magenta { background: var(--magenta-soft); border-color: transparent; color: var(--magenta); }
.chip.c-magenta.active { background: var(--magenta); color: #fff; }

/* ---------- 8. Grille & cartes ---------- */
.grid { display: grid; grid-template-columns: 1fr; gap: 15px; }
@media (min-width: 641px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .grid { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); } }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: var(--shadow); transition: box-shadow 0.15s; position: relative;
}
.card:hover { box-shadow: var(--shadow-hover); }
.card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; z-index: 2; }
.card.s-bleu::before { background: var(--blue); }
.card.s-violet::before { background: var(--violet); }
.card.s-vert::before { background: var(--vert); }
.card.s-magenta::before { background: var(--magenta); }
.card.archived { opacity: 0.55; }

.card-body { padding: 13px 14px 14px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.card-head { display: flex; align-items: flex-start; width: 100%; }
.card-head .menu-wrap { margin-left: auto; flex-shrink: 0; }
.card-title { font-family: 'Bricolage Grotesque', sans-serif; font-size: 17px; font-weight: 700; margin: 0; line-height: 1.3; min-width: 0; }
.card-title a { text-decoration: none; overflow-wrap: anywhere; }
.card-title a:hover { color: var(--violet); }
.card-domain { font-size: 13px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.card-domain img { width: 16px; height: 16px; border-radius: 4px; }
.card-desc { margin: 0; font-size: 14.5px; color: var(--muted); overflow-wrap: anywhere; }
.card-desc.i { font-style: italic; }

/* « seul » : ce texte n'a pas de titre au-dessus de lui, il EST la carte.

   La description est en --muted, gris. C'est juste quand elle accompagne un
   titre : le titre ancre, elle explique. Mais sur une idée sans titre, elle
   est le seul texte — et une carte entièrement grise a l'air éteinte à côté
   d'une carte de lien dont le titre est noir.

   C'est ce que le titre automatique allait chercher, en recopiant le début
   du texte en gras au-dessus du texte. On fonce celui qui existe plutôt que
   d'en fabriquer un second : même ancrage, 53 pixels de carte en moins. */
.card-desc.seul {
  font-size: 15.5px;
  color: var(--ink);
  font-weight: 500;
  line-height: 1.45;
}
.card-action { font-size: 13.5px; background: var(--line-soft); border-radius: 8px; padding: 8px 10px; }
.card-action b { display: block; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px; }

/* Le repère « Où j'en suis ». Compact et aligné à gauche : c'est un mot,
   pas un paragraphe — S3E7, Page 142. Un bloc pleine largeur comme
   .card-action lui donnerait l'importance d'une description.
   La flèche dit « reprendre ici » sans qu'on ait à écrire un libellé :
   « Où j'en suis : S3E7 » ferait trois fois la longueur de l'information. */
.card-repere {
  align-self: flex-start;
  display: inline-flex; align-items: baseline; gap: 6px;
  max-width: 100%;
  font-size: 13.5px; font-weight: 500; color: var(--ink);
  background: var(--line-soft); border-radius: 8px; padding: 5px 10px;
  overflow-wrap: anywhere;
}
.card-repere-fleche { color: var(--faint); font-weight: 400; }
.clamp3 {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; cursor: pointer;
}
.card-action .clamp3 { cursor: inherit; }
.card-action:has(.clamp3) { cursor: pointer; }
.clamp3.short { cursor: default; }
.detail-body { font-size: 15px; line-height: 1.6; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.detail-section { margin-bottom: 16px; }
.detail-section b { display: block; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; font-weight: 700; }
.detail-link { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); margin-bottom: 14px; }
.detail-link img { width: 16px; height: 16px; border-radius: 4px; }

.card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; padding-top: 4px; }
.card-tags { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.tag { font-size: 12.5px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--line-soft); color: var(--muted); }
.tag.t-blue { background: var(--blue-soft); color: var(--blue); }
.tag.t-violet { background: var(--violet-soft); color: var(--violet); }
.tag.t-magenta { background: var(--magenta-soft); color: var(--magenta); }
.tag.t-pink { background: var(--pink-soft); color: var(--pink); }
.tag.date { background: transparent; padding: 0; color: var(--muted); font-weight: 500; }

.status-pill {
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  padding: 5px 12px; min-height: 30px; border-radius: 999px; border: none; color: #fff; flex-shrink: 0;
}
.status-pill.p-bleu { background: var(--blue); }
.status-pill.p-violet { background: var(--violet); }
.status-pill.p-vert { background: var(--vert); }
.status-pill.p-magenta { background: var(--magenta); }

.iconbtn {
  width: 34px; height: 34px; border-radius: 9px; border: none; background: transparent;
  color: var(--faint); display: flex; align-items: center; justify-content: center;
  cursor: pointer; flex-shrink: 0;
}
.iconbtn:hover, .iconbtn:active { background: var(--line-soft); color: var(--ink); }

.menu-wrap { position: relative; }
.menu {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow-hover); overflow: hidden; z-index: 60; min-width: 190px;
}
/* Voile transparent : un clic à côté referme le menu. */
.menu-voile { position: fixed; inset: 0; z-index: 59; }
.menu button {
  display: flex; align-items: center; gap: 9px; width: 100%; border: none; background: none;
  padding: 11px 13px; font-size: 14.5px; color: var(--ink); cursor: pointer; text-align: left;
}
.menu button:hover { background: var(--line-soft); }
.menu button.danger { color: var(--magenta); }

.empty { text-align: center; padding: 60px 20px; color: var(--muted); border: 1.5px dashed var(--line); border-radius: 16px; grid-column: 1 / -1; }

/* ---------- 9. Vidéos & notes ---------- */
.thumb-wrap { position: relative; aspect-ratio: 16/9; background: var(--line-soft); cursor: pointer; }
.thumb-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb-wrap iframe { width: 100%; height: 100%; border: 0; display: block; }
.thumb-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.thumb-play span {
  width: 52px; height: 52px; border-radius: 50%; background: rgba(46,42,61,0.72);
  display: flex; align-items: center; justify-content: center; color: #fff;
  transition: transform 0.15s, background 0.15s;
}
.thumb-wrap:hover .thumb-play span { transform: scale(1.08); background: var(--magenta); }

.notes { display: flex; flex-direction: column; gap: 8px; }
.note {
  background: var(--note-bg); border-left: 4px solid var(--note-edge);
  border-radius: 6px; padding: 9px 11px 5px; font-size: 14.5px; line-height: 1.55;
}
.note-text { margin: 0 0 2px; white-space: pre-wrap; overflow-wrap: anywhere; }
.note .ts {
  color: var(--violet); font-weight: 700; text-decoration: none;
  background: var(--violet-soft); padding: 1px 7px; border-radius: 6px;
}
.note .ts:hover { background: var(--violet); color: #fff; }
.note-tools { display: flex; justify-content: flex-end; gap: 2px; }
.note-tools button { border: none; background: none; color: var(--muted); cursor: pointer; padding: 3px 6px; font-size: 13px; border-radius: 6px; }
.note-tools button:hover { background: var(--card); color: var(--ink); }
.note-edit { display: flex; gap: 6px; }
.note-edit input { flex: 1; border: 1.5px solid var(--note-edge); border-radius: 8px; padding: 7px 10px; font-size: 14px; outline: none; }

.note-add { display: flex; gap: 7px; }
.note-add input {
  flex: 1; min-width: 0; border: 1.5px solid var(--line); border-radius: 9px; padding: 9px 11px;
  font-size: 14.5px; outline: none; background: var(--card);
}
.note-add input:focus { border-color: var(--violet); }
.note-add button {
  border: none; border-radius: 9px; padding: 0 14px; min-width: 42px; background: var(--violet-soft);
  color: var(--violet); font-weight: 700; cursor: pointer; font-size: 16px;
}
.more-notes { border: 1.5px solid var(--line); background: var(--card); color: var(--muted); border-radius: 9px; padding: 8px; font-size: 13.5px; font-weight: 700; cursor: pointer; }

/* ---------- 10. Formulaires (feuilles) ---------- */
.overlay {
  position: fixed; inset: 0; background: rgba(46,42,61,0.4); z-index: 40;
  display: flex; align-items: flex-end; justify-content: center;
}
.sheet {
  background: var(--paper); width: 100%; max-height: 92vh; overflow-y: auto;
  border-radius: 20px 20px 0 0; padding: 10px 18px calc(22px + env(safe-area-inset-bottom));
  animation: up .22s ease;
}
.sheet-handle { width: 38px; height: 4px; border-radius: 3px; background: var(--line); margin: 4px auto 14px; }
@keyframes up { from { transform: translateY(100%); } to { transform: translateY(0); } }
@media (min-width: 680px) {
  .overlay { align-items: center; }
  .sheet { max-width: 540px; border-radius: 18px; padding: 22px 24px; max-height: 86vh; }
  .sheet-handle { display: none; }
}
.sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.sheet-head h2 { font-size: 19px; font-weight: 700; margin: 0; }

.field { margin-bottom: 13px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; font-weight: 700; }
.field label .hint { font-weight: 500; text-transform: none; }
.field input[type=text], .field input[type=url], .field input[type=email], .field input[type=password], .field textarea {
  width: 100%; background: var(--card); border: 1.5px solid var(--line); border-radius: 11px;
  color: var(--ink); font-size: 16px; padding: 11px 13px; outline: none;
}
.field input:focus, .field textarea:focus { border-color: var(--violet); }
.field textarea { resize: vertical; min-height: 52px; }
.form-err { color: var(--magenta-text); font-size: 13.5px; margin: 4px 0 0; }
.form-preview { width: 100%; max-width: 260px; border-radius: 10px; display: block; }

.state-choice { display: flex; gap: 8px; }
.state-choice button {
  flex: 1; border: 1.5px solid var(--line); border-radius: 12px; padding: 11px 6px;
  background: var(--card); color: var(--muted); font-size: 13.5px; font-weight: 700; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px; min-height: 44px;
}
.state-choice button.sel-bleu { border-color: var(--blue); background: var(--blue-soft); color: var(--blue); }
.state-choice button.sel-violet { border-color: var(--violet); background: var(--violet-soft); color: var(--violet); }
.state-choice button.sel-vert { border-color: var(--vert); background: var(--vert-soft); color: var(--vert); }
.state-choice button.sel-magenta { border-color: var(--magenta); background: var(--magenta-soft); color: var(--magenta); }

.disclosure {
  display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 14px; font-weight: 700;
  padding: 10px 2px; cursor: pointer; border-top: 1px solid var(--line-soft); margin-top: 6px;
}

.sheet-actions { display: flex; gap: 10px; margin-top: 16px; }
.btn { flex: 1; border-radius: 12px; padding: 13px; font-size: 15px; font-weight: 700; cursor: pointer; border: none; min-height: 48px; }
.btn-secondary { background: var(--card); border: 1.5px solid var(--line); color: var(--muted); }
.btn-primary { background: var(--grad); color: #fff; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-text { background: none; border: none; color: var(--muted); font-size: 14px; font-weight: 700; cursor: pointer; padding: 10px; }
.btn-text:hover { color: var(--ink); }

.espace-item { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.espace-nom { flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px; font-weight: 700; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.espace-code {
  display: flex; align-items: center; gap: 5px; border: 1.5px dashed var(--line);
  background: var(--card); color: var(--violet); font-weight: 700; font-size: 13px;
  letter-spacing: 0.08em; border-radius: 8px; padding: 6px 10px; cursor: pointer; flex-shrink: 0;
}
.espace-code:hover { border-color: var(--violet); }
.espace-form { display: flex; gap: 8px; margin-top: 10px; }
.espace-form input {
  flex: 1; min-width: 0; background: var(--card); border: 1.5px solid var(--line); border-radius: 10px;
  color: var(--ink); font-size: 14.5px; padding: 10px 12px; outline: none;
}
.espace-form input:focus { border-color: var(--violet); }
.espace-form .btn { flex: 0 0 auto; min-height: 42px; padding: 10px 16px; font-size: 14px; }

.saisie-champ {
  width: 100%; background: var(--paper); border: 1.5px solid var(--line); border-radius: 11px;
  color: var(--ink); font: inherit; font-size: 16px; padding: 12px 13px; outline: none;
  box-sizing: border-box; margin-bottom: 12px;
}
.saisie-champ:focus { border-color: var(--violet); }

.admin-users { display: flex; flex-direction: column; gap: 7px; margin-bottom: 6px; }
.admin-user-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 10px;
  padding: 9px 12px;
}
.admin-user-info { display: flex; align-items: center; gap: 8px; min-width: 0; }
.admin-user-email { font-size: 14.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-badge {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--violet); background: var(--violet-soft); border-radius: 999px; padding: 2px 8px; flex-shrink: 0;
}
.iconbtn.danger { color: var(--magenta); }

.reglage-bloc { border: 1.5px solid var(--line); border-radius: 12px; padding: 12px 13px; margin-bottom: 12px; background: var(--paper); }
.reglage-bloc > label { display: block; font-size: 13px; color: var(--muted); font-weight: 700; }
.admin-conso {
  font-size: 11.5px; font-weight: 700; color: var(--vert); background: var(--vert-soft);
  border-radius: 999px; padding: 2px 8px; flex-shrink: 0; white-space: nowrap;
}
.jauge { margin-top: 4px; }
.jauge-barre { height: 10px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.jauge-remplie { height: 100%; border-radius: 999px; transition: width .3s ease; }
.jauge-txt { font-size: 13.5px; color: var(--muted); margin-top: 8px; }
.jauge-txt b { color: var(--ink); }

/* L'alerte de quota : elle prévient AVANT le mur, et elle a une porte.

   Fond magenta pâle, pas rouge : ce n'est pas une erreur, c'est un
   avertissement. Rien n'est cassé, il reste de la place — mais il faut
   agir avant qu'il n'y en ait plus. Le bouton n'est pas un lien de plus
   à recopier : il ouvre un courriel déjà écrit. */
/* La tuile d'alerte de l'admin : même magenta que l'alerte de
   l'utilisateur, parce que c'est la même information vue de l'autre côté.
   Elle ne s'affiche que s'il y a quelqu'un — une tuile à zéro en
   permanence, on cesse de la voir. */
/* Le « / 500 » du cadran : présent mais discret. C'est le chiffre de
   gauche qui compte ; celui-ci ne fait que lui donner son échelle. */
.stat__sur {
  font-size: 0.55em;
  font-weight: 700;
  color: var(--faint);
  letter-spacing: 0;
}

.stat.stat--alerte {
  background: var(--magenta-soft);
  border-color: var(--magenta);
}
.stat.stat--alerte .stat__value { color: var(--magenta-text); }

.quota-alerte {
  margin-top: 12px;
  background: var(--magenta-soft);
  border: 1px solid var(--magenta);
  border-radius: 12px;
  padding: 12px 14px;
}
.quota-alerte-txt {
  margin: 0 0 10px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink);
}
.quota-alerte-txt b { color: var(--magenta-text); }
.quota-alerte-btn {
  width: 100%;
  border: none;
  border-radius: 10px;
  padding: 9px 14px;
  background: var(--magenta-text);
  color: #fff;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}
.quota-alerte-btn:active { transform: scale(0.98); }
.admin-stockage {
  font-size: 11.5px; font-weight: 700; color: var(--blue); background: var(--blue-soft);
  border-radius: 999px; padding: 2px 8px; flex-shrink: 0; white-space: nowrap;
}

.admin-neuf {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--blue); background: var(--blue-soft); border-radius: 999px; padding: 2px 8px; flex-shrink: 0;
}
.admin-attente {
  font-size: 11px; font-weight: 700; color: var(--magenta); background: var(--magenta-soft);
  border-radius: 999px; padding: 2px 8px; flex-shrink: 0; white-space: nowrap;
}

.tag-row { display: flex; align-items: stretch; gap: 6px; }
.tag-row .tag-pick {
  flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 11px;
  padding: 11px 13px; font: inherit; font-size: 14.5px; cursor: pointer; min-height: 44px;
}
.tag-row .tag-pick:hover { border-color: var(--violet); }

/* Le même bouton, mais seul dans sa liste — la feuille « Taguer N
   trouvailles » n'a pas de bouton de fusion à côté, donc pas de .tag-row
   pour l'habiller. Sans cette règle il serait nu. */
.tag-liste > .tag-pick {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 11px;
  padding: 11px 13px; font: inherit; font-size: 14.5px; cursor: pointer; min-height: 44px;
}
.tag-liste > .tag-pick:hover { border-color: var(--violet); }

/* Le choix d'un statut : pastille puis libellé, alignés à gauche. Le motif
   des tags (nom à gauche, compteur à droite) ne convient pas — il n'y a
   rien à compter, et space-between enverrait le libellé au bout de la ligne,
   loin de sa couleur. */
.statut-pick {
  width: 100%; display: flex; align-items: center; gap: 11px;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 11px;
  padding: 11px 13px; font: inherit; font-size: 14.5px; color: var(--ink);
  text-align: left; cursor: pointer; min-height: 44px;
}
.statut-pick:hover { border-color: var(--violet); }

.statut-point {
  flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%;
}
.statut-point.c-gris    { background: var(--gris); }
.statut-point.c-bleu    { background: var(--blue); }
.statut-point.c-violet  { background: var(--violet); }
.statut-point.c-magenta { background: var(--magenta); }
.statut-point.c-vert    { background: var(--vert); }
.statut-point.c-rouge   { background: var(--rouge); }
.statut-point.c-orange  { background: var(--orange); }
.statut-point.c-ocre    { background: var(--ocre); }
.statut-point.c-pink    { background: var(--pink); }
.tag-row .tag-merge {
  flex: 0 0 auto; width: 44px; display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 11px;
  color: var(--muted); cursor: pointer;
}
.tag-row .tag-merge:hover { border-color: var(--violet); color: var(--violet); }

.vues-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center; }
.vue-chip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 999px;
  padding: 7px 8px 7px 14px; font-size: 14px; font-weight: 700; color: var(--muted);
  user-select: none; -webkit-user-select: none; transition: all 0.15s;
}
.vue-chip:hover { border-color: var(--violet); }
.vue-chip.active { background: var(--violet-soft); border-color: var(--violet); color: var(--violet); }
.vue-chip .vue-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; font-size: 12px; color: var(--faint);
  background: var(--line-soft);
}
.vue-chip .vue-x:hover { background: var(--magenta-soft); color: var(--magenta); }
.vue-save {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: none; border: 1.5px dashed var(--line); border-radius: 999px;
  padding: 7px 14px; font: inherit; font-size: 13.5px; font-weight: 700; color: var(--muted);
}
.vue-save:hover { border-color: var(--violet); color: var(--violet); }

.taginput { position: relative; }
.taginput input {
  width: 100%; background: var(--paper); border: 1.5px solid var(--line); border-radius: 11px;
  color: var(--ink); font-size: 16px; padding: 12px 13px; outline: none; box-sizing: border-box;
}
.taginput input:focus { border-color: var(--violet); }
.taginput-box {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-hover); overflow: hidden; max-height: 38vh; overflow-y: auto;
}
.taginput-item {
  display: flex; align-items: center; width: 100%; border: none; background: none;
  cursor: pointer; text-align: left; padding: 10px 13px; font: inherit; font-size: 14.5px; min-height: 42px;
}
.taginput-item:hover, .taginput-item.on { background: var(--violet-soft); }
.taginput-item + .taginput-item { border-top: 1px solid var(--line-soft); }

.choix-type { display: flex; flex-direction: column; gap: 10px; }
.choix-type button {
  display: flex; align-items: center; gap: 14px; width: 100%; cursor: pointer;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 14px;
  padding: 16px 18px; font: inherit; text-align: left; transition: all 0.15s;
}
.choix-type button:hover { border-color: var(--violet); background: var(--violet-soft); }
.choix-emoji { font-size: 26px; line-height: 1; flex-shrink: 0; }
.choix-txt { display: flex; flex-direction: column; gap: 2px; }
.choix-txt b { font-size: 16px; color: var(--ink); }
.choix-txt small { font-size: 13px; color: var(--muted); }
.idee-emoji { font-size: 15px; line-height: 1; }
.idee-src { color: var(--violet); text-decoration: none; }
.idee-src:hover { text-decoration: underline; }

/* État « traduit » visible sans ouvrir le menu. */
.badge-traduit {
  font-size: 11px; font-weight: 700; color: var(--vert); background: var(--vert-soft);
  border-radius: 999px; padding: 1px 7px; margin-left: 6px; white-space: nowrap;
}
/* Dans le menu : la coche dit l'état, le sous-titre dit l'action. */
.menu button.menu-traduit { color: var(--vert); align-items: flex-start; }
.menu .menu-2l { display: flex; flex-direction: column; gap: 1px; line-height: 1.25; }
.menu .menu-2l b { font-weight: 700; }
.menu .menu-2l small { font-size: 11.5px; color: var(--muted); font-weight: 500; }

.inspi-photo {
  width: 100%; border-radius: 12px; margin: 10px 0 4px; display: block;
  border: 1.5px solid var(--line); object-fit: cover; max-height: 260px;
}
.inspi-apercu {
  width: 100%; border-radius: 12px; display: block; border: 1.5px solid var(--line);
  object-fit: cover; max-height: 240px;
}
/* Le verrou : ce qu'on voit à la place d'un bouton qu'on n'a pas le droit
   d'utiliser. Il dit pourquoi, et où aller — un mur sans porte n'est pas
   une offre, c'est une impasse. */
.photo-verrou {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  background: var(--violet-soft);
  border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 14px;
}
.photo-verrou-txt { font-size: 13.5px; color: var(--ink); }
.photo-verrou-lien {
  border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  color: var(--violet); padding: 2px 0;
  text-decoration: underline; text-underline-offset: 2px;
}
.photo-verrou-lien:active { opacity: 0.6; }

.astuce-collage { font-size: 12.5px; color: var(--muted); text-align: center; margin: 8px 0 0; }
.astuce-collage kbd {
  font: inherit; font-size: 11.5px; font-weight: 700; background: var(--line-soft);
  border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; color: var(--muted);
}

.inspi-vide {
  width: 100%; min-height: 90px; border-radius: 12px; margin: 10px 0 4px;
  border: 1.5px dashed var(--line); display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 13.5px; background: var(--paper);
}
.cache-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cache-poids { font-size: 14px; color: var(--muted); }
.cache-row .btn { flex: 0 0 auto; min-height: 40px; padding: 9px 16px; font-size: 14px; }

/* ---------- Profil : sections repliables ---------- */
.sect { border: 1.5px solid var(--line); border-radius: 14px; background: var(--card); margin-bottom: 8px; overflow: hidden; }
.sect-ouverte { border-color: var(--violet); }
.sect-tete {
  display: flex; align-items: center; gap: 12px; width: 100%; cursor: pointer;
  border: none; background: none; font: inherit; text-align: left; padding: 14px 15px; min-height: 56px;
}
.sect-tete:hover { background: var(--paper); }
.sect-icone { font-size: 19px; line-height: 1; flex-shrink: 0; }
.sect-txt { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.sect-txt b { font-size: 15px; color: var(--ink); }
.sect-txt small { font-size: 12.5px; color: var(--muted); }
.sect-chevron { color: var(--faint); flex-shrink: 0; }
.sect-corps { padding: 2px 15px 15px; border-top: 1px solid var(--line-soft); }
.deconnexion { width: 100%; margin-top: 14px; }

.vide-recherche { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.vide-recherche p { margin: 0; }
.vide-sous { font-size: 13.5px; color: var(--muted); margin-top: 6px !important; }
.vide-liens { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 4px; }
.vide-liens .chip { cursor: pointer; }

.scope-row {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 8px 4px 0; font-size: 13px; color: var(--muted); font-weight: 600;
}
.scope-chip {
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  padding: 5px 12px; border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--muted); transition: all 0.15s;
}
.scope-chip.on { background: var(--violet-soft); border-color: var(--violet); color: var(--violet); }

.enrich-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--violet-soft); border: 1.5px solid var(--violet);
  border-radius: 12px; padding: 10px 13px; margin-bottom: 14px;
  font-size: 14px; color: var(--ink);
}
.enrich-bar b { color: var(--violet); }

/* Bannière de mise à jour : visible sans être bloquante. Le contenu reste
   accessible, l'utilisateur choisit son moment. */
.maj-bar {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px;
  background: var(--violet-soft); border: 1.5px solid var(--violet);
  border-radius: 12px; padding: 11px 13px; font-size: 14px; color: var(--ink);
}
.maj-bar span { flex: 1; min-width: 0; }
.maj-bar b { color: var(--violet); }
.maj-btn {
  flex: 0 0 auto; border: none; border-radius: 999px; padding: 8px 15px;
  background: var(--grad); color: #fff; font: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer;
}
.maj-close {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; border: none; background: none;
  color: var(--faint); cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center;
}
.maj-close:hover { background: rgba(255,255,255,0.6); color: var(--violet); }

.brand-clic { cursor: pointer; border-radius: 12px; padding: 2px 6px; margin-left: -6px; transition: background .15s; }
.brand-clic:hover { background: rgba(255,255,255,0.5); }
.brand-clic:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.enrich-bar .enrich-close {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  border: none; background: none; color: var(--faint); cursor: pointer;
  font-size: 14px; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.enrich-bar .enrich-close:hover { background: var(--violet-soft); color: var(--violet); }
.enrich-bar button {
  border: none; border-radius: 9px; padding: 8px 15px; background: var(--violet);
  color: #fff; font-weight: 700; font-size: 13.5px; cursor: pointer; flex-shrink: 0;
}

.confirm-overlay {
  position: fixed; inset: 0; z-index: 80; background: rgba(46,42,61,0.45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.confirm-box {
  background: var(--violet); border-radius: 16px; padding: 20px;
  max-width: 340px; width: 100%; box-shadow: 0 14px 40px rgba(46,42,61,0.3);
  animation: bannerUp .2s ease;
}
/* pre-wrap : les dialogues qui listent des changements passent à la ligne.
   Sans lui, les \n s'écrasent en espaces et les puces se collent en pavé.
   Sans effet sur les autres dialogues : ils n'ont pas de retour à la ligne. */
.confirm-box p { margin: 0 0 16px; font-size: 15.5px; font-weight: 600; line-height: 1.5; color: var(--paper); white-space: pre-wrap; }
.btn-danger { background: var(--magenta); color: #fff; }

.labels-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.labels-grid > div { display: flex; flex-direction: column; gap: 7px; }
.labels-titre { font-size: 12px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
.labels-grid input {
  width: 100%; background: var(--card); border: 1.5px solid var(--line); border-radius: 9px;
  color: var(--ink); font-size: 14px; padding: 9px 11px; outline: none;
}
.labels-grid input:focus { border-color: var(--violet); }

.suggest-box {
  position: absolute; top: calc(100% + 6px); left: 10px; right: 10px; z-index: 30;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-hover); overflow: hidden; max-height: 46vh; overflow-y: auto;
}
.suggest-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; border: none; background: none; cursor: pointer; text-align: left;
  padding: 11px 14px; font: inherit; font-size: 14.5px; min-height: 44px;
}
.suggest-item:hover { background: var(--line-soft); }
.suggest-item + .suggest-item { border-top: 1px solid var(--line-soft); }
.suggest-tag { color: var(--violet); font-weight: 700; }
.suggest-n {
  font-size: 12.5px; font-weight: 700; color: var(--muted);
  background: var(--line-soft); border-radius: 999px; padding: 2px 9px; flex-shrink: 0;
}
.suggest-titre { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tag-liste { max-height: 52vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.tag-liste button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1.5px solid var(--line); background: var(--card); border-radius: 11px;
  padding: 11px 13px; font: inherit; font-size: 14.5px; cursor: pointer; min-height: 44px;
}
.tag-liste button:hover { border-color: var(--violet); }
.tag-liste button.tri-actif { border-color: var(--violet); background: var(--violet-soft); color: var(--violet); font-weight: 700; }
.chip-tri { display: flex; align-items: center; }

.btn-lien {
  background: none; border: none; padding: 0; font: inherit; font-size: inherit;
  color: var(--violet); font-weight: 700; text-decoration: underline; cursor: pointer;
}

.profile-card { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.profile-avatar {
  width: 46px; height: 46px; border-radius: 50%; flex-shrink: 0; background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Bricolage Grotesque', sans-serif; font-weight: 700; font-size: 18px;
}
.profile-name { font-weight: 700; font-size: 15px; overflow-wrap: anywhere; }
.profile-sub { font-size: 13px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.profile-actions { display: flex; flex-direction: column; gap: 9px; }
.profile-actions .btn { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; }
.sync-note { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0 0 14px; }

/* ---------- 11. Connexion ---------- */
.login-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: #faf8fc; color: #2e2a3d;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  overflow: hidden;
}
.login-overlay::before, .login-overlay::after {
  content: ''; position: absolute; border-radius: 50%; filter: blur(80px); opacity: 0.4; pointer-events: none;
}
.login-overlay::before { width: 380px; height: 380px; background: #5588d6; top: -120px; left: -100px; }
.login-overlay::after { width: 360px; height: 360px; background: #cc4f96; bottom: -120px; right: -100px; }
.login-glow {
  position: absolute; width: 320px; height: 320px; border-radius: 50%;
  background: #8862c9; filter: blur(90px); opacity: 0.28; pointer-events: none;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
}
.login-card {
  position: relative; z-index: 1; width: 100%; max-width: 380px;
  background: #ffffff; border: 1.5px solid #e8e2f2; border-radius: 22px;
  padding: 38px 34px 34px; box-shadow: 0 12px 40px rgba(46, 42, 61, 0.12);
  overflow: hidden;
}
.login-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 5px;
  background: linear-gradient(135deg, #5588d6, #8862c9 50%, #cc4f96);
}
.login-mark { width: 64px; height: 64px; border-radius: 17px; margin: 0 auto 16px; display: block; box-shadow: 0 6px 18px rgba(140, 90, 180, 0.28); }
.login-card h1 { font-size: 27px; font-weight: 800; text-align: center; margin: 0 0 4px; color: #2e2a3d; }
.login-sub { text-align: center; color: var(--muted); font-size: 14px; margin: 0 0 26px; }
.login-field { margin-bottom: 13px; }
.login-field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; font-weight: 700; }
.login-field input {
  width: 100%; background: #faf8fc; border: 1.5px solid #e8e2f2; border-radius: 11px;
  color: #2e2a3d; font-size: 16px; padding: 12px 13px; outline: none; box-sizing: border-box;
  transition: border-color 0.15s, background 0.15s;
}
.login-field input:focus { border-color: #8862c9; background: #ffffff; }
.login-error { color: var(--magenta-text); font-size: 13.5px; margin: 0 0 12px; }
.login-submit {
  width: 100%; border: none; border-radius: 12px; padding: 14px; font-size: 16px; font-weight: 700;
  background: linear-gradient(135deg, #5588d6, #8862c9 50%, #cc4f96); color: #fff; cursor: pointer; margin-top: 6px;
  box-shadow: 0 6px 18px rgba(140, 90, 180, 0.3);
}
.login-submit:disabled { opacity: 0.6; }

/* Champ piège : hors écran, invisible, non focalisable. Un humain ne le voit
   jamais ; un robot qui remplit tous les champs se trahit. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.turnstile { display: flex; justify-content: center; margin: 12px 0 4px; min-height: 0; }
.login-bascule { text-align: center; font-size: 14px; color: var(--muted); margin: 16px 0 0; }
.login-ok { text-align: center; }
.login-ok p { font-size: 14.5px; color: var(--ink); line-height: 1.55; margin: 0 0 12px; }

/* ---------- 12. Bannière d'installation (bas d'écran) ---------- */
.install-banner {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom));
  width: calc(100% - 24px); max-width: 560px; z-index: 60;
  background: var(--card); border: 1.5px solid var(--line);
  border-radius: 16px; padding: 14px 15px;
  box-shadow: 0 10px 32px rgba(46,42,61,0.22);
  font-size: 14.5px; line-height: 1.55;
  animation: bannerUp .3s ease;
}
@keyframes bannerUp { from { transform: translate(-50%, 30px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
.install-banner .ib-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; padding-right: 30px; }
.install-banner .ib-icon {
  width: 38px; height: 38px; border-radius: 10px; background: var(--grad);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: #fff;
}
.install-banner .ib-title { font-weight: 700; font-family: 'Bricolage Grotesque', sans-serif; font-size: 15.5px; }
.install-banner .ib-close {
  position: absolute; top: 8px; right: 8px; width: 34px; height: 34px;
  border: none; background: transparent; color: var(--faint); cursor: pointer;
  border-radius: 8px; font-size: 16px;
}
.install-banner .ib-close:hover { background: var(--line-soft); color: var(--ink); }
.install-banner .ib-steps { margin: 4px 0 0; padding-left: 0; list-style: none; color: var(--muted); }
.install-banner .ib-steps li { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.install-banner .ib-key {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; border-radius: 7px; background: var(--blue-soft);
  color: var(--blue); font-weight: 700; font-size: 13px; flex-shrink: 0;
}
.install-banner .ib-install-btn {
  margin-top: 10px; width: 100%; border: none; border-radius: 10px; padding: 12px 16px;
  background: var(--grad); color: #fff; font-weight: 700; font-size: 15px; cursor: pointer;
}

/* ---------- 13. Bouton flottant ---------- */
.fab {
  position: fixed; right: 18px; bottom: calc(20px + env(safe-area-inset-bottom)); z-index: 30;
  border: none; border-radius: 999px; padding: 15px 22px;
  background: var(--grad); color: #fff; cursor: pointer;
  font-size: 15.5px; font-weight: 700; font-family: inherit;
  display: flex; align-items: center; gap: 8px;
  box-shadow: 0 8px 22px rgba(140, 90, 180, 0.4);
}
.fab:active { transform: scale(0.96); }
.fab { transition: transform .22s ease, opacity .22s ease; }
/* Le bouton s'efface quand on descend, revient dès qu'on remonte : il ne
   masque plus le contenu qu'on est en train de lire. */
.fab.fab-cache { transform: translateY(120%); opacity: 0; pointer-events: none; }

@media (max-width: 640px) {
  /* Sur petit écran, le libellé est retiré : un rond compact chevauche
     beaucoup moins les cartes. */
  .fab { padding: 0; width: 56px; height: 56px; justify-content: center; border-radius: 50%; }
  .fab .fab-label { display: none; }
}

/* ---------- 14. Divers ---------- */
/* Notifications : contraste fort, texte plus grand et durée d'affichage
   prolongée. Les teintes restent celles de l'application. */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom)); z-index: 90;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  width: max-content; min-width: min(360px, calc(100vw - 32px));
  max-width: min(560px, calc(100vw - 32px));
  background: linear-gradient(135deg, var(--ink), #4a3f63);
  color: #fff; border: 2px solid var(--violet); border-radius: 16px;
  padding: 14px 20px; font-size: 16px; font-weight: 700; line-height: 1.35;
  box-shadow: 0 16px 42px rgba(46,42,61,.34), 0 0 0 4px rgba(136,98,201,.12);
  animation: toastEntree .28s cubic-bezier(.2,.8,.2,1);
  text-align: left;
}
.toast span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.toast svg {
  width: 24px; height: 24px; flex-shrink: 0;
  border-radius: 50%; padding: 4px; color: #fff;
  background: rgba(255,255,255,.16);
}
.toast-succes {
  background: linear-gradient(135deg, var(--ink), #276f65);
  border-color: var(--vert);
  box-shadow: 0 16px 42px rgba(46,42,61,.34), 0 0 0 4px rgba(63,157,143,.16);
}
.toast-succes svg { color: #fff; background: var(--vert); }
.toast-neutre {
  background: linear-gradient(135deg, var(--ink), #514071);
  border-color: var(--violet);
}
.toast-erreur {
  background: linear-gradient(135deg, var(--ink), #79365d);
  border-color: var(--magenta);
}
@keyframes toastEntree {
  from { transform: translate(-50%, 18px) scale(.97); opacity: 0; }
  to   { transform: translate(-50%, 0) scale(1); opacity: 1; }
}
@media (max-width: 640px) {
  .toast {
    bottom: calc(82px + env(safe-area-inset-bottom));
    min-width: 0; width: calc(100vw - 24px); max-width: calc(100vw - 24px);
    border-radius: 14px; padding: 13px 16px; font-size: 15.5px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
}

/* ---- 21 · offres (plans) et exceptions, dans l'administration ---------- */
.plans-grille { display: grid; grid-template-columns: 1fr 88px 88px 88px; gap: 6px 8px; align-items: center; margin-top: 9px; }
.plans-entete { font-size: 11px; color: var(--muted); font-weight: 700; text-align: center; letter-spacing: .02em; }
.plans-nom { font-size: 14px; color: var(--ink); font-weight: 600; }
.plans-champ, .except-grille input {
  width: 100%; border: 1.5px solid var(--line); border-radius: 9px; padding: 8px 9px;
  font: inherit; font-size: 15px; color: var(--ink); background: var(--card);
  box-sizing: border-box; outline: none; text-align: center;
}
.plans-champ:focus, .except-grille input:focus { border-color: var(--violet); }

.admin-user-row { flex-direction: column; align-items: stretch; }
.admin-user-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.admin-user-tete .admin-user-info { flex-wrap: wrap; }

.admin-plans { display: flex; gap: 6px; margin-top: 10px; }
.plan-chip {
  flex: 1; border: 1.5px solid var(--line); background: var(--card); color: var(--muted);
  border-radius: 999px; padding: 6px 4px; font: inherit; font-size: 12.5px; font-weight: 700;
  cursor: pointer; transition: background .15s, border-color .15s, color .15s;
}
.plan-chip.on { border-color: var(--violet); background: var(--violet-soft); color: var(--violet); }
.plan-chip:disabled { opacity: .5; cursor: default; }

.admin-conso-ligne { display: flex; align-items: center; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.admin-except-btn {
  margin-left: auto; border: 1.5px solid var(--line); background: var(--card); color: var(--muted);
  border-radius: 999px; padding: 3px 11px; font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
.admin-except-btn.on { border-color: var(--magenta); color: var(--magenta); background: var(--magenta-soft); }
.admin-exception {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--magenta); background: var(--magenta-soft); border-radius: 999px; padding: 2px 8px; flex-shrink: 0;
}
.admin-exception-bloc { margin-top: 11px; padding-top: 11px; border-top: 1.5px dashed var(--line); }
.except-grille { display: grid; grid-template-columns: 1fr 116px; gap: 8px; align-items: center; }
.except-grille label { font-size: 13.5px; color: var(--muted); font-weight: 600; }
.admin-exception-bloc .sheet-actions { margin-top: 11px; }

/* ---- 22 · écusson d'offre, dans la barre du haut et le profil -------- */
/* ---- l'écusson d'offre ------------------------------------------------
   Une silhouette et son étoile. Contour seul dans la barre du haut, où il
   doit pouvoir être ignoré ; pastille pleine dans le profil, où c'est
   l'information qu'on est venu chercher. */
.plan-ecusson {
  --teinte: var(--faint);
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  border: 1.5px solid transparent; border-radius: 999px;
  padding: 4px 12px 4px 9px; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .015em;
  line-height: 1; white-space: nowrap;
  background: var(--teinte); color: #fff;
  transition: transform .12s ease, box-shadow .15s ease;
}
.plan-ecusson.p-payant    { --teinte: var(--violet); }
.plan-ecusson.p-fondateur { --teinte: #c8901a; background: linear-gradient(135deg, #e0a92c, #c07d10); }
.profile-sub .plan-ecusson { cursor: default; margin-left: 2px; padding: 5px 13px 5px 10px; }
.profile-sub .plan-ecusson.p-gratuit { background: var(--line-soft); color: var(--muted); }

/* Barre du haut : contour seul, couleur portée par le texte et l'étoile. */
.topbar-right .plan-ecusson {
  background: transparent; border-color: var(--teinte); color: var(--teinte);
  padding: 0 13px 0 4px; height: 40px; font-size: 11.5px; gap: 8px;
}

/* L'avatar et sa marque. --halo est la couleur de la pastille qui porte
   les étoiles : celle du fond de l'écusson, pas un blanc arbitraire. */
.av-plan { --halo: #fff; position: relative; display: inline-flex; flex-shrink: 0; }
.av-disc {
  border-radius: 50%; background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Bricolage Grotesque', sans-serif; font-weight: 700; line-height: 1;
}
.av-lettre { transform: translate(-2px, -2px); display: block; }
.av-lettre-centree { transform: none; }
.av-marque {
  position: absolute; right: -3px; bottom: -3px; pointer-events: none;
  filter: drop-shadow(0 1px 1.5px rgba(40, 20, 70, .18));
}
.topbar-right .plan-ecusson.p-gratuit { --teinte: var(--faint); border-color: var(--line); }
.topbar-right .plan-ecusson:hover { transform: translateY(-1px); }
.topbar-right .plan-ecusson.p-gratuit:hover { border-color: var(--faint); }
/* L'avatar est descendu dans la barre du bas : celui du haut fait doublon.

   On le retire là où la barre est fixée en bas, sous le pouce — c'est-à-dire
   sous 720px, le même seuil qu'elle. Deux portes vers la même pièce, côte à
   côte, ne servent personne ; et sur ta capture, l'écusson passait à la ligne
   sous le titre et volait une rangée entière à l'écran qui en a le moins.

   Au-dessus de 720px il reste : la barre y flotte en pastille, sans place
   pour le mot « Fondateur ». L'écusson nommé garde donc sa place là où il y
   a la place de le nommer. La pastille de synchronisation reste partout —
   elle informe, elle n'emmène nulle part. */
@media (max-width: 719px) {
  .topbar-right .plan-ecusson,
  .topbar-right .avatar { display: none; }
}
@media (max-width: 380px) {
  .topbar-right .plan-ecusson .plan-nom { display: none; }
  .topbar-right .plan-ecusson { width: 42px; padding: 0; justify-content: center; gap: 0; }
}
/* ---- 23 · pastille de compte sur les chips de vue --------------------- */
.vue-n {
  font-size: 11px; font-weight: 700; color: var(--muted);
  background: var(--line-soft); border-radius: 999px; padding: 1px 7px;
  margin-left: 6px; flex-shrink: 0;
}
.vue-chip.active .vue-n { background: rgba(255,255,255,.28); color: inherit; }
.vue-n.vide { color: var(--magenta); background: var(--magenta-soft); }
/* ---- 24 · sélection multiple ------------------------------------------ */
.sel-wrap { position: relative; cursor: pointer; }
.sel-wrap > article { transition: box-shadow .12s, opacity .12s; }
.sel-wrap:not(.sel-on) > article { opacity: .82; }
.sel-wrap.sel-on > article { box-shadow: 0 0 0 2.5px var(--violet); }
.sel-coche {
  position: absolute; top: 10px; right: 10px; z-index: 5;
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 800; pointer-events: none;
  background: #fff; color: var(--faint);
  box-shadow: 0 1px 5px rgba(40,20,70,.22); border: 1.5px solid var(--line);
}
.sel-wrap.sel-on .sel-coche { background: var(--violet); color: #fff; border-color: var(--violet); }

.sel-bar {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
  z-index: 60; display: flex; align-items: center; gap: 9px;
  background: var(--ink); border: 1.5px solid var(--line); border-radius: 999px;
  padding: 9px 12px 9px 16px; box-shadow: 0 8px 28px rgba(40,20,70,.18);
  /* width: max-content — la ligne qui manquait.
     Un élément « fixed » avec left:50% et aucune largeur ne dispose, pour se
     dimensionner, que de l'espace allant de 50% à 100% : la MOITIÉ de l'écran.
     Le translateX(-50%) le recentre à l'œil, mais ne lui rend pas la place.
     La barre se croyait donc à l'étroit dans 215px sur un écran de 430, et
     s'empilait sur six rangées. Avec max-content elle réclame sa largeur
     naturelle, que max-width ramène ensuite à la taille de l'écran — et
     flex-wrap ne replie que ce qui dépasse vraiment.
     Mesuré à 320px : 369px de haut avant, 168px après. */
  width: max-content;
  max-width: calc(100vw - 24px); flex-wrap: wrap; justify-content: center;
}
.sel-bar b { font-size: 14px; white-space: nowrap; color: var(--paper) }
.sel-bar .btn { padding: 8px 14px; font-size: 13.5px; }

/* ---- 25 · détails des liens non enrichis ------------------------------ */
.enrich-bar .enrich-message {
  flex: 1 1 360px; min-width: 0; display: flex; align-items: center;
  justify-content: space-between; gap: 14px; padding: 2px 4px;
  border: 0; border-radius: 8px; background: transparent; color: var(--ink);
  font: inherit; font-size: 14px; font-weight: 500; text-align: left; cursor: pointer;
}
.enrich-bar .enrich-message:hover,
.enrich-bar .enrich-message:focus-visible {
  background: rgba(255,255,255,.48); outline: none;
}
.enrich-voir {
  flex-shrink: 0; color: var(--violet); font-weight: 800; white-space: nowrap;
}
.enrich-fail-list {
  display: flex; flex-direction: column; gap: 9px; max-height: 52vh;
  overflow-y: auto; padding: 2px;
}
.enrich-fail-item {
  display: flex; flex-direction: column; gap: 10px; padding: 12px 13px;
  border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--card);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.enrich-fail-lien {
  display: grid; grid-template-columns: minmax(0,1fr) minmax(150px,1.2fr) 24px;
  align-items: center; gap: 12px; color: var(--ink); text-decoration: none;
}
.enrich-fail-valider { align-self: flex-end; padding: 7px 13px; font-size: 13.5px; min-height: 0; }
.enrich-fail-item:hover {
  border-color: var(--violet); box-shadow: var(--shadow-hover); transform: translateY(-1px);
}
.enrich-fail-main { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.enrich-fail-main b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.enrich-fail-main small { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.enrich-fail-reason { font-size: 13px; line-height: 1.35; color: var(--muted); }
.enrich-fail-open { color: var(--violet); font-size: 20px; font-weight: 800; text-align: center; }
@media (max-width: 680px) {
  .enrich-bar { flex-wrap: wrap; }
  .enrich-bar .enrich-message { flex-basis: 100%; align-items: flex-start; }
  .enrich-fail-lien { grid-template-columns: minmax(0,1fr) 24px; }
  .enrich-fail-reason { grid-column: 1 / -1; grid-row: 2; }
  .enrich-fail-open { grid-column: 2; grid-row: 1; }
}


/* ── Filtres unifiés : pill active « libellé × » et menu Statut ─────────────
   La barre n'affiche plus la rangée de statuts : un bouton « Statut ▾ » ouvre
   un menu, et le filtre choisi revient dans la barre sous forme de pill.
   Le libellé rouvre le menu, le ✕ retire le filtre. Mêmes couleurs que les
   anciennes chips : le repère visuel des statuts est conservé. */
.chip-actif { display: inline-flex; align-items: stretch; padding: 0; }
.chip-actif .chip-lbl, .chip-actif .chip-x {
  background: none; border: none; color: inherit; font: inherit;
  font-weight: 700; cursor: pointer; display: flex; align-items: center;
}
.chip-actif .chip-lbl { padding: 0 4px 0 14px; }
.chip-actif .chip-x { padding: 0 12px 0 7px; opacity: .75; font-size: 13px; }
.chip-actif .chip-x:hover { opacity: 1; }

.statut-liste button { position: relative; }
.statut-lbl { display: flex; align-items: center; gap: 9px; min-width: 0; }
.statut-droite { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.statut-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.dot-todo { background: var(--blue); }
.dot-done { background: var(--violet); }
.dot-exploit { background: var(--vert); }
.dot-keep { background: var(--magenta); }
/* Archives : un état à part, séparé du cycle de vie par un filet */
.statut-liste .statut-archives { margin-top: 12px; }
.statut-liste .statut-archives::before {
  content: ""; position: absolute; top: -7px; left: 6px; right: 6px;
  height: 1px; background: var(--line);
}

/* Intitulé du groupe de tags hors contexte dans « Filtrer par tag ».
   Un seul espace de nommage : ces tags restent sélectionnables ici, l'état
   vide de l'onglet guidera ensuite vers là où ils vivent. */
.tags-ailleurs {
  margin: 10px 2px 2px; font-size: 12.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}


/* ---------- V2 — Texte d'accueil et barre de navigation basse ---------- */

/* Le texte qui a pris la place des onglets du haut : il dit en deux lignes
   ce que fait l'application. Il défile avec la page, il ne colle pas. */
.hero-v2 { margin: 2px 0 14px; }
.hero-v2 h2 {
  font-family: 'Bricolage Grotesque', sans-serif; font-weight: 700;
  font-size: clamp(19px, 4.6vw, 25px); line-height: 1.2;
  letter-spacing: -0.015em; margin: 0 0 5px; color: var(--ink);
}
.hero-v2 p {
  margin: 0; color: var(--muted); font-size: 14.5px;
  line-height: 1.45; max-width: 46ch;
}

/* La barre du bas EST le filtre par type : chaque appui change vraiment le
   contenu affiché. Elle remplace la rangée d'onglets du haut, dont seuls
   trois tenaient sur un écran de téléphone — les Idées et les Inspirations
   étaient cachées derrière un défilement horizontal. */
.tabbar-v2 {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(62px + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: rgba(255,255,255,0.93);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
  display: flex;
}
.tabbar-v2 .tb-item {
  flex: 1 1 0; min-width: 0; padding: 0 2px;
  border: none; background: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; font-family: inherit;
  /* --faint (#a59cb3) donnait un contraste de 2,62 sur le fond blanc de la
     barre. Le seuil WCAG AA pour du texte de cette taille est 4,5 : on en
     était à moins de la moitié. --muted (#6b6478) monte à 5,65.

     Ce n'était pas un choix, c'était un oubli — les libellés font 10 à
     11,5 px, la taille où le contraste compte le plus, et c'est justement
     là qu'on avait pris la couleur la plus pâle de la palette. */
  color: var(--muted);
  transition: color 0.15s ease;
}
.tabbar-v2 .tb-item.active { color: var(--violet); }
.tabbar-v2 .tb-item:active { transform: scale(0.93); }

/* Le Profil n'est pas un filtre.

   Les quatre premiers boutons disent « montre-moi ça », celui-ci dit
   « emmène-moi ailleurs ». Un filet le sépare : sans lui, l'œil lirait cinq
   onglets de même nature et s'attendrait à ce que le cinquième filtre
   quelque chose.

   Il ne prend pas une part entière : un avatar se lit à sa forme, pas à sa
   largeur, et les quatre filtres méritent la place. */
.tabbar-v2 .tb-profil {
  /* Une part entière, comme les quatre autres.

     Avec « flex: 0 0 auto » il n'occupait que 60px pendant que les onglets
     s'étalaient à 83px chacun : quatre boutons largement espacés, puis un
     cinquième serré contre le bord droit. Le déséquilibre se voyait.

     Je pensais qu'un avatar se lit à sa forme et non à sa largeur, et que
     les filtres méritaient la place. C'est vrai de l'avatar, faux de la
     rangée : cinq parts égales se lisent comme une rangée, quatre parts
     plus un reste se lisent comme un accident. Le filet suffit à dire que
     le cinquième n'est pas de la même nature. */
  flex: 1 1 0;
  position: relative;
}
.tabbar-v2 .tb-profil::before {
  content: ''; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 1px; height: 26px; background: var(--line);
}
/* L'avatar garde ses couleurs quel que soit l'état du bouton. */
.tabbar-v2 .tb-profil .tb-ico { color: var(--violet); }

/* Sans plan, pas d'écusson : une lettre suffit. */
.tb-avatar-lettre {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--violet); color: #fff;
  font-size: 12px; font-weight: 700; line-height: 24px;
  text-align: center; display: block;
}

.tabbar-v2 .tb-ico { position: relative; display: flex; }
/* Compteur posé sur l'icône, discret. Absent quand il n'y a rien. */
.tabbar-v2 .tb-count {
  position: absolute; top: -5px; left: 100%; margin-left: -8px;
  background: var(--line-soft); color: var(--muted);
  font-size: 9.5px; font-weight: 700; line-height: 1;
  padding: 2.5px 4px; border-radius: 999px;
  min-width: 15px; text-align: center;
  border: 1px solid var(--line);
}
.tabbar-v2 .tb-item.active .tb-count {
  background: var(--violet); color: #fff; border-color: var(--violet);
}
.tabbar-v2 .tb-lab {
  font-size: 10.5px; font-weight: 700; letter-spacing: -0.015em;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Dégager le contenu, le bouton flottant et la bannière au-dessus de la barre.
   Ces règles viennent AVANT la media query : sinon elles l'écraseraient. */
.app { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
.fab { bottom: calc(84px + env(safe-area-inset-bottom)); }
.install-banner { bottom: calc(88px + env(safe-area-inset-bottom)); z-index: 65; }

/* À partir de 720px : la barre devient une pilule flottante centrée. */
@media (min-width: 720px) {
  .tabbar-v2 {
    left: 50%; right: auto; transform: translateX(-50%);
    width: min(580px, calc(100% - 48px));
    bottom: calc(14px + env(safe-area-inset-bottom));
    height: 64px; padding-bottom: 0;
    border: 1px solid var(--line); border-radius: 999px;
    box-shadow: var(--shadow-hover);
  }
  .tabbar-v2 .tb-lab { font-size: 11.5px; }
  /* La barre flotte plus haut : le bouton et la bannière remontent d'autant. */
  .fab { bottom: calc(98px + env(safe-area-inset-bottom)); }
  .install-banner { bottom: calc(98px + env(safe-area-inset-bottom)); }
}

@media (prefers-reduced-motion: reduce) {
  .tabbar-v2 .tb-item { transition: none; }
}


/* Le bandeau rouge du nombre de comptes, sur le raccourci. */
.admin-lien-pastille {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--magenta);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1;
  margin-left: 7px;
  flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════
   PLANS & TARIFS — les trois tuiles
   ═══════════════════════════════════════════════════════════════════
   Trois colonnes tiennent sur un écran large, pas sur un téléphone :
   à 390 px, chaque tuile ferait 118 px et « environ 500 photos »
   partirait sur quatre lignes. Donc une colonne d'abord, trois à
   partir de 560 px. La grille reprend la maquette, le seuil est en
   plus — mesuré, pas deviné. */
.plan-mini-grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

@media (min-width: 560px) {
  .plan-mini-grille {
    grid-template-columns: repeat(3, 1fr);
  }
}

.plan-mini-tuile {
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 11px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* L'offre en cours se signale par un liseré, pas par un fond : un
   fond plein sur trois tuiles côte à côte écrase les deux autres. */
.plan-mini-tuile.on {
  border-color: var(--violet);
  box-shadow: 0 0 0 1.5px var(--violet);
}

.plan-mini-tuile b {
  font-size: 14px;
  color: var(--ink);
}

.plan-mini-prix {
  font-size: 15px;
  font-weight: 700;
  color: var(--violet);
  line-height: 1.2;
}

/* Le « quand » : la mécanique du prix — par mois, une fois, pour
   toujours. Il colle au prix, d'où le line-height serré. */
.plan-mini-quand {
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.3;
  margin-top: -1px;
}

/* Le « quoi » : ce que l'offre donne. Séparé du « quand » par une
   respiration — ce sont deux questions différentes. */
.plan-mini-photos {
  font-size: 12px;
  color: var(--ink);
  line-height: 1.4;
  margin-top: 5px;
}

.plan-mini-vous {
  align-self: flex-start;
  margin-top: 2px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #fff;
  background: var(--violet);
  border-radius: 999px;
  padding: 2px 7px;
}

.plan-carte-limite {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--violet);
  background: var(--violet-soft);
  border-radius: 999px;
  padding: 5px 10px;
}

/* ═══════════════════════════════════════════════════════════════════
   ADMINISTRATION
   ═══════════════════════════════════════════════════════════════════
   Écrit à la main, dans les jetons de l'app. La version précédente
   recopiait la maquette à la machine : elle a aplati les @media —
   « 4 colonnes » et « 2 colonnes » se sont retrouvées côte à côte au
   même niveau, la dernière gagnait — et laissé passer .stat, d'où le
   rectangle rose sans forme. Ici, rien n'est recopié. */

/* ── La fenêtre ─────────────────────────────────────────────────────
   Les autres feuilles font 540 px : elles portent un formulaire, une
   colonne. Celle-ci porte un tableau de SIX colonnes. À 540 px, la
   moitié — Stockage, Quota, Actions — sortait du cadre, atteignable
   seulement par une barre horizontale que personne ne voit. */
@media (min-width: 680px) {
  .sheet-admin {
    max-width: min(1140px, 94vw);
  }
}

.admin-popup-content {
  display: flex;
  flex-direction: column;
}

.admin-intro {
  margin: 0 0 14px;
}

/* ── Les quatre chiffres ────────────────────────────────────────────
   Deux de front sur un téléphone, quatre sur un écran. Le @media est
   ici, à sa place, et une seule fois. */
.admin-stat-grid,
.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}

@media (min-width: 680px) {
  .admin-stat-grid,
  .stat-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.stat {
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  padding: 13px 14px;
  min-width: 0;
}

.stat__value {
  font-family: "Bricolage Grotesque", system-ui, sans-serif;
  font-size: 26px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ink);
}

.stat__label {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 4px;
}

/* La seule tuile qui appelle un geste. Le chiffre en magenta le dit
   déjà : la teinte reste discrète, elle accompagne, elle ne crie pas. */
.stat--new {
  border-color: #f0cfe2;
  background: var(--magenta-soft);
}

.stat--new .stat__value {
  color: var(--magenta);
}

/* ── Le tableau ─────────────────────────────────────────────────────
   Pas de min-width sur grand écran : les colonnes se répartissent.
   En dessous de 680 px un tableau de six colonnes ne rentre nulle
   part — là, et là seulement, on assume le défilement horizontal. */
.admin-table-wrap,
.table-wrap {
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  overflow-x: auto;
  margin-bottom: 10px;
}

.admin-table,
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

@media (max-width: 679px) {
  .admin-table {
    min-width: 640px;
  }
}

.admin-table th {
  text-align: left;
  padding: 10px 13px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  background: var(--line-soft);
  border-bottom: 1.5px solid var(--line);
  white-space: nowrap;
}

.admin-table td {
  padding: 11px 13px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
  color: var(--ink);
}

.admin-table tbody tr:last-child > td {
  border-bottom: none;
}

.admin-table tbody tr:hover > td {
  background: #fdfbff;
}

/* L'email est la seule colonne élastique : c'est elle qui doit céder,
   pas les chiffres. Les autres se calent sur leur contenu. */
.admin-email-cell {
  width: 100%;
  min-width: 190px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  word-break: break-word;
}

.admin-table td:not(.admin-email-cell) {
  white-space: nowrap;
}

.admin-plan-select {
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  padding: 5px 26px 5px 11px;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6478' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
  transition: border-color .15s, background-color .15s;
}

.admin-plan-select:hover {
  border-color: var(--faint);
}

.admin-plan-select:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 3px var(--violet-soft);
}

/* Chaque offre porte sa couleur : on lit la colonne d'un coup d'œil,
   sans lire les mots. */
.admin-plan-select.p-payant {
  color: var(--violet);
  border-color: #d6c4f0;
  background-color: var(--violet-soft);
}

.admin-plan-select.p-fondateur {
  color: #9a6a12;
  border-color: #ecd08a;
  background-color: #fdf3dc;
}

.admin-quota-cell {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  font-weight: 700;
}

.admin-quota-cell small {
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
  margin-top: 2px;
}

.admin-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: flex-end;
}

.iconbtn.danger {
  color: var(--magenta);
}

.iconbtn.danger:hover {
  background: var(--magenta-soft);
}

/* ── Le panneau qui se déplie sous une ligne ────────────────────────
   Exception ou mot de passe. Il vit DANS le tableau, donc dans une
   cellule qui traverse toutes les colonnes : sans largeur bornée, il
   étirait la table et son bouton partait hors du cadre. */
.admin-exception-row > td {
  padding: 0;
  background: var(--note-bg);
  border-bottom: 1px solid var(--line-soft);
}

.admin-exception-panel {
  padding: 14px;
  max-width: 560px;
}

.admin-exception-panel .sync-note {
  margin: 0 0 10px;
}

.admin-exception-panel .sheet-actions {
  margin-top: 12px;
}

.admin-table-note {
  margin: 0 0 16px;
}

.admin-plafonds,
.admin-create-block {
  margin-bottom: 16px;
}

/* ── Statut par défaut ───────────────────────────────────────────────
   Un point à cocher devant chaque libellé. Un rond, pas une étoile :
   l'étoile dit déjà « Fondateur » ailleurs dans l'app, et un rond dit
   « un seul parmi plusieurs » sans qu'on ait à l'apprendre. */
.label-ligne {
  display: flex;
  align-items: center;
  gap: 9px;
}

.label-ligne + .label-ligne {
  margin-top: 7px;
}

.label-ligne input {
  flex: 1;
  min-width: 0;
}

.label-defaut {
  flex-shrink: 0;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--card);
  cursor: pointer;
  padding: 0;
  position: relative;
  transition: border-color .15s, background .15s;
}

.label-defaut:hover {
  border-color: var(--faint);
}

.label-defaut.on {
  border-color: var(--violet);
}

/* Le point : peint en ::after, pas en fond — le liseré reste visible,
   et c'est lui qui porte la couleur de la marque. */
.label-defaut.on::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--violet);
}

.label-defaut:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--violet-soft);
}

/* La légende du rond. Elle montre le contrôle dont elle parle, à trois
   centimètres de lui : un rond nu n'explique rien, un rond légendé se
   comprend sans qu'on ait à chercher la phrase qui va avec. Elle vit
   séparée de la note sur le renommage — deux idées, deux phrases. */
.defaut-legende {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 10px;
  padding: 8px 10px;
  background: var(--violet-soft);
  border-radius: 9px;
}

.defaut-legende .label-defaut {
  pointer-events: none;
  cursor: default;
}


/* ═══════════════════════════════════════════════════════════════════
   STATUTS — les couleurs et le réglage
   ═══════════════════════════════════════════════════════════════════
   Les classes portaient des noms de statuts (c-todo, c-done…) qui
   étaient en réalité des noms de couleurs déguisés. Maintenant que
   l'utilisateur choisit, elles portent leur vrai nom. Il manquait le
   gris — le fond, celui du statut par défaut, discret parce qu'il est
   sur presque toutes les cartes — et le rouge, le seul qui crie. */
:root {
  --gris: #7d7490;
  --gris-soft: #eeebf3;
  --rouge: #b3242c;
  --rouge-soft: #fbe3e4;
  /* Orange brûlé et ocre : les deux dernières places du nuancier.
     Le rose partait — il se confondait avec le magenta à un mètre
     de l'écran, et deux couleurs qu'on doit comparer côte à côte
     pour les distinguer ne distinguent rien.

     Les teintes vives ne passent PAS le contraste AA sur leur
     propre fond pastel (l'orange y tombe à 3,5). D'où --x-text :
     même teinte, assombrie juste ce qu'il faut pour franchir 4,5.
     C'est elle qui porte le libellé ; --x reste la pastille. */
  --orange: #c0642a;
  --orange-soft: #f9e8dc;
  --orange-text: #a35322;
  --ocre: #8f7117;
  --ocre-soft: #f4edd8;
  --ocre-text: #846815;
}

.chip.c-gris   { background: var(--gris-soft);   border-color: transparent; color: var(--gris); }
.chip.c-gris.active   { background: var(--gris);   color: #fff; }
.chip.c-rouge  { background: var(--rouge-soft);  border-color: transparent; color: var(--rouge); }
.chip.c-rouge.active  { background: var(--rouge);  color: #fff; }
.chip.c-pink   { background: var(--pink-soft);   border-color: transparent; color: var(--pink); }
.chip.c-pink.active   { background: var(--pink);   color: #fff; }
.chip.c-orange { background: var(--orange-soft); border-color: transparent; color: var(--orange-text); }
.chip.c-orange.active { background: var(--orange); color: #fff; }
.chip.c-ocre   { background: var(--ocre-soft);   border-color: transparent; color: var(--ocre-text); }
.chip.c-ocre.active   { background: var(--ocre);   color: #fff; }

.card.s-gris::before  { background: var(--gris); }
.card.s-rouge::before { background: var(--rouge); }
.card.s-pink::before  { background: var(--pink); }
.card.s-orange::before { background: var(--orange); }
.card.s-ocre::before   { background: var(--ocre); }

.status-pill.p-gris  { background: var(--gris); }
.status-pill.p-rouge { background: var(--rouge); }
.status-pill.p-pink  { background: var(--pink); }
.status-pill.p-orange { background: var(--orange); }
.status-pill.p-ocre   { background: var(--ocre); }

.state-choice button.sel-gris  { border-color: var(--gris);  background: var(--gris-soft);  color: var(--gris); }
.state-choice button.sel-rouge { border-color: var(--rouge); background: var(--rouge-soft); color: var(--rouge); }
.state-choice button.sel-pink  { border-color: var(--pink);  background: var(--pink-soft);  color: var(--pink); }
.state-choice button.sel-orange { border-color: var(--orange); background: var(--orange-soft); color: var(--orange-text); }
.state-choice button.sel-ocre   { border-color: var(--ocre);   background: var(--ocre-soft);   color: var(--ocre-text); }

/* ── Le réglage : une ligne par statut ──────────────────────────────
   Une seule liste maintenant, plus deux colonnes : elle prend toute
   la largeur, chaque ligne porte ses quatre commandes. */
.statuts-liste {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.statut-ligne {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}

/* Rangé : on l'estompe sans le cacher. Il doit rester lisible — c'est
   par lui qu'on le remet en service. */
.statut-ligne.off {
  opacity: .5;
}

.statut-nom {
  flex: 1;
  min-width: 110px;
}

.label-defaut:disabled {
  opacity: .4;
  cursor: not-allowed;
}

/* ── Les sept pastilles ─────────────────────────────────────────── */
.statut-couleurs {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.pastille {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  transition: transform .12s, box-shadow .12s;
}

.pastille.c-gris    { background: var(--gris); }
.pastille.c-bleu    { background: var(--blue); }
.pastille.c-violet  { background: var(--violet); }
.pastille.c-magenta { background: var(--magenta); }
.pastille.c-pink    { background: var(--pink); }
.pastille.c-orange  { background: var(--orange); }
.pastille.c-ocre    { background: var(--ocre); }
.pastille.c-vert    { background: var(--vert); }
.pastille.c-rouge   { background: var(--rouge); }

.pastille:hover:not(:disabled) { transform: scale(1.15); }

/* La couleur en cours : un anneau blanc puis le liseré d'encre. Le
   contraste tient sur les sept, du gris pâle au rouge profond. */
.pastille.on {
  box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--ink);
}

/* Prise par un autre statut. Elle n'est plus interdite : elle
   ÉCHANGE. À huit statuts pour huit couleurs, le nuancier n'offrait
   plus aucune alternative — toutes grises sauf la sienne. Interdire
   revient à demander de désactiver un statut, changer, réactiver,
   pour un simple échange bleu/violet. Un clic suffit maintenant :
   les deux statuts permutent, l'unicité tient toujours.

   Estompée, pas barrée : elle reste choisissable, on doit juste
   savoir qu'elle appartient déjà à quelqu'un. */
.pastille.pris {
  opacity: .3;
}

.pastille.pris:hover {
  opacity: .65;
}

/* ── Le pied de liste : repli des rangés + bouton d'ajout ──────────
   Les créneaux libres ne s'affichent pas en lignes vides. Un statut
   qu'on n'a pas créé n'existe pas ; une ligne fantôme demande à être
   remplie et fait passer le réglage pour un formulaire. */
/* La corbeille. Discrète au repos — elle ne vit que sur les lignes
   rangées, et une ligne rangée est déjà en retrait. Elle ne rougit
   qu'au survol : une corbeille rouge en permanence, dans une liste
   de huit, c'est huit invitations à se tromper. */
.statut-sup {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
  opacity: .55;
  transition: opacity .12s ease, color .12s ease, background .12s ease;
}

.statut-sup:hover {
  opacity: 1;
  color: var(--rouge);
  background: var(--rouge-soft);
}

.statut-sup:focus-visible {
  opacity: 1;
  outline: 2px solid var(--rouge);
  outline-offset: 1px;
}

.statuts-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}

.statuts-ranges-titre {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  padding: 4px 0;
  font: inherit;
  font-size: .82rem;
  color: var(--muted);
  cursor: pointer;
}

.statuts-ranges-titre:hover { color: var(--ink); }

.statuts-ranges-titre .chevron {
  display: inline-block;
  transition: transform .15s ease;
}

details[open] > .statuts-ranges-titre .chevron {
  transform: rotate(90deg);
}

.statuts-ranges > summary { list-style: none; }
.statuts-ranges > summary::-webkit-details-marker { display: none; }

.statuts-ranges-nb {
  background: var(--line-soft);
  border-radius: 9px;
  padding: 1px 7px;
  font-size: .72rem;
}

.statut-ajout {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 6px 11px;
  font: inherit;
  font-size: .82rem;
  color: var(--ink);
  cursor: pointer;
}

.statut-ajout:hover:not(:disabled) {
  border-color: var(--violet);
  color: var(--violet);
}

/* Grisé, jamais retiré. Un bouton qui disparaît à huit statuts
   laisse croire à une panne ; grisé, il dit qu'on a atteint la
   limite — et son title dit laquelle. */
.statut-ajout:disabled {
  opacity: .4;
  cursor: not-allowed;
}

.statut-compteur {
  font-size: .72rem;
  color: var(--muted);
  margin-left: 2px;
}

/* ── L'interrupteur actif / rangé ───────────────────────────────── */
.statut-bascule {
  flex-shrink: 0;
  width: 38px;
  height: 22px;
  border-radius: 999px;
  border: none;
  background: var(--line);
  padding: 0;
  cursor: pointer;
  position: relative;
  transition: background .18s;
}

.statut-bascule > span {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 1px 3px rgba(46, 42, 61, .25);
  transition: transform .18s;
}

.statut-bascule.on {
  background: var(--violet);
}

.statut-bascule.on > span {
  transform: translateX(16px);
}

.statut-bascule:disabled {
  opacity: .4;
  cursor: not-allowed;
}
