/*
  Vitrine map3d. La palette est ÉCHANTILLONNÉE DANS LE LOGO (`docs/assets/logo.png`),
  pas inventée : son fond bleu nuit (#020610), le bleu de son globe filaire (#0e659a)
  et le turquoise de son pin (#1acbc4). Deux conséquences voulues : l'icône recadrée
  se pose sur la page sans bord visible, puisque son fond EST le fond du site ; et le
  graticule du hero reprend le bleu du globe du logo, qui est lui-même un graticule.

  Le turquoise est réservé aux actions et aux repères, le bleu aux structures — un
  seul accent qui décide, un second qui organise.

  Typo : la largeur variable d'Archivo sert d'échelle de zoom — titres élargis
  (wdth 112), étiquettes resserrées (wdth 78).
*/

:root {
  color-scheme: dark;

  --nuit: #020610;
  --relief: #081420;
  --graticule: #14293d;
  --releve: #f0f4f6;
  --cote: #7c97a6;
  --balise: #1acbc4;
  --globe: #0e659a;

  /* Les faces latines d'abord, puis les piles système par écriture : aucune de nos
     polices ne couvre le CJK, l'arabe ou la devanagari, et sans repli explicite le
     navigateur substitue au hasard — d'une ligne à l'autre le dessin change. */
  --scripts:
    'Noto Sans SC', 'PingFang SC', 'Hiragino Sans', 'Yu Gothic', 'Noto Sans JP', 'Malgun Gothic',
    'Apple SD Gothic Neo', 'Noto Sans KR', 'Noto Sans Devanagari', 'Nirmala UI', 'Noto Naskh Arabic',
    'Geeza Pro', 'Segoe UI', system-ui;
  --display: 'Archivo', var(--scripts), sans-serif;
  --body: 'IBM Plex Sans', var(--scripts), sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, var(--scripts), monospace;

  /* Une seule échelle de rayons, pour que rien ne durcisse un coin au hasard. */
  --r-xs: 5px;
  --r-sm: 7px;
  --r-md: 9px;

  --relief-haut: #10202f;
  --shell: 1200px;
  --marge: clamp(20px, 5vw, 56px);
  /* Largeur réservée à l'altimètre en colonne fixe (0 sous 1180px). */
  --altimetre: 0px;
}

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

/* Le fond est porté par `html`, pas par `body` : le canvas du décor est un enfant de
   `body` en `z-index: -1`, il passerait DERRIÈRE un fond posé sur `body`. */
html {
  background: var(--nuit);
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: transparent;
  color: var(--releve);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: inherit;
}

code {
  font-family: var(--mono);
  font-size: 0.92em;
}

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

/* — Décor —————————————————————————————————————————————————————————
   Globe de particules rendu par `bg/globe.ts` (three.js). Le canvas est inséré par le
   script : sans WebGL, sans JS ou si le fetch échoue, rien n'apparaît et la page reste
   telle quelle. `pointer-events: none` — le décor ne prend jamais un clic. */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Le décor s'éteint là où le texte vit. Un masque en dégradé vaut mieux qu'une
     opacité globale plus basse : le globe garde toute sa densité à droite, et la
     colonne de lecture reste sur fond net. */
  --backdrop-mask: linear-gradient(to right, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.34) 30%, #000 52%);
  -webkit-mask-image: var(--backdrop-mask);
  mask-image: var(--backdrop-mask);
  /* Fondu d'entrée : les particules arrivent après le premier rendu du texte, une
     apparition franche accrocherait l'œil au mauvais moment. */
  opacity: 0;
  animation: backdrop-in 1.6s ease-out 0.25s forwards;
}

/* Sous 900 px le globe est centré : un masque latéral le couperait en deux. */
@media (max-width: 899px) {
  .backdrop {
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
    mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
  }
}

@keyframes backdrop-in {
  to {
    opacity: 1;
  }
}

/* — Blocs partagés —————————————————————————————————————————————— */

.eyebrow {
  margin: 0 0 14px;
  font-family: var(--display);
  font-variation-settings: 'wdth' 78;
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--balise);
}

.button {
  display: inline-block;
  padding: 13px 24px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-sm);
  /* Opaque, et non transparent : le décor de particules passe derrière, pas à travers. */
  background: var(--relief);
  font-family: var(--display);
  font-variation-settings: 'wdth' 92;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease,
    color 0.18s ease;
}

.button:hover {
  border-color: var(--cote);
  background: var(--relief-haut);
}

