/*
Theme Name: XL Studio
Theme URI: https://example.com
Author: Xavier Lamoureux
Author URI: https://example.com
Description: Thème sur mesure pour XL Studio — création de sites web, hébergement et applications. Système de design adapté de atolldigital.com (préfixe xl-), conçu pour être modifié facilement dans WordPress.
Version: 2.5
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: xl-studio
*/

/* ==================================================================
   1. JETONS DE DESIGN
   ================================================================== */
:root {
  --xl-ink:        #091423;
  --xl-bg:         #F0F1F4;
  --xl-bg-alt:     #F9F9F9;
  --xl-white:      #FFFFFF;
  --xl-teal:       #2C7C93;
  --xl-orange:     #E14E24;
  --xl-border:     rgba(9, 20, 35, 0.1);
  --xl-border-strong: rgba(9, 20, 35, 0.28);

  --xl-font-heading: 'Space Grotesk', Arial, sans-serif;
  --xl-font-body:    'Space Grotesk', Arial, sans-serif;
  --xl-font-serif:   'Fraunces', Georgia, serif;
  --xl-text-hero:    clamp(2.4rem, 5.5vw, 4.6rem);
  --xl-text-h2:      clamp(1.9rem, 4vw, 3rem);
  --xl-text-h3:      1.4rem;
  --xl-text-body:    1.05rem;
  --xl-text-small:   0.875rem;
  --xl-text-eyebrow: 0.75rem;

  --xl-space-section: clamp(3.5rem, 8vw, 6.5rem);
  --xl-space-gap:     1.5rem;
  --xl-radius:        6px;
  --xl-max-width:     72rem;
}

/* ==================================================================
   2. RESET & BASE
   ================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--xl-bg);
  color: var(--xl-ink);
  font-family: var(--xl-font-body);
  font-size: var(--xl-text-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--xl-teal);
  outline-offset: 3px;
}
h1, h2, h3, h4 {
  font-family: var(--xl-font-heading);
  font-weight: 500;
  line-height: 1.1;
  margin: 0 0 0.6em;
}
p { margin: 0 0 1em; }
ul { margin: 0; padding: 0; list-style: none; }

/* Le site source ne centre pas son contenu dans une colonne étroite : il
   travaille en pleine largeur avec une petite marge latérale (mesurée à
   27 px sur 1920, soit 1,4vw), et ce sont les filets qui structurent la
   page. Un conteneur centré à 72rem laissait de grandes marges vides et
   faisait retourner à la ligne les grands textes tous les deux mots.
   La longueur de ligne du texte courant est plutôt limitée composant par
   composant (.xl-content, .xl-statement-note, .xl-row-item p). */
.xl-wrap {
  max-width: none;
  margin: 0;
  padding: 0 clamp(1.25rem, 1.4vw, 2rem);
}
.screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px); white-space: nowrap;
}

/* ==================================================================
   3. EN-TÊTE / NAVIGATION
   ================================================================== */
.xl-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(240, 241, 244, 0.95);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--xl-border);
  transition: box-shadow 0.3s ease;
}
.xl-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem clamp(1.25rem, 1.4vw, 2rem);
  max-width: none;
  margin: 0;
  transition: padding 0.3s ease;
}
.xl-header.is-scrolled { box-shadow: 0 1px 24px rgba(9, 20, 35, 0.08); }
.xl-header.is-scrolled .xl-header-inner { padding: 0.55rem clamp(1.25rem, 1.4vw, 2rem); }

/* Sur l'accueil seulement : le bloc d'ouverture (.xl-hero) a déjà son
   propre menu intégré (.xl-hero-nav, voir section 10) — la barre .xl-header
   séparée resterait redondante superposée par-dessus tant qu'on est tout
   en haut de la page. Elle reste dans le DOM (accessibilité, mobile) mais
   masquée et sans hauteur jusqu'au premier défilement, moment où
   js/main.js ajoute .is-scrolled — elle prend alors le relais comme barre
   collante compacte, exactement comme le comportement observé sur le
   site source. */
body.home .xl-header {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
  border-bottom-color: transparent;
  overflow: hidden;
  transition: max-height 0.35s ease, opacity 0.3s ease;
}
body.home .xl-header.is-scrolled {
  max-height: 6rem;
  opacity: 1;
  pointer-events: auto;
  border-bottom-color: var(--xl-border);
}
@media (prefers-reduced-motion: reduce) {
  body.home .xl-header { transition: none; }
}
.xl-logo {
  font-family: var(--xl-font-heading);
  font-weight: 700;
  font-size: 1.4rem;
  letter-spacing: -0.02em;
  color: var(--xl-ink);
  transition: opacity 0.2s ease;
}
.xl-logo:hover { opacity: 0.7; }
.xl-nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--xl-border-strong);
  border-radius: 4px;
  padding: 0.4rem 0.6rem;
  font-family: var(--xl-font-heading);
  cursor: pointer;
}
.xl-nav ul {
  display: flex;
  align-items: center;
  gap: 1.75rem;
}
/* Les liens de menu reprennent le traitement relevé sur le site source :
   minuscules, et un petit triangle très pâle (l'encre à 20 % d'opacité,
   PAS un accent de couleur plein) qui devient net au survol. L'orientation
   du triangle est celle du site source — mesurée dans son SVG :
   sommets (100% 0), (100% 100%), (0 0). */
