/* ==========================================================================
   thisishumanmade.com - design V2
   Transposition des maquettes sites/_preparation_V2/design_V2/ (piste B).
   Noir et blanc, accent bleu discret. Aucune dependance externe.
   ========================================================================== */

:root {
  --ink: #000;
  --paper: #fff;
  --muted: #444;
  --meta: #6b6b6b;
  --accent: #0022ff;
  --gutter: clamp(20px, 6vw, 112px);
  --sans: 'Space Grotesk', Helvetica, Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--ink);
  color: var(--paper);
  padding: 10px 16px;
  font-family: var(--mono);
  font-size: 12px;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* Utilitaires -------------------------------------------------------------- */

.mono {
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.section {
  padding: clamp(48px, 6vw, 96px) var(--gutter);
  border-top: 2px solid var(--ink);
}

.section__head {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 48px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: clamp(24px, 3vw, 48px);
}

/* Le kicker porte le h2 de la section : meme rendu qu'un span, mais la
   hierarchie des titres reste correcte pour un lecteur d'ecran. */
.section__kicker {
  margin: 0;
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.04em;
}

.section__title {
  margin: 0 0 clamp(32px, 4vw, 64px);
  font-size: clamp(32px, 4.4vw, 72px);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 0.98;
  max-width: 20ch;
  text-wrap: pretty;
}

/* Deux colonnes : libelle a gauche, contenu a droite. */
.split {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 64px;
}
.split__label { flex: 0 0 200px; }
.split__body {
  flex: 1 1 480px;
  min-width: 0;
}
.split .section__title { max-width: 18ch; margin-bottom: clamp(32px, 4vw, 56px); }

/* Nav ---------------------------------------------------------------------- */

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
  padding: 18px var(--gutter);
  border-bottom: 2px solid var(--ink);
}

.nav__logo {
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.04em;
  font-size: 20px;
}

.nav__links {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.nav__link {
  text-decoration: none;
  border-bottom: 2px solid transparent;
  padding: 2px 0;
}
.nav__link:hover,
.nav__link[aria-current='page'] { border-color: var(--ink); }

.nav__badge {
  border: 1px solid var(--ink);
  padding: 4px 8px;
  line-height: 1;
}

.lang-toggle {
  display: flex;
  border: 1px solid var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}
.lang-toggle > * {
  padding: 6px 10px;
  line-height: 1;
  text-decoration: none;
  color: var(--ink);
}
.lang-toggle .is-active { background: var(--ink); color: var(--paper); }
.lang-toggle a:hover { background: var(--ink); color: var(--paper); }

/* Hero --------------------------------------------------------------------- */

.hero { padding: 0 var(--gutter) clamp(48px, 6vw, 96px); }

/* Le titre occupe le premier ecran, centre verticalement entre deux marges
   egales. Sa taille est bornee par la hauteur de la fenetre pour que la
   derniere ligne ne touche jamais le bas. */
.hero__intro {
  display: flex;
  align-items: center;
  min-height: calc(100vh - 76px);
  min-height: calc(100svh - 76px);
  padding: clamp(40px, 7vh, 96px) 0;
  box-sizing: border-box;
}

.hero__title {
  margin: 0;
  font-weight: 700;
  font-size: clamp(38px, min(7vw, 12.5vh), 128px);
  line-height: 0.94;
  letter-spacing: -0.045em;
  max-width: 15ch;
  text-wrap: pretty;
}

.hero__tail { color: var(--meta); }

/* Rotor : les mots sont empiles dans la meme cellule de grille, ce qui
   reserve la largeur du plus long et evite tout reflow a la rotation. */
.hero__word {
  display: inline-grid;
  vertical-align: bottom;
  /* Pas d'overflow:hidden : il rognait les jambages et la cedille de « ca ».
     Le masquage des mots sortants est porte par leur opacite. */
  text-align: left;
}
.hero__word > span {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(0.5em);
  transition: opacity 300ms ease, transform 300ms ease;
  pointer-events: none;
}
.hero__word > span.is-current {
  opacity: 1;
  transform: translateY(0);
}
.hero__word > span.is-leaving {
  opacity: 0;
  transform: translateY(-0.5em);
}

/* Data art ----------------------------------------------------------------- */

/* La section sort du gutter : l'image occupe toute la largeur de la fenetre. */
.dataart {
  position: relative;
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  background: #000;
}

.dataart__stage {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: #000;
}

/* Le plancher de 560px ne vaut que si la fenetre est plus haute : sur un
   portable bas de plafond, il ferait deborder la scene hors de l'ecran. */
@media (min-height: 560px) {
  .dataart__stage { min-height: 560px; }
}

.dataart__poster,
.dataart__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}

