/* Les Post-it.
 *
 * Tout est dessiné en CSS : aucune image, donc aucune licence, et chaque
 * collection se teinte avec le thème de l'événement.
 *
 * Deux variables portent le rendu de chaque note :
 *   --pm-c    sa couleur, prise dans la palette du thème
 *   --rot     son inclinaison, calculée à partir du numéro de case
 *
 * L'inclinaison est DÉTERMINISTE : le mur doit paraître désordonné, mais
 * rester identique d'un téléphone à l'autre et d'un rechargement au
 * suivant. Des Post-it qui bougent à chaque actualisation donneraient le
 * mal de mer.
 */

.pm-mur {
  /* L'écart est exprimé en « cqi » : 1 % de la LARGEUR du conteneur, pour
     les colonnes ET pour les rangées.
     En pourcentage, un écart vertical se calcule sur la hauteur et un
     écart horizontal sur la largeur : sur un mur plus large que haut, les
     Post-it étaient nettement plus espacés dans un sens que dans l'autre.
     Repli en pourcentage pour les navigateurs sans unités de conteneur :
     l'écart redevient inégal, mais rien ne casse. */
  --pm-gap: 1.4%;
  /* « Caveat » est hébergée par le site : c'est la seule façon que
     l'écriture manuscrite existe aussi sur Android, où aucune des
     polices système ci-dessous n'est installée. */
  --pm-main: "Caveat", "Bradley Hand", "Segoe Print", "Marker Felt", "Chalkboard SE", cursive;
  display: grid;
  grid-template-columns: repeat(var(--cols, 8), 1fr);
  gap: var(--pm-gap);
  padding: 1.5%;
}
/* ⚠ Le conteneur doit être le PARENT, jamais le mur lui-même.
   Un élément n'est pas son propre conteneur de requête : « 1.4cqi »
   écrit sur .pm-mur qui porte container-type ne trouve aucun ancêtre
   qualifié et retombe sur la LARGEUR DE FENÊTRE. Les écarts grandissaient
   donc avec l'écran pendant que les notes rétrécissaient — l'aperçu
   devenait illisible sur grand écran. */
@supports (width: 1cqi) and selector(:has(*)) {
  *:has(> .pm-mur) { container-type: inline-size; }
  .pm-mur { gap: 1.4cqi; }
  .apercu .pm-mur { gap: 4cqi; }
  .c-bulle { gap: 3cqi; }
}

/* --- Un grand mur sur un petit écran ------------------------------------
 *
 * Mesuré sur un téléphone de 375 px : une case fait 38 px à 8 colonnes,
 * mais 23 px à 12 colonnes, 16 px à 16 et **12 px à 20**. Or on vend
 * jusqu'à 400 cases. Viser 12 px au doigt, dans une salle, un verre à la
 * main : personne n'y arrive.
 *
 * On impose donc une taille minimale à la case et le mur se pousse au
 * doigt. Ce n'est pas un pis-aller : un mur, ça se longe. La colonne
 * coupée au bord dit d'elle-même qu'il y a une suite.
 */
@media (max-width: 700px) {
  *:has(> .pm-mur) { overflow-x: auto; overscroll-behavior-x: contain; }
  .pm-mur { min-width: calc(var(--cols, 8) * 42px); }
}

/* Une note qui porte sa propre forme (classe « f-… ») l'emporte sur
   celle du mur : c'est son auteur qui a choisi. */
