/*
 * FEUILLE DE DÉMARRAGE DE HUBSYM — plan « Écran de démarrage », 2026-08-30.
 *
 * CE FICHIER EST CHARGÉ EN PREMIER, ET IL EST BLOQUANT. C'est délibéré : le navigateur ne peint
 * rien avant de l'avoir lue, donc il ne peut plus peindre ni blanc, ni texte sans style. C'est la
 * correction à la racine des trois états observé au lancement — HTML brut, puis blanc, puis
 * beige.
 *
 * POURQUOI IL N'EST PAS DANS LE BUNDLE. Tout le CSS de l'application est importé par le JavaScript :
 * il n'existe donc qu'APRÈS le chargement du bundle, plusieurs centaines de millisecondes trop tard
 * pour le premier rendu. Ce fichier-ci est référencé directement par `index.html`, sans passer par
 * JavaScript.
 *
 * IL SERT DEUX FOIS, ET C'EST VOULU (sections 13 et 14) : l'écran de démarrage
 * l'utilise avant React, et le composant React `MachineAEcrire` utilise EXACTEMENT les mêmes classes
 * et les mêmes animations. Un seul tracé, un seul jeu d'images-clés, aucune version à tenir
 * d'accord avec l'autre.
 */

/*
 * LE FOND, AVANT TOUT LE RESTE.
 *
 * C'est la cause directe du flash blanc : rien ne posait de couleur sur `html`, et le beige venait
 * de `--hs-color-background-primary`, une propriété posée par JavaScript (applyGlobalTokens). Tant
 * que le bundle n'avait pas tourné, le navigateur peignait donc son blanc par défaut. La couleur est
 * ici EN DUR, seule façon de l'avoir au premier pixel — c'est exactement
 * `colors.light.background.primary`, la même valeur que le manifeste PWA et que `theme-color`.
 *
 * SUR `html` SEULEMENT, ET C'EST UN CORRECTIF (2026-09-12).
 *
 * Cette règle nommait aussi `body` et `#root`. Elle leur donnait un fond OPAQUE, et
 * `global.css` leur donne `height: 100%` — c'est-à-dire UN écran, jamais la hauteur du document.
 * Or le fond de thème (`#hs-theme-background`) est `position: fixed; z-index: -1` : dans l'ordre de
 * peinture, une couche à z-index négatif passe AVANT les fonds des blocs dans le flux. Les deux
 * boîtes beiges recouvraient donc le thème sur exactement la hauteur d'un écran, et le thème
 * réapparaissait au-delà — d'où la coupure nette en milieu de page, mesurée à 926 px sur un
 * viewport de 926 px.
 *
 * Le fond de `html` est propagé au CANEVAS, qui est peint sous toute la page, y compris sous les
 * couches à z-index négatif : il ne peut donc jamais masquer le thème. Il garde tout son effet
 * contre le flash blanc, et lui seul suffit.
 *
 * Le fond de page, lui, appartient désormais à un seul élément : `#hs-theme-background`, qui porte
 * déjà le beige sans thème et le décor avec (voir global.css).
 */
html,
#hs-theme-background {
  background-color: #f7f2ea;
}

/* Marge par défaut du navigateur : sans cela, une bande blanche apparaît sur les bords avant que la
   feuille principale ne soit chargée. */
body {
  margin: 0;
}

/*
 * L'ÉCRAN DE DÉMARRAGE.
 *
 * `position: fixed; inset: 0` plutôt que `min-height: 100dvh` : sur un élément fixé, `inset: 0` EST
 * la fenêtre d'affichage, sans dépendre du support de `dvh` ni d'une chaîne de hauteurs sur les
 * parents. Le résultat est le même partout, y compris dans une PWA iOS où `dvh` a longtemps menti.
 *
 * `z-index` très haut et `inset: 0` : il couvre tout, donc il bloque aussi les clics, la tabulation
 * et le toucher tant qu'il est là (section 16). Rien derrière lui n'est atteignable.
 */
