/* ══════════════════════════════════════════════════════════════
   AZUROTEC — couche de finition
   Chargée après premium.css : elle gagne à spécificité égale.

   Quatre rôles, dans cet ordre de priorité :
     1. Accessibilité — skip-link, anneau de focus, cible tactile
     2. Stabilité visuelle — garde-fous anti-CLS sur les médias
     3. Mouvement autonome — le site s'anime même sans le CDN GSAP
     4. Finition éditoriale — grain, micro-interactions, filets

   Tout mouvement introduit ici est neutralisé sous
   prefers-reduced-motion, en bas de fichier.
   ══════════════════════════════════════════════════════════════ */

/* ═══ 1. Accessibilité ═══════════════════════════════════════ */

/* Premier élément focusable de la page : permet d'atteindre le
   contenu sans traverser les 8 liens de navigation au clavier. */
.skip-link {
  position: absolute;
  top: 0;
  inset-inline-start: 0;
  z-index: 10000;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-burgundy);
  color: var(--color-paper);
  font-family: var(--font-body);
  font-size: var(--text-label);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-120%);
  transition: transform var(--dur-s) var(--ease-out);
}
.skip-link:focus-visible { transform: translateY(0); }

/* Anneau unique, visible sur crème comme sur bordeaux. Le décalage
   double (blanc puis encre) le garde lisible sur photo. */
:where(a, button, [tabindex], input, textarea, select, summary):focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px rgba(243, 243, 236, .85);
  border-radius: 1px;
}
.hero :where(a, button):focus-visible,
.site-footer :where(a, button):focus-visible,
.ba-section :where(a, button):focus-visible,
.era-burgundy-panel :where(a, button):focus-visible {
  outline-color: var(--color-sky);
  box-shadow: 0 0 0 5px rgba(52, 12, 36, .85);
}

::selection { background: var(--color-sky); color: var(--color-burgundy); }

/* ═══ 2. Stabilité visuelle — anti-CLS ══════════════════════ */

/* Les 31 images du site n'ont pas d'attributs width/height : sans
   ratio réservé, chaque arrivée d'image repousse le contenu. On
   réserve la place en CSS, ce qui vaut aussi pour les médias
   distants dont on ne connaît pas les dimensions intrinsèques. */
.gallery-item img,
.reveal-img img { aspect-ratio: 4 / 3; }
.process-visual,
.service-asset { aspect-ratio: 16 / 10; }
.story-modal-visual img { aspect-ratio: 16 / 10; }

/* Le poster du héros porte le LCP : il ne doit jamais faire tressauter
   la mise en page pendant le chargement de la vidéo. */
.hero-media, .hero-video { background-color: var(--color-burgundy-2); }

/* Une image encore absente reste une surface calme, pas un trou blanc. */
img { background-color: var(--color-paper-2); }
.hero-slide img, .ba-stage img { background-color: var(--color-burgundy-2); }

/* ═══ 3. Mouvement autonome ═════════════════════════════════ */

/* GSAP et Lenis viennent de jsDelivr. Si le CDN est lent, bloqué par
   un réseau d'entreprise ou indisponible, l'ancien comportement était
   « aucune animation du tout » — le site tombait à plat sans le dire.
   polish.js pose .no-gsap dans ce cas et cette couche prend le relais
   en CSS pur. Elle ne s'active jamais quand GSAP est présent, donc
   aucune animation n'est jouée deux fois. */

html.no-gsap [data-inview] {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity var(--dur-m) var(--ease-out),
    transform var(--dur-m) var(--ease-out);
  transition-delay: var(--stagger, 0ms);
  will-change: opacity, transform;
}
html.no-gsap [data-inview].is-inview {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Les titres montent depuis un masque : le geste éditorial de la
   référence, obtenu sans JS. */
html.no-gsap [data-inview="mask"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-l) var(--ease-in-out);
  transition-delay: var(--stagger, 0ms);
}
html.no-gsap [data-inview="mask"].is-inview { clip-path: inset(0 0 -10% 0); }

