/* ==========================================================================
   components.css — utilitaires transverses réutilisables sur tout le site
   ========================================================================== */

/* --------------------------------------------------------------------------
   Container
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --------------------------------------------------------------------------
   .full-bleed — un média sort de .container pour toucher les deux bords du
   viewport, pendant que le texte qui l'entoure reste contenu (audit-stanford/
   scroll-mechanics-v2.md : chez Stanford, seuls le hero et les vidéos
   « chapitre » sont réellement pleine largeur — pas les images de section
   courantes). width:100vw déborderait de la largeur visible quand la
   scrollbar verticale est affichée (100vw compte la scrollbar, pas la zone
   réellement visible) : neutralisé par overflow-x:hidden sur <html>, voir
   main.css.
   -------------------------------------------------------------------------- */
.full-bleed {
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

/* --------------------------------------------------------------------------
   Accessibilité
   -------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Focus unifié sur tout élément interactif */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--primary);
  outline-offset: var(--focus-offset);
  border-radius: 1px;
}

/* Skip link : invisible jusqu'au focus clavier */
.skip-link {
  position: fixed;
  top: 0;
  left: var(--gutter);
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--primary);
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  text-decoration: none;
  transform: translateY(-120%);
  transition: transform var(--dur-fast) var(--ease);
}

.skip-link:focus-visible {
  transform: translateY(0);
  outline-offset: 0;
}

/* --------------------------------------------------------------------------
   Eyebrow — surtitre type « News / Athletics »
   -------------------------------------------------------------------------- */
.eyebrow {
  margin: 0;
  color: var(--primary);
  font-family: var(--font-body);
  font-size: var(--fs-meta);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: var(--ls-meta);
  text-transform: uppercase;
}

.eyebrow--muted {
  color: var(--cool-grey);
}

/* --------------------------------------------------------------------------
   .link-arrow — CTA texte + flèche, soulignement animé de 0 → 100 %
   -------------------------------------------------------------------------- */
.link-arrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding-bottom: 0.35em;
  color: var(--primary);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
}

.link-arrow::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 2px;
  background-color: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-slow) var(--ease);
}

.link-arrow:hover::after,
.link-arrow:focus-visible::after {
  transform: scaleX(1);
}

.link-arrow__icon {
  flex: none;
  width: 1em;
  height: 1em;
  transition: transform var(--dur-slow) var(--ease);
}

.link-arrow:hover .link-arrow__icon,
.link-arrow:focus-visible .link-arrow__icon {
  transform: translateX(0.28em);
}

/* --------------------------------------------------------------------------
   Boutons — bouton plein arrondi (aplat de couleur d'accent), patron
   mesuré sur stanford.edu (« Stanford Report », section Actualités —
   audit-stanford/geometrie/02-actualites-news.png) : composant partagé,
   utilisé par le header (Candidater), la recherche et Actualités.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.7em 1.35em;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--white);
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--dur-base) var(--ease),
              border-color var(--dur-base) var(--ease),
              color var(--dur-base) var(--ease);
}

.btn--primary {
  background-color: var(--primary);
}

.btn--primary:hover {
  background-color: var(--primary-dark);
}

.btn--ghost {
  border-color: var(--border);
  background-color: transparent;
  color: var(--black);
}

.btn--ghost:hover {
  border-color: var(--primary);
  color: var(--primary);
}

/* --------------------------------------------------------------------------
   Bouton icône (loupe, burger…)
   -------------------------------------------------------------------------- */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--black);
  transition: color var(--dur-base) var(--ease);
}

.icon-btn:hover {
  color: var(--primary);
}

.icon-btn svg {
  width: 20px;
  height: 20px;
}

/* --------------------------------------------------------------------------
   .reveal — animé par IntersectionObserver (main.js), une seule fois
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 1;
  transform: none;
}

/* L'état initial masqué n'est appliqué que si JS est disponible,
   sinon le contenu resterait invisible sans script. */
.js .reveal {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition: opacity var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease);
  will-change: opacity, transform;
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: auto;
}

/* Décalages en cascade pour les groupes */
.js .reveal[data-reveal-delay="1"] { transition-delay: 100ms; }
.js .reveal[data-reveal-delay="2"] { transition-delay: 200ms; }
.js .reveal[data-reveal-delay="3"] { transition-delay: 300ms; }
.js .reveal[data-reveal-delay="4"] { transition-delay: 400ms; }

/* --------------------------------------------------------------------------
   Mouvement réduit : on ne garde que l'opacité
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .js .reveal {
    transform: none;
    transition: opacity var(--dur-base) linear;
  }

  .js .reveal.is-visible {
    transform: none;
  }

  .link-arrow::after {
    transition: none;
    transform: scaleX(1);
    opacity: 0;
  }

  .link-arrow:hover::after,
  .link-arrow:focus-visible::after {
    opacity: 1;
  }

  .link-arrow__icon,
  .link-arrow:hover .link-arrow__icon {
    transform: none;
    transition: none;
  }

  .skip-link {
    transition: none;
  }
}