#hs-boot {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: none;
  background-color: #f7f2ea;
  /*
   * AUCUN RETRAIT DE ZONE SÛRE ICI, ET C'EST UNE CORRECTION (2026-08-30).
   *
   * Le retrait était appliqué en padding sur ce conteneur : `env(safe-area-inset-top)` vaut 47 px sur
   * un iPhone à encoche contre 34 px en bas, donc la zone de centrage était DÉCALÉE de 6 px vers le
   * bas — et la machine avec elle. Or il n'y a rien à protéger : le fond doit couvrir tout l'écran
   * (il le fait, par `inset: 0`), et l'animation, au centre, n'approche aucun bord. Un retrait qui ne
   * sert à rien mais fausse le centrage n'est pas un retrait prudent.
   */
  overscroll-behavior: contain;
  touch-action: none;
  transition: opacity 200ms ease;
}

/*
 * Affiché par le script d'amorçage d'`index.html`, jamais par défaut : un visiteur qui arrive sur la
 * vitrine publique doit voir la vitrine, pas une animation de chargement.
 *
 * `grid` + `place-items: center` : le centrage se fait sur les deux axes en une seule déclaration,
 * par rapport à la fenêtre d'affichage réelle — `inset: 0` sur un élément fixé EST cette fenêtre,
 * sans dépendre du support de `dvh` ni d'une chaîne de hauteurs sur les parents.
 */
#hs-boot[data-visible] {
  display: grid;
  place-items: center;
}

/*
 * LE CENTRAGE VISUEL, ET NON CELUI DE LA BOÎTE DE MISE EN PAGE.
 *
 * Deux géométries faussaient le résultat, et aucune n'était visible dans les règles de centrage :
 *
 *  - `.hs-machine` porte `margin-top`, qui réserve la course de la feuille dans un flux de document.
 *    Au centre d'un écran vide, cette réserve n'a plus d'objet et ne fait que pousser la machine vers
 *    le bas.
 *  - `transform: scale()` s'applique depuis `top center` : la machine agrandie POUSSE VERS LE BAS
 *    depuis son bord supérieur, alors que la mise en page, elle, centre la boîte NON agrandie. Plus
 *    l'échelle est grande, plus l'écart se creuse.
 *
 * La correction porte donc sur l'ENVELOPPE, jamais sur le tracé : la machine reste rigoureusement celle des écrans
 * d'import, qui la posent dans un flux normal et ont besoin de cette réserve.
 *
 * Le décalage est exprimé à partir des cotes du dessin lui-même — hauteur du cadre (76 px) et centre
 * visible du corps (chariot + clavier, 33 px) — et non d'une valeur trouvée à l'œil.
 */
#hs-boot .hs-boot-visuel {
  display: grid;
  place-items: center;
  transform: translateY(calc(38px - 33px * var(--boot-echelle)));
}

#hs-boot .hs-machine {
  /* La même valeur que celle lue par l'enveloppe : une seule source, impossible à faire diverger. */
  --machine-echelle: var(--boot-echelle);
  margin: 0;
  /*
   * L'ÉCHELLE ÉTAIT COMPTÉE DEUX FOIS, et c'est là qu'était le décalage horizontal (mesuré : 45 px à
   * l'échelle 1,5, puis 86 px à 1,8 — l'écart grandissait avec l'échelle, signature d'une géométrie
   * dépendante du facteur).
   *
   * Le tracé fixe à la fois les dimensions de la boîte (`width: calc(120px * échelle)`) ET un
   * `transform: scale(échelle)`. La boîte mesurait donc 180 px pendant que son contenu, large de
   * 120 px, était agrandi autour du centre de cette boîte de 180 px : le dessin se retrouvait à
   * gauche de son propre cadre.
   *
   * La boîte retrouve ici ses cotes NON agrandies, et le `transform` fait tout le travail.
   * Rien n'est touché dans le dessin : les écrans d'import, qui posent la machine dans un flux normal,
   * gardent exactement le comportement qu'ils avaient.
   */
  width: 120px;
  height: 76px;
}