.dataart__poster {
  object-fit: cover;
  object-position: center;
  transition: opacity 400ms ease;
}

/* Une fois le direct lance, l'affiche reste derriere le temps du chargement. */
.dataart__stage.is-live .dataart__poster { opacity: 0; }

.dataart__frame { z-index: 1; }

/* La scene se lance d'elle-meme : cette croix la remplace par l'affiche pour
   qui prefere le calme. Le defilement de la page traverse deja l'iframe. */
.dataart__close {
  position: absolute;
  top: clamp(20px, 2.5vw, 32px);
  right: clamp(20px, 2.5vw, 32px);
  z-index: 4;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 22px;
  line-height: 1;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid #fff;
  cursor: pointer;
}
.dataart__close:hover { background: #fff; color: #000; }
.dataart__close[hidden] { display: none; }

/* Rien dans une scene 3D ne dit qu'elle se manipule : ce repere le montre,
   discretement, et s'efface des la premiere prise en main. */
.dataart__drag {
  position: absolute;
  left: 50%;
  bottom: clamp(20px, 3vw, 32px);
  transform: translateX(-50%);
  z-index: 4;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.5);
  color: #fff;
  text-transform: none;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transition: opacity 300ms ease;
}
.dataart__drag[hidden] { display: none; }

/* Tant que la scene retient le defilement, sa croix doit sauter aux yeux :
   c'est la sortie. */
.dataart-locked .dataart__close {
  background: #fff;
  color: #000;
  animation: dataart-pulse 2.4s ease-in-out 3;
}
@keyframes dataart-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.6); }
  50% { box-shadow: 0 0 0 10px rgba(255, 255, 255, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .dataart-locked .dataart__close { animation: none; }
}
.dataart__drag.is-gone { opacity: 0; }

/* Une main qui va et vient : l'animation dit le geste mieux qu'un mot. */
.dataart__drag-icon {
  width: 22px;
  height: 12px;
  flex: 0 0 auto;
  border-left: 1px solid #fff;
  border-right: 1px solid #fff;
  position: relative;
}
.dataart__drag-icon::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 3px;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: #fff;
  animation: dataart-drag 2.4s ease-in-out infinite;
}
@keyframes dataart-drag {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(8px); }
}

@media (prefers-reduced-motion: reduce) {
  .dataart__drag-icon::before { animation: none; }
}


.dataart__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(28px, 4vw, 64px) var(--gutter) clamp(72px, 8vw, 104px);
  /* Seul degrade du site : il sert la lisibilite du texte sur l'image. */
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 32%, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.75) 100%);
  color: #fff;
  pointer-events: none;
}
/* Seuls les elements cliquables reprennent la main sur le pointeur, pour ne
   pas bloquer une interaction future avec la scene en direct. */
.dataart__overlay a,
.dataart__overlay button { pointer-events: auto; }

.dataart__kicker {
  position: absolute;
  top: clamp(28px, 4vw, 64px);
  left: var(--gutter);
  color: #fff;
}

.dataart__title {
  margin: 0 0 16px;
  font-size: clamp(40px, 6vw, 112px);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 0.98;
  max-width: 16ch;
  text-wrap: pretty;
}

.dataart__lede {
  margin: 0;
  font-size: clamp(17px, 1.5vw, 22px);
  line-height: 1.4;
  max-width: 44ch;
  color: #e5e5e5;
  text-wrap: pretty;
}

