/* ==========================================================================
   La grille : cellules, en-têtes collants, cadre de sélection, champ de
   saisie posé sur la cellule active.
   ========================================================================== */

.zone-grille {
  position: relative;
  /* Les z-index de la grille restent à l'intérieur de la grille. */
  isolation: isolate;
  overflow: auto;
  background: var(--fond);
  outline: none;
  overscroll-behavior: contain;
  /* Le doigt fait défiler la grille ; le pincement à deux doigts est géré par
     l'application (zoom de la grille, voir js/affichage/zoom.js) au lieu
     d'agrandir toute la page. */
  touch-action: pan-x pan-y;
  /* Zoom (1 = 100 %) et hauteur des lignes à 100 %. grille.js calcule la
     hauteur réelle (--hauteur-ligne = hauteur à 100 % × zoom). */
  --zoom: 1;
  --hauteur-base: 32px;
  --hauteur-ligne: 32px;
}

/* Au doigt : lignes un peu plus hautes. */
@media (pointer: coarse) {
  .zone-grille {
    --hauteur-base: 36px;
    --hauteur-ligne: 36px;
  }
}

.grille-contenu {
  position: relative;
  width: max-content;
}

.grille {
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--police-cellules);
  font-size: calc(0.95rem * var(--zoom));
  font-variant-numeric: tabular-nums;
  /* Un appui rapide au doigt sélectionne, sans zoom par double appui. */
  touch-action: pan-x pan-y;
  user-select: none;
  -webkit-user-select: none;
}

/* --- Cellules ----------------------------------------------------------------- */

.grille td {
  height: var(--hauteur-ligne);
  padding: 0 calc(8px * var(--zoom));
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  background: var(--teinte, var(--cellule));
  border-right: 1px solid var(--quadrillage);
  border-bottom: 1px solid var(--quadrillage);
  cursor: cell;
}

/* Alignement automatique, comme dans Excel : nombres à droite, texte à gauche. */
.grille td.nombre {
  text-align: right;
}

.grille td.booleen,
.grille td.erreur {
  text-align: center;
}

.grille td.erreur {
  color: var(--erreur);
  font-family: var(--police-entetes);
  font-size: calc(0.85rem * var(--zoom));
}

.grille td.gras {
  font-weight: 700;
}

.grille td.italique {
  font-style: italic;
}

/* Retour à la ligne : le texte continue sur plusieurs lignes (les sauts de
   ligne du texte sont gardés, un mot trop long est coupé) ; grille.js donne
   à la ligne du tableau la hauteur nécessaire. */
.grille td.retour {
  padding-top: calc(3px * var(--zoom));
  padding-bottom: calc(3px * var(--zoom));
  white-space: pre-line;
  overflow-wrap: anywhere;
  text-overflow: clip;
}

/* Zone invisible où grille.js mesure le texte renvoyé à la ligne : chaque
   boîte imite une cellule « retour » (même police, mêmes marges, même trait
   en bas et à droite). Elle est vidée aussitôt la mesure faite. */
.mesure-retour {
  position: absolute;
  top: 0;
  left: 0;
  visibility: hidden;
  pointer-events: none;
  font-family: var(--police-cellules);
  font-size: calc(0.95rem * var(--zoom));
  font-variant-numeric: tabular-nums;
}