.xl-nav a {
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  gap: 0.55em;
  text-transform: lowercase;
  position: relative;
}
.xl-nav a::before {
  content: "";
  display: inline-block;
  flex: none;
  width: 0.5em;
  height: 0.5em;
  background: var(--xl-ink);
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  opacity: 0.2;
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.xl-nav a:hover::before { opacity: 1; transform: translate(2px, -2px); }
.xl-nav .xl-btn { margin-left: 0.5rem; }

/* Défilement du libellé au survol ("roll") : le libellé est enfermé dans
   une boîte de la hauteur d'une ligne, avec une deuxième copie identique
   juste en dessous ; au survol l'ensemble glisse d'une ligne vers le haut,
   la copie du bas prend la place de celle du haut. C'est le mécanisme
   exact du site source (deux copies empilées dans un conteneur en
   overflow:hidden). La structure est ajoutée par js/main.js — sans
   JavaScript, le lien reste un lien normal parfaitement lisible. */
.xl-roll {
  display: block;
  overflow: hidden;
  height: 1em;
}
.xl-roll-inner {
  display: block;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.xl-roll-inner > span {
  display: block;
  height: 1em;
  line-height: 1em;
}
.xl-nav a:hover .xl-roll-inner,
.xl-btn:hover .xl-roll-inner { transform: translateY(-1em); }

/* Menu du bloc d'ouverture : nettement plus grand que celui de la barre
   collante — 26,67 px sur un écran de 1920 sur le site source, soit
   1,39vw, ce qui donne la même présence typographique à toutes tailles. */
.xl-hero-nav a {
  font-size: clamp(1rem, 1.39vw, 1.7rem);
  font-weight: 500;
  gap: 0.6em;
}
.xl-hero-nav ul { gap: 2.1vw; flex-wrap: wrap; row-gap: 0.5rem; }

@media (max-width: 780px) {
  .xl-nav-toggle { display: inline-flex; }
  /* #xl-primary-nav seulement : la nav du hero (.xl-hero-nav) n'a pas de
     bouton "Menu" pour la déplier, elle doit rester visible en tout temps
     et simplement passer à la ligne (voir .xl-hero-nav-row plus bas). */
  #xl-primary-nav.xl-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--xl-bg);
    border-bottom: 1px solid var(--xl-border);
    padding: 1rem 1.5rem 1.5rem;
  }
  #xl-primary-nav.xl-nav.is-open { display: block; }
  #xl-primary-nav.xl-nav ul { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .xl-hero-nav ul { gap: 1.1rem 1.4rem; }
}

/* ==================================================================
   4. ÉTIQUETTES, BOUTONS, BADGES (composants du design-tokens.css)
   ================================================================== */
/* Étiquette ("eyebrow"). Mesures du site source : 11,38 px sur un écran
   de 1366 (0,83vw), graisse 500, majuscules, interlettrage NORMAL, et
   la couleur de l'encre — pas un accent de couleur, pas de triangle
   devant, pas d'interlettrage large. C'est un simple repère discret. */
.xl-eyebrow {
  display: block;
  font-family: var(--xl-font-heading);
  font-size: clamp(0.68rem, 0.83vw, 0.85rem);
  font-weight: 500;
  letter-spacing: normal;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--xl-ink);
  margin-bottom: 0.75rem;
}
.xl-section--dark .xl-eyebrow { color: var(--xl-bg); }

/* Bouton. Mesures du site source : fond encre plein, texte blanc,
   AUCUNE bordure, rayon ~5 px, majuscules, 13,28 px graisse 500,
   interlettrage normal, remplissage horizontal généreux (~38 px).
   Les coins orange en biais des versions précédentes n'existent pas
   sur le site source — retirés. Au survol, le libellé défile d'une
   ligne, exactement comme les liens du menu (voir .xl-roll). */
.xl-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--xl-font-heading);
  font-weight: 500;
  font-size: clamp(0.78rem, 0.97vw, 0.95rem);
  letter-spacing: normal;
  text-transform: uppercase;
  min-height: clamp(2.9rem, 4.17vw, 3.9rem);
  padding: 0 clamp(1.5rem, 2.78vw, 2.6rem);
  border-radius: 5px;
  border: none;
  cursor: pointer;
  background: var(--xl-ink);
  color: var(--xl-white);
  overflow: hidden;
  transition: opacity 0.25s ease;
}
.xl-btn:hover { opacity: 0.88; }
.xl-btn--ghost {
  background: transparent;
  color: var(--xl-ink);
  box-shadow: inset 0 0 0 1px var(--xl-ink);
}
.xl-btn--inverse { background: var(--xl-bg); color: var(--xl-ink); }
.xl-section--dark .xl-btn--ghost { color: var(--xl-bg); box-shadow: inset 0 0 0 1px rgba(240,241,244,0.5); }

.xl-btn-row { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1.75rem; }

.xl-badge {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--xl-ink);
  border-radius: 0; /* mesuré à 0 sur le site source, pas d'arrondi */
  padding: 0.6rem 1rem;
  transition: border-color 0.2s ease;
}
.xl-badge-label {
  font-family: var(--xl-font-heading);
  font-size: clamp(0.62rem, 0.78vw, 0.78rem);
  font-weight: 500;
  letter-spacing: normal;
  text-transform: uppercase;
  max-width: 9em;
  line-height: 1.25;
  text-align: right;
  padding-right: 0.9rem;
  margin-right: 0.9rem;
  border-right: 1px solid var(--xl-ink);
}
/* Le second segment du badge est dans une face éditoriale contrastée
   (relevé sur le site source : leur « ©2016 » et leur « 11 » ne sont pas
   dans la police du reste du site). */