.button--primary {
  border-color: var(--balise);
  background: var(--balise);
  color: var(--nuit);
}

.button--primary:hover {
  border-color: var(--releve);
  background: var(--releve);
  color: var(--nuit);
}

/* — Altimètre : le fil conducteur de la page ————————————————————————
   La page descend de l'orbite (hero) au trottoir (footer), comme la lib va du globe
   au mode piéton. Chaque section porte son altitude en `data-alt` ; `hud.js`
   interpole entre elles au scroll. */

.altimeter {
  position: fixed;
  top: 0;
  inset-inline-start: 0;
  z-index: 5;
  display: none;
  width: 72px;
  height: 100vh;
  padding: 96px 0 40px;
  border-inline-end: 1px solid var(--graticule);
  background: var(--nuit);
  text-align: center;
}

.altimeter__track {
  position: relative;
  width: 1px;
  height: calc(100vh - 240px);
  margin: 0 auto;
  background: linear-gradient(to bottom, var(--graticule), var(--graticule) 50%, transparent);
  background-size: 1px 8px;
  background-repeat: repeat-y;
}

.altimeter__cursor {
  position: absolute;
  inset-inline-start: -5px;
  top: 0;
  width: 11px;
  height: 11px;
  border: 1px solid var(--balise);
  border-radius: 50%;
  background: var(--nuit);
  transition: top 0.25s ease-out;
}

.altimeter__value {
  margin: 18px 0 0;
  font-family: var(--mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--releve);
}

.altimeter__unit {
  display: block;
  font-size: 10px;
  color: var(--cote);
}

.altimeter__caption {
  margin: 6px 0 0;
  font-family: var(--display);
  font-variation-settings: 'wdth' 78;
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cote);
}

/* — Barre haute ————————————————————————————————————————————————— */

.topbar {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  align-items: center;
  justify-content: space-between;
  padding: 14px var(--marge) 14px calc(var(--marge) + var(--altimetre));
  border-bottom: 1px solid var(--graticule);
  background: color-mix(in srgb, var(--nuit) 96%, transparent);
  backdrop-filter: blur(10px);
}

.topbar__brand {
  display: flex;
  gap: 9px;
  align-items: center;
  font-family: var(--display);
  font-variation-settings: 'wdth' 88;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.02em;
  text-decoration: none;
}

/* Le fond du PNG est exactement `--nuit` : aucun masque ni découpe à faire, l'icône
   se fond dans la barre. */
.topbar__mark {
  width: 30px;
  height: 30px;
}

.topbar__version {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 11px;
  color: var(--cote);
}

.topbar__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
  font-size: 14px;
}

.topbar__nav a {
  color: var(--cote);
  text-decoration: none;
  transition: color 0.15s ease;
}

.topbar__nav a:hover {
  color: var(--releve);
}

.topbar__source {
  color: var(--releve);
}

/* Sélecteur de langue : rendu par `build.mjs`, une entrée par dictionnaire de
   `site/i18n/`. Un menu `<details>` natif plutôt qu'une rangée de liens — au-delà de
   trois langues la rangée déborde la barre, et le menu fonctionne sans JavaScript. */
.langs {
  position: relative;
  padding-inline-start: 18px;
  border-inline-start: 1px solid var(--graticule);
}

.langs__current {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 3px 8px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-xs);
  background: var(--relief);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--releve);
  cursor: pointer;
  list-style: none;
}

.langs__current::-webkit-details-marker {
  display: none;
}

.langs__current::after {
  content: '▾';
  font-size: 10px;
  color: var(--cote);
}

.langs__current:hover {
  border-color: var(--cote);
}

.langs__menu {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-end: 0;
  z-index: 6;
  min-width: 200px;
  max-height: min(62vh, 440px);
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-sm);
  background: var(--relief);
  list-style: none;
  box-shadow: 0 18px 40px rgb(0 0 0 / 55%);
}

.langs__item {
  display: flex;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  padding: 7px 10px;
  border-radius: var(--r-xs);
  font-size: 14px;
  color: var(--cote);
  text-decoration: none;
}

.langs__item i {
  font-style: normal;
}

.langs__item b {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  color: var(--graticule);
}

a.langs__item:hover {
  background: var(--relief-haut);
  color: var(--releve);
}

.langs__item[aria-current='true'],
.langs__item[aria-current='true'] b {
  color: var(--balise);
}

/* — Hero ————————————————————————————————————————————————————————— */

