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

/* --- Micro-interactions ("dopamine") ---
   Petites animations qui rendent le tactile satisfaisant, surtout sur
   mobile (nav du bas, boutons pill) : rebond d'apparition, pastille qui
   respire, effet de brillance au tap. Tout est enfermé dans
   prefers-reduced-motion: no-preference, donc totalement désactivé si
   l'utilisateur a demandé moins de mouvement (cf. variables.css). */
@keyframes pop-in {
  0% {
    transform: scale(0.55);
    opacity: 0;
  }
  65% {
    transform: scale(1.14);
    opacity: 1;
  }
  100% {
    transform: scale(1);
  }
}

@keyframes fade-slide-up {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes dot-pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.6;
  }
}

@keyframes shimmer-sweep {
  from {
    transform: translateX(-120%);
  }
  to {
    transform: translateX(120%);
  }
}

/* Cadre plein écran : chaque page occupe exactement la hauteur du
   viewport — en-tête et pagination/nav restent toujours visibles, jamais
   besoin de scroller la page pour les atteindre. `.page` (le contenu
   propre à chaque section) reçoit l'espace restant et défile *en interne*
   si son contenu est plus long que cet espace, plutôt que de faire
   grandir le document entier. */
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  height: 100dvh;
}

#site-nav,
#site-pagination {
  flex: 0 0 auto;
}

ul,
ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  border: none;
  background: none;
  cursor: pointer;
}

img {
  max-width: 100%;
  display: block;
}

/* Typographie de base */
body {
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.5;
  background: var(--bg-light);
  color: var(--text-on-light);
  -webkit-font-smoothing: antialiased;
}

body.theme-dark {
  background: var(--bg-dark);
  color: var(--text-on-dark);
}

/* Direction "Hamza style" (Révision 2026-09-09) : titres display en
   majuscules, condensés, serrés — Anton est une police à graisse unique,
   pas besoin de font-weight custom. */
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  margin: 0;
}

.page {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 1080px;
  width: 100%;
  margin: 0 auto;
  /* max(…, env(safe-area-inset-*)) : garde 20px par défaut, et pousse le
     contenu au-delà de l'encoche en paysage sur iPhone (encoche latérale). */
  padding: 32px max(20px, env(safe-area-inset-right)) 40px max(20px, env(safe-area-inset-left));
}

/* Focus clavier visible et cohérent avec la palette */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* En-tête de section réutilisable (Musique, Vidéos, Actualités, Photos, Dates, Contact) */
.section-header {
  margin-bottom: 32px;
}

.section-header__label {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 8px;
}
body.theme-dark .section-header__label {
  color: var(--text-muted-on-dark);
}

.section-header__title {
  font-size: clamp(36px, 7.5vw, 84px);
  margin-bottom: 12px;
}

.section-header--dark .section-header__title {
  color: var(--text-on-dark);
}

.section-header__desc {
  color: var(--text-muted);
  max-width: 42ch;
  margin: 0;
}

.section-header--dark .section-header__desc,
body.theme-dark .section-header__desc {
  color: var(--text-muted-on-dark);
}

/* --- Boutons pilule (composant PillButton) --- */
.pill {
  position: relative; /* contient un éventuel enfant .visually-hidden (cf. réseaux
    sociaux Contact) : sans ancêtre positionné, un span position:absolute
    remonte jusqu'à la racine du document et fausse sa hauteur de scroll. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 22px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: transform var(--transition-fast), opacity var(--transition-fast),
    background-color var(--transition-fast);
}

.pill--accent {
  background: var(--accent);
  color: var(--text-on-dark);
}
.pill--accent:hover,
.pill--accent:focus-visible {
  background: var(--accent-hover);
  transform: translateY(-2px);
}

/* CTA principaux (Écouter, Envoyer, plateformes de streaming) : brillance
   qui balaie le bouton au survol/focus — overflow: hidden le confine à la
   forme pilule, ::after ne touche jamais le contenu (pointer-events: none). */
.pill--accent,
.pill--light {
  overflow: hidden;
}
.pill--accent::after,
.pill--light::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.4) 50%, transparent 60%);
  transform: translateX(-120%);
}
@media (prefers-reduced-motion: no-preference) {
  .pill--accent:hover::after,
  .pill--accent:focus-visible::after,
  .pill--light:hover::after,
  .pill--light:focus-visible::after {
    animation: shimmer-sweep 750ms ease;
  }
}

