/* =============================================================
   Socle · Base
   Reset minimal + défauts typographiques + focus global.
   Consomme uniquement la couche sémantique.
   ============================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--color-bg-page);
  /* Après le raccourci, qui remet l'image à none en passant. */
  background-image: var(--page-texture);
  background-size: var(--page-texture-size);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body-size);
  font-weight: var(--text-body-weight);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
  /* `font` ne transporte ni la casse ni l'interlettrage, que la feuille du
     navigateur remet à zéro sur les contrôles. Un bouton posé dans un
     en-tête de colonne perdait ainsi les capitales du sur-titre. */
  text-transform: inherit;
  letter-spacing: inherit;
}

/* `[hidden]` vaut `display: none` dans la feuille du navigateur, avec la
   spécificité d'un sélecteur d'élément : n'importe quelle classe posant un
   `display` l'emporte, et l'élément reste visible. Le cas s'est présenté
   sur `.sc-cluster`, où une barre d'actions masquée continuait de
   s'afficher. La règle est ici plutôt que dans chaque composant, et sans
   `!important` pour qu'un composant garde le droit de la surcharger. */
[hidden] {
  display: none;
}

p,
h1,
h2,
h3,
h4 {
  overflow-wrap: break-word;
}

h1 {
  font-family: var(--font-heading);
  font-size: var(--text-h1-size);
  font-weight: var(--text-h1-weight);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

h2 {
  font-family: var(--font-heading);
  font-size: var(--text-h2-size);
  font-weight: var(--text-h2-weight);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

h3 {
  font-family: var(--font-heading);
  font-size: var(--text-h3-size);
  font-weight: var(--text-h3-weight);
  line-height: var(--leading-snug);
}

h4 {
  font-family: var(--font-heading);
  font-size: var(--text-h4-size);
  font-weight: var(--text-h4-weight);
  line-height: var(--leading-snug);
}

code,
pre,
kbd {
  font-family: var(--font-code);
  font-size: var(--text-code-size);
}

::selection {
  background: var(--color-accent-subtle-hover);
  color: var(--color-text);
}

/* Anneau de focus global : tous les composants en héritent. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* Lu, jamais vu. Pour un intitulé de colonne de service, une consigne
   destinée au seul lecteur d'écran, un libellé que l'icône remplace à
   l'œil. display:none et visibility:hidden retirent l'élément de
   l'arbre d'accessibilité : c'est exactement ce qu'on ne veut pas ici.
   La recette est celle qui survit à tout, y compris au retour à la
   ligne forcé d'un conteneur étroit. */
.sc-visually-hidden {
  /* Dimension structurelle : un pixel, et son opposé en marge pour que
     l'élément n'occupe rien du flux. Aucun rôle ne dit « un pixel qui
     n'existe pas ». */
  --_vh-size: 1px;

  position: absolute;
  width: var(--_vh-size);
  height: var(--_vh-size);
  margin: calc(var(--_vh-size) * -1);
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Petites utilitaires de texte */
.sc-text-secondary {
  color: var(--color-text-secondary);
}

.sc-text-muted {
  color: var(--color-text-muted);
}

.sc-caption {
  font-size: var(--text-caption-size);
  line-height: var(--leading-snug);
}

/* Sur-titre : le petit intitulé en capitales qui ouvre une section de
   navigation, un groupe de menu ou une colonne de tableau. Les mêmes six
   déclarations vivaient à l'identique dans table.css, sidebar.css et
   menu.css, donc trois retouches pour un seul changement de style. Elles
   vivent ici, dans la couche que tout le monde charge et que l'export
   embarque toujours.

   Le rôle est une classe et pas un jeu de tokens : un composant nouveau
   pose sc-overline sur son élément sans avoir à deviner quels six tokens
   composent l'intitulé, ni dans quel ordre. Les trois sélecteurs déjà en
   place y sont rattachés parce que leur balisage ne porte pas la classe,
   et c'est le seul point où ce fichier connaît un composant.

   La graisse reste réassignable par --_overline-weight, et un seul
   endroit s'en sert : la colonne triée d'un tableau, qui monte d'un
   cran pour se séparer des deux autres états de tri.

   La couleur est l'atténué ordinaire. Il portait un cran dédié tant
   que la palette l'exigeait ; depuis que les fonds adoucis se sont
   rapprochés du fond de page, l'atténué y tient ses 7 de contraste
   dans les deux thèmes, et un rôle qui rend toujours la même valeur
   qu'un autre n'est plus un rôle. */
.sc-overline,
.sc-table thead th,
.sc-sidebar__section-title,
.sc-menu__label,
.sc-divider__label {
  /* Régulière, pas grasse. Un sur-titre se distingue déjà par sa
     casse, son interlettrage et sa famille : lui ajouter du gras, c'est
     le quatrième signal pour dire la même chose, et sur une chasse
     étrange le gras épaissit un dessin déjà dense au point de le rendre
     moins lisible que le texte qu'il annonce.
     C'est aussi la valeur que Vibecoded spécifie pour ses deux emplois
     de cette famille, le micro-libellé et l'étiquette : 400 des deux
     côtés. */
  --_overline-weight: var(--text-body-weight);

  color: var(--color-text-muted);
  font-family: var(--font-overline);
  font-size: var(--text-caption-size);
  font-weight: var(--_overline-weight);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* =============================================================
   Le store
   Le geste d'ouverture d'un panneau, partagé par le menu et le
   sélecteur : un panneau ne fond pas, il se déroule, et ses lignes
   arrivent au moment où le bord passe devant elles. C'est ce décalage
   qui fait la différence entre « le panneau apparaît » et « le panneau
   se remplit ».
   Les images-clés vivent ici plutôt que dans un composant parce que
   deux composants les emploient et qu'aucun des deux ne doit dépendre
   de l'autre. Les distances, elles, se déclarent sur le panneau qui
   s'anime : chacun garde les siennes.
   ============================================================= */

@keyframes sc-store-unfold {
  from {
    opacity: 0.4;
    clip-path: inset(0 0 100% 0);
    transform: translateY(calc(var(--_store-lift) * -1));
  }
  to {
    opacity: 1;
    clip-path: inset(0 0 0 0);
    transform: translateY(0);
  }
}

@keyframes sc-store-fold {
  from {
    opacity: 1;
    clip-path: inset(0 0 0 0);
    transform: translateY(0);
  }
  to {
    opacity: 0.4;
    clip-path: inset(0 0 100% 0);
    transform: translateY(calc(var(--_store-lift) * -1));
  }
}

@keyframes sc-store-line {
  from {
    opacity: 0;
    transform: translateY(calc(var(--_line-lift) * -1));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