.xl-badge-num {
  font-family: var(--xl-font-serif);
  font-weight: 400;
  font-size: clamp(1rem, 1.25vw, 1.3rem);
  line-height: 1.2;
}
.xl-section--dark .xl-badge { border-color: rgba(240,241,244,0.3); }
.xl-section--dark .xl-badge-label { border-color: rgba(240,241,244,0.3); }

/* ==================================================================
   5. SECTIONS
   ================================================================== */
/* Les sections sont séparées par un filet plein, pas par un gris pâle :
   c'est la grille de filets noirs qui structure la page sur le site
   source. Le rythme vertical y est plus serré que ce que le thème avait
   (les blocs se touchent, séparés par un trait, plutôt que de flotter
   dans de grandes marges). */
.xl-section {
  padding: var(--xl-space-section) 0;
  border-bottom: 1px solid var(--xl-ink);
}
.xl-section--dark {
  background: var(--xl-ink);
  color: var(--xl-bg);
  border-bottom-color: var(--xl-ink);
}
.xl-section--alt { background: var(--xl-bg-alt); }
.xl-section-head { max-width: 46rem; margin-bottom: var(--xl-space-gap); }
.xl-section h2 {
  font-size: clamp(1.8rem, 3.89vw, 3.6rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* Mot-repère géant en tête de section. Mesuré à 9,72vw, graisse 500,
   sans majuscules forcées, débordant volontairement de la grille — c'est
   le marqueur de section du site source. */
.xl-giant {
  font-family: var(--xl-font-heading);
  font-weight: 500;
  font-size: 9.72vw;
  line-height: 0.85;
  letter-spacing: -0.035em;
  margin: 0;
  padding: 0 0 0.08em;
  color: var(--xl-ink);
  overflow: hidden;
}
.xl-section--dark .xl-giant { color: var(--xl-bg); }

/* Énoncé : petite étiquette dans la marge de gauche, puis un texte large
   dont la première ligne est décalée pour lui laisser la place. */
.xl-statement { position: relative; padding-top: 0.2em; }
.xl-statement .xl-eyebrow {
  position: absolute;
  top: 0.55em;
  left: 0;
  margin: 0;
}
/* :not(.xl-eyebrow) est nécessaire : l'étiquette est elle aussi un <p>
   dans ce bloc, et sans cette exclusion elle héritait de la taille de
   l'énoncé et venait se superposer au texte. */
.xl-statement p:not(.xl-eyebrow) {
  font-size: clamp(1.35rem, 3.89vw, 3.6rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0;
  /* Décale la première ligne pour laisser la place à l'étiquette. Sert
     aussi de repli quand le texte n'est pas découpé en lignes (sans JS). */
  text-indent: 7.5em;
}
/* Une fois le texte découpé, le décalage passe sur la première ligne
   seulement (voir la note sur l'héritage de text-indent plus bas). */
.xl-statement p.xl-lines .xl-line-mask:first-child .xl-line { padding-left: 7.5em; }
@media (max-width: 780px) {
  .xl-statement .xl-eyebrow { position: static; margin-bottom: 0.8rem; }
  .xl-statement p { text-indent: 0; font-size: clamp(1.25rem, 5.4vw, 1.9rem); }
  .xl-statement p.xl-lines .xl-line-mask:first-child .xl-line { padding-left: 0; }
}

/* Grille de services : colonnes séparées par des filets verticaux, avec
   l'étiquette en haut, une icône au trait, et le texte en bas — la
   disposition relevée sur le site source. Les émojis qui servaient
   d'icônes sont remplacés par des pictogrammes dessinés en SVG. */
.xl-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--xl-ink);
  margin-top: var(--xl-space-gap);
}
.xl-section--dark .xl-grid-3,
.xl-section--dark .xl-grid-3 > div { border-color: rgba(240,241,244,0.35); }
.xl-grid-3 > div {
  display: flex;
  flex-direction: column;
  min-height: 17rem;
  padding: 1.25rem 1.5rem 1.5rem 0;
  border-right: 1px solid var(--xl-ink);
}
.xl-grid-3 > div + div { padding-left: 1.5rem; }
.xl-grid-3 > div:last-child { border-right: none; }
.xl-grid-3 .xl-icon {
  margin: 1.6rem 0 auto;
  color: inherit;
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
.xl-grid-3 .xl-icon svg { display: block; width: 2.6rem; height: 2.6rem; }
.xl-grid-3 > div:hover .xl-icon { transform: translateY(-6px); }
.xl-grid-3 h3 {
  font-size: 1.05rem;
  font-weight: 500;
  margin: 1.5rem 0 0.4em;
}
.xl-grid-3 p { font-size: 0.95rem; opacity: 0.75; margin: 0; }
@media (max-width: 780px) {
  .xl-grid-3 { grid-template-columns: 1fr; }
  .xl-grid-3 > div {
    min-height: 0;
    border-right: none;
    border-bottom: 1px solid var(--xl-ink);
    padding: 1.5rem 0;
  }
  .xl-grid-3 > div + div { padding-left: 0; }
}

/* Rangée liste : titre large + étiquette à gauche, description à droite,
   filet plein entre chaque rangée (structure relevée sur leur liste de
   projets). Au survol, la rangée glisse légèrement — pas de fond teinté. */
.xl-row-list { border-top: 1px solid var(--xl-ink); margin-top: var(--xl-space-gap); }
.xl-row-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--xl-space-gap);
  align-items: start;
  padding: clamp(1.4rem, 2.4vw, 2.4rem) 0;
  border-bottom: 1px solid var(--xl-ink);
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.xl-row-item:hover { transform: translateX(0.5rem); }
.xl-row-item h3 {
  font-size: clamp(1.6rem, 4.17vw, 3.6rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0;
}
.xl-row-tag {
  display: block;
  font-family: var(--xl-font-heading);
  font-size: clamp(0.62rem, 0.83vw, 0.8rem);
  font-weight: 500;
  letter-spacing: normal;
  text-transform: uppercase;
  margin-top: 0.5rem;
}
.xl-row-item p { margin: 0; max-width: 46ch; opacity: 0.8; }
@media (max-width: 780px) {
  .xl-row-item { grid-template-columns: 1fr; }
  .xl-row-item:hover { transform: none; }
}

/* Contact */
.xl-contact-block {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  margin-top: var(--xl-space-gap);
}
.xl-contact-item .xl-badge-label { display: block; margin-bottom: 0.3rem; }
.xl-contact-item a { font-family: var(--xl-font-heading); font-size: 1.15rem; }
.xl-contact-placeholder {
  border: 1px dashed var(--xl-ink);
  border-radius: 0;
  padding: 1.5rem;
  font-size: 0.9rem;
  opacity: 0.7;
  margin-top: 2rem;
  max-width: 60ch;
}

/* Réseaux sociaux (pages Contact et À propos). Liste horizontale, liens
   soulignés : ce sont des liens sortants, il faut qu'ils se lisent comme
   tels et non comme les boutons du site. */
.xl-social { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.xl-social-note {
  margin: 0.5rem 0 0.9rem;
  font-size: 0.9rem;
  opacity: 0.7;
  max-width: 60ch;
}
.xl-social-list { display: flex; flex-wrap: wrap; gap: 1.75rem; }
.xl-social-list a {
  font-family: var(--xl-font-heading);
  font-size: 1.05rem;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 0.3em;
  text-decoration-thickness: 1px;
  transition: opacity 0.25s ease;
}
.xl-social-list a:hover { opacity: 0.55; }

/* AVIS « SITE EN DÉVELOPPEMENT »
   Bandeau pleine largeur sous le bloc d'ouverture. Il reprend les filets
   du reste de la page plutôt qu'une boîte colorée : le but est d'informer
   sans casser le système visuel. La pastille orange suffit à attirer
   l'oeil. */
.xl-notice {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.9rem clamp(1.25rem, 1.4vw, 2rem);
  border-bottom: 1px solid var(--xl-ink);
  background: var(--xl-bg-alt);
}
.xl-notice p {
  margin: 0;
  font-size: clamp(0.82rem, 1.05vw, 0.95rem);
  line-height: 1.5;
  max-width: 90ch;
}
.xl-notice strong { font-weight: 500; }
.xl-notice-dot {
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  margin-top: 0.45rem;
  border-radius: 50%;
  background: var(--xl-orange);
}
@media (prefers-reduced-motion: no-preference) {
  .xl-notice-dot { animation: xl-notice-pulse 2.4s ease-in-out infinite; }
}
@keyframes xl-notice-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.82); }
}

