/* =============================================================
   MNEMO — 07 — MODALS
   Modal upload (multi-photos + conflit date), photo detail, commentaires.
   ============================================================= */

/* ------ MODAL ----------------------------------------------- */

.modal-scrim {
  position: fixed;
  inset: 0;
  /* Z-index 300 : au-dessus de .modal-overlay (200) pour que les modals
     déclenchés depuis l'intérieur du ProfilePage (Create/Join/Share event,
     ConfirmDeleteAccount, Legal, etc.) restent visibles via portail. */
  z-index: 300;
  /* Voile d'encre léger, pas un aplat opaque : la feuille ne s'arrête à 72 %
     que pour laisser voir le contenu derrière. Avec l'ancien papier à 85 %
     d'opacité et un flou de 12 px, le feed disparaissait complètement et la
     feuille n'avait plus de raison d'être bornée. */
  background: rgba(var(--encre-rgb), 0.3);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: grid;
  place-items: flex-end center;
  animation: fadeIn 0.2s;
}

/* .modal-overlay = comme .modal-scrim mais centré verticalement (pour les
   modals d'édition profil / sélection user). Z-index plus élevé pour passer
   au-dessus de PhotoDetail ou ProfilePage si rendu par-dessus. */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(var(--carte-rgb), 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  display: grid;
  place-items: center;
  padding: 16px;
  animation: fadeIn 0.2s;
}

.modal {
  position: relative;
  width: 100%;
  max-width: 680px;
  /* Le modal occupe TOUTE la grid cell du scrim (= 100% viewport mobile,
     100vh - 48px de padding sur desktop). align-self: stretch override le
     place-items: flex-end du scrim — sans ça, le modal anchored-bottom peut
     spiller au-dessus de la visible area sur mobile quand l'URL bar slide.
     align-self: stretch (vs height: 100dvh) évite ce flash de désync. */
  /* FEUILLE, pas plein écran (parti pris de la direction « Signal ») : la
     modale s'arrête à 72 % de la hauteur et laisse voir le contenu derrière.
     On garde ainsi le contexte — on sait d'où on vient et on peut refermer en
     tapant la photo qui dépasse.

     `dvh` et non `vh` : c'est la « dynamic viewport height », qui suit la
     barre d'URL mobile. L'ancien `align-self: stretch` avait justement été
     choisi pour éviter le flash de désynchronisation d'un `100vh` figé ;
     `max-height` en dvh répond au même besoin sans occuper tout l'écran.

     Le plein écran subsiste pour la visionneuse photo et les stories, seuls
     endroits où il se justifie (cf. .modal-photo-detail plus bas). */
  align-self: end;
  height: auto;
  max-height: 72dvh;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-top: 1.5px solid var(--encre);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 -6px 24px rgba(var(--ombre-rgb), 0.16);
  animation: slideUp 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Poignée de feuille : signale qu'on peut refermer, et donne un point de
   préhension visuel en haut de la feuille. */
.modal::before {
  content: '';
  position: absolute;
  top: 7px; left: 50%;
  transform: translateX(-50%);
  width: 38px; height: 4px;
  border-radius: calc(999px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.22);
  z-index: 2;
}

/* La visionneuse photo reste plein écran : c'est l'un des deux seuls cas que
   la direction autorise (avec les stories). Regarder une photo est l'action
   pour laquelle on veut toute la surface. */
.modal-photo-detail {
  align-self: stretch;
  height: auto;
  max-height: none;
  border-top-width: 1px;
  box-shadow: none;
}
.modal-photo-detail::before { display: none; }

@media (min-width: 680px) {
  .modal-scrim { place-items: center; padding: 24px; }
  .modal { border-radius: var(--r-xl); max-height: 86dvh; }
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp {
  from { transform: translateY(40px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

.modal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  /* +6px en haut pour dégager la poignée de feuille (.modal::before). */
  padding: 16px 16px 10px;
  border-bottom: 1px solid var(--border);
  /* Le header ne shrink pas quand le modal est full-height : on garde sa
     taille naturelle, le body absorbe le reste via flex. */
  flex-shrink: 0;
}

.modal-title {
  flex: 1;
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
}

.modal-body {
  /* GÉNÉRIQUE : le body absorbe la hauteur restante du modal
     (après header + footer) et scrolle quand le contenu déborde.
     Pour PhotoDetail (image greedy au-dessus + body capé), voir la
     variante .modal-photo-detail .modal-body ci-dessous. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 16px;
}

/* Variante PhotoDetail : l'image .detail-photo / .pinch-zoom prend toute
   la hauteur restante, le body des commentaires est capé à 40dvh. */
.modal-photo-detail .modal-body {
  flex: 0 1 auto;
  max-height: 40dvh;
}

.modal-footer {
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 10px;
  /* Footer fixe en bas du modal : ne shrink jamais. */
  flex-shrink: 0;
}


/* ------ Upload (boutons initiaux + preview) ---------------- */

.upload-drop {
  border: 2px dashed rgba(var(--tampon-rgb), 0.35);
  background: rgba(var(--tampon-rgb), 0.04);
  border-radius: var(--r-lg);
  padding: 40px 20px;
  text-align: center;
  margin-bottom: 20px;
  transition: all 0.2s;
}
.upload-drop:hover { background: rgba(var(--tampon-rgb), 0.08); border-color: var(--pink); }

.upload-preview {
  width: 100%;
  max-height: 400px;
  object-fit: contain;
  background: var(--carte);
  border-radius: var(--r-md);
  margin-bottom: 16px;
}

.upload-opts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 20px;
}

.upload-opt {
  padding: 18px;
  border-radius: var(--r-md);
  background: rgba(var(--encre-rgb), 0.05);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  transition: all 0.2s;
}
.upload-opt:hover { background: rgba(var(--encre-rgb), 0.1); border-color: var(--pink); color: var(--pink); }

.upload-opt-label { font-size: 13px; font-weight: 600; }


/* ------ UPLOAD GRID (multi-photos avant envoi) -------------- */

/* Grille de pré-upload : 3 colonnes carrées sur écrans confortables,
   2 colonnes en dessous de 360px pour rester lisible sur petits téléphones. */
.upload-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
@media (max-width: 360px) {
  .upload-grid { grid-template-columns: repeat(2, 1fr); }
}

.upload-grid-item {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: calc(10px * var(--r-k));
  overflow: hidden;
  background: rgba(var(--encre-rgb), 0.05);
  border: 1px solid rgba(var(--encre-rgb), 0.06);
  transition: opacity 0.15s, transform 0.15s;
}
.upload-grid-item-excluded {
  opacity: 0.4;
}
.upload-grid-item-excluded .upload-grid-img {
  filter: grayscale(0.6) brightness(0.85);
}

.upload-grid-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Checkbox d'inclusion en haut à gauche */
.upload-grid-check {
  position: absolute;
  top: 6px; left: 6px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(var(--encre-rgb), 0.9);
  background: rgba(var(--carte-rgb), 0.45);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.upload-grid-check:hover { transform: scale(1.08); }
.upload-grid-check-on {
  background: var(--grad-primary);
  border-color: var(--sur-grad);
}

/* Bouton supprimer en haut à droite */
.upload-grid-remove {
  position: absolute;
  top: 6px; right: 6px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: rgba(var(--encre-rgb), 0.85);
  border: 0;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.upload-grid-remove:hover {
  background: rgba(var(--tampon-rgb), 0.85);
  color: var(--sur-accent);
}

/* Footer de la vignette : heure détectée + indicateur de source */
.upload-grid-footer {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 5px 6px;
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.7) 0%, rgba(var(--carte-rgb), 0) 100%);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  font-size: 10px;
}

.upload-grid-time {
  color: var(--text);
  font-weight: 700;
  background: rgba(var(--carte-rgb), 0.5);
  padding: 1px 5px;
  border-radius: calc(4px * var(--r-k));
}

.upload-grid-source {
  color: rgba(var(--encre-rgb), 0.75);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.upload-grid-conflict {
  background: rgba(var(--tampon-rgb), 0.85);
  color: var(--encre-2);
  font-size: 9px;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: calc(4px * var(--r-k));
  border: 0;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s;
}
.upload-grid-conflict:hover {
  background: rgba(var(--tampon-rgb), 1);
}

/* ------ Overlays vidéo dans la grille upload --------------- */

/* Badge play centré sur le poster d'une vidéo */
.upload-grid-play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1.5px solid rgba(var(--encre-rgb), 0.8);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  /* Petit shift pour compenser l'asymétrie du triangle play */
  padding-left: 3px;
  box-shadow: 0 4px 12px rgba(var(--ombre-rgb), 0.22);
}

/* Durée vidéo en haut au centre */
.upload-grid-duration {
  position: absolute;
  top: 6px; left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 700;
  color: var(--text);
  background: rgba(var(--carte-rgb), 0.6);
  padding: 2px 7px;
  border-radius: calc(10px * var(--r-k));
  letter-spacing: -0.02em;
  pointer-events: none;
}

/* Placeholder quand pas encore de poster (preview blob: video ne rend rien) */
.upload-grid-img-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--carte), var(--carte));
  color: rgba(var(--encre-rgb), 0.4);
}

/* Overlay "préparation en cours" pendant l'extraction du poster */
.upload-grid-preparing {
  position: absolute;
  inset: 0;
  background: rgba(var(--carte-rgb), 0.85);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  color: rgba(var(--encre-rgb), 0.85);
  font-size: 11px;
  font-weight: 600;
  pointer-events: none;
}

/* Overlay d'erreur vidéo (durée dépassée, format illisible) */
.upload-grid-error {
  position: absolute;
  inset: 0;
  background: rgba(var(--tampon-rgb), 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px;
  gap: 4px;
  color: var(--sur-accent);
  font-size: 10px;
  font-weight: 700;
  line-height: 1.25;
}
.upload-grid-error-icon {
  font-size: 22px;
}

/* Cellule "ajouter d'autres photos" : 2 boutons côte à côte dans une cellule */
.upload-grid-add {
  aspect-ratio: 1 / 1;
  border-radius: calc(10px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.037);
  border: 2px dashed rgba(var(--encre-rgb), 0.15);
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 1px;
  overflow: hidden;
}

.upload-grid-add-btn {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: rgba(var(--encre-rgb), 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  transition: background 0.15s, color 0.15s;
}
.upload-grid-add-btn:hover {
  background: rgba(var(--encre-rgb), 0.075);
  color: var(--pink);
}

/* Barre de progression d'upload */
.upload-progress {
  margin-top: 14px;
}
.upload-progress-label {
  font-size: 12px;
  color: var(--text-mute);
  margin-bottom: 6px;
}
.upload-progress-bar {
  height: 4px;
  background: rgba(var(--encre-rgb), 0.1);
  border-radius: calc(2px * var(--r-k));
  overflow: hidden;
}
.upload-progress-fill {
  height: 100%;
  background: var(--grad-primary);
  transition: width 0.2s ease;
}

/* ------ Modal imbriqué : résolution de conflit de date ------ */

.modal-scrim-nested {
  z-index: 400; /* au-dessus de .modal-scrim (300) */
  background: rgba(var(--carte-rgb), 0.5);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.modal-sm {
  max-width: 380px;
}

.conflict-choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.conflict-choice {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: calc(10px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.05);
  border: 1.5px solid rgba(var(--encre-rgb), 0.08);
  cursor: pointer;
  text-align: left;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
  color: var(--text);
}
.conflict-choice:hover {
  background: rgba(var(--encre-rgb), 0.1);
  border-color: var(--pink);
  transform: translateY(-1px);
}
.conflict-choice-active {
  border-color: var(--pink);
  background: rgba(var(--tampon-rgb), 0.08);
}

.conflict-choice-icon {
  font-size: 22px;
  flex-shrink: 0;
}

.conflict-choice-body {
  flex: 1;
  min-width: 0;
}

.conflict-choice-label {
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 2px;
}

.conflict-choice-date {
  font-size: 12px;
  color: var(--text-mute);
}


/* ------ Comments (dans PhotoDetail) ------------------------ */

.detail-photo {
  width: 100%;
  /* L'image est GREEDY : flex:1 1 0 + min-height:0 lui fait absorber tout
     l'espace restant après header + body (capé à 40dvh) + footer. Quand le
     body est petit (peu de commentaires), l'image prend ~80-90dvh. Quand le
     body est plein, l'image est réduite mais reste prioritaire.
     object-fit: contain évite la distorsion ; les bandes noires apparaissent
     uniquement si l'aspect image ≠ aspect disponible. */
  flex: 1 1 0;
  min-height: 0;
  object-fit: contain;
  background: var(--carte);
}

.comments-list { padding: 8px 0; }

.comment {
  display: flex;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.comment:last-child { border-bottom: 0; }

.comment-body { flex: 1; min-width: 0; }

.comment-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}

.comment-user { font-weight: 700; font-size: 13px; }

.comment-time { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--text-mute); }

.comment-text { font-size: 14px; line-height: 1.4; color: var(--text); word-wrap: break-word; }

.comment-delete {
  opacity: 0;
  color: var(--text-mute);
  padding: 4px;
  transition: opacity 0.2s, color 0.2s;
}
.comment:hover .comment-delete { opacity: 1; }
.comment-delete:hover { color: var(--danger); }

.comment-input-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.comment-input {
  flex: 1;
  padding: 12px 14px;
  background: rgba(var(--carte-rgb), 0.5);
  border: 1px solid var(--border);
  border-radius: calc(999px * var(--r-k));
  font-size: 14px;
  outline: none;
}
.comment-input:focus { border-color: var(--cyan); box-shadow: 0 0 0 2px rgba(var(--ombre-rgb), 0.083); }

.comment-send {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--grad-primary);
  color: var(--sur-grad);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  transition: all 0.2s;
}
.comment-send:disabled { opacity: 0.4; }
.comment-send:not(:disabled):hover { box-shadow: var(--glow-pink); }


/* ------ CAMERA CAPTURE (viewfinder plein écran) ------------ */

.camera-capture {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--carte);
  /* 100dvh = "dynamic viewport height" : tient compte de la barre du navigateur
     mobile qui apparait/disparait. Sans ça, sur iPhone Safari, le bas est mangé
     par la barre d'URL. */
  height: 100dvh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  /* On NE met PAS de padding safe-area ici : les overlays (header/controls)
     gèrent eux-mêmes leur padding-top/bottom. Sinon ils auraient un fond noir
     en bandes au-dessus/dessous de la vidéo. */
  color: var(--text);
  user-select: none;
  -webkit-user-select: none;
  overflow: hidden;
}

/* En-tête : annuler / compteur / valider — overlay flottant.
   Position absolue pour que la vidéo en-dessous prenne tout l'écran. Le
   gradient noir → transparent assure la lisibilité des boutons sur fond
   variable, sans masquer la composition. */
.camera-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 12px;
  /* Padding-top = safe-area-inset-top pour éviter le notch / dynamic island */
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  background: linear-gradient(to bottom, rgba(var(--carte-rgb), 0.55) 0%, rgba(var(--carte-rgb), 0.2) 60%, rgba(var(--carte-rgb), 0) 100%);
  pointer-events: none; /* le fond gradient n'intercepte pas, seuls les enfants oui */
}
.camera-top > * {
  pointer-events: auto;
}

