/* Accueil — habillage de la grille libre.

   `vendor/gridstack.min.css` apporte le PLACEMENT (position absolue, largeur de
   colonne, hauteur de rangée via ses variables --gs-*). Ce fichier apporte
   l'APPARENCE, au style du projet. On ne rature jamais le fichier vendored :
   il se remplace, il ne se corrige pas.

   Tous les sélecteurs sont préfixés par `.page--free` ou portés par
   `.grid-stack`, qui n'existent nulle part ailleurs : aucune règle ne peut
   fuir vers une page restée en flux. C'est ce qui garantit zéro régression sur
   les pages non converties — `components.css` n'est pas modifié du tout. */

/* La page libre n'est plus une grille CSS : le placement vient de Gridstack.
   Elle reste le conteneur de défilement, avec ses gouttières. */
.page--free { display: block; }
.page--free .grid-stack { position: relative; width: 100%; }

/* ---- La carte devient le contenu d'un item Gridstack -------------------
   Gridstack la positionne en absolu ; `display: flex`, le padding, le rayon,
   le verre et l'ombre de `.card` restent tous valides. `grid-column` devient
   simplement inerte. Il n'y a donc rien à retirer de components.css. */

/* La carte occupe EXACTEMENT sa boîte, ni plus ni moins. C'est tout le contrat
   de la disposition libre : la taille vient de l'utilisateur, jamais du
   contenu. On laisse donc faire le fichier vendored, qui cale déjà top / right
   / bottom / left sur les gouttières — il suffit de ne rien écraser.
   `overflow: hidden` sur la carte, parce que c'est elle qui porte le rayon :
   la barre de défilement vit un cran plus bas, sur la liste. */
.page--free .grid-stack > .grid-stack-item > .grid-stack-item-content {
  overflow: hidden;
}

/* La liste prend la place qui reste et défile si le contenu déborde.
   `min-height: 0` est INDISPENSABLE : sans lui, un enfant flex refuse de
   descendre sous sa hauteur de contenu, la liste pousserait la carte au lieu
   de défiler, et `overflow` ne servirait à rien. */