/* ---------------------------------------------------------------
   PAGE PROJETS — mini-sites vivants dans un cadre de navigateur
   (template-projects.php + dossier /demos/)

   Le mini-site est un vrai document affiché dans une <iframe>. Sur
   grand écran il est rendu à 1440 px de large puis réduit par
   transform:scale() — donc on voit sa vraie mise en page de bureau,
   en petit, mais nette et utilisable. Sur mobile, pas de réduction :
   l'iframe fait la largeur disponible et le mini-site bascule sur sa
   propre version mobile, ce qui reste lisible au doigt.
   --------------------------------------------------------------- */
.xl-project { align-items: stretch; }
.xl-project-info { display: flex; flex-direction: column; }
.xl-project-info p { margin-top: 1rem; }

.xl-browser {
  border: 1px solid var(--xl-ink);
  background: var(--xl-white);
  box-shadow: 0 18px 44px rgba(9, 20, 35, 0.13);
}
.xl-browser-bar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--xl-ink);
  background: var(--xl-bg);
}
.xl-browser-dots { display: flex; gap: 0.35rem; flex: none; }
.xl-browser-dots i {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--xl-ink); opacity: 0.25;
}
.xl-browser-url {
  font-family: var(--xl-font-heading);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  opacity: 0.6;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--xl-border-strong);
  border-radius: 999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --xl-demo-scale est recalculé par js/main.js d'après la largeur réelle
   du cadre. La valeur par défaut ci-dessous correspond à une colonne
   d'environ 620 px : si le script ne tourne pas, l'aperçu reste juste,
   simplement moins ajusté. */