.camera-top-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(var(--encre-rgb), 0.1);
  color: var(--text);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
}
.camera-top-btn:hover { background: rgba(var(--carte-rgb), 0.6); }

.camera-count {
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 4px rgba(var(--ombre-rgb), 0.3);
}

.camera-top-validate {
  padding: 9px 18px;
  border-radius: calc(22px * var(--r-k));
  background: var(--grad-primary);
  border: 0;
  color: var(--sur-grad);
  font-weight: 800;
  font-size: 14px;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(var(--ombre-rgb), 0.22);
  transition: transform 0.1s, box-shadow 0.15s;
}
.camera-top-validate:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 18px rgba(var(--ombre-rgb), 0.275);
}
.camera-top-validate-disabled {
  background: rgba(var(--encre-rgb), 0.125) !important;
  color: rgba(var(--encre-rgb), 0.4) !important;
  box-shadow: none !important;
  cursor: not-allowed;
}

/* Outils flottants à droite : torch + switch caméra */
.camera-tools {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 70px);
  right: 12px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.camera-tool-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(var(--encre-rgb), 0.12);
  color: rgba(var(--encre-rgb), 0.9);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.camera-tool-btn:hover { background: rgba(var(--carte-rgb), 0.7); color: var(--text); }
.camera-tool-btn-on {
  background: var(--yellow);
  color: var(--encre-2);
  border-color: rgba(var(--encre2-rgb), 0.2);
}
.camera-tool-btn-on:hover {
  background: var(--yellow);
  color: var(--encre-2);
}

/* Viewfinder : prend tout l'espace vertical entre header et contrôles */
/* Viewfinder : prend tout l'écran (les overlays header/strip/controls sont
   par-dessus en position absolute). C'est le pattern des apps natives :
   l'image de la caméra prend l'écran entier, les UI sont des overlays. */
.camera-viewfinder {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  background: var(--carte);
  display: flex;
  align-items: center;
  justify-content: center;
}

.camera-video {
  /* Cadre 5:8 portrait centré façon appareil photo natif (iOS/Android Camera) :
     le frame reste constant, les UI (header, controls) tombent dans les bandes
     noires top/bottom hors du cadre. Capture WYSIWYG strict : ce qui est visible
     dans ce frame = ce qui sera enregistré. */
  aspect-ratio: 5 / 8;
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
  background: var(--carte);
}
/* Miroir pour la caméra avant (selfie) — comportement attendu */
.camera-video-mirrored {
  transform: scaleX(-1);
}

.camera-loading,
.camera-error,
.camera-fallback-overlay {
  text-align: center;
  padding: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

/* Overlay positionné par-dessus la <video> qui est toujours rendue : c'est ce
   qui permet à React de monter le <video> dès le départ tout en affichant
   un état de chargement par-dessus. Sans ça, la vidéo restait noire sur
   certains téléphones (Pixel Android). */
.camera-loading-overlay {
  position: absolute;
  inset: 0;
  background: rgba(var(--carte-rgb), 0.85);
  z-index: 2;
  justify-content: center;
  color: rgba(var(--encre-rgb), 0.85);
}

.camera-fallback-overlay {
  color: rgba(var(--encre-rgb), 0.85);
  max-width: 320px;
}
.camera-fallback-title {
  font-size: 18px;
  font-weight: 800;
}
.camera-fallback-desc {
  font-size: 13px;
  color: rgba(var(--encre-rgb), 0.65);
  line-height: 1.5;
}

.camera-error {
  color: var(--tampon);
  font-weight: 600;
}

/* Flash blanc bref lors de la capture */
.camera-flash-overlay {
  position: absolute;
  inset: 0;
  background: white;
  z-index: 2;
  animation: cameraFlash 0.25s ease-out;
  pointer-events: none;
}@keyframes cameraFlash {
  0%   { opacity: 0.9; }
  100% { opacity: 0; }
}

/* Strip horizontal des vignettes (photos prises pas encore validées) */
/* Strip de vignettes : overlay au-dessus des controls.
   Position absolue, ancrée juste au-dessus du bloc controls. */
.camera-strip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 130px; /* au-dessus du bloc controls (~130px hauteur) */
  z-index: 2;
  display: flex;
  gap: 8px;
  padding: 10px 16px;
  overflow-x: auto;
  scrollbar-width: thin;
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.55) 0%, rgba(var(--carte-rgb), 0) 100%);
}
.camera-strip::-webkit-scrollbar { height: 4px; }
.camera-strip::-webkit-scrollbar-thumb { background: rgba(var(--encre-rgb), 0.14); border-radius: calc(2px * var(--r-k)); }

.camera-strip-item {
  position: relative;
  flex: 0 0 56px;
  height: 56px;
  border-radius: calc(8px * var(--r-k));
  overflow: hidden;
  border: 2px solid rgba(var(--encre-rgb), 0.4);
}
.camera-strip-item img {
  width: 100%; height: 100%;
  object-fit: cover;
}
.camera-strip-remove {
  position: absolute;
  top: 2px; right: 2px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.7);
  color: var(--text);
  border: 0;
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
}
.camera-strip-remove:hover {
  background: rgba(var(--tampon-rgb), 0.9);
}

/* Zone basse : toggle Photo/Vidéo au-dessus, shutter en bas — overlay flottant. */
.camera-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  /* Padding-bottom = safe-area-inset-bottom (home indicator iOS) + marge */
  padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.6) 0%, rgba(var(--carte-rgb), 0.25) 60%, rgba(var(--carte-rgb), 0) 100%);
  pointer-events: none;
}
.camera-controls > * {
  pointer-events: auto;
}

/* Toggle Photo / Vidéo : 2 onglets côte à côte */
.camera-mode-toggle {
  display: flex;
  gap: 4px;
  background: rgba(var(--carte-rgb), 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: calc(22px * var(--r-k));
  padding: 4px;
  border: 1px solid rgba(var(--encre-rgb), 0.1);
}

.camera-mode-btn {
  padding: 7px 18px;
  border-radius: calc(18px * var(--r-k));
  background: transparent;
  border: 0;
  color: rgba(var(--encre-rgb), 0.7);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.camera-mode-btn:hover:not(:disabled) { color: var(--text); }
.camera-mode-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.camera-mode-btn-active {
  background: var(--papier-vif);
  color: var(--encre-2);
}
.camera-mode-btn-active:hover { color: var(--encre-2) !important; }

/* Shutter : rond blanc par défaut (mode photo), rond avec contour rouge en mode vidéo */
.camera-shutter {
  width: 76px; height: 76px;
  border-radius: 50%;
  background: rgba(var(--encre-rgb), 0.14);
  border: 4px solid var(--papier-vif);
  padding: 0;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform 0.08s, background 0.15s, border-color 0.15s;
}
.camera-shutter:hover:not(:disabled) { background: rgba(var(--carte-rgb), 0.3); }
.camera-shutter:active:not(:disabled) { transform: scale(0.93); }
.camera-shutter:disabled { opacity: 0.5; cursor: not-allowed; }

/* Mode vidéo : contour blanc, pastille rouge à l'intérieur */
.camera-shutter-video {
  border-color: var(--text);
}
.camera-shutter-video .camera-shutter-inner {
  background: var(--tampon);
}

/* Mode vidéo + enregistrement en cours : pastille devient un carré rouge */
.camera-shutter-recording .camera-shutter-inner {
  width: 28px; height: 28px;
  border-radius: calc(4px * var(--r-k));
  background: var(--tampon);
  animation: recPulse 1.2s ease-in-out infinite;
}

@keyframes recPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--ombre-rgb), 0.3); }
  50%      { box-shadow: 0 0 0 8px rgba(var(--ombre-rgb), 0); }
}

.camera-shutter-inner {
  width: 60px; height: 60px;
  border-radius: 50%;
  background: var(--papier-vif);
  transition: width 0.18s, height 0.18s, border-radius 0.18s, background 0.18s;
}