.pill--light {
  background: var(--bg-card);
  color: var(--bg-dark);
}
.pill--light:hover,
.pill--light:focus-visible {
  transform: translateY(-2px);
}

.pill--dark {
  background: var(--bg-dark-elevated);
  color: var(--text-on-dark);
}
.pill--dark:hover,
.pill--dark:focus-visible {
  transform: translateY(-2px);
}

.pill--outline {
  background: transparent;
  color: var(--text-on-light);
  border: 1px solid var(--border-subtle);
}
.pill--outline:hover,
.pill--outline:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}
/* Utilisée directement sur le fond de page (onglets Musique) : contrairement
   à .embed-card/.video-card (cartes claires autonomes), elle doit suivre le
   thème de la page — cf. Révision 2026-09-05, pages en fond sombre partout. */
body.theme-dark .pill--outline {
  color: var(--text-on-dark);
  border-color: var(--border-on-dark);
}
body.theme-dark .pill--outline:hover,
body.theme-dark .pill--outline:focus-visible {
  border-color: var(--accent-on-dark);
  color: var(--accent-on-dark);
}

.pill--outline-light {
  background: transparent;
  color: var(--text-on-dark);
  border: 1px solid var(--border-on-dark);
}
.pill--outline-light:hover,
.pill--outline-light:focus-visible {
  border-color: var(--text-on-dark);
}

.pill--neutral {
  background: var(--bg-card);
  color: var(--text-on-light);
  border: 1px solid var(--border-subtle);
}

.pill--disabled,
.pill[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
  transform: none !important;
}

/* Retour tactile immédiat au tap — surtout utile sur mobile, où il n'y a
   pas de :hover pour signaler qu'un bouton a réagi. Placé après les règles
   :hover ci-dessus pour gagner sur les transform en cas d'égalité de
   spécificité (même sélecteur `.pill--accent`/`.pill--light`). */