/* Sortie : une simple disparition, courte. Ni zoom, ni glissement (section 15). */
#hs-boot[data-sortie] {
  opacity: 0;
  pointer-events: none;
}

/* Pendant l'écran de démarrage, la page ne défile pas derrière — et le défilement est rendu tel quel
   au retrait, puisqu'il suffit de retirer cette classe. */
.hs-boot-actif,
.hs-boot-actif body {
  overflow: hidden;
}

/*
 * TAILLE DE LA MACHINE AU DÉMARRAGE : plus grande que dans les encarts d'import, où elle accompagne
 * un texte. Ici elle est seule au centre de l'écran, et doit sembler voulue. Deux paliers plutôt
 * qu'une formule au pixel près : rien n'est calé sur un modèle de téléphone, et l'écran d'ordinateur
 * n'hérite pas d'une machine géante (section 36).
 */
/*
 * L'ÉCHELLE EST POSÉE SUR LE CONTENEUR, ET NON SUR LA MACHINE — ce n'est pas un détail.
 *
 * Elle vivait sur `.hs-machine`. Or les propriétés personnalisées descendent, elles ne remontent
 * pas : l'enveloppe qui centre, étant le PARENT, ne la voyait pas et retombait sur 1. Sa compensation
 * était donc calculée pour une échelle qui n'était pas celle affichée — 17 px trop bas, mesurés.
 * Posée ici, la même valeur sert au dessin et à son centrage, et ne peut plus diverger.
 */
#hs-boot {
  --boot-echelle: 1.5;
}

@media (min-width: 900px) {
  #hs-boot {
    --boot-echelle: 1.8;
  }
}

/* Le bloc d'erreur d'amorçage — normalement jamais vu (voir index.html). Styles volontairement
   minimaux : il doit rester lisible même si rien d'autre n'a pu être chargé. */
#hs-boot-erreur {
  display: none;
  max-width: 320px;
  padding: 0 24px;
  text-align: center;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  color: #1f2933;
}

#hs-boot[data-erreur] #hs-boot-erreur {
  display: block;
}

#hs-boot[data-erreur] .hs-machine {
  display: none;
}

#hs-boot-erreur button {
  margin-top: 16px;
  min-height: 44px;
  padding: 0 20px;
  border: 1px solid #ece5da;
  border-radius: 9999px;
  background-color: #fbf8f3;
  color: #1f2933;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

/*
 * MACHINE À ÉCRIRE — d'après le composant Uiverse de dilmurod_3869.
 * Source : https://uiverse.io/dilmurod_3869/new-penguin-19
 *
 * Le tracé, les proportions et les quatre animations (rebond, chariot, feuille, touches) sont ceux
 * de l'original, conservés tels quels : c'est ce qui fait qu'on la reconnaît. Ce qui change ici :
 *
 *  - LES COULEURS, toutes reprises de la palette HubSym. Le bleu/violet d'origine (`--blue`,
 *    `--blue-dark`) devient la terracotta, `--tool` la nuance pêche, `--paper` et `--key` la crème.
 *  - L'ÉCHELLE, exposée en une seule variable pour que l'appelant l'adapte à sa place.
 *  - LE MOUVEMENT RÉDUIT, absent de l'original.
 *
 * POURQUOI `--base-color-*` ET NON `--hs-color-*` : cette machine EST HubSym, elle n'est pas un
 * contrôle de l'interface. Les tokens `--base-` sont insensibles au thème par construction (voir
 * applyGlobalTokens.ts) — un thème d'hiver bleu ne doit pas repeindre la machine, alors qu'il doit
 * repeindre un bouton. (2026-08-30) « la machine doit garder une identité
 * HubSym », « ne pas appliquer naïvement une couleur de thème sur tous les éléments ».
 */