/* Indicateur d'enregistrement vidéo : pastille rouge clignotante + chrono */
.camera-rec-indicator {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 70px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: calc(22px * var(--r-k));
  background: rgba(var(--carte-rgb), 0.7);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(var(--tampon-rgb), 0.4);
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  pointer-events: none;
}
.camera-rec-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--tampon);
  animation: recBlink 1s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes recBlink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
.camera-rec-max {
  color: rgba(var(--encre-rgb), 0.6);
  font-size: 11px;
  font-weight: 500;
}

/* Strip : variante vidéo (placeholder avec icône play, car la preview blob:
   d'une vidéo ne s'affiche pas dans un <img>) */
.camera-strip-item-video {
  border-color: rgba(var(--tampon-rgb), 0.6);
}
.camera-strip-video-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--papier), var(--carte));
  color: var(--text);
}

/* ============================================================
   PROFILE PAGE — page profil plein écran
   ============================================================ */

.profile-overlay {
  /* Pas de fond noir derrière car le modal prend toute la fenêtre */
  background: rgba(var(--carte-rgb), 0.96);
}

.profile-page {
  width: 100%;
  max-width: 720px;
  /* Feuille haute : le profil devient lui aussi une feuille plutôt qu'un plein
     écran, mais à 88dvh et non 72dvh — il empile 3 onglets, des sous-onglets et
     une grille de photos, et serait à l'étroit au format standard. C'est le
     seul palier dérogatoire, et il est volontaire : on garde un liseré du feed
     visible en haut pour signaler qu'on est en surcouche. */
  height: auto;
  max-height: 88dvh;
  align-self: end;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  border-top: 1.5px solid var(--encre);
  box-shadow: 0 -6px 24px rgba(var(--ombre-rgb), 0.16);
  display: flex;
  flex-direction: column;
  background: var(--bg);
  overflow-y: auto;
  /* Évite l'effet "modal" — on veut une vraie page plein écran */
  border-radius: 0;
  padding-top: env(safe-area-inset-top);
}

.profile-loading {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Header avec retour */
.profile-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px clamp(8px, 4vw, 18px);
  background: rgba(var(--carte-rgb), 0.85);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border-bottom: 1px solid var(--border);
}

.profile-back {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  background: rgba(var(--encre-rgb), 0.1);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
}
.profile-back:hover {
  background: rgba(var(--encre-rgb), 0.14);
}

.profile-header-title {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(var(--encre-rgb), 0.65);
}

/* Bloc d'identité */
.profile-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 16px 22px;
}

.profile-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--pink), var(--cyan));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  font-weight: 800;
  color: var(--sur-grad);
  letter-spacing: -0.02em;
  box-shadow:
    0 0 0 3px rgba(var(--ombre-rgb), 0.3),
    0 0 0 5px rgba(var(--ombre-rgb), 0.3),
    0 8px 24px rgba(var(--ombre-rgb), 0.193);
}

.profile-name {
  font-size: 22px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.02em;
}

.profile-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: calc(999px * var(--r-k));
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.profile-badge-mod {
  background: linear-gradient(135deg, rgba(var(--bleue-rgb), 0.25), rgba(var(--bleue-rgb), 0.15));
  border: 1px solid rgba(var(--bleue-rgb), 0.4);
  color: rgba(var(--encre-rgb), 0.95);
}

/* Stats : 3 chiffres clés */
.profile-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: rgba(var(--encre-rgb), 0.063);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.profile-stat {
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px 10px;
  gap: 4px;
}

.profile-stat-value {
  font-size: 24px;
  font-weight: 800;
  color: var(--sur-grad);
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--pink), var(--cyan));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.profile-stat-label {
  font-size: 10px;
  font-weight: 600;
  color: rgba(var(--encre-rgb), 0.5);
  letter-spacing: 0.04em;
  text-transform: lowercase;
}

/* Section title */
.profile-section-title {
  padding: 20px 16px 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(var(--encre-rgb), 0.55);
}

/* Grille des photos */
.profile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 0 2px 32px;
}

.profile-grid-cell {
  position: relative;
  aspect-ratio: 1 / 1;
  padding: 0;
  border: 0;
  background: var(--carte);
  cursor: pointer;
  overflow: hidden;
  transition: transform 0.15s;
}
.profile-grid-cell:hover { transform: scale(0.97); z-index: 2; }

.profile-grid-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.profile-grid-cell-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 4px 6px;
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.85), rgba(var(--carte-rgb), 0));
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 9px;
  font-weight: 700;
  color: var(--text);
  pointer-events: none;
}
.profile-grid-cell-overlay span {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.profile-grid-cell-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1.5px solid rgba(var(--encre-rgb), 0.85);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 2px;
  pointer-events: none;
}

.profile-grid-cell-video {
  outline: 1.5px solid rgba(var(--tampon-rgb), 0.4);
  outline-offset: -1.5px;
}

/* État vide */
.profile-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
  gap: 8px;
}
.profile-empty-icon { font-size: 48px; opacity: 0.6; }
.profile-empty-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}
.profile-empty-desc {
  font-size: 13px;
  color: rgba(var(--encre-rgb), 0.55);
  max-width: 280px;
  line-height: 1.5;
}

/* ============================================================
   PHOTODETAIL — header user info cliquable
   ============================================================ */

.modal-header-userinfo {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  flex: 1;
  min-width: 0;
  text-align: left;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 1px;
  border-radius: calc(6px * var(--r-k));
  transition: background 0.15s;
}
.modal-header-userinfo:hover {
  background: rgba(var(--encre-rgb), 0.063);
}

.modal-header-username {
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
}

.modal-header-date {
  font-size: 11px;
  color: var(--text-mute);
  font-family: 'Space Mono', monospace;
}

/* Commentaire : pseudo devient cliquable comme lien */
.comment-user-link {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
  transition: color 0.15s;
}
.comment-user-link:hover {
  color: rgba(var(--tampon-rgb), 0.95);
}

/* ============================================================
   PROFILE EDIT MODAL — modal d'édition pseudo + avatar
   ============================================================ */

.profile-edit-modal {
  max-width: 460px;
  width: min(100%, 460px);
  border-radius: calc(16px * var(--r-k));
  overflow: hidden;
}

.profile-edit-body {
  padding: 18px 18px 6px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Bloc avatar : preview large + actions sur le côté */
.profile-edit-avatar-block {
  display: flex;
  align-items: center;
  gap: 14px;
}

.profile-edit-avatar-preview {
  width: 88px;
  height: 88px;
  font-size: 28px;
  flex-shrink: 0;
  /* Surcharge du .profile-avatar : on garde le gradient et le glow,
     mais avec une taille réduite (la grosse version est sur ProfilePage). */
}
.profile-edit-avatar-preview .profile-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

.profile-edit-avatar-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.profile-edit-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.profile-edit-hint {
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.5);
  line-height: 1.4;
  margin-top: 2px;
}
.profile-edit-hint code {
  background: rgba(var(--encre-rgb), 0.1);
  padding: 1px 5px;
  border-radius: calc(4px * var(--r-k));
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: rgba(var(--encre-rgb), 0.7);
}

.profile-edit-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 18px 18px;
  border-top: 1px solid rgba(var(--encre-rgb), 0.06);
}

/* Bouton "Modifier le profil" sur ProfilePage */
.profile-edit-btn {
  margin-top: 8px;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid rgba(var(--tampon-rgb), 0.35);
  background: rgba(var(--tampon-rgb), 0.1);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  padding: 7px 14px;
  border-radius: calc(999px * var(--r-k));
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.profile-edit-btn:hover {
  background: rgba(var(--tampon-rgb), 0.18);
  border-color: rgba(var(--tampon-rgb), 0.55);
}

/* Image custom dans le grand avatar du ProfilePage */
.profile-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}
.profile-avatar {
  /* On s'assure que le grand avatar peut accueillir une image proprement */
  overflow: hidden;
  position: relative;
}

/* ============================================================
   PHOTO TAGS — Identifications de personnes (Phase 3a)
   ============================================================ */

/* Ligne d'identifications dans PhotoDetail, entre les actions et le caption */
.photo-tags-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  padding: 6px 0 14px;
  font-size: 13px;
  line-height: 1.5;
}

.photo-tags-label {
  color: var(--text-mute);
  font-size: 12px;
  margin-right: 2px;
}

/* Une "pill" pour chaque tag : pseudo cliquable + croix pour retirer.
   Pas de fond visible, juste le texte coloré. */
.photo-tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.photo-tag-name {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 700;
  color: rgba(var(--tampon-rgb), 0.95);
  cursor: pointer;
  transition: color 0.15s;
}
.photo-tag-name:hover {
  color: var(--text);
  text-decoration: underline;
}

.photo-tag-remove {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(var(--encre-rgb), 0.1);
  border: 0;
  padding: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: rgba(var(--encre-rgb), 0.6);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  margin-left: 1px;
}
.photo-tag-remove:hover {
  background: rgba(var(--tampon-rgb), 0.3);
  color: var(--text);
}

.photo-tag-sep {
  color: rgba(var(--encre-rgb), 0.25);
  font-size: 11px;
  margin: 0 2px;
}

/* ============================================================
   TAG PICKER MODAL — sélection d'un utilisateur
   ============================================================ */

.tag-picker-modal {
  max-width: 460px;
  width: min(100%, 460px);
  border-radius: calc(16px * var(--r-k));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 80vh;
}

.tag-picker-search {
  padding: 12px 18px 6px;
  flex: 0 0 auto;
}

.tag-picker-list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 4px 8px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tag-picker-item {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: calc(10px * var(--r-k));
  text-align: left;
  color: inherit;
  cursor: pointer;
  font: inherit;
  transition: background 0.12s;
}
.tag-picker-item:hover:not(:disabled) {
  background: rgba(var(--encre-rgb), 0.075);
}
.tag-picker-item-disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