.pm-note[class*=" f-"] { --forme-propre: 1; }
.pm-note {
  position: relative;
  aspect-ratio: 1;
  border: 0;
  /* ⚠ LE REMBOURRAGE EST EN QUATRE JETONS, ET C'EST UN CORRECTIF — 23/08. Chaque
     forme réservait sa place en réécrivant « padding » ; or la projection pose
     « .grande-note .pm-note { padding: 6% 6.5% } », qui gagne en spécificité et
     ÉCRASAIT les huit réservations d'un coup. Mesuré : les huit formes rendaient
     « 6% 6.5% 6% 6.5% » sur la grande note, donc le scotch, la punaise et l'œillet
     passaient sur le texte là-bas — alors que le mur, lui, était juste.
     En jetons, une surface qui veut son propre minimum le COMPOSE
     (« max(6%, var(--pm-pb)) ») au lieu de l'effacer. */
  --pm-pt: 8%; --pm-pr: 7%; --pm-pb: 8%; --pm-pl: 7%;
  padding: var(--pm-pt) var(--pm-pr) var(--pm-pb) var(--pm-pl);
  margin: 0;
  font: inherit;
  /* L'encre d'une note s'adapte au thème : sur les palettes sombres,
     un texte presque noir sur un papier presque noir ne se lit pas. */
  color: var(--note-encre, #2f2b27);
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3%;
  overflow: hidden;
  /* Dans une grille, un élément refuse par défaut de descendre sous la
     largeur minimale de son contenu (min-width:auto) : un prénom en
     « white-space:nowrap » suffit alors à élargir la colonne et à faire
     déborder tout le mur de son cadre. On l'autorise à rétrécir. */
  min-width: 0;
  min-height: 0;
  background-color: var(--pm-c, #f3d9a4);
  /* Ombre en deux temps : un contact net juste sous le papier, puis un
     halo large et doux. C'est ce qui fait qu'une note « décolle ». */
  box-shadow:
    0 1px 1px rgba(40, 34, 28, .13),
    0 7px 14px -6px rgba(40, 34, 28, .30);
  transform: rotate(var(--rot, 0deg));
  transition: transform .16s ease, box-shadow .16s ease;
  /* léger grain de papier */
  background-image:
    repeating-linear-gradient(102deg, rgba(255,255,255,.10) 0 2px, transparent 2px 6px);
}

/* Le relief au survol ne concerne QUE les notes sur lesquelles on peut
   cliquer. Les murs de démonstration (accueil, galerie) sont des <span>
   décoratifs : les faire réagir promettait une action qui n'existe pas,
   et la note agrandie se faisait trancher par le cadre de la vitrine. */
.pm-note:not(.deco):hover {
  transform: rotate(var(--rot, 0deg)) translateY(-3px) scale(1.04);
  box-shadow:
    0 2px 2px rgba(40, 34, 28, .14),
    0 16px 26px -8px rgba(40, 34, 28, .36);
  z-index: 5;
}
.pm-note.deco { cursor: default; }
.pm-note:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; z-index: 6; }

/* ⚠ LE TEXTE PASSE AU PREMIER PLAN DE TOUTES LES NOTES — 23/08, demandé, et c'est
   le bon levier. Les décors (le rabat du coin corné, le scotch, la punaise, l'œillet
   de l'étiquette, la queue de la bulle) sont des pseudo-éléments POSITIONNÉS : en CSS,
   un élément positionné se peint APRÈS le contenu en flux, donc au-dessus. Le rabat
   du coin corné recouvrait ainsi la fin de la phrase — « Chapeau bas ma Belle & Happy
   Birth[day !] » — et aucun rembourrage n'y changeait rien : le texte était là, il
   était couvert.
   ⚠ ET C'EST PRÉFÉRABLE À RÉDUIRE LA POLICE : on projette dans une salle, il faut que
   ça se lise du fond. Un texte qui passe sur l'ombre d'une pliure se lit ; un texte
   rapetissé pour l'éviter, non. La demande était explicite, et elle a raison.
   ⚠ Ce que le premier plan NE peut pas régler : ce que la découpe RETIRE. Le coin
   corné et le papier déchiré rognent le papier lui-même (« clip-path ») — sous la
   diagonale, il n'y a plus de note du tout, et aucun empilement ne fait apparaître du
   texte sur du vide. C'est pour cela que ces deux formes gardent leur réservation de
   place, et seulement elles. */
.pm-note .pm-qui,
.pm-note .pm-txt,
.pm-note .pm-photo { position: relative; z-index: 3; }

.pm-note .pm-qui {
  font-weight: 700;
  /* « ech » : d'une écriture à l'autre la hauteur d'x varie du simple au
     double. Sans ce facteur, « Capitales étroites » serait minuscule à
     côté de « Marqueur ». */
  font-size: calc(clamp(6px, 1.25vw, 13px) * var(--pm-ech, 1));
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: none;
}
.pm-note .pm-txt {
  font-size: calc(clamp(5px, 1.05vw, 11.5px) * var(--pm-ech, 1));
  line-height: 1.25;
  overflow: hidden;
}
/* ⚠ COUPÉ À LA LIGNE, AVEC DES POINTS DE SUSPENSION — 23/08. Posée par
   « PMnote.couper() » sur les seules vignettes dont le texte dépasse, et sur elles
   seules : « display: -webkit-box » change la boîte, donc l'appliquer à toutes les notes
   toucherait aussi le poster imprimé, pour rien.
   Le nombre de lignes vient du script (« -webkit-line-clamp » en style en ligne) parce
   qu'il dépend de la taille de la vignette, laquelle dépend de la grille et de la largeur
   de la fenêtre — voir la note de couper().
   ⚠ SANS LE SCRIPT, RIEN NE CASSE : un « -webkit-box » sans nombre de lignes se comporte
   comme avant, l'« overflow: hidden » ci-dessus faisant le travail. Le repli est l'état
   d'hier, pas un état neuf. */
.pm-note .pm-txt.pm-coupe {
  display: -webkit-box;
  -webkit-box-orient: vertical;
}
.pm-note.ecrit-main { --pm-ech: 1.20; }        /* l'échelle de Caveat */
.pm-note.ecrit-main .pm-qui,
.pm-note.ecrit-main .pm-txt { font-family: var(--pm-main); font-synthesis-weight: none; }
.pm-note.ecrit-main .pm-qui { font-weight: 400; }
.pm-note.ecrit-imprime .pm-qui,
.pm-note.ecrit-imprime .pm-txt { font-family: var(--serif); font-style: italic; }

/* --- Dégradé -----------------------------------------------------------
   Le grain de papier est redéclaré parce qu'on empile deux images de
   fond : le grain par-dessus, le dégradé en dessous. */
.pm-note.deg {
  background-image:
    repeating-linear-gradient(102deg, rgba(255,255,255,.10) 0 2px, transparent 2px 6px),
    linear-gradient(155deg, var(--pm-a), var(--pm-b));
}

/* --- L'icône d'une note ------------------------------------------------
   EN HAUT À DROITE, et c'est le seul coin possible : le coin corné occupe
   le bas-droit, le ruban et la punaise le haut-centre, l'œillet de
   l'étiquette le haut-gauche, la bulle le bas-gauche. Reste celui-là.
   Elle est décorative — d'où aria-hidden — mais on la veut visible :
   3:1 minimum sur le papier de la note (WCAG 1.4.11). */
.pm-note .pm-ic {
  position: absolute; right: 6%; top: 6%;
  width: clamp(9px, 1.7vw, 18px); height: clamp(9px, 1.7vw, 18px);
  pointer-events: none; opacity: .92;
}
.pm-note .pm-ic svg { width: 100%; height: 100%; display: block; }
/* Le prénom s'arrête avant l'icône, sinon il passe dessous. */
.pm-note:has(.pm-ic) .pm-qui { padding-right: 20%; }

/* Cases encore libres : discrètes, mais visiblement cliquables. */
.pm-note.libre {
  background-color: transparent;
  background-image: none;
  border: 1.5px dashed var(--sage-pale);
  box-shadow: none;
  align-items: center;
  justify-content: center;
  color: var(--sage-pale);
  font-size: clamp(12px, 2.4vw, 22px);
  transform: none;
}
.pm-note.libre:not(.deco):hover {
  background-color: rgba(255, 255, 255, .5);
  border-color: var(--sage);
  color: var(--sage);
  transform: scale(1.04);
  box-shadow: none;
}
/* La case qu'on vient de demander : elle réagit AVANT la réponse du
   serveur. L'aller-retour dure une fraction de seconde en salle, plus
   longtemps sur un wifi saturé — et pendant ce temps, sans ce signal,
   le mur avait l'air cassé. */
.pm-note.en-cours {
  border-style: solid;
  border-color: var(--sage);
  background-color: color-mix(in srgb, var(--sage) 12%, transparent);
  cursor: progress;
}
.pm-note.en-cours::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%,
              color-mix(in srgb, var(--sage) 22%, transparent) 50%, transparent 70%);
  background-size: 260% 100%;
  animation: pm-attente 1.05s linear infinite;
}
@keyframes pm-attente { from { background-position: 130% 0; } to { background-position: -30% 0; } }
@media (prefers-reduced-motion: reduce) { .pm-note.en-cours::after { animation: none; } }