.hero {
  display: grid;
  gap: clamp(36px, 5vw, 64px);
  max-width: var(--shell);
  margin: 0 auto;
  padding: clamp(56px, 9vw, 108px) var(--marge) clamp(40px, 6vw, 72px);
}

/* Le texte porte la thèse, la capture la prouve : dans cet ordre à toutes les
   tailles, alors que le HTML place le cadre en premier pour le préchargement. */
.hero__copy {
  order: -1;
  min-width: 0;
  max-width: 64ch;
}

.hero__title {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: 'wdth' 112;
  font-weight: 700;
  font-size: clamp(38px, 7vw, 82px);
  line-height: 0.98;
  letter-spacing: -0.025em;
}

.hero__sub {
  margin: 18px 0 0;
  font-size: clamp(16px, 2.2vw, 20px);
  font-style: italic;
  color: var(--cote);
}

.hero__lede {
  text-wrap: pretty;
  margin: 22px 0 0;
  max-width: 52ch;
  font-size: clamp(16px, 1.6vw, 18px);
  color: color-mix(in srgb, var(--releve) 82%, var(--nuit));
}

.hero__lede code {
  color: var(--releve);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.hero__install {
  margin: 22px 0 0;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--cote);
}

.hero__install code {
  padding: 7px 12px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-sm);
  background: var(--relief);
  color: var(--releve);
  user-select: all;
}

.hero__frame {
  position: relative;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--graticule);
  border-radius: var(--r-md);
  background: var(--relief);
}

.hero__shot {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* Graticule superposé : c'est ce que la lib dessine, pas un motif décoratif. */
.hero__graticule {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--globe) 42%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--globe) 42%, transparent) 1px, transparent 1px);
  background-size: 12.5% 25%;
}

.hero__plate {
  position: absolute;
  inset-inline-end: 0;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin: 0;
  padding: 8px 14px;
  border-top: 1px solid var(--graticule);
  border-inline-start: 1px solid var(--graticule);
  border-start-start-radius: var(--r-sm);
  background: color-mix(in srgb, var(--nuit) 82%, transparent);
  backdrop-filter: blur(6px);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--cote);
}

.hero__plate span:first-child {
  color: var(--releve);
}

/* — Bandeau de faits ————————————————————————————————————————————— */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--marge);
  border-top: 1px solid var(--graticule);
  border-bottom: 1px solid var(--graticule);
}

.facts > div {
  padding: 18px 0 18px 22px;
  border-inline-start: 1px solid var(--graticule);
}

.facts > div:first-child {
  padding-inline-start: 0;
  border-inline-start: 0;
}

.facts dt {
  font-family: var(--display);
  font-variation-settings: 'wdth' 78;
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cote);
}

.facts dd {
  margin: 5px 0 0;
  font-family: var(--mono);
  font-size: 14px;
}

/* — Sections ————————————————————————————————————————————————————— */

.section {
  max-width: var(--shell);
  margin: 0 auto;
  padding: clamp(64px, 9vw, 116px) var(--marge) 0;
}

.section__head {
  margin-bottom: clamp(28px, 4vw, 44px);
}

.section__title {
  margin: 0;
  font-family: var(--display);
  text-wrap: balance;
  font-variation-settings: 'wdth' 104;
  font-weight: 700;
  font-size: clamp(28px, 4.4vw, 46px);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.section__lede {
  text-wrap: pretty;
  max-width: 62ch;
  margin: 16px 0 0;
  color: var(--cote);
}

.section__lede a {
  color: var(--releve);
  text-decoration-color: var(--graticule);
  text-underline-offset: 3px;
}

.section__lede a:hover {
  text-decoration-color: var(--balise);
}

/* — Démos ———————————————————————————————————————————————————————— */

.demos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
}

.demo {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--graticule);
  border-radius: var(--r-md);
  background: var(--relief);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.2s ease,
    transform 0.2s ease;
}

a.demo:hover {
  border-color: var(--balise);
  transform: translateY(-3px);
}

.demo__shot {
  display: block;
  overflow: hidden;
  border-bottom: 1px solid var(--graticule);
}

.demo__shot img {
  width: 100%;
  transition: transform 0.4s ease;
}

a.demo:hover .demo__shot img {
  transform: scale(1.02);
}

.demo__body {
  display: block;
  padding: 22px 24px 26px;
}

.demo__tag {
  display: inline-block;
  align-self: flex-start;
  margin-bottom: 12px;
  padding: 3px 9px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-xs);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--balise);
}