.tag-picker-item-name {
  flex: 1;
  min-width: 0;
  font-weight: 700;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tag-picker-item-badge {
  font-size: 10px;
  color: rgba(var(--bleue-rgb), 0.85);
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.tag-picker-loading,
.tag-picker-empty {
  padding: 30px 20px;
  text-align: center;
  color: var(--text-mute);
  font-size: 13px;
}
.tag-picker-loading .spinner {
  margin: 0 auto;
}

/* ============================================================
   PROFILE TABS — onglets "Ses moments" / "Identifié sur" (Phase 3b)
   ============================================================ */

.profile-tabs {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0 0 14px;
  padding: 0 4px;
  border-bottom: 1px solid rgba(var(--encre-rgb), 0.08);
  position: sticky;
  /* Reste collé en haut (sous le header sticky du modal) au scroll */
  top: 0;
  background: var(--bg);
  z-index: 5;
}

.profile-tab {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 12px 16px 13px;
  margin-bottom: -1px; /* fait chevaucher la border-bottom du parent */
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: rgba(var(--encre-rgb), 0.55);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
  transition: color 0.15s;
  border-bottom: 2px solid transparent;
}
.profile-tab:hover {
  color: rgba(var(--encre-rgb), 0.85);
}
.profile-tab-active {
  color: var(--text);
  border-bottom-color: rgba(var(--tampon-rgb), 0.95);
}

.profile-tab-count {
  font-size: 11px;
  font-weight: 600;
  color: rgba(var(--encre-rgb), 0.45);
  padding: 2px 7px;
  border-radius: calc(999px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.075);
  letter-spacing: 0.02em;
}
.profile-tab-active .profile-tab-count {
  color: rgba(var(--encre-rgb), 0.95);
  background: rgba(var(--tampon-rgb), 0.25);
}

/* ============================================================
   PROFILE ACTIVITY LIST — timeline likes + commentaires (Phase 3c)
   ============================================================ */

.profile-activity-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.profile-activity-item {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-radius: calc(10px * var(--r-k));
  transition: background 0.12s;
}
.profile-activity-item:hover {
  background: rgba(var(--encre-rgb), 0.063);
}

.profile-activity-icon {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: rgba(var(--tampon-rgb), 0.15);
  color: rgba(var(--tampon-rgb), 0.95);
}
/* Variante visuelle légère pour les commentaires (icône cyan) */
.profile-activity-item:has(.profile-activity-quote) .profile-activity-icon,
.profile-activity-item .profile-activity-icon:last-child {
  /* fallback : pas de :has() support → on garde le style rose par défaut */
}

.profile-activity-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.profile-activity-text {
  font-size: 13px;
  color: rgba(var(--encre-rgb), 0.85);
  line-height: 1.35;
  /* Tronque à 2 lignes pour les longs commentaires */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
.profile-activity-text strong {
  color: var(--text);
  font-weight: 700;
}

.profile-activity-quote {
  color: rgba(var(--encre-rgb), 0.55);
  font-style: italic;
}

.profile-activity-time {
  font-size: 10px;
  color: rgba(var(--encre-rgb), 0.4);
  letter-spacing: 0.04em;
}

.profile-activity-thumb {
  width: 44px;
  height: 44px;
  border-radius: calc(8px * var(--r-k));
  overflow: hidden;
  flex-shrink: 0;
  background: rgba(var(--encre-rgb), 0.05);
  position: relative;
}
.profile-activity-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.profile-activity-thumb-badge {
  position: absolute;
  bottom: 3px;
  right: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(var(--carte-rgb), 0.7);
  display: grid;
  place-items: center;
  color: var(--text);
}

/* ============================================================
   PROFILE EDIT TOGGLE — switch "Activité publique" (Phase 3d)
   ============================================================ */

/* Wrapper qui rend toute la ligne (texte + switch) cliquable */
.profile-edit-toggle {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  background: rgba(var(--encre-rgb), 0.037);
  border: 1px solid rgba(var(--encre-rgb), 0.08);
  border-radius: calc(10px * var(--r-k));
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  position: relative;
}
.profile-edit-toggle:hover {
  background: rgba(var(--encre-rgb), 0.063);
}

.profile-edit-toggle-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.profile-edit-toggle-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}

.profile-edit-toggle-desc {
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.55);
  line-height: 1.4;
}

/* L'input réel est masqué mais reste accessible (clavier/lecteur d'écran) */
.profile-edit-toggle-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Switch visuel : rond qui glisse à droite quand coché */
.profile-edit-toggle-switch {
  flex-shrink: 0;
  width: 40px;
  height: 22px;
  border-radius: calc(999px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.14);
  position: relative;
  transition: background 0.18s;
}
.profile-edit-toggle-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--papier-vif);
  transition: transform 0.18s cubic-bezier(0.22, 1, 0.36, 1);
  box-shadow: 0 2px 6px rgba(var(--ombre-rgb), 0.22);
}
.profile-edit-toggle-input:checked + .profile-edit-toggle-switch {
  background: rgba(var(--tampon-rgb), 0.85);
}
.profile-edit-toggle-input:checked + .profile-edit-toggle-switch::after {
  transform: translateX(18px);
}
.profile-edit-toggle-input:focus-visible + .profile-edit-toggle-switch {
  outline: 2px solid rgba(var(--tampon-rgb), 0.6);
  outline-offset: 2px;
}

/* ============================================================
   PHOTO DETAIL — variante annonce (Phase 4a)
   ============================================================ */

/* Icône étoile dorée à la place de l'avatar pour les annonces */
.modal-announcement-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--jaune), var(--tampon));
  color: var(--encre-2);
  font-weight: 900;
  font-size: 15px;
  box-shadow:  0 1px 5px rgba(var(--ombre-rgb), 0.248);
}

/* Variante du userinfo : bloc statique non-cliquable pour annonces */
.modal-header-userinfo-static {
  cursor: default;
}
.modal-header-userinfo-static:hover {
  background: transparent;
}

/* Titre de l'annonce dans PhotoDetail (en gros sous l'image) */
.post-announcement-title {
  font-family: 'Figtree', sans-serif;
  font-weight: 900;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--text);
  padding: 6px 0 10px;
  /* Petit accent doré à gauche */
  border-left: 3px solid rgba(var(--jaune-rgb), 0.85);
  padding-left: 12px;
  margin-bottom: 6px;
  /* Préserve les retours à la ligne saisis par le modérateur dans le titre */
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* ============================================================
   ANNOUNCEMENT CREATOR — preview image dans le panneau mod
   ============================================================ */

.announcement-image-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.announcement-image-preview {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  background: rgba(var(--encre-rgb), 0.037);
  border: 1px solid rgba(var(--encre-rgb), 0.08);
  border-radius: calc(10px * var(--r-k));
}
.announcement-image-preview img {
  width: 100%;
  max-height: 200px;
  object-fit: cover;
  border-radius: calc(6px * var(--r-k));
  display: block;
}

/* ============================================================
   STORIES VIEWER — affichage immersif annonces (Phase 4 — story mode)
   ============================================================ */

.stories-viewer {
  /* Plein écran. On utilise position absolute pour être dans le flow du
     feed (pas un overlay fixed), parce que le viewer remplace la grille
     quand le filtre Annonces est actif. */
  position: relative;
  flex: 1 1 auto;
  width: 100%;
  background: var(--carte);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  user-select: none;
  -webkit-user-select: none;
  /* Empêche le bounce iOS qui interfère avec le swipe */
  touch-action: pan-y;
}

/* Barres de progression en haut — une par story */
.stories-progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  gap: 4px;
  padding: 12px 14px 8px;
  pointer-events: none;
}

.stories-progress-bar {
  flex: 1 1 auto;
  height: 2.5px;
  background: rgba(var(--encre-rgb), 0.14);
  border-radius: calc(2px * var(--r-k));
  transition: background 0.25s;
}
.stories-progress-bar-seen {
  background: rgba(var(--carte-rgb), 0.75);
}
.stories-progress-bar-current {
  background: rgba(var(--jaune-rgb), 0.95);
  box-shadow:  0 1px 3px rgba(var(--ombre-rgb), 0.3);
}

/* Header en haut : icône + titre + bouton fermer */
.stories-header {
  position: absolute;
  top: 22px;
  left: 0;
  right: 0;
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 14px;
  pointer-events: none;
}

.stories-header-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--jaune), var(--tampon));
  color: var(--encre-2);
  font-weight: 900;
  font-size: 15px;
  box-shadow:  0 1px 5px rgba(var(--ombre-rgb), 0.248);
}

.stories-header-title {
  flex: 1;
  font-size: 14px;
  font-weight: 800;
  color: var(--text);
  text-shadow: 0 1px 4px rgba(var(--ombre-rgb), 0.3);
}
.stories-header-count {
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.6);
  margin-left: 6px;
  font-weight: 600;
}

.stories-close {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(var(--carte-rgb), 0.35);
  border: 0;
  color: var(--text);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  pointer-events: auto; /* override du parent qui désactive les events */
  transition: background 0.15s;
}
.stories-close:hover {
  background: rgba(var(--carte-rgb), 0.55);
}

/* Image plein écran avec dégradés haut/bas pour la lisibilité */
.stories-media {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.stories-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.stories-gradient-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 120px;
  background: linear-gradient(to bottom, rgba(var(--carte-rgb), 0.65), transparent);
  pointer-events: none;
}
.stories-gradient-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 50%;
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.85) 0%, rgba(var(--carte-rgb), 0.45) 50%, transparent 100%);
  pointer-events: none;
}

/* Zones tactiles invisibles pour la navigation tap.
   Couvrent toute la hauteur sauf le contenu textuel en bas. */
.stories-nav-zone {
  position: absolute;
  top: 60px; /* sous les barres de progression et le header */
  bottom: 220px; /* au-dessus du contenu textuel */
  z-index: 3;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.stories-nav-zone:disabled {
  cursor: not-allowed;
}
.stories-nav-zone-left  { left: 0;  width: 33%; }
.stories-nav-zone-right { right: 0; width: 67%; }

/* Contenu textuel en bas par-dessus l'image */
/* Container du bloc texte overlay. Par défaut ancré en bas (position
   classique des stories) mais peut être déplacé en haut/centre via
   les classes -pos-* (Phase 4c). */
/* Bloc texte stylable : titre + message, positionnable selon announcement_style.
   Occupe l'espace entre le header et la bottom-bar. Le justify-content gère
   la position verticale (top/center/bottom). */
.stories-text-block {
  position: absolute;
  left: 0;
  right: 0;
  top: 60px;        /* sous progress bars + header */
  bottom: 200px;    /* au-dessus de la bottom-bar (date + boutons + détails) */
  z-index: 5;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
}

/* Position verticale du bloc texte */
.stories-text-block-pos-top    { justify-content: flex-start; }
.stories-text-block-pos-center { justify-content: center; }
.stories-text-block-pos-bottom { justify-content: flex-end; }

/* Alignement horizontal du texte (titre + message) */
.stories-text-block-align-left  .stories-title,
.stories-text-block-align-left  .stories-message {
  text-align: left;
}
.stories-text-block-align-center .stories-title,
.stories-text-block-align-center .stories-message {
  text-align: center;
}
.stories-text-block-align-right  .stories-title,
.stories-text-block-align-right  .stories-message {
  text-align: right;
}
/* Le badge "Terminé" suit aussi l'alignement */
.stories-text-block-align-left  .stories-past-badge { align-self: flex-start; }
.stories-text-block-align-center .stories-past-badge { align-self: center; }
.stories-text-block-align-right  .stories-past-badge { align-self: flex-end; }

/* Barre d'actions fixée en bas (toujours visible quel que soit le positionnement
   du texte). Contient date/likes/comments + bouton "Voir détails". */
.stories-bottom-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  padding: 16px 20px calc(20px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  /* Léger fond noir pour garantir la lisibilité quel que soit le contenu */
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.85) 0%, rgba(var(--carte-rgb), 0.45) 60%, transparent 100%);
}

.stories-past-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 3px 9px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(var(--encre-rgb), 0.85);
  background: rgba(var(--carte-rgb), 0.55);
  border: 1px solid rgba(var(--encre-rgb), 0.25);
  border-radius: calc(999px * var(--r-k));
  pointer-events: auto;
}

.stories-title {
  font-family: 'Figtree', sans-serif;
  font-weight: 900;
  font-size: 26px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
  text-shadow: 0 2px 14px rgba(var(--ombre-rgb), 0.3);
  white-space: pre-wrap;
  word-wrap: break-word;
  pointer-events: auto;
}

.stories-message {
  font-size: 15px;
  line-height: 1.5;
  color: rgba(var(--encre-rgb), 0.92);
  text-shadow: 0 1px 8px rgba(var(--ombre-rgb), 0.3);
  white-space: pre-wrap;
  word-wrap: break-word;
  pointer-events: auto;
  /* Limite à 5 lignes pour ne pas envahir l'écran. Le user peut ouvrir
     les détails pour tout lire. */
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.stories-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 4px;
  pointer-events: auto;
}

.stories-meta-date {
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.7);
  text-shadow: 0 1px 4px rgba(var(--ombre-rgb), 0.3);
}

.stories-meta-actions {
  display: flex;
  gap: 8px;
}