.dataart__actions {
  margin-top: clamp(24px, 3vw, 36px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dataart__facts {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(24px, 3vw, 40px);
  z-index: 2;
  margin: 0;
  /* Assez large pour tenir sur une ligne sur un ecran ordinaire : les
     chiffres du projet se lisent d'un coup, pas en escalier. */
  max-width: min(72ch, calc(100vw - 2 * var(--gutter)));
  text-align: right;
  color: #9a9a9a;
  text-transform: none;
  letter-spacing: 0.02em;
  line-height: 1.5;
}

/* Compteurs ---------------------------------------------------------------- */

.counters-band {
  padding: clamp(32px, 4vw, 56px) var(--gutter);
  border-bottom: 2px solid var(--ink);
}

.counters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 24px 32px;
  margin-top: 0;
  border-top: 2px solid var(--accent);
  padding-top: 20px;
}

.counter__value {
  font-weight: 700;
  font-size: clamp(56px, 6.5vw, 112px);
  line-height: 0.9;
  letter-spacing: -0.05em;
}
.counter__label { margin-top: 12px; }

/* Dernier projet livre ------------------------------------------------------ */

.latest__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 48px 64px;
  align-items: flex-start;
}

.latest__text { flex: 1 1 420px; min-width: 0; }

/* Le nom est a l'echelle du hero : c'est LE projet du moment. */
.latest__name {
  margin: 0 0 16px;
  font-size: clamp(56px, 8vw, 144px);
  font-weight: 700;
  letter-spacing: -0.05em;
  line-height: 0.9;
}

.latest__lede {
  margin: 0 0 32px;
  font-size: clamp(20px, 2vw, 30px);
  line-height: 1.3;
  letter-spacing: -0.015em;
  max-width: 34ch;
  color: var(--muted);
  text-wrap: pretty;
}

.latest__facts {
  margin: 0;
  border-top: 1px solid var(--ink);
  max-width: 44ch;
  text-transform: none;
  letter-spacing: 0.02em;
}
.latest__facts > div {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 24px;
  padding: 10px 0;
  border-bottom: 1px solid var(--ink);
}
.latest__facts dt { flex: 0 0 100px; color: var(--meta); }
.latest__facts dd { flex: 1 1 200px; margin: 0; color: var(--ink); }

.latest__actions {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px 32px;
  align-items: baseline;
}

/* Planche-contact : trois captures alignees, decalees pour le rythme.
   Pas d'ombre, pas de perspective : ce sont des captures, pas des mockups. */
.latest__shots {
  flex: 1 1 520px;
  min-width: 0;
  display: flex;
  gap: 16px;
  align-items: flex-start;
}
.latest__shots img {
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--ink);
  border-radius: 4px;
}
.latest__shots img:nth-child(2) { margin-top: 40px; }
.latest__shots img:nth-child(3) { margin-top: 80px; }

/* Principes (bloc noir) ----------------------------------------------------- */

.principles {
  background: var(--ink);
  color: var(--paper);
}
.principles .section__head { margin-bottom: clamp(32px, 4vw, 64px); }

.principles__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 32px;
}

.principle { border-left: 1px solid currentColor; padding-left: 20px; }
.principle__num { font-family: var(--mono); font-size: 12px; margin-bottom: 16px; }
.principle h3 {
  margin: 0 0 12px;
  font-size: clamp(30px, 3.2vw, 52px);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
}
.principle p { margin: 0; font-size: 16px; line-height: 1.5; max-width: 30ch; }

/* Apps --------------------------------------------------------------------- */

/* Les filets sont portes par les cartes, pas par le fond de la grille :
   une derniere ligne incomplete laisserait sinon un aplat noir. */
.apps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 272px), 1fr));
  gap: 0;
  border: 1px solid var(--ink);
  border-width: 1px 0 0 1px;
}

.app-card {
  background: var(--paper);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 280px;
  border: 1px solid var(--ink);
  border-width: 0 1px 1px 0;
}

.app-card__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.app-card__icon {
  width: 56px;
  height: 56px;
  display: block;
  border: 1px solid var(--ink);
  border-radius: 4px;
  object-fit: cover;
}

.app-card__mono {
  width: 56px;
  height: 56px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 16px;
  flex: 0 0 auto;
}

