/* =============================================================
   Socle · Mise en page
   Se charge après css/base.css et avant les composants.
   Cinq intentions, relevées sur trois pages bâties à l'aveugle
   avec l'export : elles avaient inventé 37 classes, dont ces
   cinq motifs, chacun avec ses propres nombres.
   .sc-page, .sc-stack, .sc-cluster, .sc-grid, .sc-app
   ============================================================= */

/* ---- Page ----
   La colonne de contenu : une largeur maximale, centrée, avec sa
   respiration latérale. Le modificateur --prose la resserre à une
   largeur de lecture. */

.sc-page {
  --_page-measure: var(--measure-page);
  /* La marge au bord, et c'est le premier réglage d'une page. À 16 le
     contenu venait toucher le filet de la barre latérale d'une coquille
     d'application, et une carte collée à un bord se lit comme si elle
     dépassait. 24 est aussi la valeur de la référence. */
  --_page-padding-inline: var(--padding-3xl);
  --_page-padding-block: var(--padding-3xl);

  max-inline-size: var(--_page-measure);
  margin-inline: auto;
  padding-inline: var(--_page-padding-inline);
  padding-block: var(--_page-padding-block);
}

.sc-page--prose {
  --_page-measure: var(--measure-prose);
}

/* Dans une coquille d'application, la page ne se centre plus sur la
   fenêtre mais sur la zone principale, qui porte déjà son défilement. */
.sc-page--flush {
  --_page-padding-block: 0;
}

/* ---- Pile ----
   L'empilement vertical, et l'écart est tout ce qui le distingue.
   C'est le motif que les trois pages ont réécrit le plus souvent. */

.sc-stack {
  --_stack-gap: var(--gap-l);

  display: flex;
  flex-direction: column;
  gap: var(--_stack-gap);
}

.sc-stack--xs { --_stack-gap: var(--gap-2xs); }
.sc-stack--s { --_stack-gap: var(--gap-s); }
.sc-stack--m { --_stack-gap: var(--gap-m); }
.sc-stack--xl { --_stack-gap: var(--gap-xl); }

/* Le rythme d'une page : ce qui sépare deux sections, pas deux blocs. */
.sc-stack--sections { --_stack-gap: var(--gap-3xl); }

/* ---- Grappe ----
   La rangée qui passe à la ligne : une barre d'actions, une liste
   d'étiquettes, un en-tête dont le titre et les boutons se séparent. */

.sc-cluster {
  --_cluster-gap: var(--gap-m);
  --_cluster-align: center;
  --_cluster-justify: flex-start;

  display: flex;
  flex-wrap: wrap;
  align-items: var(--_cluster-align);
  justify-content: var(--_cluster-justify);
  gap: var(--_cluster-gap);
}

.sc-cluster--between { --_cluster-justify: space-between; }
.sc-cluster--end { --_cluster-justify: flex-end; }

/* Un en-tête dont le titre tient sur deux lignes ne doit pas centrer
   ses boutons sur sa hauteur : ils se calent en haut. */
.sc-cluster--top { --_cluster-align: flex-start; }

.sc-cluster--s { --_cluster-gap: var(--gap-s); }
.sc-cluster--l { --_cluster-gap: var(--gap-l); }

/* ---- Grille ----
   Les colonnes se replient seules sous leur largeur minimale, sans
   point de rupture à écrire. Le minimum se réassigne quand le contenu
   demande plus large. */

.sc-grid {
  --_grid-min: var(--measure-column-min);
  --_grid-gap: var(--gap-l);

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--_grid-min), 1fr));
  gap: var(--_grid-gap);
}

.sc-grid--s { --_grid-gap: var(--gap-s); }
.sc-grid--xl { --_grid-gap: var(--gap-xl); }

/* ---- Coquille d'application ----
   Plein écran, sans défilement de la fenêtre : c'est la zone principale
   qui défile, pour que la barre latérale reste en place. C'est ce motif
   que deux pages avaient nommé pareil en lui donnant des rôles opposés,
   coquille plein écran chez l'une, colonne de lecture chez l'autre. */

.sc-app {
  display: flex;
  block-size: 100dvh;
  overflow: hidden;
}

.sc-app__main {
  /* min-inline-size à zéro, sans quoi un tableau large pousse la zone
     principale au lieu de défiler à l'intérieur. */
  flex: 1;
  min-inline-size: 0;
  overflow-y: auto;
}

/* ---- Bande ----
   Le bandeau horizontal qui coiffe une zone : titre et actions d'un écran,
   barre d'outils au-dessus d'un tableau. Quatre agents construisant à
   l'aveugle l'ont réinventé, et le quatrième a produit un défaut visible :
   sa bande collante n'avait pas de plan, si bien que les cases à cocher
   du tableau lui passaient par-dessus au défilement.

   La cause vaut d'être écrite, parce qu'elle se reproduira. Une bande
   collée est un élément positionné, une case à cocher aussi (elle porte
   sa coche en pseudo-élément absolu). Deux éléments positionnés sans
   `z-index` se peignent dans l'ordre du DOM : ce qui vient après passe
   devant, même si l'autre est collé. D'où `--z-sticky`, qui existait dans
   les tokens sans que rien ne le consomme. */

.sc-bar {
  --_bar-bg: var(--color-bg-surface);
  /* La bande s'aligne sur la page qu'elle surmonte : deux marges
     différentes font décrocher le titre d'une barre du contenu qu'il
     annonce, et c'est visible dès qu'on descend de quelques pixels. */
  --_bar-padding-inline: var(--padding-3xl);
  --_bar-padding-block: var(--padding-l);
  --_bar-border: var(--border-hairline) solid var(--color-border);

  padding-inline: var(--_bar-padding-inline);
  padding-block: var(--_bar-padding-block);
  background: var(--_bar-bg);
  border-block-end: var(--_bar-border);
}

/* Collée en haut de la zone qui défile, avec son plan. Le modificateur
   porte le `z-index` pour qu'on ne puisse pas coller une bande en
   oubliant le plan : c'est ce couple qui manquait. */
.sc-bar--sticky {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
}

/* Au pied d'une zone : le filet passe au-dessus, la bande se colle en bas. */
.sc-bar--bottom {
  --_bar-border: none;

  border-block-start: var(--border-hairline) solid var(--color-border);
}

.sc-bar--bottom.sc-bar--sticky {
  inset-block-start: auto;
  inset-block-end: 0;
}