.stories-meta-btn {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 12px;
  background: rgba(var(--carte-rgb), 0.55);
  border: 1px solid rgba(var(--encre-rgb), 0.15);
  border-radius: calc(999px * var(--r-k));
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.stories-meta-btn:hover {
  background: rgba(var(--carte-rgb), 0.75);
  border-color: rgba(var(--encre-rgb), 0.3);
}
.stories-meta-btn-liked {
  color: rgba(var(--tampon-rgb), 0.95);
  border-color: rgba(var(--tampon-rgb), 0.5);
}

.stories-details-btn {
  appearance: none;
  -webkit-appearance: none;
  padding: 11px 16px;
  background: rgba(var(--jaune-rgb), 0.92);
  border: 0;
  border-radius: calc(12px * var(--r-k));
  color: var(--encre-2);
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  pointer-events: auto;
  transition: filter 0.15s;
  box-shadow: 0 4px 16px rgba(var(--ombre-rgb), 0.165);
  letter-spacing: 0.01em;
}
.stories-details-btn:hover {
  filter: brightness(1.08);
}

/* État vide quand pas d'annonces */
.stories-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
  color: var(--text-mute);
}
.stories-empty-icon {
  font-size: 56px;
  margin-bottom: 16px;
  opacity: 0.7;
}
.stories-empty-title {
  font-size: 16px;
  font-weight: 700;
  color: rgba(var(--encre-rgb), 0.85);
  margin-bottom: 6px;
}
.stories-empty-desc {
  font-size: 13px;
  color: rgba(var(--encre-rgb), 0.5);
  max-width: 320px;
  line-height: 1.45;
}

/* ============================================================
   STORIES BLOCKS — rendu des blocs de texte indépendants (Phase 4c.1)
   ============================================================ */

/* Chaque bloc est positionné absolument en % par-dessus l'image.
   On centre via translate(-50%, -50%) sur le point (xPct, yPct).
   La taille et la couleur sont définies en inline style. */
.stories-block {
  position: absolute;
  z-index: 5;
  font-family: 'Figtree', sans-serif;
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 14px rgba(var(--ombre-rgb), 0.3), 0 0 6px rgba(var(--ombre-rgb), 0.275);
  white-space: pre-wrap;
  word-wrap: break-word;
  max-width: 85%;
  pointer-events: none; /* laisse passer les taps de navigation */
}

/* Le badge "Terminé" reste en haut à gauche (indépendant des blocs) */
.stories-past-badge {
  position: absolute;
  top: 60px;
  left: 16px;
  z-index: 6;
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: rgba(var(--encre-rgb), 0.9);
  background: rgba(var(--carte-rgb), 0.6);
  border: 1px solid rgba(var(--encre-rgb), 0.25);
  border-radius: calc(999px * var(--r-k));
}

/* Le bloc "extra" dans PhotoDetail (= les blocs au-delà du 1er) */
.post-announcement-extra {
  font-size: 14px;
  line-height: 1.5;
  color: rgba(var(--encre-rgb), 0.85);
  padding: 0 0 12px 12px;
  border-left: 2px solid rgba(var(--jaune-rgb), 0.4);
  margin-bottom: 4px;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* ============================================================
   STORIES BLOCK COUNTDOWN — style spécifique des blocs countdown (Phase 4d)
   ============================================================ */

/* Les countdowns utilisent une police monospace pour éviter le sautillement
   des chiffres + un effet de lueur dorée. */
.stories-block-countdown {
  font-family: 'Space Mono', 'Menlo', monospace !important;
  font-weight: 800;
  letter-spacing: 0.02em;
  /* Glow doré subtil pour distinguer du texte normal */
  filter: drop-shadow(0 0 12px rgba(var(--encre-rgb), 0.22));
}

/* ============================================================
   PHOTODETAIL — rendu countdown dans la liste des blocs (Phase 4d.5)
   ============================================================ */

.post-announcement-countdown {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  margin: 0 0 10px;
  background: rgba(var(--jaune-rgb), 0.06);
  border: 1px solid rgba(var(--jaune-rgb), 0.25);
  border-radius: calc(10px * var(--r-k));
}

.post-announcement-countdown-icon {
  font-size: 22px;
  line-height: 1;
  filter: drop-shadow(0 0 6px rgba(var(--ombre-rgb), 0.22));
  flex-shrink: 0;
}

.post-announcement-countdown-body {
  flex: 1;
  min-width: 0;
}

.post-announcement-countdown-value {
  font-size: 18px;
  font-weight: 800;
  color: rgba(var(--jaune-rgb), 0.95);
  letter-spacing: 0.02em;
  line-height: 1.2;
}

.post-announcement-countdown-target {
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.55);
  letter-spacing: 0.05em;
  margin-top: 2px;
}

/* ============================================================
   DETAIL ANNOUNCEMENT MEDIA — image + blocs sur image (Phase 4d.6)
   ============================================================ */

/* Conteneur 9:16 cohérent avec story/feed/édition. Largeur prend toute la
   modal, hauteur déduite par aspect-ratio. */
.detail-ann-media {
  position: relative;
  width: 100%;
  aspect-ratio: 9 / 16;
  /* Greedy comme .detail-photo : flex:1 1 0 absorbe l'espace restant après
     header + body + footer. L'aspect-ratio 9:16 est respecté : si la largeur
     du modal donne une hauteur supérieure à l'espace dispo, le conteneur
     se rétrécit en largeur pour rester en 9:16 (bandes latérales). */
  flex: 1 1 0;
  min-height: 0;
  background: var(--carte);
  overflow: hidden;
  margin: 0 auto;
  max-width: 100%;
  border-radius: 0;
  /* Centrer horizontalement la frame dans la modal si l'aspect-ratio fait
     que la hauteur est limitée par max-height (donc largeur réduite). */
  margin: 0 auto;
}

.detail-ann-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.detail-ann-gradient {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 30%;
  background: linear-gradient(to top, rgba(var(--carte-rgb), 0.65), transparent);
  pointer-events: none;
  z-index: 2;
}

/* Blocs positionnés en %. Même style que ann-card-block/stories-block pour
   cohérence visuelle complète. */
.detail-ann-block {
  position: absolute;
  z-index: 3;
  font-family: 'Figtree', sans-serif;
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 14px rgba(var(--ombre-rgb), 0.3), 0 0 6px rgba(var(--ombre-rgb), 0.275);
  white-space: pre-wrap;
  word-wrap: break-word;
  max-width: 85%;
  pointer-events: none;
}

/* ===========================================================
   CROP / ROTATE EDITOR
   =========================================================== */

.crop-editor-overlay {
  position: fixed;
  inset: 0;
  z-index: 250;
  background: var(--carte);
  display: flex;
  flex-direction: column;
  animation: fadeIn 0.15s;
}

.crop-editor-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  padding-top: max(10px, env(safe-area-inset-top));
  background: rgba(var(--carte-rgb), 0.6);
}

.crop-editor-topbtn {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(var(--encre-rgb), 0.125);
  border: 0;
  color: var(--text);
  width: 36px;
  height: 36px;
  border-radius: calc(999px * var(--r-k));
  display: grid;
  place-items: center;
  cursor: pointer;
}

.crop-editor-title {
  flex: 1;
  color: var(--text);
  font-family: 'Figtree', sans-serif;
  font-weight: 700;
  font-size: 16px;
  text-align: center;
}

.crop-editor-save-btn {
  appearance: none;
  -webkit-appearance: none;
  background: var(--yellow);
  color: var(--encre-2);
  border: 0;
  padding: 8px 16px;
  border-radius: calc(999px * var(--r-k));
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

.crop-editor-stage {
  flex: 1;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: 16px;
}

/* Image-frame : wrapper centré dans le stage, aspect-ratio dynamique pour
   matcher l'image (post-rotation). C'est le système de coordonnées pour le
   rectangle de crop overlay.
   container-type: size permet aux unités cqw/cqh sur les enfants de
   référencer les dimensions de la frame (utile quand on swap width/height
   pour la rotation 90°/270°). */
.crop-editor-image-frame {
  position: relative;
  width: min(100%, 90vh);
  max-width: 100%;
  max-height: 100%;
  background: var(--carte);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  container-type: size;
}

/* Image affichée par-dessus la frame. Centrée via top/left 50% + translate.
   Pour rotation 0/180 : width/height 100% du frame.
   Pour rotation 90/270 (classe -side) : on inverse les dimensions via
   cqw/cqh pour qu'après rotation l'image remplisse exactement la frame. */
.crop-editor-image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  transform-origin: 50% 50%;
}
.crop-editor-image-side {
  width: 100cqh;
  height: 100cqw;
}

/* Rectangle de sélection draggable. Le shadow inset noir simule le masque
   sombre sur le reste de l'image (technique du "trou" via box-shadow). */
.crop-editor-rect {
  position: absolute;
  border: 2px solid var(--text);
  box-shadow: 0 0 0 9999px rgba(var(--ombre-rgb), 0.3);
  cursor: move;
  touch-action: none;
}

/* Poignées aux 4 coins du rect — petites pastilles draggables pour resize */
.crop-editor-handle {
  position: absolute;
  width: 18px;
  height: 18px;
  background: var(--carte);
  border-radius: 50%;
  border: 2px solid var(--yellow);
  cursor: nwse-resize;
  touch-action: none;
}
.crop-editor-handle-tl { left: -9px;  top: -9px;    cursor: nwse-resize; }
.crop-editor-handle-tr { right: -9px; top: -9px;    cursor: nesw-resize; }
.crop-editor-handle-bl { left: -9px;  bottom: -9px; cursor: nesw-resize; }
.crop-editor-handle-br { right: -9px; bottom: -9px; cursor: nwse-resize; }

/* Grille rule-of-thirds à l'intérieur du rect (visuel d'aide au cadrage) */
.crop-editor-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.crop-editor-grid-v,
.crop-editor-grid-h {
  position: absolute;
  background: rgba(var(--carte-rgb), 0.35);
}
.crop-editor-grid-v {
  top: 0; bottom: 0;
  width: 1px;
}
.crop-editor-grid-v:nth-of-type(1) { left: 33.33%; }
.crop-editor-grid-v:nth-of-type(2) { left: 66.66%; }
.crop-editor-grid-h {
  left: 0; right: 0;
  height: 1px;
}
.crop-editor-grid-h:nth-of-type(3) { top: 33.33%; }
.crop-editor-grid-h:nth-of-type(4) { top: 66.66%; }

.crop-editor-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: rgba(var(--carte-rgb), 0.6);
}

.crop-editor-tool-btn {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(var(--encre-rgb), 0.1);
  border: 1px solid rgba(var(--encre-rgb), 0.12);
  color: var(--text);
  padding: 8px 12px;
  border-radius: calc(8px * var(--r-k));
  font-size: 12px;
  font-family: 'Space Mono', monospace;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.crop-editor-tool-btn:hover { background: rgba(var(--encre-rgb), 0.14); }

.crop-editor-tool-spacer { flex: 1; }

.crop-editor-hint {
  text-align: center;
  font-size: 11px;
  color: rgba(var(--encre-rgb), 0.5);
  padding: 6px 0;
  padding-bottom: max(6px, env(safe-area-inset-bottom));
}

/* Bouton recadrer dans la grille d'upload — placé en haut, à gauche de la
   croix de suppression. Mis en évidence (doré) si la photo est paysage ET
   pas encore recadrée (needsCropAttention). Subtilement coloré quand un
   crop/rotation a déjà été défini. */
.upload-grid-crop {
  appearance: none;
  -webkit-appearance: none;
  position: absolute;
  top: 6px;
  right: 32px;
  width: 22px;
  height: 22px;
  border-radius: calc(999px * var(--r-k));
  background: rgba(var(--carte-rgb), 0.6);
  color: var(--text);
  border: 1px solid rgba(var(--encre-rgb), 0.2);
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  z-index: 2;
}
.upload-grid-crop:hover { background: rgba(var(--carte-rgb), 0.8); }

/* Variante : un crop a été défini → indique visuellement que l'item est calé. */
.upload-grid-crop-set {
  background: rgba(var(--bleue-rgb), 0.85);
  color: var(--encre-2);
  border-color: rgba(var(--bleue-rgb), 0.95);
}

/* Variante : paysage sans crop → on attire l'œil en doré pulsé. */
.upload-grid-crop-attention {
  background: var(--yellow);
  color: var(--encre-2);
  border-color: var(--yellow);
  animation: cropPulse 1.8s ease-in-out infinite;
}
@keyframes cropPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--ombre-rgb), 0.3); }
  50%      { box-shadow: 0 0 0 4px rgba(var(--ombre-rgb), 0); }
}