.mesure-retour > div {
  padding: calc(3px * var(--zoom)) calc(8px * var(--zoom));
  border-right: 1px solid transparent;
  border-bottom: 1px solid transparent;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.mesure-retour > .erreur {
  font-family: var(--police-entetes);
  font-size: calc(0.85rem * var(--zoom));
}

.mesure-retour > .gras {
  font-weight: 700;
}

.mesure-retour > .italique {
  font-style: italic;
}

/* Alignement choisi par la personne (il remplace l'alignement automatique). */
.grille td[data-align="gauche"] { text-align: left; }
.grille td[data-align="centre"] { text-align: center; }
.grille td[data-align="droite"] { text-align: right; }

/* Couleur du texte : l'attribut data-encre choisit la teinte du thème. */
[data-encre="rouge"] { color: var(--encre-rouge); }
[data-encre="orange"] { color: var(--encre-orange); }
[data-encre="jaune"] { color: var(--encre-jaune); }
[data-encre="vert"] { color: var(--encre-vert); }
[data-encre="bleu"] { color: var(--encre-bleu); }
[data-encre="violet"] { color: var(--encre-violet); }
[data-encre="gris"] { color: var(--encre-gris); }

/* --- Cellules fusionnées ---------------------------------------------------------
   Un bloc posé sur les cellules couvertes (voir grille.js), qui ressemble à une
   cellule ordinaire : même fond, même police, même quadrillage à droite et en bas.
   Il passe sous les cadres de sélection (z-index 1) et sous la ligne figée. */
.cellule-fusionnee {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: 0 calc(8px * var(--zoom));
  overflow: hidden;
  background: var(--teinte, var(--cellule));
  border-right: 1px solid var(--quadrillage);
  border-bottom: 1px solid var(--quadrillage);
  /* (Pas de « color » ici : la couleur du texte vient de data-encre ou de la page.) */
  font-family: var(--police-cellules);
  font-size: calc(0.95rem * var(--zoom));
  font-variant-numeric: tabular-nums;
  text-align: left;
  cursor: cell;
}

.cellule-fusionnee > span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.cellule-fusionnee.nombre { text-align: right; }
.cellule-fusionnee.booleen,
.cellule-fusionnee.erreur { text-align: center; }
.cellule-fusionnee.erreur { color: var(--erreur); }
.cellule-fusionnee.gras { font-weight: 700; }
.cellule-fusionnee.italique { font-style: italic; }
.cellule-fusionnee.retour > span {
  white-space: pre-line;
  overflow-wrap: anywhere;
  max-height: 100%;
}
.cellule-fusionnee[data-align="gauche"] { text-align: left; }
.cellule-fusionnee[data-align="centre"] { text-align: center; }
.cellule-fusionnee[data-align="droite"] { text-align: right; }

/* Lignes d'espacement de la grille virtuelle : elles remplacent les lignes
   qui ne sont pas dessinées (hors de l'écran). Des traits horizontaux
   imitent les lignes pendant un défilement très rapide. */
.grille tr.espace td {
  height: auto;
  padding: 0;
  border: 0;
  background: repeating-linear-gradient(
    to bottom,
    var(--cellule) 0 calc(var(--hauteur-ligne) - 1px),
    var(--quadrillage) calc(var(--hauteur-ligne) - 1px) var(--hauteur-ligne)
  );
}

/* Couleurs de fond : l'attribut data-fond choisit la teinte du thème, utilisée
   par les cellules, les pastilles du nuancier et le témoin du bouton « Fond ». */
[data-fond="jaune"] { --teinte: var(--fond-jaune); }
[data-fond="orange"] { --teinte: var(--fond-orange); }
[data-fond="rouge"] { --teinte: var(--fond-rouge); }
[data-fond="rose"] { --teinte: var(--fond-rose); }
[data-fond="violet"] { --teinte: var(--fond-violet); }
[data-fond="bleu"] { --teinte: var(--fond-bleu); }
[data-fond="vert"] { --teinte: var(--fond-vert); }
[data-fond="gris"] { --teinte: var(--fond-gris); }

/* --- En-têtes (A, B, C… en haut ; 1, 2, 3… à gauche), toujours visibles ----- */

.grille th {
  height: var(--hauteur-ligne);
  padding: 0 4px;
  background: var(--entete);
  color: var(--entete-texte);
  font-family: var(--police-entetes);
  font-size: calc(0.8rem * var(--zoom));
  font-weight: 500;
  border-right: 1px solid var(--trait);
  border-bottom: 1px solid var(--trait);
  text-align: center;
  cursor: pointer;
}

/* Ordre d'empilement dans la grille (du dessous vers le dessus) :
   cellules < cadres de sélection (1) < ligne figée (2) < couche figée et
   champ de saisie (3) < en-têtes (4) < numéro de la ligne figée (5) < coin (6). */
.grille thead th {
  position: sticky;
  top: 0;
  z-index: 4;
}

.grille tbody th {
  position: sticky;
  left: 0;
  z-index: 4;
}

.grille th.coin {
  left: 0;
  z-index: 6;
}

/* --- Première ligne figée : collée sous les en-têtes A, B, C… --------------- */

.grille tr.ligne-figee td {
  position: sticky;
  top: var(--hauteur-ligne);
  z-index: 2;
}

.grille tr.ligne-figee th {
  top: var(--hauteur-ligne);
  z-index: 5;
}

/* Couche qui reste collée au-dessus de la ligne figée : elle porte les cadres
   de sélection et le champ de saisie de la ligne 1. Hauteur nulle : elle ne
   décale pas le tableau. */
.couche-figee {
  position: sticky;
  top: var(--hauteur-ligne);
  height: 0;
  z-index: 3;
}

.couche-figee[hidden] {
  display: none;
}

/* Trait plus épais sous la ligne figée, pour la repérer (--hauteur-figee :
   hauteur de la ligne 1, plus grande si elle a du texte renvoyé à la ligne). */
.couche-figee::after {
  content: "";
  position: absolute;
  top: calc(var(--hauteur-figee, var(--hauteur-ligne)) - 2px);
  left: 0;
  right: 0;
  height: 2px;
  background: var(--trait);
  pointer-events: none;
}

.grille th.surligne {
  background: var(--entete-surligne);
  color: var(--entete-surligne-texte);
}

/* Poignée pour changer la largeur d'une colonne (bord droit de l'en-tête). */
.entete-colonne {
  position: relative;
}

.poignee-largeur {
  position: absolute;
  top: 0;
  right: 0;
  width: 12px;
  height: 100%;
  cursor: col-resize;
  z-index: 1;
  touch-action: none;
}

/* Au doigt : poignée plus large, avec un petit trait pour la repérer. */
@media (pointer: coarse) {
  .poignee-largeur {
    width: 22px;
  }
  .poignee-largeur::after {
    content: "";
    position: absolute;
    top: 30%;
    bottom: 30%;
    right: 4px;
    width: 3px;
    border-radius: 2px;
    background: var(--trait);
  }
}

/* --- Sélection ---------------------------------------------------------------- */

.cadre-plage,
.cadre-actif {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 1;
}

.cadre-plage {
  background: var(--selection);
  border: 1px solid var(--selection-trait);
}

.cadre-actif {
  border: 2px solid var(--selection-trait);
}

.cadre-plage[hidden],
.cadre-actif[hidden] {
  display: none;
}

/* Plage coupée en deux par la ligne figée : pas de trait à la jonction. */
.cadre-plage.sans-haut {
  border-top-width: 0;
}

.cadre-plage.sans-bas {
  border-bottom-width: 0;
}

/* Poignée ronde pour étendre la sélection au doigt (seulement au toucher). */
.poignee-selection {
  /* Elle suit un peu le zoom, sans devenir trop petite pour le doigt. */
  --taille-poignee: calc(26px * clamp(0.75, var(--zoom), 1.25));
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: var(--taille-poignee);
  height: var(--taille-poignee);
  margin: calc(var(--taille-poignee) / -2) 0 0 calc(var(--taille-poignee) / -2);
  border-radius: 50%;
  background: var(--selection-trait);
  border: 3px solid var(--cellule);
  z-index: 1;
  touch-action: none;
}

.mode-toucher .poignee-selection {
  display: block;
}

.en-edition .poignee-selection {
  display: none;
}

/* Poignée de recopie (à la souris) : petit carré dans le coin de la
   sélection, à tirer vers le bas, le haut, la droite ou la gauche. */
.poignee-recopie {
  position: absolute;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  margin: -6px 0 0 -6px;
  background: var(--selection-trait);
  border: 2px solid var(--cellule);
  box-sizing: content-box;
  z-index: 1;
  cursor: crosshair;
  touch-action: none;
}

.mode-toucher .poignee-recopie,
.en-edition .poignee-recopie {
  display: none;
}

/* Zone qui sera remplie pendant qu'on tire la poignée de recopie. */
.cadre-recopie {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  border: 2px dashed var(--selection-trait);
  z-index: 1;
}

.cadre-recopie[hidden] {
  display: none;
}

/* --- Champ de saisie sur la cellule ------------------------------------------- */

.editeur-cellule {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  margin: 0;
  padding: 0 calc(7px * var(--zoom));
  border: 2px solid var(--selection-trait);
  border-radius: 0;
  background: var(--cellule);
  color: var(--texte);
  font-family: var(--police-cellules);
  font-size: calc(0.95rem * var(--zoom));
  outline: none;
}

/* Hors édition : le champ reste sur la cellule active pour recevoir le
   clavier, mais il est invisible et laisse passer les clics. */
body:not(.en-edition) .editeur-cellule {
  opacity: 0;
  pointer-events: none;
  caret-color: transparent;
}