.pm-note.occupee { cursor: default; }
.pm-note.occupee::after {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(45deg,
    rgba(255,255,255,.30) 0 6px, transparent 6px 12px);
}

/* ------------------------------------------------------------------
   1. Classique — le carré de bureau, bande adhésive en haut
   ------------------------------------------------------------------ */
.c-classique .pm-note:not([class*=" f-"])::before, .pm-note.f-classique::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 20%;
  background: linear-gradient(180deg, rgba(0,0,0,.06), rgba(0,0,0,0));
  pointer-events: none;
}

/* ------------------------------------------------------------------
   2. Coin corné — le bas du papier se décolle
   ------------------------------------------------------------------ */
/* Le coin est RÉELLEMENT découpé, pas peint.
 *
 * Il était rempli de « var(--cream) », la couleur de fond de page. Ça ne
 * tient que si la note est posée sur cette couleur : sur une carte
 * blanche — l'aperçu de création, la galerie, la vitrine d'accueil — le
 * coin apparaissait blanc au lieu de laisser voir ce qu'il y a dessous.
 * Signalé deux fois, et à juste titre.
 *
 * « clip-path » enlève la matière : ce qui est dessous transparaît, quelle
 * que soit la surface. En contrepartie il rogne aussi l'ombre portée —
 * d'où le passage à « drop-shadow », comme pour le papier déchiré. */