.xl-browser-view {
  --xl-demo-w: 1440px;
  --xl-demo-h: 900px;
  --xl-demo-scale: 0.43;
  position: relative;
  overflow: hidden;
  height: calc(var(--xl-demo-h) * var(--xl-demo-scale));
  background: var(--xl-bg-alt);
}
.xl-browser-view iframe {
  position: absolute;
  top: 0; left: 0;
  width: var(--xl-demo-w);
  height: var(--xl-demo-h);
  border: 0;
  transform: scale(var(--xl-demo-scale));
  transform-origin: 0 0;
  pointer-events: none; /* activé au clic sur le voile */
}
.xl-browser.is-live .xl-browser-view iframe { pointer-events: auto; }

.xl-browser-shield {
  position: absolute;
  inset: 0;
  width: 100%;
  border: 0;
  cursor: pointer;
  background: rgba(240, 241, 244, 0.35);
  backdrop-filter: blur(1px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 1.1rem;
  transition: opacity 0.3s ease;
}
.xl-browser-shield span {
  font-family: var(--xl-font-heading);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--xl-white);
  background: var(--xl-ink);
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
}
.xl-browser.is-live .xl-browser-shield { opacity: 0; pointer-events: none; }

.xl-demo-note {
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  font-size: 0.9rem;
  opacity: 0.65;
  max-width: 60ch;
}

@media (max-width: 900px) {
  /* Pas de réduction sur petit écran : un site de bureau miniaturisé y est
     illisible. L'iframe prend la largeur disponible et le mini-site affiche
     sa propre mise en page mobile. */
  .xl-browser-view {
    --xl-demo-w: 100%;
    --xl-demo-h: 520px;
    --xl-demo-scale: 1;
    height: var(--xl-demo-h);
  }
  .xl-project-demo { margin-top: 1.5rem; }
}

/* Liste "notre approche" : filet plein en tête de colonne, comme partout
   ailleurs (le liseré orange précédent était un accent décoratif). */
.xl-approach { display: grid; gap: 1.25rem 1.5rem; margin-top: var(--xl-space-gap); grid-template-columns: repeat(3, 1fr); }
.xl-approach > div { border-top: 1px solid var(--xl-ink); padding-top: 0.9rem; }
.xl-section--dark .xl-approach > div { border-color: rgba(240,241,244,0.35); }
.xl-approach h3 { font-size: 1.05rem; font-weight: 500; margin-bottom: 0.3em; }
.xl-approach p { font-size: 0.92rem; opacity: 0.75; margin: 0; }
@media (max-width: 780px) { .xl-approach { grid-template-columns: 1fr; } }

/* ==================================================================
   6. PIED DE PAGE
   ================================================================== */
/* Pied de page, structure relevée sur le site source : deux colonnes de
   liens séparées par un filet vertical, un filet horizontal en dessous,
   puis le mot-symbole géant qui remplit la moitié gauche, et enfin une
   ligne de mentions alignée à droite. Les filets sont nets (35 %
   d'opacité sur fond sombre), pas des gris à peine visibles. */
.xl-footer { background: var(--xl-ink); color: var(--xl-bg); }
.xl-footer-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-bottom: 1px solid rgba(240,241,244,0.35);
}
.xl-footer-cols > div { padding: 1.75rem 1.5rem 2.25rem; border-right: 1px solid rgba(240,241,244,0.35); }
.xl-footer-cols > div:last-child { border-right: none; }
.xl-footer-cols h4 {
  font-size: 1.15rem;
  font-weight: 500;
  margin-bottom: 1.4rem;
}
.xl-footer-cols li { margin-bottom: 0.75rem; font-size: clamp(0.8rem, 0.97vw, 0.95rem); font-weight: 500; }
.xl-footer-cols a { transition: opacity 0.25s ease; }
.xl-footer-cols a:hover { opacity: 0.6; }
.xl-footer-wordmark {
  margin: 0;
  font-family: var(--xl-font-heading);
  font-weight: 500;
  font-size: 22vw;
  color: var(--xl-bg);
  padding: 0.1em 0 0 0.06em;
  line-height: 0.78;
  letter-spacing: -0.035em;
  overflow: hidden;
}
.xl-colophon {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 0.75rem 2.5rem;
  padding: 0.75rem 1.5rem 1.75rem;
  font-size: clamp(0.68rem, 0.83vw, 0.82rem);
  font-weight: 500;
  text-transform: uppercase;
}
/* Bloc « réseaux sociaux » du pied de page. La note est volontairement
   plus petite et un peu effacée : c'est une précision, pas un titre. */
.xl-footer-social-note {
  margin: 1.6rem 0 0.7rem;
  font-size: clamp(0.72rem, 0.85vw, 0.82rem);
  line-height: 1.45;
  opacity: 0.65;
  max-width: 26ch;
}
.xl-footer-social li { margin-bottom: 0.5rem; }
.xl-footer-social a { text-decoration: underline; text-underline-offset: 0.25em; }

@media (max-width: 980px) {
  .xl-footer-cols { grid-template-columns: 1fr 1fr; }
  .xl-footer-cols > div:nth-child(2) { border-right: none; }
  .xl-footer-cols > div:nth-child(3) { grid-column: 1 / -1; border-top: 1px solid rgba(240,241,244,0.35); }
}
@media (max-width: 780px) {
  .xl-footer-cols { grid-template-columns: 1fr; }
  .xl-footer-cols > div { border-right: none; border-bottom: 1px solid rgba(240,241,244,0.35); }
  .xl-footer-cols > div:nth-child(3) { border-top: none; }
  .xl-footer-cols > div:last-child { border-bottom: none; }
  .xl-colophon { justify-content: flex-start; }
}

