/* =============================================================
   Socle · Menu (.sc-menu)
   Liste d'actions ancrée sous un déclencheur [data-menu-toggle],
   câblée par js/components/menu.js (initMenus).
   Anatomie : .sc-menu > déclencheur + __list > __label,
   __item (+ __shortcut), __separator.
   La liste est masquée par [hidden] ; --end l'aligne à droite.
   ============================================================= */

.sc-menu {
  /* Tokens de composant : l'alignement ne fait que réassigner ceci. */
  --_menu-min-width: 12rem;   /* dimension structurelle */

  position: relative;
  display: inline-block;
}

.sc-menu__list {
  /* L'alignement est un token de composant : la variante --end
     ne fait que réassigner ces deux ancres. */
  --_menu-inset-start: 0;
  --_menu-inset-end: auto;

  position: absolute;
  inset-block-start: calc(100% + var(--gap-2xs));
  inset-inline-start: var(--_menu-inset-start);
  inset-inline-end: var(--_menu-inset-end);
  z-index: var(--z-dropdown);
  min-width: var(--_menu-min-width);
  padding: var(--padding-xs);
  background: var(--color-bg-surface);
  border: var(--border-hairline) solid var(--color-border);
  border-radius: var(--radius-surface);
  box-shadow: var(--elevation-floating);
  list-style: none;
}

.sc-menu__list[hidden] {
  display: none;
}

/* Alignement sur le bord droit du déclencheur. */
.sc-menu__list--end {
  --_menu-inset-start: auto;
  --_menu-inset-end: 0;
}

/* ---- Items ---- */

.sc-menu__item {
  /* Les variantes ne font que réassigner ceci. */
  --_item-text: var(--color-text);
  --_item-icon: var(--color-text-muted);
  --_item-bg-hover: var(--color-bg-hover);
  --_item-bg-active: var(--color-bg-active);

  display: flex;
  align-items: center;
  gap: var(--gap-s);
  width: 100%;
  /* Même plancher que l'option d'un sélecteur : les deux sont des
     lignes de liste dans un panneau, elles ne peuvent pas se viser
     différemment. */
  min-block-size: var(--control-height-m);
  padding: var(--padding-m) var(--padding-l);
  border: none;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--_item-text);
  font-family: var(--font-body);
  font-size: var(--text-label-size);
  font-weight: var(--text-body-weight);
  line-height: var(--leading-snug);
  text-align: start;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--motion-fast),
    color var(--motion-fast);
}

/* L'icône reste discrète et suit la variante. */
.sc-menu__item svg {
  flex: none;
  color: var(--_item-icon);
}

/* Un item peut être un <a> plutôt qu'un <button> : la garde
   couvre donc :disabled ET [data-disabled], que menu.js écarte
   déjà de la navigation clavier. */
.sc-menu__item:is(:hover, [data-state="hover"]):not(:disabled):not([data-disabled]) {
  background: var(--_item-bg-hover);
}

.sc-menu__item:is(:active, [data-state="active"]):not(:disabled):not([data-disabled]) {
  background: var(--_item-bg-active);
}

/* Simulation du focus clavier pour la doc (le vrai focus passe
   par :focus-visible dans base.css). */