.c-coin-corne .pm-note:not([class*=" f-"]):not(.libre), .pm-note.f-coin-corne:not(.libre) {
  clip-path: polygon(0 0, 100% 0, 100% 74%, 74% 100%, 0 100%);
  box-shadow: none;
  filter:
    drop-shadow(0 1px 1px rgba(40, 34, 28, .16))
    drop-shadow(0 6px 11px rgba(40, 34, 28, .26));
}
.c-coin-corne .pm-note:not([class*=" f-"]):not(.libre):not(.deco):hover, .pm-note.f-coin-corne:not(.libre):not(.deco):hover {
  filter:
    drop-shadow(0 2px 2px rgba(40, 34, 28, .16))
    drop-shadow(0 13px 20px rgba(40, 34, 28, .32));
}
/* ⚠ LA DÉCOUPE RÉSERVE SA PLACE — 23/08, signalé sur une note de la fête de
   Mélanie : « Chapeau bas ma Belle & Happy Birthday » passait sous le rabat.
   Le tracé va de (100 %, 74 %) à (74 %, 100 %) : au bord droit du texte, qui
   s'arrête à 93 %, la coupe est déjà à 81 %. Avec 8 % de rembourrage bas le texte
   descendait à 92 % — soit onze points DANS la découpe. Dix-neuf pour cent le
   dégagent, et un peu d'air avec.
   ⚠ Une autre voie existait — « shape-outside » sur un flotteur, pour que le texte
   contourne le triangle sans perdre de hauteur. Écartée à cinq jours de la fête :
   elle est élégante et difficile à éprouver sur huit formes ; un rembourrage se
   mesure. À reprendre plus tard si la place manque. */
.c-coin-corne .pm-note:not([class*=" f-"]):not(.libre), .pm-note.f-coin-corne:not(.libre) {
  --pm-pb: 19%;
}

/* Le rabat : le dessous du papier, plus sombre. Le découpage ci-dessus en
   retire la moitié, il ne reste que le triangle. */