.hs-machine {
  /*
   * LES DEUX BOUTS DU DÉGRADÉ SONT ÉLOIGNÉS, ET C'EST CE QUI DONNE LE VOLUME. L'original va d'un
   * bleu vif à un quasi-noir : c'est cet écart, pas la teinte, qui fait lire un objet en trois
   * dimensions. Deux crans voisins de terracotta (500 et 700) donnaient une forme plate — un bloc
   * orange découpé, relevé le 2026-08-30.
   */
  --blue: var(--base-color-primary-500, #C96F4A);
  --blue-dark: var(--base-color-primary-900, #502C1E);
  --key: var(--base-color-surface-default, #FBF8F3);
  --paper: var(--base-color-surface-default, #FBF8F3);
  --text: var(--base-color-primary-300, #E7BEAE);
  --tool: var(--base-color-primary-300, #E7BEAE);
  --duration: 3s;
  /*
   * L'original mesure 120px de large. `--machine-echelle` permet à chaque appelant de l'ajuster —
   * une feuille d'import a de la place, l'encart d'une page de recette beaucoup moins — sans jamais
   * retoucher une seule des cotes ci-dessous, toutes solidaires du tracé.
   */
  --machine-echelle: 1;

  position: relative;
  /* La marge du haut réserve la course de la feuille, qui sort du cadre de la machine. */
  margin: calc(30px * var(--machine-echelle)) auto 0;
  width: calc(120px * var(--machine-echelle));
  height: calc(76px * var(--machine-echelle));
  transform: scale(var(--machine-echelle));
  transform-origin: top center;
  animation: rebond var(--duration) linear infinite;
}

.hs-machine-chariot {
  width: 92px;
  height: 20px;
  border-radius: 3px;
  margin-left: 14px;
  transform: translateX(14px);
  background: linear-gradient(var(--blue), var(--blue-dark));
  animation: chariot var(--duration) ease infinite;
}

.hs-machine-chariot::before,
.hs-machine-chariot::after,
.hs-machine-chariot i::before {
  content: "";
  position: absolute;
  background: var(--tool);
}

.hs-machine-chariot::before {
  width: 2px;
  height: 8px;
  top: 6px;
  left: 100%;
}

.hs-machine-chariot::after {
  left: 94px;
  top: 3px;
  height: 14px;
  width: 6px;
  border-radius: 3px;
}

.hs-machine-chariot i {
  display: block;
  position: absolute;
  right: 100%;
  width: 6px;
  height: 4px;
  top: 4px;
  background: var(--tool);
}

.hs-machine-chariot i::before {
  right: 100%;
  top: -2px;
  width: 4px;
  border-radius: 2px;
  height: 14px;
}

.hs-machine-feuille {
  position: absolute;
  left: 24px;
  top: -26px;
  width: 40px;
  height: 46px;
  border-radius: 5px;
  background: var(--paper);
  /* Absent de l'original, qui posait une feuille lavande sur un fond quelconque. Ici la feuille est
     crème ET le fond de HubSym est crème : sans ce filet, elle disparaît dans la page. */
  border: 1px solid var(--base-color-border-default, #ECE5DA);
  transform: translateY(46px);
  animation: feuille var(--duration) linear infinite;
}

/* Les quatre lignes de texte qui apparaissent sur la feuille. */
.hs-machine-feuille::before {
  content: "";
  position: absolute;
  left: 6px;
  right: 6px;
  top: 7px;
  border-radius: 2px;
  height: 4px;
  transform: scaleY(0.8);
  background: var(--text);
  box-shadow:
    0 12px 0 var(--text),
    0 24px 0 var(--text),
    0 36px 0 var(--text);
}

.hs-machine-clavier {
  width: 120px;
  height: 56px;
  margin-top: -10px;
  z-index: 1;
  position: relative;
}

.hs-machine-clavier::before,
.hs-machine-clavier::after {
  content: "";
  position: absolute;
}

.hs-machine-clavier::before {
  inset: 0;
  border-radius: 7px;
  background: linear-gradient(135deg, var(--blue), var(--blue-dark));
  transform: perspective(10px) rotateX(2deg);
  transform-origin: 50% 100%;
}

.hs-machine-clavier::after {
  left: 2px;
  top: 25px;
  width: 11px;
  height: 4px;
  border-radius: 2px;
  box-shadow:
    15px 0 0 var(--key),
    30px 0 0 var(--key),
    45px 0 0 var(--key),
    60px 0 0 var(--key),
    75px 0 0 var(--key),
    90px 0 0 var(--key),
    22px 10px 0 var(--key),
    37px 10px 0 var(--key),
    52px 10px 0 var(--key),
    60px 10px 0 var(--key),
    68px 10px 0 var(--key),
    83px 10px 0 var(--key);
  animation: touches var(--duration) linear infinite;
}

@keyframes rebond {
  85%,
  92%,
  100% {
    transform: scale(var(--machine-echelle)) translateY(0);
  }

  89% {
    transform: scale(var(--machine-echelle)) translateY(-4px);
  }

  95% {
    transform: scale(var(--machine-echelle)) translateY(2px);
  }
}

@keyframes chariot {
  5% {
    transform: translateX(14px);
  }

  15%,
  30% {
    transform: translateX(6px);
  }

  40%,
  55% {
    transform: translateX(0);
  }

  65%,
  70% {
    transform: translateX(-4px);
  }

  80%,
  89% {
    transform: translateX(-12px);
  }

  100% {
    transform: translateX(14px);
  }
}

@keyframes feuille {
  5% {
    transform: translateY(46px);
  }

  20%,
  30% {
    transform: translateY(34px);
  }

  40%,
  55% {
    transform: translateY(22px);
  }

  65%,
  70% {
    transform: translateY(10px);
  }

  80%,
  85% {
    transform: translateY(0);
  }

  92%,
  100% {
    transform: translateY(46px);
  }
}

@keyframes touches {
  5%,
  12%,
  21%,
  30%,
  39%,
  48%,
  57%,
  66%,
  75%,
  84% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  9% {
    box-shadow:
      15px 2px 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  18% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 2px 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  27% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 12px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  36% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 12px 0 var(--key),
      60px 12px 0 var(--key),
      68px 12px 0 var(--key),
      83px 10px 0 var(--key);
  }

  45% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 2px 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  54% {
    box-shadow:
      15px 0 0 var(--key),
      30px 2px 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  63% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 12px 0 var(--key);
  }

  72% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 2px 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 10px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }

  81% {
    box-shadow:
      15px 0 0 var(--key),
      30px 0 0 var(--key),
      45px 0 0 var(--key),
      60px 0 0 var(--key),
      75px 0 0 var(--key),
      90px 0 0 var(--key),
      22px 10px 0 var(--key),
      37px 12px 0 var(--key),
      52px 10px 0 var(--key),
      60px 10px 0 var(--key),
      68px 10px 0 var(--key),
      83px 10px 0 var(--key);
  }
}

/*
 * MOUVEMENT RÉDUIT : la machine reste, elle s'immobilise. La feuille se fige à mi-course plutôt qu'à
 * sa position de départ (hors du cadre) — sans quoi le dessin perdrait la moitié de ce qui le rend
 * lisible, et il ne resterait plus qu'un rectangle. Aucune information de progression ne dépend de
 * cette animation : les étapes, le pourcentage et la barre disent tout par eux-mêmes.
 */
@media (prefers-reduced-motion: reduce) {
  .hs-machine,
  .hs-machine-chariot,
  .hs-machine-feuille,
  .hs-machine-clavier::after {
    animation: none;
  }

  .hs-machine-feuille {
    transform: translateY(16px);
  }
}