.pill:active {
  transform: scale(0.94);
}
.pill--sent {
  animation: pop-in 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* --- Badge --- */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.badge--accent {
  background: var(--accent);
  color: var(--text-on-dark);
}

.badge--neutral {
  background: var(--border-subtle);
  color: var(--text-muted);
}

/* --- Placeholder média (motif diagonal) --- */
.placeholder-media {
  position: relative;
  background-color: var(--bg-card);
  background-image: repeating-linear-gradient(
    45deg,
    var(--border-subtle),
    var(--border-subtle) 2px,
    transparent 2px,
    transparent 12px
  );
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

/* --- En-tête : logo + nav + CTA + bouton menu ---
   Élément flex fixe du cadre plein écran (cf. body/.page ci-dessus) :
   reste toujours visible, .page défile en interne sous lui si besoin.
   Essai "bandeau plein largeur, coins arrondis en bas" (Révision
   2026-09-09, référence supaste.com/updates, desktop ET mobile) : remplace
   la piste pilule puis la barre flottante en pilule des essais précédents
   par un bandeau plaqué contre le haut de l'écran sur toute sa largeur,
   avec juste les coins bas arrondis — `position: relative` pour ancrer le
   panneau de nav mobile (`position: absolute`, cf. @media max-width:767px
   plus bas). */
.site-header {
  position: relative;
  flex: 0 0 auto;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px max(20px, env(safe-area-inset-right)) 14px max(20px, env(safe-area-inset-left));
  border-radius: 0 0 24px 24px;
  background: var(--bg-light);
}
/* Le flou est posé sur un ::before plutôt que directement sur .site-header :
   un `backdrop-filter` (ou `filter`/`transform`) sur un élément crée un
   "containing block" pour SES descendants en `position: fixed` — le menu
   plein écran mobile (`.site-nav`, imbriqué dans le header, cf. src/nav.ts)
   se retrouvait alors positionné par rapport à la petite boîte du header au
   lieu du viewport entier (bug repéré à la vérification Playwright de la
   révision "menu plein écran mobile", 2026-09-09). Un ::before a le flou
   sans porter lui-même de descendant fixed, donc le problème disparaît. */
body.theme-dark .site-header {
  background: transparent;
}
body.theme-dark .site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: rgba(24, 24, 15, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.site-header__logo {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: 20px;
  color: var(--text-on-light);
  flex-shrink: 0;
}
body.theme-dark .site-header__logo {
  color: var(--text-on-dark);
}

/* CTA "Écouter" — desktop uniquement (masqué <768px, cf. media query plus
   bas) : sur mobile il est repris comme dernier lien du plein écran
   (`.site-nav__link--cta`, cf. plus bas), pas dans la barre elle-même. */
.site-header__cta {
  display: none;
  flex-shrink: 0;
  white-space: nowrap;
}

.site-nav {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
}

/* Desktop (≥768px, cf. media query plus bas pour <768px) : piste de liens
   texte plat, façon hamza.net — plus de piste pilule ni de fond. */
.site-nav__list {
  display: flex;
  gap: 28px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  max-width: 100%;
}
.site-nav__list::-webkit-scrollbar {
  display: none;
}

.site-nav__item {
  flex: 0 0 auto;
}

.site-nav__link {
  position: relative; /* contient .site-nav__label (cf. .pill, même raison) */
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  font-family: var(--font-display);
  font-size: 14px;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--text-on-light);
  opacity: 0.55;
  transition: opacity var(--transition-fast);
}
body.theme-dark .site-nav__link {
  color: var(--text-on-dark);
}
.site-nav__link:hover,
.site-nav__link:focus-visible {
  opacity: 1;
}

.site-nav__link svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: none;
}

/* Lien CTA "Écouter" du plein écran mobile (cf. src/nav.ts) — masqué par
   défaut/desktop : sur desktop le vrai CTA est `.site-header__cta` dans la
   barre, ce lien n'existe que pour le plein écran mobile (réactivé dans le
   @media max-width:767px plus bas). Doit rester déclaré APRÈS `.site-nav__link`
   ci-dessus (même spécificité — sinon ce `display: none` perd le conflit et
   le lien reste visible ; bug repéré et corrigé à la vérification de cette
   révision, il s'affichait collé après "Contact" dans la nav desktop). */
.site-nav__link--cta {
  display: none;
}

/* Sélecteur de langue FR/EN (cf. src/nav.ts, buildLocaleToggle) — même
   duplication desktop/mobile que le CTA "Écouter" : `--bar` dans la barre
   (desktop), `--panel` dans le plein écran mobile, jamais les deux visibles
   ensemble (cf. media queries plus bas). */
.locale-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  border: 1px solid var(--border-on-dark);
  flex-shrink: 0;
}
.locale-toggle__option {
  padding: 4px 10px;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  border-radius: 999px;
  color: var(--text-muted-on-dark);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.locale-toggle__option--active {
  background: rgba(255, 252, 240, 0.12);
  color: var(--text-on-dark);
}
.locale-toggle--bar {
  display: none;
}
.locale-toggle--panel {
  display: none;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.site-nav__link--active {
  opacity: 1;
}
/* Rebond d'apparition de l'onglet actif à chaque chargement de page — donne
   un peu de vie à une nav par ailleurs statique (site multi-pages, pas de
   SPA : ce rebond ne se rejoue qu'au (re)chargement, ce qui est voulu). */
@media (prefers-reduced-motion: no-preference) {
  .site-nav__link--active {
    animation: pop-in 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
  }
}

.site-nav__link:active {
  transform: scale(0.96);
}

.error-state {
  color: var(--text-muted);
  padding: 40px 0;
}
body.theme-dark .error-state {
  color: var(--text-muted-on-dark);
}

/* < 768px : la nav quitte la barre pour devenir un plein écran noir,
   pattern exact de hamza.net (demande de BABS, 2026-09-09 : "enleve les
   icone et fait le comme le nav bar en mobile de hamza.net") — remplace la
   colonne verticale d'icônes de l'essai précédent. Fermé par défaut
   (`display: none`), ouvert via le bouton texte "MENU" (`.site-header__toggle`,
   cf. src/nav.ts). Liens en très grand, majuscules, empilés à gauche,
   **sans icône** — plus besoin de `NAV_ICONS` sur mobile. */
@media (max-width: 767px) {
  .site-header {
    padding: 14px max(16px, env(safe-area-inset-right)) 14px max(16px, env(safe-area-inset-left));
  }

  /* Le logo reste visible par-dessus le plein écran ouvert (même logique
     de z-index que `.site-header__toggle` ci-dessous). */
  .site-header__logo {
    position: relative;
    z-index: 250;
  }

  /* `position: relative` + `z-index` plus haut que `.site-nav` (200) —
     sans ça le bouton (pourtant après `.site-nav` dans le flux) reste
     invisible aux clics une fois le plein écran ouvert : un élément non
     positionné n'a pas de z-index effectif, donc l'overlay `position: fixed`
     du menu passe systématiquement par-dessus. Repéré et corrigé lors de
     la vérification Playwright de cette révision (bouton "FERMER"
     inatteignable après ouverture). */
  .site-header__toggle {
    position: relative;
    z-index: 250;
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    font-family: var(--font-display);
    font-size: 16px;
    text-transform: uppercase;
    letter-spacing: -0.005em;
    color: var(--text-on-dark);
  }

  .site-header__cta {
    display: none;
  }

  /* `justify-content: flex-start` + un padding-top qui dégage l'en-tête,
     pas `center` : avec 6 onglets + le CTA en très grand texte, le total
     dépasse la hauteur de beaucoup de mobiles, et un flex centré ne laisse
     pas toujours défiler jusqu'au contenu qui dépasse en haut — testé et
     confirmé cassé lors de la vérification Playwright de cette révision. */
  .site-nav {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 200;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 28px;
    padding: 96px max(24px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom))
      max(24px, env(safe-area-inset-left));
    background: var(--bg-dark);
    overflow-y: auto;
  }
  .site-nav--open {
    display: flex;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    overflow: visible;
    max-width: none;
    width: 100%;
  }

  .site-nav__item {
    flex: none;
    width: 100%;
  }

  .site-nav__link {
    width: 100%;
    height: auto;
    padding: 6px 0;
    font-size: clamp(40px, 13vw, 64px);
    letter-spacing: -0.01em;
    line-height: 0.98;
    opacity: 1;
    color: var(--text-on-dark);
  }
  body.theme-dark .site-nav__link--active {
    color: var(--accent-on-dark);
  }
  .site-nav__link--active {
    color: var(--accent);
  }

  /* Dernier lien du plein écran : le CTA "Écouter" (cf. src/nav.ts) — même
     taille que les autres liens mais en accent, pour se distinguer comme
     action plutôt que destination. */
  .site-nav__link--cta {
    display: flex;
    margin-top: 8px;
    font-size: clamp(28px, 9vw, 40px);
  }
  body.theme-dark .site-nav__link--cta {
    color: var(--accent-on-dark);
  }
  .site-nav__link--cta {
    color: var(--accent);
  }

  .locale-toggle--panel {
    display: inline-flex;
    margin-top: 20px;
  }
}

/* Empêche le fond de défiler derrière le plein écran mobile ouvert (classe
   posée sur <body> par src/nav.ts, retirée à la fermeture). */
.site-nav-open-lock {
  overflow: hidden;
}

/* Plus de pagination bas de page (Révision 2026-09-09, direction "Hamza
   style") : hamza.net n'en a pas — la nav texte plat en en-tête suffit à se
   repérer dans 6 pages. Le conteneur reste dans le HTML (id="site-pagination",
   requis par src/main.ts) mais n'est plus rendu visuellement nulle part. */
.site-pagination {
  display: none;
}

@media (min-width: 768px) {
  .page {
    padding: 40px max(32px, env(safe-area-inset-right)) 56px max(32px, env(safe-area-inset-left));
  }

  .site-pagination {
    padding-left: max(32px, env(safe-area-inset-left));
    padding-right: max(32px, env(safe-area-inset-right));
  }

  .site-header__cta {
    display: inline-flex;
  }

  .locale-toggle--bar {
    display: inline-flex;
  }

  .site-header__toggle {
    display: none;
  }
}