.sc-menu__item[data-state="focus"] {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

.sc-menu__item:disabled,
.sc-menu__item[data-disabled] {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
}

/* ---- Variante danger ---- */

.sc-menu__item--danger {
  --_item-text: var(--color-danger-text);
  --_item-icon: currentColor;
  --_item-bg-hover: var(--color-danger-subtle);
  /* L'enfoncé prend le cran au-dessus, sans quoi il rend le même pixel
     que le survol, alors que l'item ordinaire distingue bien les deux. */
  --_item-bg-active: var(--color-danger-subtle-hover);
}

/* ---- Structure de la liste ---- */

.sc-menu__separator {
  border: none;
  border-block-start: var(--border-hairline) solid var(--color-border);
  margin-block: var(--padding-xs);
  margin-inline: 0;
}

/* Sur-titre de groupe. La typographie vient de .sc-overline, dans
   css/base.css, auquel ce sélecteur est rattaché : il ne reste ici que
   le calage dans la liste. */
.sc-menu__label {
  display: block;
  padding: var(--padding-2xs) var(--padding-s);
}

/* Chasse fixe comme le sur-titre du groupe juste au-dessus : un
   raccourci clavier est une étiquette technique, et deux étiquettes
   techniques voisines ne se lisent pas dans deux polices. Le rôle du
   code plutôt que celui du sur-titre : ce sont des touches à recopier,
   pas un intitulé de section, donc ni capitales ni interlettrage. */
.sc-menu__shortcut {
  margin-inline-start: auto;
  padding-inline-start: var(--padding-l);
  color: var(--color-text-muted);
  font-family: var(--font-code);
  font-size: var(--text-caption-size);
}

/* ---- Le store ----
   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 ».
   Valeurs relevées sur la console Vibecoded : 220 ms à l'ouverture,
   150 à la fermeture, un pas de 14 ms à l'entrée et de 9 ms à la sortie,
   six lignes au plus à l'entrée et cinq à la sortie. Au-delà on attend
   le menu, et une liste de vingt entrées ferait défiler une vague
   jusqu'en bas.
   La fermeture est plus serrée que l'ouverture, et le bord remonte,
   donc les lignes du bas partent les premières : une entrée se regarde,
   on découvre ce qui arrive ; une sortie, on a déjà décidé et on attend
   que ça libère la place. La symétrie est dans le geste, pas dans la
   durée.
   base.css annule ces animations sous prefers-reduced-motion. */

.sc-menu__list {
  /* Dimensions et pas du geste. Le décalage vertical est trop court
     pour tomber sur un cran d'espacement : il ne déplace pas, il
     suggère que le panneau vient de plus haut. */
  --_store-lift: 3px;
  --_line-lift: 4px;
  --_line-base: 40ms;
  --_line-step: 14ms;
  --_fold-step: 9ms;
}

.sc-menu__list.is-unfolding {
  animation: sc-store-unfold var(--motion-enter) both;
}

/* Le panneau est encore dans le document pendant sa fermeture et
   intercepterait le clic suivant pendant un dixième de seconde, ce qui
   se ressent sans se voir. */
.sc-menu__list.is-folding {
  animation: sc-store-fold var(--motion-leave) both;
  pointer-events: none;
}

.sc-menu__list.is-unfolding .sc-menu__item {
  animation: sc-store-line var(--motion-base) both;
  animation-delay: calc(var(--_line-base) + 5 * var(--_line-step));
}

.sc-menu__list.is-unfolding .sc-menu__item:nth-child(1) { animation-delay: var(--_line-base); }
.sc-menu__list.is-unfolding .sc-menu__item:nth-child(2) { animation-delay: calc(var(--_line-base) + 1 * var(--_line-step)); }
.sc-menu__list.is-unfolding .sc-menu__item:nth-child(3) { animation-delay: calc(var(--_line-base) + 2 * var(--_line-step)); }
.sc-menu__list.is-unfolding .sc-menu__item:nth-child(4) { animation-delay: calc(var(--_line-base) + 3 * var(--_line-step)); }
.sc-menu__list.is-unfolding .sc-menu__item:nth-child(5) { animation-delay: calc(var(--_line-base) + 4 * var(--_line-step)); }

/* À la sortie, les lignes du bas partent les premières. */
.sc-menu__list.is-folding .sc-menu__item {
  animation: sc-store-line var(--motion-leave) reverse both;
  animation-delay: calc(4 * var(--_fold-step));
}

.sc-menu__list.is-folding .sc-menu__item:nth-last-child(1) { animation-delay: calc(0 * var(--_fold-step)); }
.sc-menu__list.is-folding .sc-menu__item:nth-last-child(2) { animation-delay: var(--_fold-step); }
.sc-menu__list.is-folding .sc-menu__item:nth-last-child(3) { animation-delay: calc(2 * var(--_fold-step)); }
.sc-menu__list.is-folding .sc-menu__item:nth-last-child(4) { animation-delay: calc(3 * var(--_fold-step)); }