/* ===========================================================
   MODE RAFALE / GIF (Phase 6)
   =========================================================== */

/* Indicateur "RAFALE 5/15" affiché en bas-centre pendant la capture rafale */
.camera-burst-indicator {
  position: absolute;
  bottom: 180px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(var(--tampon-rgb), 0.95);
  color: var(--sur-accent);
  padding: 6px 14px;
  border-radius: calc(999px * var(--r-k));
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  z-index: 4;
  box-shadow: 0 4px 12px rgba(var(--ombre-rgb), 0.22);
  pointer-events: none;
  animation: burstIndicatorPulse 1s ease-in-out infinite;
}
.camera-burst-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--carte);
  animation: burstDotBlink 0.5s ease-in-out infinite;
}
@keyframes burstIndicatorPulse {
  0%, 100% { box-shadow: 0 4px 12px rgba(var(--ombre-rgb), 0.22); }
  50%      { box-shadow: 0 4px 20px rgba(var(--ombre-rgb), 0.3); }
}
@keyframes burstDotBlink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}

/* Shutter pendant la rafale : couleur rose pulsée */
.camera-shutter-burst .camera-shutter-inner {
  background: var(--pink) !important;
  animation: burstShutterPulse 0.6s ease-in-out infinite;
}
@keyframes burstShutterPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(0.85); }
}

/* ----- Burst Review Modal ----- */

.burst-review-overlay {
  position: fixed;
  inset: 0;
  z-index: 260;
  background: var(--carte);
  display: flex;
  flex-direction: column;
  animation: fadeIn 0.15s;
}

.burst-review-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  padding-top: max(10px, env(safe-area-inset-top));
  background: rgba(var(--carte-rgb), 0.6);
  border-bottom: 1px solid var(--border);
}

.burst-review-topbtn {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(var(--encre-rgb), 0.125);
  border: 0;
  color: var(--text);
  width: 36px;
  height: 36px;
  border-radius: calc(999px * var(--r-k));
  display: grid;
  place-items: center;
  cursor: pointer;
}

.burst-review-title {
  flex: 1;
  color: var(--text);
  font-family: 'Figtree', sans-serif;
  font-weight: 700;
  font-size: 16px;
  text-align: center;
}

.burst-review-validate-btn {
  appearance: none;
  -webkit-appearance: none;
  background: var(--yellow);
  color: var(--encre-2);
  border: 0;
  padding: 8px 14px;
  border-radius: calc(999px * var(--r-k));
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
}
.burst-review-validate-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.burst-review-hint {
  text-align: center;
  padding: 10px 16px;
  color: rgba(var(--encre-rgb), 0.55);
  font-size: 11px;
}

.burst-review-grid {
  flex: 1;
  overflow-y: auto;
  padding: 8px 16px 24px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  align-content: start;
}

.burst-review-thumb {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  aspect-ratio: 1 / 1;
  border: 2px solid var(--yellow);
  background: var(--carte);
  border-radius: calc(8px * var(--r-k));
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  transition: opacity 0.15s, border-color 0.15s;
}
.burst-review-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.burst-review-thumb-num {
  position: absolute;
  top: 4px;
  left: 4px;
  background: rgba(var(--carte-rgb), 0.7);
  color: var(--text);
  padding: 2px 6px;
  border-radius: calc(999px * var(--r-k));
  font-size: 10px;
}
.burst-review-thumb-x {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(var(--carte-rgb), 0.55);
  color: var(--text);
}
.burst-review-thumb-discarded {
  opacity: 0.5;
  border-color: rgba(var(--encre-rgb), 0.2);
}

.burst-review-encoding-overlay {
  position: absolute;
  inset: 0;
  background: rgba(var(--carte-rgb), 0.8);
  display: grid;
  place-items: center;
  gap: 16px;
  z-index: 10;
  color: var(--text);
}
.burst-review-encoding-text {
  margin-top: 12px;
  font-size: 13px;
  color: rgba(var(--encre-rgb), 0.8);
}

/* Aperçu live du GIF dans la review modal : <img> qui cycle entre les
   frames retenues à BURST_FPS_OUTPUT (= 5 fps). Affiche exactement ce
   que le .gif final donnera. */
.burst-review-preview {
  position: relative;
  margin: 0 16px 8px;
  background: var(--carte);
  border-radius: calc(8px * var(--r-k));
  overflow: hidden;
  max-height: 35vh;
  display: grid;
  place-items: center;
}
.burst-review-preview-img {
  max-width: 100%;
  max-height: 35vh;
  display: block;
  object-fit: contain;
}
.burst-review-preview-label {
  position: absolute;
  top: 6px;
  right: 8px;
  background: rgba(var(--carte-rgb), 0.65);
  color: var(--text);
  padding: 3px 8px;
  border-radius: calc(999px * var(--r-k));
  font-size: 10px;
  pointer-events: none;
}

/* ===========================================================
   FAILED UPLOADS MODAL (queue de retry IndexedDB)
   =========================================================== */
.failed-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.failed-item {
  display: flex;
  gap: 10px;
  padding: 10px;
  background: rgba(var(--encre-rgb), 0.037);
  border: 1px solid rgba(var(--encre-rgb), 0.08);
  border-radius: calc(8px * var(--r-k));
  align-items: center;
}
.failed-item-thumb {
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  border-radius: calc(6px * var(--r-k));
  overflow: hidden;
  background: var(--carte);
  display: grid;
  place-items: center;
}
.failed-item-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.failed-item-thumb-placeholder {
  font-size: 24px;
  color: rgba(var(--encre-rgb), 0.4);
}
.failed-item-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.failed-item-meta {
  font-size: 11px;
  color: var(--text-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.failed-item-caption {
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.failed-item-error {
  font-size: 10px;
  color: rgba(var(--tampon-rgb), 0.85);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.failed-item-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 0 0 auto;
}

/* =============================================================
   MULTI-EVENT — NoEventScreen / Switcher / Share / Modals
   ============================================================= */

/* ---- NoEventScreen --------------------------------------------- */
.no-event-splash { gap: 22px; }
.no-event-card {
  display: flex; flex-direction: column; align-items: center;
  gap: 16px; max-width: 360px; padding: 24px;
  background: var(--bg-1, var(--carte));
  border-radius: var(--r-xl);
  border: 1px solid rgba(var(--encre-rgb), 0.08);
}
.no-event-title { font-size: 18px; font-weight: 600; }
.no-event-sub  { font-size: 14px; color: var(--text-mute); text-align: center; line-height: 1.5; }
.no-event-actions { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.no-event-actions .btn { width: 100%; }
.no-event-logout { margin-top: 6px; font-size: 12px; opacity: 0.7; }

/* ---- EventSwitcher (header) ----------------------------------- */
.header-title-row {
  display: flex; align-items: center; gap: 6px;
  min-width: 0;
}
.event-switcher { position: relative; flex: 0 0 auto; }
.event-switcher-trigger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border: none; background: rgba(var(--encre-rgb), 0.075);
  border-radius: 50%; color: var(--text-mute);
  cursor: pointer; padding: 0;
}
.event-switcher-trigger:hover { background: rgba(var(--encre-rgb), 0.14); color: var(--text); }
.event-switcher-menu {
  position: absolute; top: calc(100% + 6px); right: 0;
  min-width: 240px; max-width: 86vw;
  background: var(--bg-1, var(--carte));
  border: 1px solid rgba(var(--encre-rgb), 0.1);
  border-radius: var(--r-md);
  box-shadow: 0 12px 36px rgba(var(--ombre-rgb), 0.3);
  padding: 6px;
  z-index: 200;
}
.event-switcher-section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-mute); padding: 6px 10px 4px;
}
.event-switcher-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 9px 10px;
  background: transparent; border: none; color: inherit;
  text-align: left; cursor: pointer; border-radius: calc(6px * var(--r-k));
  font-size: 14px;
}
.event-switcher-item:hover { background: rgba(var(--encre-rgb), 0.075); }
.event-switcher-item-active { background: rgba(var(--tampon-rgb), 0.12); }
.event-switcher-item-active .event-switcher-item-name { color: var(--pink); font-weight: 600; }
.event-switcher-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.event-switcher-item-role {
  font-size: 10px; color: var(--text-mute); text-transform: uppercase;
  padding: 2px 6px; border-radius: calc(4px * var(--r-k)); background: rgba(var(--encre-rgb), 0.075);
  flex: 0 0 auto;
}
.event-switcher-separator {
  height: 1px; background: rgba(var(--encre-rgb), 0.1);
  margin: 6px 4px;
}
.event-switcher-action {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 9px 10px;
  background: transparent; border: none; color: inherit;
  text-align: left; cursor: pointer; border-radius: calc(6px * var(--r-k));
  font-size: 14px;
}
.event-switcher-action:hover { background: rgba(var(--encre-rgb), 0.075); }

/* ---- Join code input ------------------------------------------ */
.join-help { font-size: 13px; color: var(--text-mute); margin: 0 0 12px; line-height: 1.5; }
.join-code-input {
  font-size: 28px; letter-spacing: 0.4em;
  text-align: center; text-transform: uppercase;
  padding: 14px 8px;
}

/* ---- EventShareModal (QR) ------------------------------------- */
.event-share-body {
  display: flex; flex-direction: column; align-items: center;
  gap: 14px; padding-top: 8px;
}
.event-qr-wrap {
  background: var(--carte); padding: 12px;
  border-radius: var(--r-md);
  display: flex; align-items: center; justify-content: center;
}
.event-qr-canvas { display: block; }
.event-qr-fallback {
  background: var(--carte); color: var(--encre-2);
  padding: 18px; border-radius: var(--r-md);
  word-break: break-all; font-size: 12px;
}
.event-share-code {
  font-size: 26px; letter-spacing: 0.3em;
  padding: 10px 18px;
  background: rgba(var(--encre-rgb), 0.075);
  border: 1px solid rgba(var(--encre-rgb), 0.12);
  border-radius: var(--r-md);
  color: var(--text); cursor: pointer;
}
.event-share-code:hover { background: rgba(var(--encre-rgb), 0.125); }
.event-share-hint { font-size: 12px; color: var(--text-mute); text-align: center; margin: 0; }