.c-coin-corne .pm-note:not([class*=" f-"]):not(.libre)::after, .pm-note.f-coin-corne:not(.libre)::after {
  content: "";
  position: absolute; right: 0; bottom: 0;
  width: 26%; aspect-ratio: 1;
  background: linear-gradient(315deg,
    color-mix(in srgb, var(--pm-c) 74%, #000 11%) 0 62%,
    color-mix(in srgb, var(--pm-c) 88%, #000 4%) 100%);
  pointer-events: none;
}

/* ------------------------------------------------------------------
   3. Ruban adhésif — une bande de scotch tient la note
   ------------------------------------------------------------------ */
.c-ruban { padding-top: 3.5%; }
.c-ruban .pm-note:not([class*=" f-"]), .pm-note.f-ruban { overflow: visible; --pm-pt: 14%; }
.c-ruban .pm-note:not([class*=" f-"])::before, .pm-note.f-ruban::before {
  content: "";
  position: absolute; top: -7%; left: 50%; width: 44%; height: 15%;
  transform: translateX(-50%) rotate(-3.5deg);
  background: linear-gradient(180deg, rgba(255,255,255,.62), rgba(255,255,255,.30));
  border-left: 1px solid rgba(255,255,255,.55);
  border-right: 1px solid rgba(255,255,255,.55);
  box-shadow: 0 1px 2px rgba(40,34,28,.16);
  pointer-events: none;
}
.c-ruban .pm-note:not([class*=" f-"]).libre::before, .pm-note.f-ruban.libre::before { display: none; }

/* ------------------------------------------------------------------
   4. Punaise — épinglé sur un panneau
   ------------------------------------------------------------------ */
.c-punaise { padding-top: 3%; }
.c-punaise .pm-note:not([class*=" f-"]), .pm-note.f-punaise { overflow: visible; }
/* La tête d'épingle est posée dans la marge du haut, pas sur le texte :
   la note commence donc plus bas. */
.c-punaise .pm-note:not([class*=" f-"]), .pm-note.f-punaise { --pm-pt: 20%; }
.c-punaise .pm-note:not([class*=" f-"])::before, .pm-note.f-punaise::before {
  content: "";
  position: absolute; top: 4%; left: 50%; width: 12%; aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255,255,255,.85), transparent 58%),
    var(--sage);
  box-shadow: 0 2px 3px rgba(40,34,28,.45);
  pointer-events: none;
  z-index: 2;
}
.c-punaise .pm-note:not([class*=" f-"]).libre::before, .pm-note.f-punaise.libre::before { display: none; }

/* ------------------------------------------------------------------
   5. Papier déchiré — bord inférieur arraché
   ------------------------------------------------------------------ */
/* Tracé de découpe plutôt qu'un masque en dégradé conique : la
   composition de plusieurs couches de masque n'est pas rendue de la même
   façon partout, et l'effet disparaissait purement et simplement. Les
   points sont volontairement irréguliers — un zigzag régulier fait
   « dentelle », pas « papier arraché ». */
.c-dechire .pm-note:not([class*=" f-"]):not(.libre), .pm-note.f-dechire:not(.libre) {
  clip-path: polygon(
    0 0, 100% 0, 100% 87%,
    96% 93%, 92.5% 87.5%, 88% 94%, 84.5% 88.5%, 80% 95%, 76.5% 89.5%,
    72% 96%, 68.5% 90.5%, 64% 94.5%, 60.5% 88%, 56% 93.5%, 52.5% 87.5%,
    48% 95%, 44.5% 89.5%, 40% 96%, 36.5% 90.5%, 32% 94%, 28.5% 88%,
    24% 95%, 20.5% 89.5%, 16% 93.5%, 12.5% 88.5%, 8% 95%, 4.5% 90%, 0 93.5%
  );
  box-shadow: none;                /* un découpage rogne aussi l'ombre */
  filter: drop-shadow(0 3px 5px rgba(40, 34, 28, .30));
}
.c-dechire .pm-note:not([class*=" f-"]):not(.libre):not(.deco):hover, .pm-note.f-dechire:not(.libre):not(.deco):hover {
  filter: drop-shadow(0 8px 12px rgba(40, 34, 28, .34));
}
/* ⚠ ET LE PAPIER DÉCHIRÉ RÉSERVE AUSSI — même défaut que le coin corné, trouvé en
   dressant le tableau des huit formes plutôt qu'en regardant une capture. Le point
   le plus haut de l'arrachage est à 87 % ; le texte descendait à 92 %. Quinze pour
   cent le dégagent. */
.c-dechire .pm-note:not([class*=" f-"]):not(.libre), .pm-note.f-dechire:not(.libre) {
  --pm-pb: 15%;
}

/* ------------------------------------------------------------------
   6. Mémo ligné — papier réglé et sa marge rouge
   ------------------------------------------------------------------ */
.c-memo-ligne .pm-note:not([class*=" f-"]), .pm-note.f-memo-ligne {
  background-image:
    repeating-linear-gradient(180deg,
      transparent 0 20%, rgba(58, 88, 138, .20) 20%, rgba(58, 88, 138, .20) calc(20% + 1px)),
    linear-gradient(90deg,
      transparent 0 13%, rgba(184, 76, 70, .42) 13%, rgba(184, 76, 70, .42) calc(13% + 1px),
      transparent calc(13% + 1px));
  border-radius: 1px;
}
.c-memo-ligne .pm-note:not([class*=" f-"]), .pm-note.f-memo-ligne { --pm-pl: 16%; }

/* ------------------------------------------------------------------
   7. Bulle — bulle de bande dessinée
   ------------------------------------------------------------------ */
.c-bulle { --pm-gap: 3%; }
.c-bulle .pm-note:not([class*=" f-"]), .pm-note.f-bulle {
  border-radius: 16%;
  overflow: visible;
  --pm-pt: 11%; --pm-pr: 10%; --pm-pb: 14%; --pm-pl: 10%;
}
.c-bulle .pm-note:not([class*=" f-"]):not(.libre)::after, .pm-note.f-bulle:not(.libre)::after {
  content: "";
  position: absolute; bottom: -8%; left: 20%;
  width: 0; height: 0;
  border-style: solid;
  border-width: 0 0 11% 13%;
  border-color: transparent transparent transparent var(--pm-c);
  filter: drop-shadow(1px 3px 2px rgba(40,34,28,.18));
}
.c-bulle .pm-note:not([class*=" f-"]).libre, .pm-note.f-bulle.libre { border-radius: 16%; }

/* ------------------------------------------------------------------
   8. Étiquette kraft — coin coupé et œillet
   ------------------------------------------------------------------ */
/* Le coin coupé ET l'œillet occupent le HAUT-GAUCHE — exactement là où
   se trouve le prénom. Il était donc masqué à moitié. Le texte est
   décalé vers la droite d'autant que le coin est retiré. */
.c-etiquette .pm-note:not([class*=" f-"]), .pm-note.f-etiquette {
  clip-path: polygon(14% 0, 100% 0, 100% 100%, 0 100%, 0 14%);
  border-radius: 2px;
  --pm-pt: 15%; --pm-pr: 7%; --pm-pb: 8%; --pm-pl: 20%;
}
.c-etiquette .pm-note:not([class*=" f-"])::before, .pm-note.f-etiquette::before {
  content: "";
  position: absolute; top: 6%; left: 6%; width: 8%; aspect-ratio: 1;
  border-radius: 50%;
  background: var(--cream);
  box-shadow: inset 0 0 0 1.5px rgba(40, 34, 28, .30);
  pointer-events: none;
}
.c-etiquette .pm-note:not([class*=" f-"]).libre, .pm-note.f-etiquette.libre { clip-path: none; }
.c-etiquette .pm-note:not([class*=" f-"]).libre::before, .pm-note.f-etiquette.libre::before { display: none; }

/* ------------------------------------------------------------------
   À l'impression : plus d'inclinaison ni d'ombre. Le poster doit être
   une grille nette, sinon les Post-it se chevauchent au massicot.
   ------------------------------------------------------------------ */
@media print {
  .pm-note {
    transform: none !important;
    box-shadow: none !important;
    filter: none !important;
  }
  .pm-mur { gap: .35cm; padding: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .pm-note, .pm-note:hover { transition: none; }
}

/* ------------------------------------------------------------------
   Message vocal : une pastille discrète sur la note, pour qu'on sache
   qu'il y a une voix à écouter sans surcharger la mosaïque.
   ------------------------------------------------------------------ */
.pm-note .pm-voix {
  position: absolute; right: 6%; bottom: 6%;
  width: 22%; max-width: 20px; aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, .82);
  box-shadow: 0 1px 3px rgba(40, 34, 28, .35);
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.pm-note .pm-voix::after {
  content: "";
  width: 0; height: 0;
  border-style: solid;
  border-width: 4px 0 4px 6px;
  border-color: transparent transparent transparent var(--note-encre, #2f2b27);
  margin-left: 1px;
}
.pm-note .pm-voix.attente { opacity: .45; }

/* ------------------------------------------------------------------
   La note photographiée.
   Ici la photo n'est pas un ornement : c'est LE mot. Elle prend donc la
   place restante dans la case, sous le prénom et sous le texte s'il y en
   a un — et « cover » plutôt que « contain », parce que la case est
   carrée et la photo rarement : on remplit et l'on rogne, comme un
   tirage. Le détail se lit dans la fenêtre de lecture, en grand.
   ------------------------------------------------------------------ */
/* ⚠ « display:block » ci-dessous BAT la règle « [hidden] » du navigateur, dont
   la spécificité est plus faible : sans cette ligne, poser « hidden » sur la
   photo ne la cacherait pas, et la note en grand garderait celle de la
   précédente. Vérifié par le calcul de spécificité, pas à l'œil. */
.pm-note .pm-photo[hidden] { display: none; }
.pm-note .pm-photo {
  display: block;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  object-fit: cover;
  /* LE HAUT, pas le centre. Un mot se commence en haut de la feuille : cadrée
     au centre, une note portrait montrait sa deuxième moitié et l'on ne lisait
     ni « Joyeux » ni le début de la phrase.
     ⚠ Ne vaut que parce que la vignette est rognée de sa bordure unie au dépôt
     (image_boite_utile) : sans ce rognage, cadrer en haut sur une feuille posée
     sur une table cadrerait la table. Les deux vont ensemble. */
  object-position: top;
  border-radius: 2px;
  /* Un fond le temps du chargement : sans lui, une case affiche un trou
     blanc au milieu du papier coloré, ce qui se remarque plus que l'attente. */
  background: rgba(40, 34, 28, .07);
}
/* Un mot qui N'EST QU'UNE PHOTO : elle va jusqu'au bord du papier, comme un
   tirage collé sur la note. Le padding de la case lui coûtait 15 % de sa largeur
   — sur cent quarante pixels, c'est une ligne d'écriture. */
.pm-note.photo-seule { padding: 0; }
.pm-note.photo-seule .pm-qui { padding: 7% 7% 0; }
.pm-note.photo-seule .pm-photo { border-radius: 0 0 2px 2px; }
/* Avant la révélation : on dit qu'il y a une photo, on ne la montre pas.
   Même pastille que la voix, mais à gauche — une note peut avoir les deux. */
.pm-note .pm-photo-att {
  position: absolute; left: 6%; bottom: 6%;
  width: 22%; max-width: 20px; aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, .82);
  box-shadow: 0 1px 3px rgba(40, 34, 28, .35);
  display: flex; align-items: center; justify-content: center;
  opacity: .45;
  pointer-events: none;
}
.pm-note .pm-photo-att::after {
  content: "";
  width: 46%; height: 38%;
  border: 1.5px solid var(--note-encre, #2f2b27);
  border-radius: 1.5px;
}

/* --- Une case libre qui ne l'est plus pour vous ---------------------------
 *
 * ⚠ Posée par assets/mur.js quand l'invité a déjà écrit son mot. La règle
 * « une note par personne » vivait côté serveur sans que rien ne l'annonce :
 * quatre-vingts cases restaient invitantes et l'on découvrait la règle en
 * cliquant. Éteinte, la case dit d'elle-même qu'elle n'est plus pour vous.
 * ⚠ Sans icône « + » : le plus est une INVITATION, et il n'y a plus rien à
 * ajouter. La garder grisée aurait été un bouton désactivé qui fait signe. */
.pm-note.libre.eteinte {
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  border-style: solid; border-color: color-mix(in srgb, var(--ink) 10%, transparent);
  box-shadow: none; cursor: default; opacity: .55;
}
.pm-note.libre.eteinte:hover { transform: none; background: color-mix(in srgb, var(--ink) 7%, transparent); }