.demo__name {
  display: block;
  font-family: var(--display);
  text-wrap: balance;
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.01em;
}

.demo__text {
  text-wrap: pretty;
  display: block;
  margin-top: 10px;
  color: var(--cote);
  font-size: 15px;
}

.demo__note {
  display: block;
  margin-top: 14px;
  padding-inline-start: 12px;
  border-inline-start: 2px solid var(--graticule);
  font-size: 13px;
  color: var(--cote);
}

.demo__cta {
  display: block;
  margin-top: 20px;
  font-family: var(--display);
  font-variation-settings: 'wdth' 88;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.04em;
  color: var(--balise);
}

.demo__cta::after {
  content: ' →';
}

/* — Rail de la galerie ——————————————————————————————————————————
   Une descente, pas une grille : les vues sont ORDONNÉES de l'orbite au trottoir, et
   chacune porte son altitude. Le rail défile horizontalement — quatre vues ou dix, la
   composition ne se déséquilibre jamais. */

.section__head--rail {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-end;
  justify-content: space-between;
  max-width: none;
}

.section__head--rail > div {
  max-width: min(100%, 68ch);
}

.rail__nav {
  display: flex;
  gap: 8px;
}

.rail__nav[hidden] {
  display: none;
}

.rail__button {
  width: 38px;
  height: 38px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-sm);
  background: var(--relief);
  color: var(--releve);
  font-size: 15px;
  cursor: pointer;
  transition:
    border-color 0.18s ease,
    color 0.18s ease;
}

.rail__button:hover:not(:disabled) {
  border-color: var(--balise);
  background: var(--relief-haut);
  color: var(--balise);
}

.rail__button:disabled {
  color: var(--graticule);
  cursor: default;
}

.rail {
  /* Largeurs de fondu, posées par `hud.js` selon ce qu'il reste à défiler de chaque
     côté : un fondu au départ mangerait la première vignette pour rien. */
  --fade-left: 0px;
  --fade-right: 0px;

  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(84vw, 430px);
  gap: 18px;
  overflow-x: auto;
  /* Le rail reste dans la colonne, aligné sur les autres blocs : le faire déborder à
     droite décalait toute la section par rapport aux titres et aux grilles. C'est le
     fondu de bord, pas un débordement, qui supprime la coupure nette.
     Le padding bas ne réserve plus la barre, juste de quoi loger l'anneau de focus. */
  margin: 0;
  padding: 0 0 6px;
  list-style: none;
  scroll-snap-type: x mandatory;
  /* Barre masquée : le fondu de bord et les flèches disent déjà qu'il y a une suite,
     et le rail reste défilable à la molette, au trackpad et au clavier. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  --rail-mask: linear-gradient(
    to right,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
  -webkit-mask-image: var(--rail-mask);
  mask-image: var(--rail-mask);
}

.rail::-webkit-scrollbar {
  display: none;
}

.rail__item {
  overflow: hidden;
  border: 1px solid var(--graticule);
  border-radius: var(--r-md);
  background: var(--relief);
  scroll-snap-align: start;
}

.rail__item img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-bottom: 1px solid var(--graticule);
}

.rail__caption {
  margin: 0;
  padding: 16px 18px 20px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--cote);
}

/* La cote d'altitude relie la vignette à l'altimètre de la marge : même échelle,
   même unité, même lecture. */
.rail__alt {
  display: block;
  margin-bottom: 8px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--balise);
}

.rail--plain .rail__caption b {
  margin-bottom: 5px;
}

.rail__caption b {
  display: block;
  margin-bottom: 3px;
  font-family: var(--display);
  font-variation-settings: 'wdth' 88;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--releve);
}

/* — Capacités ———————————————————————————————————————————————————— */

.caps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1px;
  overflow: hidden;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--graticule);
  border: 1px solid var(--graticule);
  border-radius: var(--r-md);
}

.caps li {
  background: var(--nuit);
}

.caps a {
  display: block;
  height: 100%;
  padding: 26px 26px 28px;
  text-decoration: none;
  transition: background-color 0.18s ease;
}

.caps a:hover {
  background: var(--relief);
}

.caps__name {
  display: block;
  font-family: var(--display);
  text-wrap: balance;
  font-variation-settings: 'wdth' 96;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.005em;
}

.caps a > code {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--balise);
}

.caps__text {
  text-wrap: pretty;
  display: block;
  margin-top: 10px;
  font-size: 14.5px;
  color: var(--cote);
}