.app-card h3 {
  margin: 0 0 6px;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.app-card p { margin: 0; font-size: 15px; line-height: 1.45; color: var(--muted); }

.app-card__links {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.btn-mono {
  text-decoration: none;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 5px 8px;
  line-height: 1;
}
.btn-mono:hover { background: var(--ink); color: var(--paper); }
.btn-mono--dashed { border-style: dashed; }
.btn-mono--off {
  color: var(--meta);
  border: 1px dashed var(--meta);
  padding: 5px 8px;
  line-height: 1;
}

/* Variantes claires, posees APRES les regles de base : sur le fond noir du
   Data art, un bouton noir sur noir serait invisible. */
.btn-mono--inverse {
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  background: none;
  color: #fff;
  border: 1px solid #fff;
  border-radius: 0;
  cursor: pointer;
}
.btn-mono--inverse:hover { background: #fff; color: #000; }


.badge {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 5px 8px;
  line-height: 1;
  white-space: nowrap;
}
.badge--soon { background: var(--accent); color: var(--paper); }
.badge--beta { border: 1px solid var(--ink); color: var(--ink); }

.app-card__icon--dim { filter: grayscale(1); }

.apps-subhead {
  margin: clamp(48px, 6vw, 88px) 0 clamp(24px, 3vw, 48px);
}

/* Sites offerts ------------------------------------------------------------- */

.rows { border-top: 1px solid var(--ink); }

.row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 32px;
  align-items: baseline;
  padding: 20px 0;
  border-bottom: 1px solid var(--ink);
}
.row__name { flex: 1 1 220px; font-weight: 700; font-size: 22px; letter-spacing: -0.03em; }
.row__desc { flex: 2 1 300px; font-size: 16px; color: var(--muted); }
.row__link {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 13px;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 2px solid var(--accent);
}
.row__link:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* Articles (extrait home + listing) ----------------------------------------- */

.post-list { border-top: 1px solid var(--ink); }
.post-list--strong { border-top-width: 2px; }

.post {
  display: block;
  text-decoration: none;
  color: var(--ink);
  padding: 24px 0;
  border-bottom: 1px solid var(--ink);
}
.post:hover {
  background: var(--ink);
  color: var(--paper);
  padding-left: 16px;
  padding-right: 16px;
}
.post__meta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 10px;
}
.post__tag { border: 1px solid currentColor; padding: 2px 6px; line-height: 1; }
.post__title {
  font-weight: 700;
  font-size: clamp(22px, 2.2vw, 32px);
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-bottom: 8px;
  text-wrap: pretty;
}
.post__line { font-size: 16px; opacity: 0.75; }

.more-link {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  align-items: baseline;
}
.link-strong {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 3px solid var(--accent);
}
.link-strong:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.link-mono {
  text-decoration: none;
  color: var(--ink);
  border-bottom: 2px solid var(--accent);
  font-family: var(--mono);
}
.link-mono:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.link-mono--inverse {
  color: #fff;
  border-bottom-color: #fff;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.link-mono--inverse:hover { background: #fff; color: #000; border-color: #fff; }

/* Listing des articles ------------------------------------------------------ */

.listing-header { padding: clamp(48px, 7vw, 120px) var(--gutter) clamp(32px, 4vw, 56px); }
.listing-header__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 48px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 24px;
}
.listing-header h1 {
  margin: 0;
  font-weight: 700;
  font-size: clamp(42px, 7vw, 120px);
  line-height: 0.94;
  letter-spacing: -0.045em;
  max-width: 14ch;
  text-wrap: pretty;
}
.listing-controls {
  margin-top: clamp(32px, 4vw, 56px);
  display: flex;
  flex-wrap: wrap;
  gap: 16px 32px;
  justify-content: space-between;
  align-items: center;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.filter {
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 6px 10px;
  line-height: 1;
  cursor: pointer;
}
.filter:hover { background: var(--ink); color: var(--paper); }
.filter[aria-pressed='true'] { background: var(--ink); color: var(--paper); }

.listing-body { padding: 0 var(--gutter) clamp(48px, 6vw, 96px); }

.post--row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 32px;
  align-items: baseline;
  padding: 22px 0;
}
.post--row .post__date { flex: 0 0 96px; font-family: var(--mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }
.post--row .post__main { flex: 1 1 420px; min-width: 0; }
.post--row .post__title { font-size: clamp(20px, 1.9vw, 28px); line-height: 1.12; margin-bottom: 6px; }
.post--row .post__line { font-size: 15px; opacity: 0.72; max-width: 70ch; }
.post--row .post__tags {
  flex: 0 0 auto;
  display: flex;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.post--row .post__tags span { border: 1px solid currentColor; padding: 3px 6px; line-height: 1; }

.post[hidden] { display: none; }

.listing-footer {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 32px;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.listing-footer__count { color: var(--meta); }
.load-more {
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  background: none;
  border: 0;
  border-bottom: 2px solid var(--accent);
  color: var(--ink);
  padding: 0 0 2px;
  cursor: pointer;
}
.load-more:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.empty-state {
  padding: 48px 0;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--meta);
}

/* Bandeau Lab --------------------------------------------------------------- */

.lab-strip {
  padding: clamp(32px, 4vw, 56px) var(--gutter);
  border-top: 1px solid var(--ink);
  display: flex;
  flex-wrap: wrap;
  gap: 16px 64px;
  align-items: baseline;
}
.lab-strip__label { flex: 0 0 200px; }
.lab-strip p {
  flex: 1 1 480px;
  margin: 0;
  font-size: clamp(18px, 1.6vw, 22px);
  line-height: 1.4;
  text-wrap: pretty;
}
.lab-strip .link-mono { font-size: 14px; white-space: nowrap; }

/* Qui ---------------------------------------------------------------------- */

.who__body {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 48px;
  align-items: flex-start;
}
.who__photo {
  flex: 0 0 220px;
  width: 220px;
  height: 220px;
  object-fit: cover;
  object-position: top center;
  display: block;
  border: 1px solid var(--ink);
  filter: grayscale(1);
}
.who__text {
  flex: 1 1 320px;
  margin: 0;
  font-size: clamp(20px, 2vw, 28px);
  line-height: 1.35;
  letter-spacing: -0.015em;
  max-width: 34ch;
  text-wrap: pretty;
}

/* Contact ------------------------------------------------------------------- */

.contact__mail {
  display: inline-block;
  font-weight: 700;
  font-size: clamp(28px, 5vw, 84px);
  letter-spacing: -0.045em;
  line-height: 1;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 4px solid var(--accent);
  word-break: break-all;
}
.contact__mail:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.contact__links {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  font-family: var(--mono);
  font-size: 14px;
}
.contact__note { color: var(--meta); }

/* Footer -------------------------------------------------------------------- */

.footer {
  padding: 28px var(--gutter) 40px;
  border-top: 2px solid var(--ink);
  display: flex;
  flex-wrap: wrap;
  gap: 20px 48px;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
}
.footer__legal { flex: 1 1 320px; max-width: 52ch; }
.footer__legal span { color: var(--meta); }
.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.footer__links a {
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
}
.footer__links a:hover { background: var(--ink); color: var(--paper); }

/* Article ------------------------------------------------------------------- */

.article-header {
  padding: clamp(40px, 6vw, 96px) var(--gutter) clamp(32px, 4vw, 56px);
  border-bottom: 2px solid var(--ink);
}
.article-header__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 28px;
}
.article-header__meta .sep { color: var(--meta); }
.article-header__meta .chip { border: 1px solid var(--ink); padding: 3px 6px; line-height: 1; }
.article-header h1 {
  margin: 0;
  font-weight: 700;
  font-size: clamp(36px, 5.6vw, 96px);
  line-height: 0.96;
  letter-spacing: -0.045em;
  max-width: 18ch;
  text-wrap: pretty;
}
.article-header__lede {
  margin: 28px 0 0;
  font-size: clamp(19px, 1.8vw, 26px);
  line-height: 1.35;
  letter-spacing: -0.01em;
  max-width: 50ch;
  color: var(--muted);
  text-wrap: pretty;
}
.article-header__tags {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.article-header__tags span { border: 1px solid var(--ink); padding: 4px 8px; line-height: 1; }

.article-body {
  padding: clamp(40px, 5vw, 80px) var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: 40px 80px;
  align-items: flex-start;
}

.toc {
  flex: 0 0 200px;
  position: sticky;
  top: 24px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
}
.toc__title {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--ink);
}
.toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.toc a {
  text-decoration: none;
  color: var(--ink);
  border-bottom: 2px solid transparent;
  align-self: flex-start;
}
.toc a:hover,
.toc a.is-active { border-bottom-color: var(--ink); }

/* Corps de l'article : les elements sont styles par leur balise, car le HTML
   vient des JSON d'elastik.eu et n'a plus aucune classe apres transformation. */
.prose {
  flex: 1 1 480px;
  min-width: 0;
  max-width: 68ch;
  font-size: clamp(17px, 1.35vw, 20px);
  line-height: 1.55;
}
.prose > :first-child { margin-top: 0; }
.prose h2 {
  margin: 48px 0 16px;
  font-size: clamp(26px, 2.6vw, 40px);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1.05;
  scroll-margin-top: 24px;
}
.prose h3 {
  margin: 36px 0 12px;
  font-size: clamp(21px, 1.9vw, 28px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
}
.prose h4 {
  margin: 28px 0 10px;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.prose p { margin: 0 0 20px; text-wrap: pretty; }
.prose ul,
.prose ol { margin: 0 0 20px; padding-left: 1.4em; }
.prose li { margin-bottom: 8px; }
.prose li > ul,
.prose li > ol { margin-top: 8px; }
.prose strong { font-weight: 700; }
.prose a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
}
.prose a:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.prose code {
  font-family: var(--mono);
  font-size: 0.9em;
  border: 1px solid var(--ink);
  padding: 1px 5px;
  /* Les articles d'elastik contiennent des <code> multilignes hors <pre> :
     un nowrap les ferait deborder la page sur telephone. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.prose kbd {
  font-family: var(--mono);
  font-size: 0.85em;
  border: 1px solid var(--ink);
  border-bottom-width: 3px;
  border-radius: 3px;
  padding: 1px 6px;
}
.prose pre {
  margin: 0 0 24px;
  padding: 20px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.6;
  overflow-x: auto;
}
.prose pre code {
  border: 0;
  padding: 0;
  font-size: inherit;
  color: inherit;
  white-space: pre;
}

.prose blockquote {
  margin: 32px 0;
  padding: 0 0 0 20px;
  border-left: 2px solid var(--ink);
  font-size: clamp(20px, 2vw, 28px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.2;
  text-wrap: pretty;
}
.prose blockquote p { margin: 0; }

.prose figure { margin: 32px 0; }
.prose figure img { display: block; width: 100%; border: 1px solid var(--ink); }
.prose figcaption {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--meta);
  margin-top: 10px;
}
.prose > img { display: block; border: 1px solid var(--ink); margin: 32px 0; }

.table-wrap { overflow-x: auto; margin: 0 0 24px; }
.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  text-align: left;
}
.prose th {
  border-bottom: 2px solid var(--ink);
  padding: 10px 16px 10px 0;
  font-weight: 700;
  vertical-align: bottom;
}
.prose td {
  border-bottom: 1px solid var(--ink);
  padding: 10px 16px 10px 0;
  vertical-align: top;
}
.prose tr:last-child td { border-bottom: 0; }

.callout {
  display: block;
  margin: 28px 0;
  padding: 20px;
  border: 1px solid var(--ink);
  border-left-width: 4px;
  font-size: 0.95em;
}
.callout > :last-child { margin-bottom: 0; }
.callout--dark {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.callout--dark code { border-color: var(--paper); }
.callout--dark a { color: var(--paper); border-bottom-color: var(--paper); }
.callout--dark a:hover { background: var(--paper); color: var(--ink); }

.article-foot {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--ink);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  align-items: baseline;
  font-family: var(--mono);
  font-size: 12px;
}
.article-foot__note { color: var(--meta); }

.article-cta { margin: 40px 0 0; }

.prevnext {
  border-top: 2px solid var(--ink);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: 1px;
  background: var(--ink);
}
.prevnext a {
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
  padding: 32px var(--gutter);
}
.prevnext a:hover { background: var(--ink); color: var(--paper); }
.prevnext__label {
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 12px;
}
.prevnext__title {
  font-weight: 700;
  font-size: clamp(20px, 2vw, 28px);
  letter-spacing: -0.03em;
  line-height: 1.1;
  text-wrap: pretty;
}

/* Pages legales -------------------------------------------------------------- */

.legal { padding: clamp(40px, 6vw, 96px) var(--gutter); }
.legal .prose { max-width: 68ch; flex: 1 1 auto; }

/* Chat ---------------------------------------------------------------------- */

.chat-pill {
  position: fixed;
  right: clamp(16px, 3vw, 32px);
  bottom: calc(clamp(16px, 3vw, 32px) + env(safe-area-inset-bottom, 0px));
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  line-height: 1;
  cursor: pointer;
  max-width: calc(100vw - 32px);
}
.chat-pill:hover { background: var(--paper); color: var(--ink); }
.chat-pill__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Le point porte l'etat : vert disponible, ambre occupe, gris hors ligne. */
.chat-pill__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--meta);
  flex: 0 0 auto;
}
.chat-pill__dot.is-available { background: #17c964; }
.chat-pill__dot.is-busy { background: #f5a623; }
.chat-pill__dot.is-offline { background: #6b6b6b; }

.chat-pill__unread {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  line-height: 1;
}
.chat-pill__unread[hidden] { display: none; }

.chat-panel {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 60;
  width: min(400px, 100vw);
  height: 100%;
  height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-left: 2px solid var(--ink);
  transform: translateX(100%);
  transition: transform 240ms ease;
}
.chat-panel[hidden] { display: none; }
.chat-panel.is-open { transform: translateX(0); }

.chat-panel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 20px 16px;
  border-bottom: 2px solid var(--ink);
}
.chat-panel__title {
  margin: 0 0 6px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.02em;
}
.chat-panel__status {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--meta);
  text-transform: none;
  letter-spacing: 0.02em;
}
.chat-panel__close {
  font-family: var(--mono);
  font-size: 22px;
  line-height: 1;
  background: none;
  border: 1px solid var(--ink);
  color: var(--ink);
  padding: 4px 10px;
  cursor: pointer;
  flex: 0 0 auto;
}
.chat-panel__close:hover { background: var(--ink); color: var(--paper); }

.chat-panel__privacy {
  margin: 0;
  padding: 14px 20px;
  border-bottom: 1px solid var(--ink);
  color: var(--meta);
  text-transform: none;
  letter-spacing: 0.01em;
  line-height: 1.5;
  font-size: 11px;
}

.chat-panel__messages {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.chat-msg { display: flex; gap: 10px; align-items: flex-end; }
.chat-msg--visitor { flex-direction: row-reverse; }

.chat-msg__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  filter: grayscale(1);
  border: 1px solid var(--ink);
  flex: 0 0 auto;
}

.chat-msg__body { max-width: 78%; }
.chat-msg__bubble {
  padding: 10px 14px;
  border: 1px solid var(--ink);
  font-size: 15px;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.chat-msg--visitor .chat-msg__bubble { background: var(--ink); color: var(--paper); }
.chat-msg__time {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--meta);
}
.chat-msg--visitor .chat-msg__time { text-align: right; }

.chat-msg--system .chat-msg__bubble {
  border-style: dashed;
  color: var(--meta);
  font-family: var(--mono);
  font-size: 12px;
}

.chat-typing {
  display: flex;
  gap: 4px;
  padding: 10px 14px;
  border: 1px solid var(--ink);
  align-self: flex-start;
}
.chat-typing span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink);
  animation: chat-blink 1.2s infinite;
}
.chat-typing span:nth-child(2) { animation-delay: 0.2s; }
.chat-typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes chat-blink {
  0%, 60%, 100% { opacity: 0.25; }
  30% { opacity: 1; }
}

.chat-panel__blocked {
  margin: 0;
  padding: 12px 20px;
  border-top: 1px solid var(--ink);
  color: var(--meta);
  text-transform: none;
  letter-spacing: 0.01em;
}
.chat-panel__blocked[hidden] { display: none; }

.chat-panel__form {
  display: flex;
  gap: 0;
  border-top: 2px solid var(--ink);
  padding: 0 0 env(safe-area-inset-bottom, 0px);
}
.chat-panel__input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--sans);
  font-size: 15px;
  padding: 14px 16px;
  border: 0;
  background: var(--paper);
  color: var(--ink);
}
.chat-panel__input:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.chat-panel__input:disabled { background: #f2f2f2; color: var(--meta); }
.chat-panel__send {
  flex: 0 0 auto;
  border: 0;
  border-left: 1px solid var(--ink);
  background: var(--paper);
  padding: 14px 18px;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.chat-panel__send:hover { background: var(--ink); color: var(--paper); }

/* Entree du chat dans la section Contact. */
.contact__chat {
  margin: 28px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px 24px;
}
.contact__chat button.link-strong {
  font-family: var(--sans);
  background: none;
  color: var(--ink);
  border: 0;
  border-bottom: 3px solid var(--accent);
  padding: 0 0 2px;
  cursor: pointer;
}
/* Sans cette regle, le background:none ci-dessus l'emporte au survol sur
   .link-strong:hover, moins specifique : texte blanc sur fond blanc. */
.contact__chat button.link-strong:hover {
  background: var(--ink);
  color: var(--paper);
  border-bottom-color: var(--ink);
}
.contact__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--meta);
  text-transform: none;
  letter-spacing: 0.02em;
}