/* ==================================================================
   7. BLOG / PAGE GÉNÉRIQUE (index.php, page.php)
   ================================================================== */
.xl-post-list { max-width: 46rem; margin: 0 auto; }
.xl-post-list article { padding: 2rem 0; border-bottom: 1px solid var(--xl-border); }
.xl-post-list h2 { font-size: 1.4rem; margin-bottom: 0.3em; }
.xl-content { max-width: 46rem; }
.xl-content h2 { font-size: 1.6rem; margin-top: 1.5em; }
.xl-content p { font-size: 1.05rem; }

/* ==================================================================
   8. ANIMATIONS
   Révélation au défilement (xl-reveal), entrée du hero au chargement,
   micro-interactions au survol. Tout est désactivé automatiquement
   si le visiteur a demandé "réduire les animations" dans son système.
   ================================================================== */

/* Révélation au scroll : appliquer la classe .xl-reveal à un élément,
   js/main.js ajoute .is-visible via IntersectionObserver quand il
   entre dans le viewport. Ajouter .xl-reveal--1 / --2 / --3 pour
   décaler l'entrée d'éléments voisins (effet de cascade). */
.xl-reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.xl-reveal.is-visible { opacity: 1; transform: none; }
.xl-reveal--1.is-visible { transition-delay: 0.08s; }
.xl-reveal--2.is-visible { transition-delay: 0.16s; }
.xl-reveal--3.is-visible { transition-delay: 0.24s; }
.xl-reveal--4.is-visible { transition-delay: 0.32s; }

/* --------------------------------------------------------------
   Révélation ligne par ligne (l'animation signature du site source)

   Relevé dans leur code : chaque LIGNE d'un titre ou d'un énoncé est
   enfermée dans une boîte en overflow:hidden de la hauteur d'une ligne,
   et part de `rotate(2deg) translateY(160%)` — c'est-à-dire décalée de
   1,6 fois la hauteur de ligne vers le bas ET légèrement pivotée de 2
   degrés. En arrivant dans l'écran, chaque ligne remonte et se redresse,
   décalée dans le temps par rapport à la précédente.

   La découpe en lignes est faite par js/main.js (impossible en CSS seul :
   il faut mesurer où le texte retourne à la ligne). Sans JavaScript, le
   texte s'affiche normalement, sans animation.

   Le petit débord vertical (padding + marge négative) évite que la boîte
   ne rogne les jambages des lettres comme g, p ou y.
   -------------------------------------------------------------- */
.xl-line-mask {
  display: block;
  overflow: hidden;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}
.xl-line {
  display: block;
  transform: rotate(2deg) translateY(160%);
  transform-origin: 50% 50%;
  transition: transform 0.95s cubic-bezier(0.16, 1, 0.3, 1);
}
/* text-indent est une propriété héritée : sans ça, le décalage de la
   première ligne d'un énoncé se retrouverait appliqué à TOUTES les
   lignes une fois le texte découpé. */
.xl-line-mask,
.xl-line { text-indent: 0; }
.xl-lines.is-visible .xl-line { transform: none; }
/* Décalage progressif d'une ligne à l'autre */
.xl-lines.is-visible .xl-line-mask:nth-child(1) .xl-line { transition-delay: 0s; }
.xl-lines.is-visible .xl-line-mask:nth-child(2) .xl-line { transition-delay: 0.09s; }
.xl-lines.is-visible .xl-line-mask:nth-child(3) .xl-line { transition-delay: 0.18s; }
.xl-lines.is-visible .xl-line-mask:nth-child(4) .xl-line { transition-delay: 0.27s; }
.xl-lines.is-visible .xl-line-mask:nth-child(5) .xl-line { transition-delay: 0.36s; }
.xl-lines.is-visible .xl-line-mask:nth-child(n+6) .xl-line { transition-delay: 0.45s; }

/* L'étiquette qui accompagne un énoncé apparaît en fondu, comme sur le
   site source (leur « ABOUT » et « EXPERTISE » démarrent à opacité 0). */
.xl-fade { opacity: 0; transition: opacity 0.8s ease; }
.xl-fade.is-visible { opacity: 1; }

/* Entrée du hero au chargement de la page : animation CSS pure,
   décalée par enfant, pour que le titre, le texte et les boutons
   arrivent l'un après l'autre plutôt que tous en même temps. */