/* Les médias se dévoilent par un volet, l'image restant fixe derrière. */
html.no-gsap [data-inview="wipe"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 100%);
  transition: clip-path var(--dur-xl) var(--ease-in-out);
  transition-delay: var(--stagger, 0ms);
}
html.no-gsap [data-inview="wipe"].is-inview { clip-path: inset(0 0 0 0); }
[dir="rtl"] html.no-gsap [data-inview="wipe"] { clip-path: inset(0 100% 0 0); }

/* ═══ 3b. Défilement natif (sans JS ni CDN) ═════════════════ */

/* animation-timeline pilote le mouvement par le compositeur : pas de
   listener de scroll, pas de reflow, et cela fonctionne même si tout
   le JavaScript échoue. Les navigateurs sans support ignorent le bloc. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Le filet de section se trace à l'entrée dans le viewport.
       Cible .section-eyebrow::after : le filet posé par editorial.css.
       (.section-head n'existe pas dans ce HTML — règle morte corrigée.) */
    .section-eyebrow::after,
    .era-panel-line {
      animation: rule-draw linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 32%;
    }
    /* Dérive lente des visuels : parallaxe discrète, jamais du
       scroll-jacking — la page garde son défilement natif. */
    .gallery-item img,
    .reveal-img img {
      animation: drift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
  }
}
@keyframes rule-draw { from { transform: scaleX(0); transform-origin: left; } to { transform: scaleX(1); } }
@keyframes drift { from { transform: scale(1.08) translateY(1.5%); } to { transform: scale(1.08) translateY(-1.5%); } }
[dir="rtl"] .section-eyebrow::after { transform-origin: right; }

/* ═══ 4. Finition éditoriale ════════════════════════════════ */

/* Grain papier — SVG en ligne, aucune requête réseau. C'est ce qui
   donne la matière « imprimé » au crème plat. */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Liens de navigation : le filet se trace depuis le bord d'attaque,
   et se retire du même côté — il suit la direction du texte en arabe. */
.site-nav a {
  position: relative;
  padding-block-end: 2px;
}
.site-nav a::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: inline-start;
  transition: transform var(--dur-s) var(--ease-out);
}
.site-nav a:hover::after,
.site-nav a:focus-visible::after { transform: scaleX(1); }

/* Boutons : l'enfoncement remplace le rebond. Durée courte, sortie
   en ease-out — un bouton qui traîne paraît cassé. */
.btn {
  transition:
    background-color var(--dur-s) var(--ease-out),
    color var(--dur-s) var(--ease-out),
    border-color var(--dur-s) var(--ease-out),
    transform 180ms var(--ease-out);
}
.btn:active { transform: translateY(1px) scale(.994); }

/* Cartes : l'ombre se creuse, le filet s'allume. Pas de lévitation —
   l'élévation reste feutrée, conformément aux tokens. */
.process-card, .service-card, .pricing-card, .gallery-item {
  transition:
    transform var(--dur-m) var(--ease-out),
    box-shadow var(--dur-m) var(--ease-out),
    border-color var(--dur-m) var(--ease-out);
}
.process-card:hover, .service-card:hover, .pricing-card:hover, .gallery-item:hover {
  box-shadow: var(--shadow-lg);
}

/* Le curseur doit annoncer ce qui est cliquable. */
.gallery-trigger, .process-card[data-modal], [role="button"] { cursor: pointer; }

/* Cible tactile : 44px minimum sur les contrôles compacts. */
@media (pointer: coarse) {
  .ba-tab, .site-nav a, .modal-close { min-height: 44px; min-width: 44px; }
}

/* Le wrapper <main> hérite du z-index de body > * ; on le fige pour
   que le grain et l'en-tête restent au-dessus. */
main { position: relative; z-index: 1; }

/* ═══ 5. Mouvement réduit ═══════════════════════════════════ */

/* Sévérité « High » dans les référentiels d'accessibilité : parallaxe
   et défilement piloté provoquent des nausées. On coupe tout, y
   compris ce que cette couche a introduit. */
@media (prefers-reduced-motion: reduce) {
  html.no-gsap [data-inview],
  html.no-gsap [data-inview="mask"],
  html.no-gsap [data-inview="wipe"] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }
  .section-eyebrow::after,
  .era-panel-line,
  .gallery-item img,
  .reveal-img img { animation: none !important; }
  .btn:active { transform: none; }
}