@media (max-width: 720px) {
  .chat-panel {
    width: 100vw;
    border-left: 0;
    /* La hauteur reelle est posee par le JS depuis visualViewport : sur iOS,
       le clavier reduit la fenetre visuelle sans reduire celle de mise en
       page, et 100svh laisse le champ sous le clavier. */
    height: 100%;
  }

  /* Safari iOS zoome la page des qu'un champ fait moins de 16px. */
  .chat-panel__input { font-size: 16px; }

  .chat-panel__messages {
    /* Le glissement dans les messages ne doit pas emporter la page. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* L'en-tete prenait la moitie de l'ecran avant le premier message. */
  .chat-panel__head { padding: 14px 16px 10px; }
  .chat-panel__title { font-size: 16px; margin-bottom: 4px; }
  .chat-panel__status {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .chat-panel__privacy {
    font-size: 10px;
    line-height: 1.4;
    padding: 10px 16px;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Pastille ronde : 238px de large, elle recouvrait la scene STIB.
     Le libelle reste dans aria-label, l'accessibilite ne perd rien. */
  .chat-pill {
    padding: 0;
    gap: 0;
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
    position: fixed;
  }
  .chat-pill__label { display: none; }
  .chat-pill__dot { width: 12px; height: 12px; }
  .chat-pill__unread {
    position: absolute;
    top: -6px;
    right: -6px;
  }
}

/* Panneau ouvert : la page ne doit pas defiler derriere lui. */
html.chat-open,
html.chat-open body {
  overflow: hidden;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .chat-panel { transition: none; }
  .chat-typing span { animation: none; opacity: 0.6; }
}

/* Accessibilite -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 720px) {
  /* Sur telephone, un titre de 38px centre dans un ecran entier flotte dans
     le vide : on le laisse couler normalement. */
  .hero__intro { min-height: 0; padding: 48px 0 40px; }

  .dataart__stage { height: 70svh; min-height: 420px; }
  .dataart__overlay { padding-bottom: clamp(56px, 12vw, 88px); }
  .dataart__facts {
    position: static;
    margin: 0;
    padding: 16px var(--gutter) 20px;
    text-align: left;
    max-width: none;
  }
  .dataart { padding-bottom: 0; }

  /* Les captures passent en bande a defilement : trois colonnes de 24vw
     seraient illisibles. */
  .latest__shots {
    flex: 1 1 100%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 8px;
  }
  .latest__shots img {
    flex: 0 0 72vw;
    width: 72vw;
    scroll-snap-align: start;
  }
  .latest__shots img:nth-child(2),
  .latest__shots img:nth-child(3) { margin-top: 0; }
  .toc { position: static; flex: 1 1 100%; }
  .split__label { flex: 1 1 100%; }
  .lab-strip__label { flex: 1 1 100%; }
  .who__photo { flex: 0 0 160px; width: 160px; height: 160px; }
  .post--row .post__date { flex: 1 1 100%; }
  .post--row .post__tags { flex: 1 1 100%; }
}

@media print {
  .nav, .footer, .toc, .prevnext, .article-foot { display: none; }
  body { font-size: 12pt; }
  .prose { max-width: none; }
}