@keyframes xl-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
.xl-hero .xl-eyebrow,
.xl-hero h1,
.xl-hero p.xl-dek,
.xl-hero .xl-btn-row,
.xl-hero .xl-badge {
  animation: xl-rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.xl-hero .xl-eyebrow   { animation-delay: 0.05s; }
.xl-hero h1             { animation-delay: 0.15s; }
.xl-hero p.xl-dek       { animation-delay: 0.28s; }
.xl-hero .xl-btn-row    { animation-delay: 0.4s; }
.xl-hero .xl-badge      { animation-delay: 0.5s; }

/* Grande section pleine largeur inversée : léger effet de zoom-avant
   sur le titre pour appuyer le changement de ton clair/sombre. */
.xl-section--dark h2.xl-reveal { transform: translateY(28px) scale(0.98); }
.xl-section--dark h2.xl-reveal.is-visible { transform: none; }

/* Respect total de "prefers-reduced-motion" : tout s'affiche
   directement, sans mouvement ni fondu. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .xl-reveal,
  .xl-line,
  .xl-fade,
  .xl-hero .xl-eyebrow,
  .xl-hero h1,
  .xl-hero p.xl-dek,
  .xl-hero .xl-btn-row,
  .xl-hero .xl-badge,
  .xl-hero-word > span,
  .xl-hero-nav-row {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .xl-line-mask { overflow: visible; }
  .xl-btn:hover,
  .xl-row-item:hover,
  .xl-grid-3 > div:hover .xl-icon,
  .xl-nav a:hover .xl-roll-inner {
    transform: none;
  }
}

/* ==================================================================
   9. COUCHE "AGENCE" — révélation du titre mot par mot et transitions
   de page. Ajoutée dynamiquement par js/animations.js (GSAP, chargé
   depuis un CDN). Si GSAP ne charge pas, ou si prefers-reduced-motion
   est actif, ce script ne crée jamais ces éléments — rien ici ne
   peut donc bloquer ou cacher le contenu du site.

   RETIRÉ en v1.9 : le curseur personnalisé (point orange + anneau) et
   les formes floutées flottantes (dégradés teal/orange derrière le bloc
   d'ouverture et les sections sombres). Ces deux effets étaient de la
   décoration ajoutée par-dessus le système de design, alors que le site
   source repose justement sur la retenue : deux couleurs, une police,
   des filets noirs, de l'air. Ils sont supprimés, pas seulement masqués.
   ================================================================== */

/* Titre du hero révélé mot par mot (masque + glissement vers le haut) */
/* Le titre du bloc d'ouverture se révèle ligne par ligne (voir .xl-line
   en section 8) : l'animation d'entrée générique du hero ne doit donc
   pas s'y appliquer en plus, sinon les deux se marchent dessus. */
.xl-hero h1[data-xl-split] { animation: none; }

.xl-hero { position: relative; }

/* Wordmark du pied de page, mis à l'échelle au défilement */
.xl-footer-wordmark { will-change: transform, opacity; }

/* Voile de transition entre les pages */
.xl-page-transition {
  position: fixed;
  inset: 0;
  background: var(--xl-ink);
  z-index: 10000;
  pointer-events: none;
  transform: translateY(100%);
}

@media (prefers-reduced-motion: reduce) {
  .xl-page-transition {
    display: none !important;
  }
}

/* ==================================================================
   10. BLOC D'OUVERTURE (v1.9 — proportions mesurées sur le site source)
   Toutes les valeurs ci-dessous viennent de mesures réelles prises dans
   le navigateur sur atolldigital.com à 1920x911, converties en vw pour
   rester proportionnelles :
     - bloc complet          : 453 px  (~50 % de la hauteur d'écran)
     - grille                : 960 px / 960 px, soit exactement 50/50
     - bande du menu         : 85 px de haut
     - menu                  : 26,67 px, minuscules, graisse 500
     - titre                 : 64 px, interligne 69 px, graisse 400
     - filets                : 1 px plein #091423 (l'encre, pas un gris pâle)
     - mot-symbole           : surdimensionné et ROGNÉ par la colonne,
                               il ne pousse pas la hauteur du bloc
   La règle de composition du site source, c'est la retenue : deux
   couleurs, une police, des filets noirs, beaucoup d'air. Pas d'accent
   de couleur décoratif ici — c'est ce qui manquait aux versions
   précédentes.
   ================================================================== */
.xl-hero { padding: 0; }
/* Le filet du bas est porté par la grille, pas par la section : ainsi il
   rejoint exactement le bas du trait vertical (comme sur le site source),
   et l'indication « défiler » reste en dehors du bloc, sous le filet. */
.xl-hero-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid var(--xl-ink);
}
/* Colonne de gauche : le mot-symbole est en position absolue, donc il ne
   participe JAMAIS au calcul de la hauteur de la rangée — c'est la colonne
   de droite qui décide de la hauteur du bloc, et les lettres sont rognées
   par le débordement, exactement comme sur le site source (leurs
   hauts de lettres sont coupés par le haut de la page). C'est aussi ce qui
   évite le défaut des v1.7/v1.8, où la taille du "XL" dépendait de la
   hauteur du contenu voisin et devenait imprévisible. */