/* ---- ProfileEventsBlock (section "Mes événements" dans le profil) --- */
.profile-events-block {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px; margin: 12px 16px;
  background: rgba(var(--encre-rgb), 0.05);
  border: 1px solid rgba(var(--encre-rgb), 0.08);
  border-radius: var(--r-md);
}
.profile-events-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute);
}
.profile-events-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.profile-event-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 10px 12px;
  background: rgba(var(--encre-rgb), 0.037);
  border: 1px solid rgba(var(--encre-rgb), 0.06);
  border-radius: calc(8px * var(--r-k));
  color: inherit; cursor: pointer; text-align: left;
}
.profile-event-row:hover { background: rgba(var(--encre-rgb), 0.088); }
.profile-event-row-active {
  border-color: var(--pink);
  background: rgba(var(--tampon-rgb), 0.1);
}
.profile-event-row-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-event-row-name {
  font-size: 14px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.profile-event-row-meta { font-size: 11px; color: var(--text-mute); text-transform: uppercase; }
.profile-event-row-active-badge {
  font-size: 10px; letter-spacing: 0.1em; font-weight: 700;
  color: var(--pink);
  padding: 2px 8px; border-radius: calc(4px * var(--r-k));
  background: rgba(var(--tampon-rgb), 0.18);
  flex: 0 0 auto;
}
.profile-events-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.profile-events-actions .btn { flex: 1 1 auto; font-size: 13px; }

/* ---- AuthScreen : acceptation CGU + liens en bas ----------- */
.auth-terms {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 12px; line-height: 1.5;
  color: var(--text-mute);
  margin: 8px 0 2px;
  cursor: pointer;
}
.auth-terms input[type="checkbox"] {
  flex: 0 0 auto;
  margin-top: 2px;
  accent-color: var(--pink);
  width: 16px; height: 16px;
}
.auth-legal-links { margin-top: 14px; justify-content: center; }

.legal-links {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; font-size: 11px; color: var(--text-mute);
}
.legal-link {
  background: none; border: none; padding: 0;
  color: var(--text-mute); cursor: pointer;
  text-decoration: underline;
  font: inherit;
}
.legal-link:hover { color: var(--pink); }
.legal-links-sep { opacity: 0.5; }

/* ---- LegalModal -------------------------------------------- */
.legal-modal { max-width: 640px; }
.legal-modal-tabs {
  display: flex; gap: 4px;
  padding: 0 12px 8px;
  overflow-x: auto;
  scrollbar-width: thin;
  border-bottom: 1px solid rgba(var(--encre-rgb), 0.08);
}
.legal-modal-tab {
  background: transparent; border: none;
  padding: 7px 10px; border-radius: calc(6px * var(--r-k));
  color: var(--text-mute); cursor: pointer;
  font-size: 12px; white-space: nowrap;
  flex: 0 0 auto;
}
.legal-modal-tab:hover { background: rgba(var(--encre-rgb), 0.063); color: var(--text); }
.legal-modal-tab-active {
  background: rgba(var(--tampon-rgb), 0.14);
  color: var(--pink);
  font-weight: 600;
}
.legal-modal-body {
  font-size: 14px; line-height: 1.6;
  color: var(--text);
  padding: 18px 20px;
}
.legal-modal-body h3 {
  font-size: 14px; font-weight: 700;
  margin: 18px 0 8px;
  color: var(--text);
}
.legal-modal-body h3:first-child { margin-top: 0; }
.legal-modal-body p { margin: 0 0 10px; }
.legal-modal-body ul { margin: 0 0 12px; padding-left: 22px; }
.legal-modal-body li { margin-bottom: 4px; }
.legal-modal-body a { color: var(--pink); }
.legal-modal-body code {
  background: rgba(var(--encre-rgb), 0.1);
  padding: 1px 6px; border-radius: calc(4px * var(--r-k));
  font-size: 12px;
}
.legal-modal-body .legal-intro {
  background: rgba(var(--tampon-rgb), 0.08);
  border-left: 3px solid var(--pink);
  padding: 10px 12px;
  border-radius: 0 calc(6px * var(--r-k)) calc(6px * var(--r-k)) 0;
  margin-bottom: 16px;
}
.legal-modal-body .legal-version {
  margin-top: 24px; padding-top: 12px;
  border-top: 1px solid rgba(var(--encre-rgb), 0.06);
  font-size: 11px; color: var(--text-mute);
  text-align: right;
}

/* ---- TermsGate (modal bloquante post-login) ---------------- */
.terms-gate-scrim { z-index: 500; /* au-dessus de tout */ }
.terms-gate-modal { max-width: 480px; }
.terms-gate-intro {
  font-size: 14px; line-height: 1.55;
  color: var(--text);
  margin: 0 0 12px;
}
.terms-gate-links { justify-content: flex-start; }

/* ---- RgpdActionsBlock (profil) ----------------------------- */
.rgpd-block {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px; margin: 32px 16px 16px;
  background: rgba(var(--tampon-rgb), 0.04);
  border: 1px solid rgba(var(--tampon-rgb), 0.18);
  border-radius: var(--r-md);
  /* Trait de séparation pour bien marquer la danger zone en bas de page. */
  position: relative;
}
.rgpd-block::before {
  content: '';
  position: absolute;
  top: -16px; left: 0; right: 0;
  height: 1px; background: rgba(var(--encre-rgb), 0.1);
}
.rgpd-block-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute);
}
.rgpd-block-help {
  font-size: 12px; color: var(--text-mute);
  margin: 0; line-height: 1.5;
}
.rgpd-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.rgpd-actions .btn { flex: 1 1 auto; font-size: 13px; }
.rgpd-actions .btn-danger {
  background: rgba(var(--tampon-rgb), 0.12);
  border: 1px solid rgba(var(--tampon-rgb), 0.35);
  color: var(--tampon);
}
.rgpd-actions .btn-danger:hover:not(:disabled) {
  background: rgba(var(--tampon-rgb), 0.2);
  color: var(--sur-accent);
}

/* ---- NotificationBell + Panel ----------------------------- */
.notif-bell-wrap { position: relative; flex: 0 0 auto; }
.notif-bell-btn { position: relative; }
.notif-bell-badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: calc(8px * var(--r-k));
  background: var(--pink);
  color: var(--sur-accent);
  font-size: 10px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
}

.notif-panel {
  position: absolute;
  top: calc(100% + 6px); right: 0;
  width: min(360px, 92vw);
  max-height: 70dvh;
  background: var(--bg-1, var(--carte));
  border: 1px solid rgba(var(--encre-rgb), 0.1);
  border-radius: var(--r-md);
  box-shadow: 0 12px 36px rgba(var(--ombre-rgb), 0.3);
  display: flex; flex-direction: column;
  z-index: 200;
}
.notif-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid rgba(var(--encre-rgb), 0.08);
}
.notif-panel-title { font-size: 14px; font-weight: 600; }
.notif-panel-mark-all {
  background: transparent; border: none;
  color: var(--text-mute); cursor: pointer;
  font-size: 11px; padding: 4px 6px;
}
.notif-panel-mark-all:hover { color: var(--pink); }
.notif-panel-body {
  overflow-y: auto;
  padding: 4px;
  -webkit-overflow-scrolling: touch;
}
.notif-panel-empty {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px; padding: 28px 16px;
  color: var(--text-mute); font-size: 13px; text-align: center;
}
.notif-panel-empty-icon { font-size: 28px; opacity: 0.6; }

.notif-row {
  display: flex; align-items: flex-start; gap: 10px;
  width: 100%; padding: 10px;
  background: transparent; border: none; color: inherit;
  text-align: left; cursor: pointer; border-radius: calc(8px * var(--r-k));
}
.notif-row:hover { background: rgba(var(--encre-rgb), 0.063); }
.notif-row-unread { background: rgba(var(--tampon-rgb), 0.06); }
.notif-row-icon {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
}
.notif-row-emoji { font-size: 22px; }
.notif-row-body { flex: 1 1 auto; min-width: 0; }
.notif-row-text {
  font-size: 13px; line-height: 1.4;
  color: var(--text);
}
.notif-row-sub {
  font-size: 12px; color: var(--text-mute);
  margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.notif-row-time {
  font-size: 11px; color: var(--text-mute);
  margin-top: 4px;
}
.notif-row-dot {
  flex: 0 0 auto;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pink);
  margin-top: 12px;
}

/* ---- ProfileEventsBlock : bouton Quitter par ligne -------- */
.profile-event-li {
  display: flex; align-items: stretch; gap: 6px;
  list-style: none;
}
.profile-event-li > .profile-event-row { flex: 1 1 auto; }
.profile-event-leave {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px;
  background: rgba(var(--tampon-rgb), 0.08);
  border: 1px solid rgba(var(--tampon-rgb), 0.25);
  border-radius: calc(8px * var(--r-k));
  color: var(--tampon);
  cursor: pointer;
}
.profile-event-leave:hover {
  background: rgba(var(--tampon-rgb), 0.18);
  color: var(--sur-accent);
}

/* ---- LeaveEventModal : choix garde/supprime -------------- */
.leave-choice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px;
  border: 1px solid rgba(var(--encre-rgb), 0.08);
  border-radius: var(--r-md);
  cursor: pointer;
  margin-bottom: 8px;
  background: rgba(var(--encre-rgb), 0.025);
}
.leave-choice:hover { background: rgba(var(--encre-rgb), 0.075); }
.leave-choice input[type="radio"] {
  margin-top: 3px;
  accent-color: var(--pink);
  width: 16px; height: 16px;
  flex: 0 0 auto;
}
.leave-choice-active {
  border-color: var(--pink);
  background: rgba(var(--tampon-rgb), 0.1);
}
.leave-choice-label {
  font-size: 14px; font-weight: 600;
  margin-bottom: 3px;
}
.leave-choice-sub {
  font-size: 12px; color: var(--text-mute); line-height: 1.5;
}

/* ---- ProfilePage : top-level tabs (Profil / Événements / Compte) ---- */
.profile-top-tabs {
  display: flex; gap: 4px;
  padding: 4px;
  margin: 0 16px 12px;
  background: rgba(var(--encre-rgb), 0.05);
  border-radius: var(--r-md);
  border: 1px solid rgba(var(--encre-rgb), 0.06);
}
.profile-top-tab {
  flex: 1 1 0;
  padding: 9px 8px;
  background: transparent;
  border: none;
  color: var(--text-mute);
  cursor: pointer;
  font-size: 13px; font-weight: 600;
  border-radius: calc(6px * var(--r-k));
  transition: background 0.15s, color 0.15s;
}
.profile-top-tab:hover { color: var(--text); }
.profile-top-tab-active {
  background: var(--pink);
  color: var(--sur-accent);
}

/* ---- Bouton action avec badge (toggle commentaires) ------- */
.action-btn-active {
  background: rgba(var(--tampon-rgb), 0.14) !important;
  color: var(--pink) !important;
}
.action-btn-badge {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: calc(4px * var(--r-k));
  background: rgba(var(--encre-rgb), 0.1);
  font-size: 11px; font-weight: 700;
  line-height: 1.4;
}
.action-btn-active .action-btn-badge {
  background: rgba(var(--tampon-rgb), 0.2);
  color: var(--pink);
}

/* ---- PinchZoomImage ---------------------------------------- */
.pinch-zoom {
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  position: relative;
  cursor: zoom-in;
  /* Empêche le scroll de la page de capter les gestes tactiles. */
  touch-action: none;
}
.pinch-zoom > img {
  display: block;
  max-width: 100%; max-height: 100%;
  pointer-events: auto;
  will-change: transform;
}

/* ---- PinchZoomImage : wrapper greedy équivalent à .detail-photo ---- */
/* La pinch-zoom remplace l'<img className="detail-photo"> direct, donc elle
   doit reproduire son comportement greedy (flex:1 1 0 + min-height:0) pour
   absorber l'espace restant du modal. L'<img> à l'intérieur passe en
   max-width/height:100% + object-fit:contain. */
.modal-detail .pinch-zoom {
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
}
.modal-detail .pinch-zoom > .detail-photo {
  flex: 0 1 auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
  object-fit: contain;
}

/* Override : la pinch-zoom dans PhotoDetail doit être greedy comme l'était
   .detail-photo en accès direct. */
.modal > .pinch-zoom {
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  background: var(--carte);
}
.modal > .pinch-zoom > .detail-photo {
  flex: 0 1 auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
  object-fit: contain;
  background: transparent;
}