.caps__text code {
  color: var(--releve);
}

/* — Bloc de code ————————————————————————————————————————————————— */

.code {
  overflow-x: auto;
  margin: 0;
  padding: 24px;
  border: 1px solid var(--graticule);
  border-radius: var(--r-md);
  background: var(--relief);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
  color: color-mix(in srgb, var(--releve) 88%, var(--nuit));
}

.code b {
  font-weight: 500;
  color: var(--balise);
}

.code i {
  font-style: normal;
  color: #6fa8d6;
}

/* — Pied ————————————————————————————————————————————————————————— */

.footer {
  display: grid;
  gap: 24px;
  max-width: var(--shell);
  margin: clamp(72px, 10vw, 128px) auto 0;
  padding: 36px var(--marge) 56px;
  border-top: 1px solid var(--graticule);
}

/* Le logo complet signe le bas de page — seul endroit où il a la place de se lire,
   wordmark compris. */
.footer__logo {
  width: 88px;
  height: 88px;
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  font-family: var(--display);
  font-variation-settings: 'wdth' 88;
  font-weight: 600;
  font-size: 14px;
}

.footer__links a {
  text-decoration: none;
  color: var(--releve);
  transition: color 0.15s ease;
}

.footer__links a:hover {
  color: var(--balise);
}

.footer__legal {
  margin: 20px 0 0;
  font-size: 13px;
  color: var(--cote);
}

.footer__legal a {
  color: var(--cote);
  text-underline-offset: 3px;
}

/* — Adaptations ————————————————————————————————————————————————— */

@media (max-width: 719px) {
  .facts > div {
    padding: 14px 0;
    border-top: 1px solid var(--graticule);
    border-inline-start: 0;
  }

  .facts > div:first-child {
    border-top: 0;
  }
}

@media (min-width: 900px) {
  .hero {
    gap: clamp(40px, 5vw, 60px);
  }

  .footer {
    grid-template-columns: auto 1fr;
    column-gap: 36px;
    align-items: start;
  }

  .footer__logo {
    grid-row: span 2;
  }

  /* Une seule démo pour l'instant : elle prend toute la largeur, capture à gauche et
     texte à droite, plutôt que de laisser une demi-colonne vide. Une deuxième démo
     rebasculera la grille en deux colonnes de cartes. */
  .demo {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    align-items: stretch;
  }

  .demo__shot {
    height: 100%;
    border-inline-end: 1px solid var(--graticule);
    border-bottom: 0;
  }

  .demo__shot img {
    height: 100%;
    object-fit: cover;
  }

  .demo__body {
    align-self: center;
    padding: 30px 32px;
  }
}

@media (min-width: 1180px) {
  :root {
    --altimetre: 72px;
  }

  .altimeter {
    display: block;
  }

  .hero,
  .facts,
  .section,
  .footer {
    padding-inline-start: calc(var(--marge) + var(--altimetre));
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* — Sens de lecture inverse (arabe) ————————————————————————————————
   Tout le reste du fichier est en propriétés logiques, donc déjà miroité par le
   navigateur. Ne restent que les dégradés, qui ignorent `dir`, et la position du
   globe — traitée dans `bg/globe.ts`, qui lit `dir` sur la racine. */

[dir='rtl'] .backdrop {
  --backdrop-mask: linear-gradient(to left, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.34) 30%, #000 52%);
}

[dir='rtl'] .rail {
  --rail-mask: linear-gradient(
    to left,
    transparent 0,
    #000 var(--fade-left),
    #000 calc(100% - var(--fade-right)),
    transparent 100%
  );
}

/* Le code d'exemple n'est pas de la prose : il se lit de gauche à droite en arabe
   comme ailleurs. */
[dir='rtl'] .code,
[dir='rtl'] .hero__install code {
  direction: ltr;
  text-align: left;
}

/* Le pavillon du sélecteur de langue. Taille fixée en `em` pour qu'il suive le texte, et
   `line-height: 1` parce que les emoji drapeaux ont une hauteur de ligne propre qui
   décalait la ligne de base des noms à côté d'eux. */
.langs__flag {
  flex: none;
  font-size: 1.05em;
  line-height: 1;
}

/* Avec le pavillon la ligne porte trois éléments, et `space-between` les aurait écartés
   un à un — drapeau à gauche, nom au milieu, code à droite. Le nom prend l'espace qui
   reste : le drapeau lui reste collé, le code à deux lettres tient la droite. */
.langs__item i {
  flex: 1;
}