.xl-hero-word {
  position: relative;
  overflow: hidden;
  border-right: 1px solid var(--xl-ink);
  min-height: 0;
}
.xl-hero-word > span {
  /* inset + flex plutôt que top:50% + translateY(-50%) : l'animation
     d'entrée xl-rise se termine sur `transform: none`, ce qui effacerait
     un centrage fait au transform. Le centrage passe donc par le flex,
     et le transform reste libre pour l'animation. */
  position: absolute;
  inset: 0 0 0 1.4vw;
  display: flex;
  align-items: center;
  font-family: var(--xl-font-heading);
  font-weight: 700;
  font-size: 24vw;
  line-height: 0.75;
  letter-spacing: -0.035em;
  color: var(--xl-ink);
  white-space: nowrap;
  overflow: hidden;
  animation: xl-rise 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.xl-hero-content {
  --xl-hero-pad-x: 1.4vw;
  padding: 0 var(--xl-hero-pad-x) 1.4vw;
  display: flex;
  flex-direction: column;
}
/* Bande du menu : 85/911 de la hauteur d'écran sur le site source. Le
   filet sous le menu ne traverse QUE la colonne de droite (mesuré : il
   part de x=960 et va jusqu'au bord droit), d'où les marges négatives
   qui le font déborder jusqu'aux bords de la colonne. */
.xl-hero-nav-row {
  display: flex;
  align-items: center;
  min-height: 4.43vw;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--xl-ink);
  margin-left: calc(-1 * var(--xl-hero-pad-x));
  margin-right: calc(-1 * var(--xl-hero-pad-x));
  padding-left: var(--xl-hero-pad-x);
  padding-right: var(--xl-hero-pad-x);
}
.xl-hero-body {
  padding-top: 1.3vw;
}
.xl-hero-body h1 {
  font-size: 3.34vw;
  line-height: 1.08;
  font-weight: 400;
  letter-spacing: -0.01em;
  max-width: none;
  margin: 0;
}
.xl-hero-body .xl-badge { margin-top: 2.76vw; align-self: flex-start; }

.xl-scroll-cue {
  text-align: center;
  font-family: var(--xl-font-heading);
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  opacity: 0.5;
  padding: 1.4rem 0;
  margin: 0;
}

@media (max-width: 900px) {
  .xl-hero-grid { grid-template-columns: 1fr; }
  .xl-hero-word {
    border-right: none;
    border-bottom: 1px solid var(--xl-ink);
    min-height: 26vw;
  }
  .xl-hero-word > span { font-size: 22vw; left: 1.5rem; }
  .xl-hero-content { --xl-hero-pad-x: 1.5rem; padding-bottom: 2.5rem; }
  .xl-hero-nav-row { min-height: 0; padding-top: 1rem; padding-bottom: 1rem; }
  .xl-hero-body h1 { font-size: clamp(1.9rem, 6.4vw, 2.6rem); max-width: none; }
  .xl-hero-body { padding-top: 1.6rem; }
  .xl-hero-body .xl-badge { margin-top: 1.6rem; }
}

/* Note qui suit un énoncé : texte courant + boutons, alignés à droite
   pour créer l'asymétrie typique du site source (grand énoncé à gauche,
   bloc de texte plus petit décalé en dessous à droite). */
.xl-statement-note {
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
  margin-left: auto;
  max-width: 34rem;
}
.xl-statement-note p { font-size: 1.05rem; opacity: 0.8; margin: 0; }
@media (max-width: 780px) {
  .xl-statement-note { margin-left: 0; }
}

/* Badge "pilule" avec accent serif (utilisé dans le hero) */
.xl-badge--pill {
  border-radius: 999px;
  padding: 0.5rem 1.35rem 0.5rem 1.1rem;
}
.xl-badge--pill .xl-badge-label {
  border-right: 1px solid var(--xl-border-strong);
  padding-right: 0.9rem;
  margin-right: 0.15rem;
}
.xl-section--dark .xl-badge--pill .xl-badge-label { border-color: rgba(240,241,244,0.3); }
.xl-badge--pill .xl-badge-num {
  font-family: var(--xl-font-serif);
  font-weight: 400;
  font-style: italic;
  font-size: 1.05rem;
  max-width: 12em;
  line-height: 1.2;
}

/* ==================================================================
   11. VOILE D'OUVERTURE (page d'accueil seulement)
   Le grand mot-symbole apparaît d'abord seul, en plein écran, puis
   s'efface pour révéler la page — l'effet "décalé" observé sur le
   site source. Ajouté dynamiquement par js/animations.js seulement
   si GSAP a démarré ; sinon la page s'affiche normalement tout de
   suite, sans ce voile.
   ================================================================== */
.xl-loader {
  position: fixed;
  inset: 0;
  z-index: 10001;
  background: var(--xl-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.xl-loader span {
  font-family: var(--xl-font-heading);
  font-weight: 700;
  font-size: clamp(4rem, 14vw, 9rem);
  letter-spacing: -0.03em;
  color: var(--xl-ink);
}
@media (prefers-reduced-motion: reduce) {
  .xl-loader { display: none !important; }
}

/* ==================================================================
   14. INTERTITRES DE SECTION EN <h2>
   ==================================================================
   Les étiquettes de section et les mots-repères géants sont de vrais
   <h2> depuis la refonte du référencement : une page dont les sections
   ne sont pas des titres n'est lisible ni par Google ni par un lecteur
   d'écran.

   Mais `.xl-section h2` (une classe + un élément) l'emporte sur
   `.xl-eyebrow` et `.xl-giant` (une classe seule). Sans les deux règles
   ci-dessous, l'étiquette s'affichait à la taille d'un énoncé et venait
   se superposer au texte, et le mot-repère géant rapetissait.
   ================================================================== */
.xl-section h2.xl-eyebrow {
  font-size: clamp(0.68rem, 0.83vw, 0.85rem);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: normal;
  text-wrap: wrap;
}
.xl-section h2.xl-giant {
  font-size: 9.72vw;
  font-weight: 500;
  line-height: 0.85;
  letter-spacing: -0.035em;
  text-wrap: wrap;
}
