/* ══════════════════════════════════════════════════════════════════
   At Aero — police variable, auto-hébergée.
   Un seul fichier (105 Ko) couvre toutes les graisses de 100 à 900, au lieu
   d'un fichier par graisse. Aucun appel à un serveur tiers : la police part
   du même domaine que la page, donc pas de connexion supplémentaire à
   ouvrir avant que le texte s'affiche.

   ⚠ Les graisses nommées d'At Aero ne tombent pas sur des valeurs rondes :
       Air 100 · Thin 190 · Light 282 · Retina 375 · Regular 421
       Medium 500 · Semibold 585 · Bold 665 · Black 827 · Super 900
   Écrire font-weight: 400 donne donc un poids légèrement différent du
   « Regular » dessiné. Les valeurs exactes sont utilisées plus bas.

   ⚠ L'axe italique va de 0 à 10, pas de 0 à 1. `font-style: italic` ne
   déclenche qu'un dixième de l'inclinaison. Pour un vrai italique :
       font-variation-settings: "ital" 10;
   ══════════════════════════════════════════════════════════════════ */
@font-face {
  font-family: "At Aero";
  src: url("/fonts/at-aero-var-v1.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ══════════════════════════════════════════════════════════════════
   Tout le look tient dans les variables ci-dessous.
   ══════════════════════════════════════════════════════════════════ */
:root {
  /* Noir pur, volontairement : hero.jpg a un fond noir. Sur un écran plus
     large que l'image (ratio > 16:9), les bords laissent voir cette couleur —
     toute autre teinte ferait apparaître le rectangle de la photo. */
  --bg: #000;

  --ink: #f3f0ea; /* texte principal */
  --ink-soft: rgba(243, 240, 234, 0.58); /* texte secondaire */
  --ink-faint: rgba(243, 240, 234, 0.34); /* placeholder */
  --line: rgba(243, 240, 234, 0.2); /* contour du champ */
  --on-accent: #000; /* le pictogramme DANS le bouton blanc */
  --danger: #ffa896;

  /* Hauteur réservée à l'image, du haut de l'écran jusqu'au bas de
     l'étiquette qui pend. Le bloc titre + formulaire + réseaux se centre
     dans TOUT l'espace restant en dessous.

     C'est le seul réglage à toucher si le cadrage de la photo change : monte
     la valeur si le texte mord sur l'étiquette, baisse-la s'il y a trop de
     vide. En `vh` et non `svh` pour coller exactement à la boîte de .bg,
     qui est en position fixed. */
  --tag-zone: 63vh;

  /* Une seule famille sur tout le site. La substitution système est choisie
     pour des métriques proches, afin que le texte ne saute pas quand la
     police finit de charger. */
  --font: "At Aero", "Helvetica Neue", system-ui, -apple-system, sans-serif;

  /* Graisses réelles d'At Aero, pas des arrondis. */
  --w-light: 282;
  --w-regular: 421;
  --w-medium: 500;
}

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

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

body {
  min-height: 100svh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-weight: var(--w-regular);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ───────────────────────────── Scène ───────────────────────────── */

.stage {
  position: relative;
  z-index: 2;
  min-height: 100svh;
  display: grid;
  /* Rangée 1 : l'image jusqu'au bas de l'étiquette. Rangée 2 : le reste.
     Le bloc se centre dans la rangée 2, donc à équidistance du bas de
     l'étiquette et du bas de la page. */
  grid-template-rows: var(--tag-zone) 1fr;
  justify-items: center;
  padding: 0 1.5rem;
}

.content {
  grid-row: 2;
  align-self: center;
  /* Marge de sécurité : sur un écran très court, le bloc déborderait de sa
     rangée et sortirait de l'écran. */
  padding: 1rem 0;
  width: 100%;
  max-width: 30rem;
  text-align: center;
}

/* ────────────────────────── Image de fond ──────────────────────────
   hero.jpg : 3200×1786, 227 Ko, réencodé depuis l'original 5504×3072.
   Cette largeur couvre les écrans retina jusqu'à ~1600 px de large sans
   agrandissement. Pour remplacer l'image, réexporte à 3200 px de large,
   qualité 80 : au-delà le poids grimpe sans gain visible, l'image étant
   presque entièrement noire.

   `position: fixed` plutôt que `background-attachment: fixed` : ce dernier
   est cassé sur iOS Safari.
   ────────────────────────────────────────────────────────────────── */
.bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: #000 url("/hero.jpg") center / cover no-repeat;
  pointer-events: none;
}

/* Cadrage portrait dédié. Sans lui, `cover` sur une photo 16:9 affichée dans
   un écran de téléphone rogne ~70 % de la largeur et grossit le sujet à
   l'excès. Un navigateur ne télécharge que l'image de la media query qui
   correspond : un mobile ne paie jamais les 227 Ko de la version paysage. */
@media (orientation: portrait) {
  .bg {
    background-image: url("/hero-mobile.jpg");
  }

  /* En portrait, `cover` affiche toute la hauteur de l'image : aucune marge
     de recadrage vertical, donc l'étiquette tombe toujours au même
     pourcentage de l'écran, quel que soit le téléphone. */
  :root {
    --tag-zone: 64vh;
  }

  .title {
    margin-bottom: 1.5rem;
  }

  .social {
    margin-top: 1.5rem;
  }
}

/* ────────────────────────── Typographie ────────────────────────── */

.title {
  font-weight: var(--w-light);
  font-size: clamp(1.5rem, 5.2vw, 2.25rem);
  line-height: 1.12;
  /* Un géométrique a besoin d'un resserrage plus marqué qu'un serif aux
     grandes tailles, sinon les mots se délitent. */
  letter-spacing: -0.03em;
  margin-bottom: 2.25rem;
  text-wrap: balance;
}

/* ────────── Formulaire : champ rectangulaire + bouton carré ────────── */

.form {
  margin: 0 auto;
  max-width: 26rem;
}

.field {
  display: flex;
  align-items: stretch;
  gap: 0.625rem;
  /* La hauteur vit ici : le bouton la reprend pour rester parfaitement
     carré quoi qu'il arrive. */
  height: 3.25rem;
}

.input {
  flex: 1;
  min-width: 0;
  height: 100%;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 2px;
  outline: none;
  color: var(--ink);
  /* Les champs de formulaire n'héritent d'aucun style typographique par
     défaut : sans ces deux lignes, le navigateur impose sa police système. */
  font-family: inherit;
  font-weight: inherit;
  font-size: 1rem;
  padding: 0 1rem;
  text-align: left;
  transition: border-color 0.25s ease;
}

.input::placeholder {
  color: var(--ink-faint);
}

.input:hover {
  border-color: rgba(243, 240, 234, 0.32);
}

.input:focus {
  border-color: var(--ink);
}

.input:-webkit-autofill {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 100px #000 inset;
}

.button {
  flex: 0 0 auto;
  /* Carré : la largeur suit la hauteur de la rangée. */
  width: 3.25rem;
  height: 100%;
  display: grid;
  place-items: center;
  background: var(--ink);
  color: var(--on-accent);
  border: none;
  border-radius: 2px;
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.button .icon {
  /* L'avion pointe en haut à droite : un léger décalage le recentre
     optiquement dans le carré. */
  transform: translate(-1px, 1px);
}

@media (hover: hover) {
  .button:hover:not(:disabled) {
    transform: translateY(-2px);
  }
}

.button:active:not(:disabled) {
  transform: translateY(0);
}

.button:disabled {
  opacity: 0.45;
  cursor: progress;
}

.button:focus-visible,
.input:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Pendant l'envoi, l'avion s'envole en boucle. */
.button.is-busy .icon {
  animation: fly 0.9s ease-in-out infinite;
}

/* ─────────────────────────── Messages ─────────────────────────── */

.status {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--danger);
  margin-top: 0.9rem;
}

.status:empty {
  margin-top: 0;
}

/* ────────────────────────── Confirmation ────────────────────────── */

.done-title {
  font-weight: var(--w-light);
  font-size: clamp(1.375rem, 4.6vw, 1.875rem);
  line-height: 1.15;
  letter-spacing: -0.028em;
  margin-bottom: 0.5rem;
}

.done-body {
  font-size: 1rem;
  color: var(--ink-soft);
}

.done:focus {
  outline: none;
}

/* ────────────────────────── Réseaux sociaux ────────────────────────── */

.social {
  display: flex;
  justify-content: center;
  gap: 1.5rem;
  margin-top: 2.25rem;
}

.social-link {
  /* Zone tactile de 44 px, le minimum utilisable au doigt, alors que le
     pictogramme n'en fait que 21. */
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--ink);
  border-radius: 999px;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

@media (hover: hover) {
  .social-link:hover {
    transform: translateY(-2px);
  }
  .social-link:not(:hover) {
    opacity: 0.78;
  }
}

.social-link:active {
  transform: translateY(0);
}

.social-link:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ────────────────────────── Utilitaires ────────────────────────── */

/* Le piège à bots. Surtout pas display:none : certains bots l'ignorent. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}

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

/* ────────────────────────── Animations ────────────────────────── */

.r {
  animation: rise 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.r1 { animation-delay: 0.05s; }
.r2 { animation-delay: 0.2s; }
.r3 { animation-delay: 0.32s; }

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fly {
  0%   { transform: translate(-1px, 1px); opacity: 1; }
  55%  { transform: translate(9px, -9px); opacity: 0; }
  56%  { transform: translate(-9px, 9px); opacity: 0; }
  100% { transform: translate(-1px, 1px); opacity: 1; }
}

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

/* ──────────────────────────── Mobile ──────────────────────────── */

@media (max-width: 480px) {
  .field {
    height: 3.5rem;
  }

  .button {
    width: 3.5rem;
  }
}

/* Écran court et large (paysage mobile) : on resserre pour que l'image et
   le formulaire tiennent ensemble sans scroll. */
@media (max-height: 560px) and (orientation: landscape) {
  :root {
    /* Écran court : l'étiquette est plus haute en proportion, et le bloc a
       besoin de plus de place. */
    --tag-zone: 50vh;
  }

  .title {
    font-size: clamp(1.5rem, 4vw, 2rem);
    margin-bottom: 1.25rem;
  }

  .field {
    height: 2.875rem;
  }

  .button {
    width: 2.875rem;
  }
}