.page--free .grid-stack-item-content.card > .links {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* La barre reste réservée en largeur mais INVISIBLE au repos : seul
     scrollbar-color change au survol, ce qui ne déplace pas un pixel de
     contenu — passer de 'none' à 'thin' aurait fait sauter la mise en page
     à chaque approche du curseur. */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.page--free .grid-stack-item:hover .grid-stack-item-content.card > .links {
  scrollbar-color: rgba(255, 255, 255, .26) transparent;
}

/* Le défilement se fait par crans, piloté en JS (voir ui-render.js) : on coupe
   donc l'inertie et l'ancrage du navigateur, qui replaceraient la liste entre
   deux crans. */
.page--free .grid-stack-item-content.card > .links {
  scroll-behavior: auto;
  overscroll-behavior: contain;
}

/* ---- Poignées de redimensionnement -------------------------------------
   Zones de saisie généreuses mais invisibles au repos : la carte reste propre,
   et le geste est disponible dès qu'on approche d'un bord. Elles suivent la
   même règle que le déplacement — `body.can-arrange`, posé quand le glisser
   est autorisé : en édition toujours, hors édition si la page n'est pas
   verrouillée. */
.page--free .ui-resizable-handle { display: none; }
.can-arrange .page--free .ui-resizable-handle {
  display: block; position: absolute; z-index: 3; background: none;
  /* Le fichier vendored fait tourner les poignées d'angle de -45° pour
     redresser sa propre icône en SVG. Nous n'en voulons pas — et la rotation
     n'était pas neutre : elle transformait notre repère d'angle en POINTE, ce
     qui se lisait comme une flèche, et gonflait la boîte de saisie de 20 à
     28 px en la décalant hors de la carte. */
  transform: none;
}
/* Les poignées sont posées sur l'ITEM Gridstack, qui est plus grand que la
   carte de toute la gouttière. Sans compensation elles flottent à 17 px du
   bord — mesuré — et il faut viser le vide entre deux cartes pour
   redimensionner. On les ramène donc sur les bords de la CARTE, où elles
   chevauchent la bordure de 5 px de part et d'autre. */
.can-arrange .page--free .ui-resizable-handle {
  --gut-t: var(--gs-item-margin-top, 10px);
  --gut-r: var(--gs-item-margin-right, 10px);
  --gut-b: var(--gs-item-margin-bottom, 10px);
  --gut-l: var(--gs-item-margin-left, 10px);
}
.can-arrange .page--free .ui-resizable-n  { top: calc(var(--gut-t) - 5px); left: calc(var(--gut-l) + 14px); right: calc(var(--gut-r) + 14px); height: 11px; cursor: ns-resize; }
.can-arrange .page--free .ui-resizable-s  { bottom: calc(var(--gut-b) - 5px); left: calc(var(--gut-l) + 14px); right: calc(var(--gut-r) + 14px); height: 11px; cursor: ns-resize; }
.can-arrange .page--free .ui-resizable-e  { right: calc(var(--gut-r) - 5px); top: calc(var(--gut-t) + 14px); bottom: calc(var(--gut-b) + 14px); width: 11px; cursor: ew-resize; }
.can-arrange .page--free .ui-resizable-w  { left: calc(var(--gut-l) - 5px); top: calc(var(--gut-t) + 14px); bottom: calc(var(--gut-b) + 14px); width: 11px; cursor: ew-resize; }
.can-arrange .page--free .ui-resizable-ne { top: calc(var(--gut-t) - 5px); right: calc(var(--gut-r) - 5px); width: 20px; height: 20px; cursor: nesw-resize; }
.can-arrange .page--free .ui-resizable-nw { top: calc(var(--gut-t) - 5px); left: calc(var(--gut-l) - 5px); width: 20px; height: 20px; cursor: nwse-resize; }
.can-arrange .page--free .ui-resizable-sw { bottom: calc(var(--gut-b) - 5px); left: calc(var(--gut-l) - 5px); width: 20px; height: 20px; cursor: nesw-resize; }
.can-arrange .page--free .ui-resizable-se { bottom: calc(var(--gut-b) - 5px); right: calc(var(--gut-r) - 5px); width: 20px; height: 20px; cursor: nwse-resize; }

/* Un seul repère visible, au coin bas-droit, révélé au survol de la carte : un
   ARC posé SUR la bordure de la carte, dont il reprend exactement le tracé —
   même rayon, même position. Il épaissit le coin plutôt que de dessiner une
   seconde ligne à l'intérieur, ce qui se lisait comme un ornement de plus.
   Les deux traits obliques d'avant, eux, dessinaient une pointe qu'on prenait
   pour une flèche ; un arc ne montre pas de direction, il souligne un coin.

   La poignée déborde de 5 px hors de la carte : l'arc est donc décalé de ces
   5 px pour retomber pile sur le bord. */
.can-arrange .page--free .ui-resizable-se::after {
  content: ""; position: absolute; right: 5px; bottom: 5px; width: 22px; height: 22px;
  border: 1.5px solid transparent;
  border-right-color: rgba(var(--accent-rgb), .75);
  border-bottom-color: rgba(var(--accent-rgb), .75);
  border-radius: 0 0 var(--r-2xl) 0;
  opacity: 0; transition: opacity .12s ease;
}
.can-arrange .page--free .grid-stack-item:hover .ui-resizable-se::after { opacity: 1; }

/* ---- Fantôme de dépôt et carte en cours de glisser ---------------------
   Même vocabulaire visuel que le glisser SortableJS (voir components.css,
   `.card.sortable-ghost`) : le pointillé d'accent veut dire « ça se posera
   là », quel que soit le moteur. */
.page--free .grid-stack-placeholder > .placeholder-content {
  background: rgba(var(--accent-rgb), .06);
  border: 1px dashed rgba(var(--accent-rgb), .5);
  border-radius: var(--r-2xl);
}
.page--free .grid-stack-item.ui-draggable-dragging { z-index: 40; }
.page--free .grid-stack-item.ui-draggable-dragging > .card {
  opacity: .92;
  box-shadow: var(--sheen), 0 30px 60px -18px rgba(0, 0, 0, .8);
}

/* ---- Bouton « Ajouter une section » ------------------------------------
   Il est hors de la grille : en item Gridstack il occuperait une case et
   fausserait le placement automatique. Bande pleine largeur sous la grille. */
.add--free {
  width: 100%; height: 52px; margin-top: var(--gap);
  border-radius: var(--r-2xl); justify-content: center;
}