/* ---- PushSettingsBlock (onglet Compte) -------------------- */
.push-block {
  display: flex; flex-direction: column;
  padding: 14px; margin: 0 16px 16px;
  background: rgba(var(--bleue-rgb), 0.05);
  border: 1px solid rgba(var(--bleue-rgb), 0.2);
  border-radius: var(--r-md);
}
.push-block-row {
  display: flex; align-items: center; gap: 12px;
}
.push-block-body { flex: 1 1 auto; min-width: 0; }
.push-block-title {
  font-size: 13px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--text);
  margin-bottom: 4px;
}
.push-block-help {
  font-size: 12px; color: var(--text-mute); line-height: 1.5;
}
.push-block-blocked {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  padding: 4px 8px; border-radius: calc(4px * var(--r-k));
  background: rgba(var(--tampon-rgb), 0.15); color: var(--tampon);
}

/* =============================================================
   SONDAGES (polls) dans les annonces
   ============================================================= */

/* Rendu overlay d'un sondage (carte, story, détail, aperçu éditeur).
   Question + liste des réponses possibles, pour qu'on comprenne d'un coup
   d'œil qu'il s'agit d'un sondage. Le badge "SONDAGE" n'est PAS dans le
   canvas : il remplace le badge "annonce officielle" (haut gauche / header).
   Le vote interactif reste en vue détail (PollVoter). */
.poll-overlay {
  display: inline-flex;
  flex-direction: column;
  gap: 0.3em;
  max-width: 100%;
  padding: 0.55em 0.7em;
  background: rgba(var(--carte-rgb), 0.42);
  border: 1px solid rgba(var(--encre-rgb), 0.18);
  border-radius: calc(0.5em * var(--r-k));
  backdrop-filter: blur(2px);
}
.poll-overlay-q {
  font-weight: 800;
  line-height: 1.25;
}

/* Sondage allégé et INTERACTIF dans le FEED comme en STORY : pas de cadre,
   juste la question (discrète) + les réponses cliquables (vote inline via
   PollVoter). Lisibilité assurée par l'ombre portée par-dessus l'image. Les
   deux surfaces partagent exactement le même rendu (seule la largeur diffère,
   la story étant plein écran). */
.ann-card-block-poll,
.stories-block-poll,
.detail-ann-block-poll,
.ann-preview-block-poll {
  pointer-events: auto; /* capte les taps de vote sans ouvrir le détail / naviguer */
}
/* Largeur unifiée sur les quatre surfaces. Avant : 240 px max en carte de feed,
   360 px en story, et aucune règle en vue détail ni dans l'aperçu de l'éditeur
   — ces deux-là retombaient sur le style par défaut de .poll-voter, d'où un
   sondage minuscule et encadré en détail et un rendu encore différent dans
   l'éditeur. En pourcentage du média, le bloc garde la même proportion partout,
   et la mise à l'échelle des polices (scaleFontPxToWidth) fait le reste. */
.ann-card-block-poll,
.stories-block-poll,
.detail-ann-block-poll,
.ann-preview-block-poll { width: 86%; max-width: 86%; }

.ann-card-block-poll .poll-voter,
.stories-block-poll .poll-voter,
.detail-ann-block-poll .poll-voter,
.ann-preview-block-poll .poll-voter {
  margin: 0;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
}
.ann-card-block-poll .poll-voter-q,
.stories-block-poll .poll-voter-q,
.detail-ann-block-poll .poll-voter-q,
.ann-preview-block-poll .poll-voter-q {
  font-size: 13px;
  font-weight: 800;
  color: var(--text);
  margin-bottom: 8px;
  letter-spacing: normal; /* annule le letter-spacing négatif hérité du bloc (illisible en paysage desktop) */
  text-shadow: 0 2px 8px rgba(var(--encre-rgb), 0.3), 0 0 4px rgba(var(--encre-rgb), 0.3);
}
/* Pied de sondage : il était masqué sur les quatre surfaces, ce qui effaçait
   trois informations que personne ne pouvait deviner ailleurs — la règle de
   vote (choix unique / multiple), la date de clôture, et le fait qu'il faut
   voter pour voir les résultats. On le garde donc, mais discret : 0.62 em du
   bloc, pour qu'il suive la mise à l'échelle sans jamais peser autant que les
   réponses. */
.ann-card-block-poll .poll-voter-foot,
.stories-block-poll .poll-voter-foot,
.detail-ann-block-poll .poll-voter-foot,
.ann-preview-block-poll .poll-voter-foot {
  margin-top: 7px;
  font-size: 0.62em;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: normal;
  color: rgba(var(--encre-rgb), 0.72);
  text-shadow: 0 1px 6px rgba(var(--ombre-rgb), 0.28);
  text-align: center;
}
.ann-card-block-poll .poll-voter-options,
.stories-block-poll .poll-voter-options,
.detail-ann-block-poll .poll-voter-options,
.ann-preview-block-poll .poll-voter-options { gap: 6px; }
.ann-card-block-poll .poll-opt,
.stories-block-poll .poll-opt,
.detail-ann-block-poll .poll-opt,
.ann-preview-block-poll .poll-opt {
  padding: 7px 11px;
  font-size: 13px;
  font-weight: 600;
  background: rgba(var(--carte-rgb), 0.5);
  border: 1px solid rgba(var(--encre-rgb), 0.28);
  border-radius: calc(999px * var(--r-k));
  backdrop-filter: blur(2px);
}
.poll-overlay-options {
  display: flex;
  flex-direction: column;
  gap: 0.28em;
  margin-top: 0.1em;
}
.poll-overlay-opt {
  display: flex;
  align-items: center;
  gap: 0.45em;
  line-height: 1.3;
}
.poll-overlay-opt-dot {
  flex: 0 0 auto;
  width: 0.62em;
  height: 0.62em;
  border-radius: 50%;
  border: 0.13em solid currentColor;
  opacity: 0.85;
}
.poll-overlay-opt-text {
  font-weight: 600;
  opacity: 0.95;
}

/* Les blocs sondage sont ancrés par le HAUT (et non centrés comme les autres
   blocs) : ainsi la question démarre toujours exactement à yPct quel que soit
   le nombre d'options ou les retours à la ligne. Position identique sur toutes
   les surfaces (carte feed, story, vue détail, aperçu éditeur). */
.ann-card-block-poll,
.stories-block-poll,
.detail-ann-block-poll,
.ann-preview-block-poll,
.detail-ann-block-poll,
.ann-preview-block-poll {
  transform: translate(-50%, 0) !important;
}

/* ---- Éditeur : liste d'options ---------------------------- */
.poll-edit-options { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.poll-edit-option { display: flex; align-items: center; gap: 6px; }
.poll-edit-option .mod-input { flex: 1 1 auto; }
.poll-edit-option-del {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(var(--tampon-rgb), 0.3); background: rgba(var(--tampon-rgb), 0.08);
  border-radius: calc(8px * var(--r-k)); color: var(--tampon); cursor: pointer;
}
.poll-edit-add-option {
  display: inline-flex; align-items: center; gap: 6px;
  align-self: flex-start;
  padding: 7px 12px; margin-top: 2px;
  background: rgba(var(--encre-rgb), 0.075);
  border: 1px dashed rgba(var(--encre-rgb), 0.2);
  border-radius: calc(8px * var(--r-k)); color: var(--text-mute); cursor: pointer;
  font-size: 13px;
}
.poll-edit-add-option:hover { color: var(--text); background: rgba(var(--encre-rgb), 0.125); }

/* ---- Éditeur : temps de réponse max (clôture du vote) ----- */
.poll-deadline-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.poll-deadline-btn {
  padding: 6px 12px;
  background: rgba(var(--encre-rgb), 0.05);
  border: 1px solid rgba(var(--encre-rgb), 0.18);
  border-radius: calc(999px * var(--r-k));
  color: var(--text-mute); cursor: pointer;
  font-size: 13px; font-weight: 600;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.poll-deadline-btn:hover { color: var(--text); background: rgba(var(--encre-rgb), 0.1); }
.poll-deadline-btn-active {
  color: var(--tampon);
  background: rgba(var(--tampon-rgb), 0.12);
  border-color: var(--tampon);
}
.poll-deadline-info {
  margin-top: 6px; font-size: 11px;
  color: var(--text-mute);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* ---- Vote (vue détail) ------------------------------------ */
.poll-voter {
  margin: 0 0 14px;
  padding: 14px;
  background: rgba(var(--encre-rgb), 0.063);
  border: 1px solid rgba(var(--encre-rgb), 0.1);
  border-radius: var(--r-md);
}
.poll-voter-q { font-size: 15px; font-weight: 700; margin-bottom: 12px; line-height: 1.3; }
.poll-voter-options { display: flex; flex-direction: column; gap: 8px; }
.poll-opt {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 12px 14px;
  background: rgba(var(--encre-rgb), 0.063);
  border: 1.5px solid rgba(var(--encre-rgb), 0.12);
  border-radius: calc(10px * var(--r-k));
  color: var(--text);
  cursor: pointer; text-align: left;
  overflow: hidden;
  font-size: 14px;
  transition: border-color 0.15s, background 0.15s;
}
.poll-opt:hover:not(:disabled) { border-color: rgba(var(--encre-rgb), 0.3); }
.poll-opt-mine { border-color: var(--pink); }
/* Barre de résultat (derrière le label), visible après vote */
.poll-opt-bar {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: rgba(var(--tampon-rgb), 0.18);
  z-index: 0;
  transition: width 0.4s cubic-bezier(0.2,0.8,0.2,1);
}
.poll-opt-mine .poll-opt-bar { background: rgba(var(--tampon-rgb), 0.3); }
.poll-opt-label { position: relative; z-index: 1; display: flex; align-items: center; gap: 7px; }
.poll-opt-check { color: var(--pink); font-weight: 800; }
.poll-opt-stat { position: relative; z-index: 1; font-size: 12px; color: var(--text-mute); flex: 0 0 auto; }
.poll-opt-voted .poll-opt-stat { color: var(--text); }
.poll-voter-foot {
  margin-top: 10px; font-size: 11px; color: var(--text-mute);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* ---- Upload : photo hors période de l'événement ----------- */
.upload-grid-outperiod {
  position: absolute;
  left: 4px; bottom: 4px;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 7px;
  border-radius: calc(6px * var(--r-k));
  font-size: 10px; font-weight: 700;
  background: rgba(var(--tampon-rgb), 0.9); color: var(--text-mute);
  z-index: 3;
}
.upload-grid-outperiod-blocked {
  background: rgba(var(--tampon-rgb), 0.92); color: var(--sur-accent);
}
.upload-grid-item-blocked .upload-grid-img { filter: grayscale(0.6) brightness(0.7); }

.upload-blocked-note {
  margin: 0 16px 8px;
  padding: 9px 12px;
  border-radius: calc(8px * var(--r-k));
  background: rgba(var(--tampon-rgb), 0.12);
  border: 1px solid rgba(var(--tampon-rgb), 0.3);
  color: var(--encre-3);
  font-size: 12px; line-height: 1.45;
}

/* Tampons — décalages propres à chaque surface (le style de base est dans
   01-utility.css). Seule la position varie d'une surface à l'autre ; la
   signalétique elle-même est identique partout. */
/* En story, l'en-tête (avatar + « Annonces n/N » + fermeture) occupe les 44
   premiers pixels du média : les tampons se plaçaient dessous et passaient
   derrière. On les descend juste sous cet en-tête. */
.stories-tampons    { top: 74px; left: 14px; }
.detail-ann-tampons { top: 12px; left: 12px; }
.ann-preview-tampons { top: 10px; left: 10px; }
