/* Une affiche, pas une page.
 *
 * Le prochain cours occupe tout l'ecran, teinte a sa couleur. Les autres
 * cours du jour tiennent en bas. Ce qui suit se lit en glissant vers le bas,
 * par-dessus l'affiche, qui reste en place. Une bande d'actions se tire depuis
 * le haut. Aucune boite, aucun trait : la taille et l'opacite font tout.
 *
 * Toucher un cours ouvre une feuille montee du bas, coiffee du meme champ
 * colore que l'affiche. Feuille de reglages et feuille de detail partagent le
 * meme mecanisme : meme courbe, meme voile, meme glissement du doigt.
 */

/* -- palette de la page -------------------------------------------------- */

:root {
  --fond: #0b0b10;
  --surface: #16161f;
  --surface-2: #1f1f2a;
  --trait: #262631;
  --texte: #f4f4f7;
  --gris: #8e8e9c;
  --alerte: #f0a742;
  --live: #43d787;

  --marge: 22px;
  --haut: env(safe-area-inset-top, 0px);
  --bas: env(safe-area-inset-bottom, 0px);

  /* Courbe des feuilles : depart franc, arrivee posee. Celle des panneaux
     d'iOS, la seule qui ne donne pas l'impression d'un rideau qui tombe. */
  --glisse: cubic-bezier(0.32, 0.72, 0, 1);
}

/* Pastel : les memes teintes, claires, avec un texte sombre. La barre d'etat
   iOS garde un fond fonce de la meme teinte : en plein ecran son texte est
   blanc, et il resterait illisible sur du pastel. */
:root[data-theme="pastel"] {
  --fond: #f4f2ee;
  --surface: #ffffff;
  --surface-2: #eeece7;
  --trait: #e2dfd8;
  --texte: #16151b;
  --gris: #6d6c75;
  --alerte: #b25e00;
  --live: #1f8a4c;
  --barre: hsl(var(--h) calc(var(--sat) * 0.5) 24%);
}

@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] {
    --fond: #f4f2ee;
    --surface: #ffffff;
    --surface-2: #eeece7;
    --trait: #e2dfd8;
    --texte: #16151b;
    --gris: #6d6c75;
    --alerte: #b25e00;
    --live: #1f8a4c;
    --barre: hsl(var(--h) calc(var(--sat) * 0.5) 24%);
  }
}

/* -- palette du champ colore ---------------------------------------------
 *
 * Les couleurs derivees sont calculees la ou elles sont declarees : posees sur
 * `:root` seulement, elles ignoreraient la teinte locale d'un champ. Chaque
 * bloc nomme donc `:root` ET `.champ`, ce qui permet a la feuille de detail de
 * porter la couleur de SON cours pendant que l'affiche garde la sienne.       */

:root,
.champ {
  /* Teinte et saturation, posees par le script. */
  --h: 252;
  --sat: 70%;

  --affiche-fond: hsl(var(--h) calc(var(--sat) * 0.55) 11%);
  --affiche-texte: #ffffff;
  --affiche-gris: rgba(255, 255, 255, 0.64);
  --bulle-1: hsl(var(--h) var(--sat) 54% / 0.78);
  --bulle-2: hsl(calc(var(--h) + 52) var(--sat) 62% / 0.5);
  --bulle-3: hsl(calc(var(--h) - 40) var(--sat) 46% / 0.7);
  --bulle-4: hsl(calc(var(--h) + 20) var(--sat) 70% / 0.32);
  --grain: 0.3;
}

:root[data-theme="pastel"],
:root[data-theme="pastel"] .champ {
  --affiche-fond: hsl(var(--h) calc(var(--sat) * 0.6) 90%);
  --affiche-texte: hsl(var(--h) 38% 12%);
  --affiche-gris: hsl(var(--h) 22% 32% / 0.8);
  --bulle-1: hsl(var(--h) var(--sat) 72% / 0.8);
  --bulle-2: hsl(calc(var(--h) + 52) var(--sat) 78% / 0.6);
  --bulle-3: hsl(calc(var(--h) - 40) var(--sat) 66% / 0.6);
  --bulle-4: hsl(calc(var(--h) + 20) var(--sat) 82% / 0.5);
  --grain: 0.26;
}

@media (prefers-color-scheme: light) {
  :root[data-theme="auto"],
  :root[data-theme="auto"] .champ {
    --affiche-fond: hsl(var(--h) calc(var(--sat) * 0.6) 90%);
    --affiche-texte: hsl(var(--h) 38% 12%);
    --affiche-gris: hsl(var(--h) 22% 32% / 0.8);
    --bulle-1: hsl(var(--h) var(--sat) 72% / 0.8);
    --bulle-2: hsl(calc(var(--h) + 52) var(--sat) 78% / 0.6);
    --bulle-3: hsl(calc(var(--h) - 40) var(--sat) 66% / 0.6);
    --bulle-4: hsl(calc(var(--h) + 20) var(--sat) 82% / 0.5);
    --grain: 0.26;
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* A specificite egale, la derniere regle gagne : sans ce !important, un
   `display: flex` l'emporte sur le [hidden] du navigateur. */
[hidden] { display: none !important; }

html {
  background: var(--fond);
  /* Pas d'elastique en haut : c'est notre geste, pas celui du navigateur. */
  overscroll-behavior-y: none;
}

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 16px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

body.fige { overflow: hidden; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* En plein ecran iOS, le texte de la barre d'etat est blanc et le contenu
   passe dessous. Sur l'affiche sombre il se lit tel quel ; en pastel, cette
   bande lui rend un fond fonce de la meme teinte. */
body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--haut);
  z-index: 10;
  pointer-events: none;
  background: var(--barre, transparent);
}

a.b { text-decoration: none; display: inline-block; color: inherit; }

/* -- le champ colore, partage par l'affiche et la feuille de detail ------ */

.champ {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  color: var(--affiche-texte);
  background: var(--affiche-fond);
}

/* Les vagues : des nappes de couleur etirees, floues, qui derivent lentement. */
.champ::before {
  content: "";
  position: absolute;
  inset: -30%;
  z-index: -2;
  background:
    radial-gradient(58% 22% at 26% 30%, var(--bulle-1), transparent 72%),
    radial-gradient(52% 18% at 78% 22%, var(--bulle-2), transparent 72%),
    radial-gradient(64% 20% at 60% 58%, var(--bulle-4), transparent 72%),
    radial-gradient(72% 26% at 44% 84%, var(--bulle-3), transparent 72%);
  filter: blur(30px);
  transform: rotate(-11deg);
}

/* Le grain : un bruit fin, fondu dans la couleur. */
.champ::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: var(--grain);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.92' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-size: 220px 220px;
}

@media (prefers-reduced-motion: no-preference) {
  .champ::before { animation: derive 26s ease-in-out infinite alternate; }
  @keyframes derive {
    from { transform: rotate(-11deg) translate(0, 0); }
    to { transform: rotate(-6deg) translate(4%, 3%); }
  }
}

/* Avec une image choisie pour la matiere : l'image couvre tout, un voile de
   la teinte garde le texte lisible, le grain reste. */
.champ--image {
  background-image: linear-gradient(hsl(var(--h) 40% 8% / 0.30), hsl(var(--h) 40% 8% / 0.78)), var(--image, none);
  background-size: cover;
  background-position: center;
  color: #fff;
  --affiche-gris: rgba(255, 255, 255, 0.7);
}
.champ--image::before { display: none; }

/* -- l'affiche ----------------------------------------------------------- */

.affiche {
  position: sticky;
  top: 0;
  z-index: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: calc(var(--haut) + 16px) var(--marge) calc(var(--bas) + 20px);
}

/* Quand l'invitation a poser l'application est visible, l'affiche lui laisse
   la place au lieu de cacher les cours du jour dessous. */
body.avec-pose .affiche { padding-bottom: calc(var(--bas) + 96px); }

/* -- ligne du haut ------------------------------------------------------ */

.tete {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-height: 30px;
  font-size: 14px;
  letter-spacing: 0.01em;
  color: var(--affiche-gris);
  text-align: left;
  width: 100%;
}

.tete .retard { color: var(--alerte); font-weight: 600; }
:root[data-theme="sombre"] .tete .retard,
:root[data-theme="auto"] .tete .retard { color: #ffc46b; }

/* -- le cours ----------------------------------------------------------- */

.grand {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 26px 0;
  text-align: left;
  width: 100%;
  color: inherit;
  transition: transform 0.2s ease-out;
}

.grand:active { transform: scale(0.985); }

.quand {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--affiche-gris);
}

.quand--live::before {
  content: "";
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--live);
  vertical-align: 1px;
}
@media (prefers-reduced-motion: no-preference) {
  .quand--live::before { animation: pouls 2.2s ease-in-out infinite; }
  @keyframes pouls { 50% { opacity: 0.35; } }
}

.titre {
  margin: 0 0 22px;
  font-size: clamp(36px, 10.5vw, 58px);
  line-height: 1.02;
  font-weight: 800;
  letter-spacing: -0.035em;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.heure,
.salle {
  margin: 0;
  font-size: clamp(24px, 7vw, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.salle { margin-top: 4px; }

.plus {
  margin: 14px 0 0;
  font-size: 15px;
  color: var(--affiche-gris);
}

.rien {
  font-size: clamp(30px, 8vw, 44px);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: 0;
}

/* -- ce qui a ete pose a la main ----------------------------------------
 *
 * Un creneau de revision occupe l'ecran exactement comme un cours : meme
 * echelle, meme couleur, meme place. Un seul signe l'en distingue, un liseré
 * en pointilles, et il est toujours a gauche -- sur l'affiche, dans les
 * listes, sur la fiche. Le pointille, c'est l'ecrit a la main contre
 * l'imprime : il ne ressemble a rien d'autre dans l'application, et il n'a
 * donc besoin d'aucun mot pour se faire comprendre.
 *
 * `width: auto` avec une marge negative : le liseré sort dans la marge, le
 * texte ne bouge pas d'un pixel, et le bloc reste au ras du bord droit. */
.grand--perso {
  width: auto;
  margin-left: -14px;
  padding-left: 12px;
  border-left: 2px dashed var(--affiche-gris);
}

/* -- la porte d'entree, sans compte ------------------------------------- */
/* L'adresse nue mene ici : c'est le premier ecran du service pour quelqu'un
   qui n'a pas encore de lien, et le dernier pour celui qui vient d'effacer
   son compte. Meme champ colore que l'ecran de creation d'acces, pour que le
   passage de l'un a l'autre ne ressemble pas a un changement de site. */

/* Pas d'align-items ici : les enfants s'etirent, comme sur les autres ecrans.
   En flex-start, le titre se dimensionne sur son contenu et deborde a droite
   des que le prochain mot est plus long que la ligne. */
/* Borne la colonne : c'est le seul ecran de l'application qui s'ouvre aussi
   sur un ordinateur, et un titre etale sur 1280 px ne se lit pas. */
.porte { justify-content: center; max-width: 560px; }

.porte-dit {
  margin: 0 0 30px;
  font-size: 17px;
  line-height: 1.45;
  max-width: 32ch;
  color: var(--affiche-gris);
}

.porte-b {
  display: block;
  text-align: center;
  text-decoration: none;
}

.porte-note {
  margin: 18px 0 0;
  font-size: 14px;
  line-height: 1.5;
  max-width: 34ch;
  color: var(--affiche-gris);
}

/* Ce qui vient d'arriver passe devant ce qu'on propose de faire. */
.porte-note--fort {
  margin: 0 0 18px;
  font-size: 16px;
  font-weight: 600;
  color: var(--affiche-texte);
}

/* La seconde porte : centree sous le bouton, sans lui disputer la place. Celui
   qui a deja un acces la cherche, celui qui n'en a pas ne la voit pas.
   Le meme trait sert a l'ecran d'attente, ou signaler un probleme est la seule
   action possible sans devoir etre la plus voyante : attendre n'est pas une
   panne, et l'ecran ne doit pas en avoir l'air. */
.porte-second {
  display: block;
  width: 100%;
  margin-top: 16px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 15px;
  text-align: center;
  color: var(--affiche-gris);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* -- les autres cours du jour, en bas ----------------------------------- */

.jour { flex: 0 0 auto; }

.jour ul,
.suite ul { list-style: none; margin: 0; padding: 0; }

.jour li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 7px 0;
  font-size: 16px;
  line-height: 1.3;
  cursor: pointer;
  transition: opacity 0.15s ease-out;
}

.jour li:active,
.suite li:active { opacity: 0.5; }

.jour .passe { opacity: 0.42; }

.jour .h {
  flex: 0 0 48px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.jour .n {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.jour .s {
  flex: 0 0 auto;
  max-width: 44%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--affiche-gris);
  font-variant-numeric: tabular-nums;
}

/* -- la suite, qui glisse par-dessus ------------------------------------ */

.suite {
  position: relative;
  z-index: 1;
  background: var(--fond);
  padding: 8px var(--marge) calc(var(--bas) + 40px);
  max-width: 620px;
  margin: 0 auto;
  box-shadow: 0 -30px 60px rgba(0, 0, 0, 0.25);
}

.suite:empty { display: none; }

.suite h2 {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  padding: calc(var(--haut) + 14px) 0 8px;
  background: linear-gradient(var(--fond) 78%, transparent);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gris);
}

.suite ul { margin: 0 0 22px; }

/* Poser un creneau la ou on le lit : le jour est deja rempli, et personne n'a
   a retaper une date qu'il a sous les yeux. Discret, au bout du titre de la
   journee : ce n'est pas le geste principal de cet ecran. */
.jour-plus {
  flex: 0 0 auto;
  margin: -6px -6px -6px 0;
  padding: 6px 8px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  color: var(--gris);
}

.suite li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 11px 0;
  cursor: pointer;
  transition: opacity 0.15s ease-out;
}

.suite .h {
  flex: 0 0 66px;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.suite .h::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 9px;
  vertical-align: 1px;
  background: hsl(var(--h) var(--sat) 62%);
}

.suite .n {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 16px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.suite .s {
  flex: 0 0 auto;
  max-width: 44%;
  font-size: 14px;
  color: var(--gris);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -- ce qui a change, sept jours --------------------------------------- */

/* Un cours annule ne disparait plus : il reste barre une semaine, le temps
   qu'on comprenne pourquoi la journee a un trou. Le nom seul est barre, pas
   l'heure ni la salle : une ligne entierement barree ne se lit plus. */
.annule .n {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.jour .annule,
.suite .annule { opacity: 0.5; }

.suite .annule .h::before { background: var(--gris); }

/* Ajoute recemment : un aplat a peine pose, tire de la teinte du cours, qui
   deborde des marges pour se lire comme un surlignage et non comme une carte. */
.recent {
  position: relative;
  isolation: isolate;
}

.recent::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 1px -10px;
  border-radius: 8px;
  background: hsl(var(--h) var(--sat) 58% / 0.14);
}

/* Le coup de fluo d'une notification groupee : la meme forme, une fois, plus
   franche, puis elle s'efface. Le surlignage de sept jours reste dessous. */
.fluo::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 1px -10px;
  border-radius: 8px;
  background: hsl(var(--h) var(--sat) 58% / 0.42);
  animation: fluo 2.6s var(--glisse) forwards;
}

.fluo {
  position: relative;
  isolation: isolate;
}

@keyframes fluo {
  0%, 45% { opacity: 1; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fluo::after { animation: none; opacity: 0; }
}

/* Le meme liseré que sur l'affiche, a la taille d'une ligne. Dans la marge lui
   aussi : les heures d'une journee restent alignees entre elles, qu'un creneau
   se soit glisse au milieu ou non. */
.jour .perso,
.suite .perso {
  padding-left: 10px;
  margin-left: -12px;
}

.jour .perso { border-left: 2px dashed var(--affiche-gris); }

.suite .perso { border-left: 2px dashed hsl(var(--h) var(--sat) 62% / 0.8); }

/* -- les AG de la mobilisation ----------------------------------------- */

/* Le jaune de l'agenda d'ou elles viennent, le meme sur toutes les teintes et
   dans tous les themes : une AG n'est pas un cours, elle n'en prend pas la
   couleur. Un champ plein qui deborde des marges, pas une carte. */
.ag {
  display: block;
  margin: 0 -10px 10px;
  padding: 10px;
  background: #e4ff1a;
  color: #111;
  text-decoration: none;
}

.ag:active { opacity: 0.7; }

.ag-n {
  display: block;
  font-size: 16px;
  font-weight: 800;
  line-height: 1.25;
}

.ag-q {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.suite .ag { margin-bottom: 4px; }

/* -- retour en haut ----------------------------------------------------- */

.haut {
  position: fixed;
  z-index: 6;
  left: 50%;
  bottom: calc(var(--bas) + 18px);
  transform: translateX(-50%);
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--texte);
  color: var(--fond);
  font-size: 14px;
  font-weight: 700;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

/* -- la bande d'actions, tiree depuis le haut --------------------------- */

.bande {
  position: fixed;
  z-index: 7;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: calc(var(--haut) + 10px) var(--marge) 12px;
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--trait);
  transform: translateY(-100%);
  transition: transform 0.22s ease-out;
  font-size: 14px;
}

.bande--ouverte { transform: translateY(0); }

.etat {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  color: var(--gris);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 8px 0;
}

.etat--retard { color: var(--alerte); font-weight: 600; }

.reglages {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--surface-2);
  font-weight: 600;
}

/* Le seul endroit de l'application qui porte des actions : c'est donc ici que
   s'ajoute un creneau, et nulle part ailleurs. */
.ajouter {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--texte);
  font-size: 21px;
  font-weight: 500;
  line-height: 1;
}

/* -- invitation a poser sur l'ecran d'accueil ---------------------------- */

.pose {
  position: fixed;
  z-index: 5;
  left: var(--marge);
  right: var(--marge);
  bottom: calc(var(--bas) + 16px);
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--trait);
  border-radius: 14px;
  background: var(--surface);
  color: var(--texte);
  font-size: 14px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
}

/* min-width nul, sinon l'element flex refuse de descendre sous la largeur de
   son texte et le bandeau deborde de l'ecran, croix comprise. */
.pose span { flex: 1 1 auto; min-width: 0; line-height: 1.3; }

.pose button {
  flex: 0 0 auto;
  border-radius: 9px;
  padding: 7px 12px;
  font-weight: 600;
  background: var(--texte);
  color: var(--fond);
}

.pose .fermer {
  background: none;
  color: var(--gris);
  padding: 7px 4px;
  font-size: 18px;
  line-height: 1;
}

/* -- les feuilles montees du bas ---------------------------------------- */

.voile {
  position: fixed;
  z-index: 8;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.42s var(--glisse);
}

.voile--ouvert { opacity: 1; }

.feuille {
  position: fixed;
  z-index: 9;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 92vh;
  max-height: 92dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  border-radius: 24px 24px 0 0;
  background: var(--surface);
  color: var(--texte);
  box-shadow: 0 -16px 50px rgba(0, 0, 0, 0.45);
  /* translate3d et non translateY : la couche part sur le compositeur, et le
     glissement du doigt ne repeint plus rien a chaque image. */
  transform: translate3d(0, 100%, 0);
  transition: transform 0.44s var(--glisse);
  will-change: transform;
}

.feuille--ouverte { transform: translate3d(0, 0, 0); }

/* Pendant que le doigt tient la feuille, aucune transition : elle doit coller
   au pouce, pas le suivre avec un retard. */
.feuille--glisse { transition: none; }

@media (prefers-reduced-motion: reduce) {
  .feuille,
  .voile { transition-duration: 0.01ms; }
}

.poignee {
  width: 38px;
  height: 4px;
  margin: 0 auto 14px;
  border-radius: 2px;
  background: var(--trait);
}

.poignee--clair { background: rgba(255, 255, 255, 0.42); }

.fermer-panneau {
  position: absolute;
  top: 12px;
  right: var(--marge);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--gris);
  font-size: 18px;
  line-height: 1;
}

/* -- la feuille de reglages --------------------------------------------- */

.panneau { padding: 10px var(--marge) calc(var(--bas) + 24px); }

.panneau h3 {
  margin: 22px 0 6px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gris);
}

.panneau h3:first-of-type { margin-top: 4px; }

.ligne {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 50px;
  padding: 6px 0;
  border-top: 1px solid var(--trait);
}

.ligne:first-of-type,
h3 + .ligne { border-top: none; }

.ligne .l {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ligne .l small {
  display: block;
  font-size: 13px;
  color: var(--gris);
  white-space: normal;
}

.note {
  margin: 6px 0 0;
  font-size: 14px;
  color: var(--gris);
  line-height: 1.4;
}

.note--serre { margin-top: 2px; font-size: 13px; }

/* interrupteur */
.bascule {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 50px;
  height: 30px;
  margin: 0;
  border-radius: 15px;
  background: var(--surface-2);
  border: 1px solid var(--trait);
  position: relative;
  transition: background 0.18s;
}

.bascule::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  transition: transform 0.18s;
}

.bascule:checked { background: var(--live); border-color: var(--live); }
.bascule:checked::after { transform: translateX(20px); }
.bascule:disabled { opacity: 0.4; }

/* boutons secondaires */
.b {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.b--plein { background: var(--texte); color: var(--fond); }
.b--discret {
  background: none;
  border: 1px solid var(--trait);
  color: var(--gris);
  padding: 7px 13px;
  font-size: 13px;
}
.b:disabled { opacity: 0.45; }
/* La charte est un lien, pas un bouton : elle quitte l'application. Elle en
   garde l'apparence pour ne pas faire exception dans la liste des reglages. */
a.b { text-decoration: none; }
/* `a.b { color: inherit }`, plus haut, l'emporte sur `.b--plein` : un lien
   dessine en bouton plein prenait la couleur de texte de la feuille, claire,
   sur un fond devenu clair lui aussi. Le bouton s'affichait vide, et personne
   ne clique sur ce qu'il ne voit pas. */
a.b--plein { color: var(--fond); }

/* choix a segments */
.segments {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 12px;
  background: var(--surface-2);
}

.segments button {
  flex: 1 1 0;
  padding: 9px 0;
  border-radius: 9px;
  font-size: 14px;
  font-weight: 600;
  color: var(--gris);
}

.segments .actif { background: var(--surface); color: var(--texte); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); }

/* champ de saisie */
.champ-texte {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px 14px;
  border-radius: 12px;
  border: 1px solid var(--trait);
  background: var(--surface-2);
  color: var(--texte);
  font: inherit;
  font-size: 15px;
}

.champ-texte::placeholder { color: var(--gris); }
.champ-texte:focus { outline: 2px solid hsl(var(--h) var(--sat) 60%); outline-offset: -1px; }

/* Le formulaire d'un creneau : un jour et deux heures tiennent sur une ligne,
   a condition qu'ils cessent de s'etirer. `appearance: none` parce que Safari
   habille les champs de date et d'heure a sa facon, avec son propre fond
   clair, illisible sur une feuille sombre. */
.champ-texte--court {
  flex: 0 0 auto;
  width: 7.4em;
  text-align: center;
  appearance: none;
  -webkit-appearance: none;
}

/* Une date francaise plus son bouton de calendrier : « 20/09/2026 » se
   terminait par une parenthese coupee a 7,4 em. */
.champ-texte--jour { width: 9.4em; }

.cr-a { flex: 0 0 auto; font-size: 14px; color: var(--gris); }

.cr-note-champ { resize: none; line-height: 1.4; }

/* matieres */
.pastille {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  padding: 0;
  border: 2px solid var(--trait);
  background: hsl(var(--h) var(--sat) 58%);
  position: relative;
  overflow: hidden;
}

.pastille input {
  position: absolute;
  inset: -8px;
  width: 200%;
  height: 200%;
  opacity: 0;
  cursor: pointer;
}

.pastille--image {
  border-radius: 8px;
  background-size: cover;
  background-position: center;
}

.cache { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* icones */
.icones {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 6px 0 2px;
}

.icones button {
  width: 52px;
  height: 52px;
  border-radius: 13px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  position: relative;
  transition: transform 0.16s ease-out;
}

.icones button:active { transform: scale(0.93); }

.icones .actif::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 17px;
  border: 2px solid var(--texte);
}

/* calendrier et lien secret */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 0 2px;
}

.secret {
  margin: 8px 0 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--surface-2);
  font-size: 13px;
  line-height: 1.45;
  color: var(--gris);
  word-break: break-all;
  user-select: all;
  -webkit-user-select: all;
}

/* -- la feuille de detail d'un cours ------------------------------------ */

.detail { padding: 0 0 calc(var(--bas) + 20px); }

.d-tete {
  padding: 12px var(--marge) 26px;
  border-radius: 24px 24px 0 0;
}

.d-quand {
  margin: 6px 0 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--affiche-gris);
}

.d-titre {
  margin: 0 0 16px;
  font-size: clamp(28px, 8vw, 40px);
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.035em;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.d-heure,
.d-salle {
  margin: 0;
  font-size: clamp(20px, 5.6vw, 27px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.d-salle { margin-top: 3px; }

/* Une seance annulee : le titre barre, le mot « annulé » au-dessus a la place
   du « dans 2 h », et l'heure et la salle en retrait. Pas de pastille : le
   titre barre dit deja tout, et une etiquette de plus ferait doublon. */
.d-tete--annule .d-titre {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  opacity: 0.72;
}

.d-tete--annule .d-heure,
.d-tete--annule .d-salle { opacity: 0.6; }

/* Le liseré de l'affiche, a l'echelle de la fiche : il court sur toute la
   hauteur du champ colore, du meme cote que partout ailleurs. */
.d-tete--perso {
  border-left: 2px dashed var(--affiche-gris);
  padding-left: calc(var(--marge) - 2px);
}

/* Modifier se lit apres ce qu'on est venu lire, pas avant. */
.detail .actions { padding: 16px 0 2px; }

.d-corps { padding: 4px var(--marge) 0; }

.d-corps dl { margin: 0; }

.d-corps .r {
  display: flex;
  gap: 14px;
  align-items: baseline;
  padding: 13px 0;
  border-top: 1px solid var(--trait);
}

.d-corps .r:first-child { border-top: none; }

.d-corps dt {
  flex: 0 0 34%;
  font-size: 14px;
  color: var(--gris);
}

.d-corps dd {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  overflow-wrap: anywhere;
}

/* -- la pose sur l'ecran d'accueil, au premier lancement -----------------
 *
 * Deux ecrans qui prennent tout : le choix de l'icone, puis la marche a
 * suivre, jouee dans un telephone dessine. Meme champ colore que l'affiche,
 * meme echelle typographique, memes boutons : ce n'est pas une autre
 * application, c'est la meme, avant qu'elle ait sa place sur l'ecran.
 *
 * L'icone est choisie AVANT la pose parce qu'iOS fige celle qui est servie au
 * moment ou l'on ajoute : la choisir apres coup n'aurait aucun effet.
 */

.accueil {
  position: fixed;
  z-index: 7;
  inset: 0;
}

/* La page du guide defile ; le volet et son voile, eux, restent en place
   par-dessus. D'ou deux couches et non une. */
.ac-page {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  /* Pas de marge basse ici : elle appartient au pied, qui colle au bas de
     l'ecran et doit donc porter lui-meme la hauteur de la barre du telephone. */
  padding: calc(var(--haut) + 18px) var(--marge) 0;
  overflow-y: auto;
  /* La main du telephone dessine depasse a droite ; sur un ecran etroit, elle
     ne doit pas ouvrir un defilement horizontal. */
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* Le volet : la meme feuille que partout ailleurs dans l'application, meme
   courbe, meme voile, meme glissement du doigt pour la refermer. */
.ac-voile {
  position: absolute;
  z-index: 2;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.42s var(--glisse);
}

.ac-voile--ouvert { opacity: 1; }

.ac-volet {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 90%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 10px var(--marge) calc(var(--bas) + 22px);
  border-radius: 24px 24px 0 0;
  background: var(--surface);
  color: var(--texte);
  box-shadow: 0 -16px 50px rgba(0, 0, 0, 0.45);
  transform: translate3d(0, 100%, 0);
  transition: transform 0.44s var(--glisse);
  will-change: transform;
}

.ac-volet--ouvert { transform: translate3d(0, 0, 0); }
.ac-volet--glisse { transition: none; }

@media (prefers-reduced-motion: reduce) {
  .ac-volet,
  .ac-voile { transition-duration: 0.01ms; }
}

.ac-volet h2 {
  margin: 4px 0 8px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.ac-volet .ac-b { margin-top: 16px; max-width: none; background: var(--texte); color: var(--fond); }
.ac-volet .ac-b--creux { background: none; border: 1px solid var(--trait); color: var(--texte); }
.ac-volet .ac-note { color: var(--gris); max-width: none; }
.ac-volet .ac-saisie {
  margin-top: 12px;
  max-width: none;
  border-color: var(--trait);
  background: var(--surface-2);
  color: var(--texte);
}
.ac-volet .ac-saisie::placeholder { color: var(--gris); }
.ac-volet .ac-saisie:focus { outline-color: hsl(var(--h) var(--sat) 60%); }

.ac-question {
  margin: 22px 0 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.ac-volet .ac-deux { margin-top: 10px; max-width: none; }

.ac-vue {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}

@media (prefers-reduced-motion: no-preference) {
  .ac-vue { animation: apparait 0.34s var(--glisse) both; }
}

.ac-titre {
  margin: 0;
  font-size: clamp(30px, 8.4vw, 44px);
  line-height: 1.03;
  font-weight: 800;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.ac-dit {
  margin: -8px 0 0;
  font-size: 15px;
  line-height: 1.45;
  color: var(--affiche-gris);
  max-width: 30ch;
}

/* Le pied ne descend jamais sous le pli. Sur un telephone, la grille des dix
   habillages suffisait a pousser « Continuer » hors de l'ecran : il ne restait
   plus rien a toucher, et le carreau du crayon, dernier objet visible, se
   retrouvait promu bouton principal par accident. Il colle donc au bas du
   champ, et le champ transparait derriere lui, flou. */
.ac-pied {
  position: sticky;
  bottom: 0;
  z-index: 1;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 18px 0 calc(var(--bas) + 18px);
}

/* Le flou vit sur une couche a part : porte par le pied lui-meme, le degrade
   qui l'adoucit mangerait aussi le haut du bouton. */
.ac-pied::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 26px);
  mask-image: linear-gradient(to bottom, transparent, #000 26px);
}

.ac-b {
  width: 100%;
  max-width: 420px;
  padding: 15px;
  border-radius: 14px;
  background: var(--affiche-texte);
  color: var(--affiche-fond);
  font-size: 16px;
  font-weight: 700;
  transition: transform 0.16s ease-out;
}

.ac-b:active { transform: scale(0.98); }
.ac-b:disabled { opacity: 0.4; }

/* Deux boutons pleins l'un sous l'autre, sur l'ecran du navigateur embarque :
   les 4 px du pied les collent, et le second se lit comme la moitie basse du
   premier. */
.ac-pied .ac-b + .ac-b { margin-top: 8px; }

/* La sortie : presente, jamais mise en avant. */
.ac-fuite {
  padding: 12px 8px;
  font-size: 14px;
  color: var(--affiche-gris);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Le guide est le seul ecran de l'application qu'on voit aussi sur un
   ordinateur : l'inscription y mene tout droit, et la fin du parcours s'y joue
   avec le QR. Le reste de l'application vit sur un telephone et n'a pas a
   savoir ce qu'est un ecran large. Une colonne, donc, plutot que quarante
   caracteres de titre etires sur 1280 pixels. */
@media (min-width: 620px) {
  .ac-page {
    padding-left: max(var(--marge), calc((100% - 560px) / 2));
    padding-right: max(var(--marge), calc((100% - 560px) / 2));
  }

  /* Et cette colonne est centree pour de bon. Le titre et sa phrase restaient
     cales a gauche pendant que l'icone, la grille et le bouton se centraient :
     une meme colonne avec deux axes, ce qui se lit comme un texte oublie sur le
     bord. Sur un telephone la question ne se pose pas -- la colonne fait toute
     la largeur, et un titre d'affiche se lit a gauche. */
  .ac-page { text-align: center; }
  .ac-vue { align-items: center; }
  .ac-vue > * { max-width: 100%; }
  .ac-dit,
  .ac-note,
  .ac-rappel { margin-left: auto; margin-right: auto; }
  /* La liste numerotee garde ses numeros alignes : c'est le bloc qu'on centre,
     pas chacune de ses lignes. */
  .ac-pas { text-align: left; }
  /* Centree, elle n'a plus de bord sur lequel se caler : la largeur de 34
     caracteres, faite pour ca, y coupait « : garde-le pour toi » sur une ligne
     a elle. */
  .ac-vue .ac-note--gauche { align-self: center; text-align: center; max-width: 46ch; }
}

/* Ce que l'inscription n'a pas pu dire elle-meme, faute d'ecran de fin :
   l'ancien lien vient de mourir. Une seule phrase, au-dessus de tout. */
.ac-rappel {
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(0, 0, 0, 0.22);
  font-size: 14px;
  line-height: 1.45;
  color: var(--affiche-texte);
}

/* -- le pont vers le telephone, sur ordinateur -------------------------- */

/* Le QR est rendu en noir sur blanc : un code se lit par son contraste, et le
   teinter au theme de l'application le rendrait illisible a l'appareil photo
   dans l'un des deux. Il porte donc son propre fond, quel que soit le reste. */
.ac-qr {
  display: flex;
  justify-content: center;
  padding: 4px 0;
}

/* La note du pont se cale sur le texte qui la precede, et non sur le bouton :
   deux paragraphes qui se suivent ne commencent pas a deux endroits. */
.ac-vue .ac-note--gauche { align-self: flex-start; max-width: 34ch; }

.ac-qr img {
  width: 220px;
  height: 220px;
  border-radius: 14px;
  background: #fff;
  padding: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.42);
}

/* -- l'icone, telle qu'elle sera posee ---------------------------------- */

.ac-scene {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  padding: 8px 0 4px;
}

.ac-tuile {
  width: 88px;
  height: 88px;
  border-radius: 21px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.42);
  transition: background-image 0.2s linear;
}

.ac-nom {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--affiche-texte);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.ac-choix {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
}

/* Dix carreaux : une grille de cinq, deux rangees pleines. En laissant faire
   le retour a la ligne, la seconde rangee se retrouvait decentree. */
.ac-choix--grille {
  display: grid;
  grid-template-columns: repeat(5, 46px);
  justify-content: center;
  gap: 12px;
}

.ac-choix button {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.32);
  position: relative;
  transition: transform 0.16s ease-out;
}

.ac-choix button:active { transform: scale(0.92); }

.ac-choix .actif::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 16px;
  border: 2px solid var(--affiche-texte);
}

/* Le dixieme carreau : le meme objet que les habillages, mais creux. Une
   fois une icone sur mesure choisie, il porte son apercu. */
/* Il etait creux et pointille sur un fond colore : a cote de neuf carreaux
   pleins, il ne se lisait pas comme un dixieme, et personne ne le voyait. Il
   porte donc une matiere, comme les autres. */
.ac-crayon {
  border: 1px solid var(--affiche-gris);
  background-color: color-mix(in srgb, var(--affiche-texte) 20%, transparent);
  color: var(--affiche-texte);
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ac-crayon svg { width: 20px; height: 20px; }
.ac-crayon.actif { border-style: solid; }
.ac-crayon.actif svg { display: none; }

.ac-label {
  margin: 2px 0 -6px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--affiche-gris);
  text-align: center;
}

.ac-teintes {
  display: grid;
  grid-template-columns: repeat(6, 32px);
  justify-content: center;
  gap: 10px;
}

/* La pastille de teinte est dessinee par le navigateur, pas servie par le
   serveur : douze images de plus a telecharger pour choisir une couleur
   seraient douze allers-retours pour rien. */
.ac-teintes button {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  position: relative;
  background:
    radial-gradient(80% 80% at 30% 26%, hsl(var(--t) 84% 62%), transparent 70%),
    radial-gradient(80% 80% at 74% 78%, hsl(calc(var(--t) - 40) 76% 44%), transparent 70%),
    hsl(var(--t) 70% 34%);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
  transition: transform 0.16s ease-out;
}

.ac-teintes button:active { transform: scale(0.9); }

.ac-teintes .actif::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid var(--affiche-texte);
}

/* -- le telephone dessine ------------------------------------------------
 *
 * Toutes les couches sont la en meme temps, empilees : l'application, l'ecran
 * d'accueil, la barre du navigateur, son menu, la feuille de partage, la
 * confirmation. `data-scene` sur le cadre dit laquelle se montre, et chaque
 * couche sait, ici, ou elle se tient dans chaque scene. La main, la feuille
 * qui defile et la boucle sont menees par la partition du script, en
 * animations natives ; le CSS ne touche jamais aux memes proprietes qu'elle.
 *
 * Trois navigateurs, reconnaissables au premier regard : Safari 26 (`tel--
 * safari`, barre en bas, trois points a droite), Chrome sur iPhone (`tel--
 * chrome-ios`, barre d'adresse en haut, partage a son bout, outils en bas),
 * Chrome sur Android (`tel--android`, menu en haut a droite). Plus Safari
 * d'avant iOS 26 (`tel--safari-ancien`), le partage au milieu de ses outils.
 * Le systeme, lui, est `tel--ios` ou `tel--android` : c'est lui qui dessine
 * la feuille, la confirmation et l'ecran d'accueil.                         */

.tel {
  position: relative;
  width: 220px;
  height: 430px;
  margin: 0 auto;
  flex: 0 0 auto;
  border-radius: 36px;
  padding: 3px;
  background: linear-gradient(160deg, #3a3a4a, #16161d 40%, #2c2c38);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55), 0 0 0 0.5px rgba(255, 255, 255, 0.08);
  color: #f4f4f7;
  font-size: 10px;
  line-height: 1.3;
  user-select: none;
  -webkit-user-select: none;
}

.tel-ecran {
  position: absolute;
  inset: 3px;
  border-radius: 33px;
  overflow: hidden;
  background: #0b0b10;
}

/* La remise a zero entre deux tours se fait sans transition, dans le noir. */
.tel--fige,
.tel--fige * { transition: none !important; }

.tel-noir {
  position: absolute;
  z-index: 7;
  inset: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.38s ease-in;
}

.tel--noir .tel-noir { opacity: 1; }

/* -- la barre d'etat ------------------------------------------------------
   C'est elle, plus que le cadre, qui fait lire l'objet comme un telephone. */

.tel-haut {
  position: absolute;
  z-index: 6;
  top: 0;
  left: 0;
  right: 0;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 15px 0 19px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.92);
  pointer-events: none;
}

.tel-signes { display: flex; align-items: center; gap: 4px; }
.tel-reseau { display: flex; align-items: flex-end; gap: 1px; height: 8px; }
.tel-reseau b { display: block; width: 2px; border-radius: 1px; background: rgba(255, 255, 255, 0.9); }
.tel-reseau b:nth-child(1) { height: 3px; }
.tel-reseau b:nth-child(2) { height: 5px; }
.tel-reseau b:nth-child(3) { height: 7px; }
.tel-reseau b:nth-child(4) { height: 8px; }

.tel-wifi {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2.5px solid transparent;
  border-top-color: rgba(255, 255, 255, 0.9);
  margin-top: 4px;
}

.tel-pile {
  display: block;
  width: 15px;
  height: 8px;
  border-radius: 2.5px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  position: relative;
}

.tel-pile::before {
  content: "";
  position: absolute;
  inset: 1.5px;
  right: 4px;
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.9);
}

/* -- l'application ---------------------------------------------------------
   La vraie affiche, en miniature, avec le cours du moment. Elle herite du
   champ colore, donc de la teinte du cours affiche. */

.tel-app {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 34px 15px 46px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: opacity 0.3s ease-out;
}

.tel--haut .tel-app { padding-top: 70px; }
.tel--chrome-ios .tel-app { padding-bottom: 50px; }
.tel--safari-ancien.tel--bas .tel-app { padding-bottom: 70px; }

/* Sous une feuille ou une confirmation, l'application s'assombrit, comme le
   fait le systeme. */
.tel-app::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  pointer-events: none;
  transition: background 0.4s ease-out;
}

.tel[data-scene="feuille"] .tel-app::after,
.tel[data-scene="defile"] .tel-app::after,
.tel[data-scene="cible"] .tel-app::after,
.tel[data-scene="dialogue"] .tel-app::after { background: rgba(0, 0, 0, 0.5); }

.tel-quand {
  margin: 0 0 9px;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--affiche-gris);
}

.tel-titre {
  margin: 0 0 12px;
  font-size: 22px;
  line-height: 1.03;
  font-weight: 800;
  letter-spacing: -0.035em;
  overflow-wrap: anywhere;
}

.tel-h,
.tel-s {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.tel-s { margin-top: 2px; color: var(--affiche-gris); }

/* Le bouton de l'application, sur Android quand le navigateur a invite : c'est
   lui qu'on touche a la premiere etape, pas un bouton du navigateur. */
.tel-bouton {
  display: none;
  align-items: center;
  justify-content: center;
  margin-top: 16px;
  height: 24px;
  padding: 0 12px;
  border-radius: 12px;
  background: #fff;
  color: #14141d;
  font-size: 9.5px;
  font-weight: 700;
  white-space: nowrap;
  transition: transform 0.15s ease-out;
}

.tel--invite .tel-bouton { display: flex; }
.tel-bouton.presse { transform: scale(0.96); background: #e4e4ea; }
.tel[data-scene="ouverte"] .tel-bouton { display: none; }

/* -- l'ecran d'accueil du telephone ---------------------------------------
   Celui du systeme, avec ses icones a lui : c'est a elles qu'on le reconnait. */

.tel-accueil {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 32px 12px 10px;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transition: opacity 0.45s ease-out;
}

.tel--ios .tel-accueil {
  background:
    radial-gradient(120% 70% at 15% 5%, rgba(96, 74, 190, 0.75) 0%, rgba(96, 74, 190, 0) 60%),
    radial-gradient(90% 60% at 95% 95%, rgba(38, 118, 176, 0.8) 0%, rgba(38, 118, 176, 0) 60%),
    linear-gradient(160deg, #1c1a36, #0e0e1e 60%, #131a2c);
}

.tel--android .tel-accueil {
  background:
    radial-gradient(100% 60% at 85% 0%, rgba(58, 118, 176, 0.8) 0%, rgba(58, 118, 176, 0) 60%),
    radial-gradient(90% 60% at 5% 100%, rgba(140, 70, 140, 0.7) 0%, rgba(140, 70, 140, 0) 60%),
    linear-gradient(170deg, #161a2e, #0c0d18);
}

.tel-grille {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 11px 8px;
  align-content: start;
  padding-top: 4px;
}

.tel-case { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; }

.tel-case i {
  display: block;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background-size: cover;
  background-position: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

.tel--android .tel-case i,
.tel--android .tel-dock i { border-radius: 50%; }

.tel-case span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 6.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

/* La notre arrive avec un rebond, apres que l'ecran s'est montre. */
.tel-case--cible i {
  opacity: 0;
  transform: scale(0.3);
  transition: opacity 0.3s ease-out 0.35s, transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.35s;
}

.tel-case--cible span { opacity: 0; transition: opacity 0.3s ease-out 0.65s; }

.tel-points { display: flex; justify-content: center; gap: 5px; padding: 6px 0 9px; }
.tel-points i { display: block; width: 4px; height: 4px; border-radius: 50%; background: rgba(255, 255, 255, 0.35); }
.tel-points i.on { background: rgba(255, 255, 255, 0.9); }

.tel-cherche {
  height: 26px;
  margin: 0 6px 10px;
  padding: 0 10px;
  border-radius: 13px;
  background: rgba(255, 255, 255, 0.16);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.tel-cherche b { font-size: 12px; font-weight: 700; color: #fff; }
.tel-cherche i { display: flex; color: rgba(255, 255, 255, 0.85); }
.tel-cherche svg { width: 12px; height: 12px; }

.tel-dock {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 7px 9px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.tel--android .tel-dock { background: none; padding: 0 8px 4px; gap: 10px; }
.tel-dock i { display: block; width: 100%; aspect-ratio: 1; border-radius: 10px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35); }

/* -- la barre du navigateur, et ce qu'on y touche en premier -------------- */

.tel-url {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  padding: 0 10px;
  font-size: 9px;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  overflow: hidden;
}

.tel-url i { display: flex; flex: none; color: rgba(255, 255, 255, 0.6); }
.tel-url i svg { width: 9px; height: 9px; }

.tel-glyphe { transition: background 0.15s ease-out, color 0.15s ease-out; }
.tel-glyphe svg { width: 14px; height: 14px; display: block; }

.tel-barre,
.tel-outils { transition: opacity 0.3s ease-out; }

/* Safari 26 : la barre flotte en bas, en verre ; le retour a gauche, l'adresse
   au milieu, les trois points a droite. */
.tel--safari .tel-barre {
  position: absolute;
  z-index: 2;
  left: 8px;
  right: 8px;
  bottom: 8px;
  height: 34px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.tel--safari .tel-url {
  flex: 1 1 auto;
  height: 34px;
  border-radius: 17px;
  background: rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.18);
}

.tel-rond {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.18);
  color: #fff;
}

.tel-rond svg { width: 15px; height: 15px; }
.tel--safari .tel-glyphe.presse { background: #fff; color: #14141d; }

/* Safari d'avant iOS 26, en bas : l'adresse, puis la rangee d'outils, le
   partage au milieu. Sur iPad, une seule rangee en haut. */
.tel--safari-ancien.tel--bas .tel-barre {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 6px 10px 5px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: rgba(22, 22, 28, 0.94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.tel--safari-ancien .tel-url { height: 26px; border-radius: 9px; background: rgba(255, 255, 255, 0.12); }

.tel--safari-ancien.tel--haut .tel-barre {
  position: absolute;
  z-index: 2;
  top: 24px;
  left: 0;
  right: 0;
  height: 38px;
  padding: 0 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(22, 22, 28, 0.94);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  color: #5aa0ff;
}

.tel--safari-ancien.tel--haut .tel-barre > span:not(.tel-url) { display: flex; width: 22px; height: 22px; align-items: center; justify-content: center; flex: none; border-radius: 6px; }
.tel--safari-ancien.tel--haut .tel-barre > span:not(.tel-url) svg { width: 15px; height: 15px; }
.tel--safari-ancien.tel--haut .tel-url { flex: 1 1 auto; }

.tel-outils {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 24px;
  color: #5aa0ff;
}

.tel-outils span { display: flex; width: 24px; height: 24px; align-items: center; justify-content: center; border-radius: 7px; }
.tel-outils svg { width: 15px; height: 15px; }
.tel--safari-ancien .tel-glyphe.presse,
.tel--chrome-ios .tel-glyphe.presse { background: rgba(90, 160, 255, 0.28); }

/* Chrome sur iPhone : la barre d'adresse en haut, sombre, le partage a son
   bout droit ; les outils en bas, en gris. */
.tel--chrome-ios .tel-barre {
  position: absolute;
  z-index: 2;
  top: 24px;
  left: 0;
  right: 0;
  height: 40px;
  padding: 5px 8px;
  display: flex;
  align-items: center;
  background: #1f1f23;
}

.tel--chrome-ios .tel-url {
  flex: 1 1 auto;
  height: 30px;
  border-radius: 15px;
  padding: 0 4px 0 10px;
  justify-content: flex-start;
  background: #34343a;
}

.tel--chrome-ios .tel-glyphe {
  margin-left: auto;
  display: flex;
  flex: none;
  width: 22px;
  height: 22px;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  font-style: normal;
  color: #8ab4f8;
}

.tel--chrome-ios .tel-outils {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0;
  height: 40px;
  padding: 0 6px 5px;
  background: #1f1f23;
  color: rgba(255, 255, 255, 0.8);
}

/* Chrome sur Android : la barre en haut, l'accueil a gauche, les trois points
   verticaux a droite. */
.tel--android .tel-barre {
  position: absolute;
  z-index: 2;
  top: 24px;
  left: 0;
  right: 0;
  height: 40px;
  padding: 4px 6px;
  display: flex;
  align-items: center;
  gap: 4px;
  background: #202124;
  color: rgba(255, 255, 255, 0.85);
}

.tel--android .tel-barre > span:first-child { display: flex; flex: none; width: 26px; height: 26px; align-items: center; justify-content: center; }
.tel--android .tel-barre > span:first-child svg { width: 15px; height: 15px; }
.tel--android .tel-url { flex: 1 1 auto; height: 30px; border-radius: 15px; justify-content: flex-start; padding-left: 10px; background: #303134; }
.tel--android .tel-glyphe { display: flex; flex: none; width: 26px; height: 26px; align-items: center; justify-content: center; border-radius: 50%; }
.tel--android .tel-glyphe.presse { background: rgba(255, 255, 255, 0.2); }

/* -- le menu du navigateur ------------------------------------------------- */

.tel-menu {
  position: absolute;
  z-index: 3;
  opacity: 0;
  transform: scale(0.85);
  pointer-events: none;
  transition: opacity 0.2s ease-out, transform 0.32s var(--glisse);
}

.tel--safari-ancien .tel-menu,
.tel--chrome-ios .tel-menu { display: none; }

.tel[data-scene="menu"] .tel-menu { opacity: 1; transform: scale(1); }

.tel-rang { transition: background 0.12s ease-out; }
.tel-rang.presse { background: rgba(255, 255, 255, 0.16); }

/* Safari : une liste, le partage en tete, les icones a droite. */
.tel--ios .tel-menu {
  right: 8px;
  bottom: 48px;
  width: 150px;
  padding: 2px 0;
  border-radius: 13px;
  background: rgba(52, 52, 58, 0.97);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6), inset 0 0 0 0.5px rgba(255, 255, 255, 0.12);
  transform-origin: 92% 100%;
}

.tel--ios .tel-menu .tel-rang {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 29px;
  padding: 0 11px;
  font-size: 10px;
  color: rgba(255, 255, 255, 0.92);
  border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
  white-space: nowrap;
}

.tel--ios .tel-menu .tel-rang:last-child { border-bottom: 0; }
.tel--ios .tel-menu .tel-rang i { display: flex; color: rgba(255, 255, 255, 0.85); }
.tel--ios .tel-menu .tel-rang svg { width: 13px; height: 13px; }

/* Chrome Android : une rangee d'icones, puis la liste, le texte seul. */
.tel--android .tel-menu {
  right: 5px;
  top: 30px;
  width: 158px;
  padding: 0 0 4px;
  border-radius: 6px;
  background: #2d2f33;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.6);
  transform-origin: 96% 0;
}

.tel-menu-icones {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 36px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.8);
}

.tel-menu-icones svg { width: 14px; height: 14px; display: block; }

.tel--android .tel-menu .tel-rang {
  display: flex;
  align-items: center;
  height: 27px;
  padding: 0 14px;
  font-size: 9.8px;
  color: rgba(255, 255, 255, 0.9);
  white-space: nowrap;
}

/* -- la feuille de partage d'iOS ------------------------------------------ */

.tel-feuille {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  height: 68%;
  padding: 6px 10px 0;
  border-radius: 16px 16px 0 0;
  background: #1c1c1e;
  box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  transform: translateY(102%);
  transition: transform 0.5s var(--glisse);
}

.tel[data-scene="feuille"] .tel-feuille,
.tel[data-scene="defile"] .tel-feuille,
.tel[data-scene="cible"] .tel-feuille { transform: translateY(0); }

.tel-poignee { width: 32px; height: 4px; margin: 0 auto 8px; border-radius: 2px; background: rgba(255, 255, 255, 0.3); }

/* La liste est tiree par la main, dans le script : pas de transition ici. */
.tel-liste { will-change: transform; }

.tel-carte {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 2px 9px;
  border-bottom: 0.5px solid rgba(255, 255, 255, 0.12);
}

.tel-carte i {
  display: block;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 7px;
  background-size: cover;
  background-position: center;
}

.tel-carte div { flex: 1 1 auto; min-width: 0; }
.tel-carte b { display: block; font-size: 10.5px; font-weight: 700; }
.tel-carte u { display: block; text-decoration: none; font-size: 8.5px; color: rgba(255, 255, 255, 0.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tel-carte em { flex: none; display: flex; align-items: center; font-style: normal; font-size: 9px; color: rgba(255, 255, 255, 0.6); }
.tel-carte em svg { width: 9px; height: 9px; }

.tel-gens,
.tel-applis { display: flex; gap: 10px; padding: 9px 2px 6px; }

.tel-gens span,
.tel-applis span { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 38px; min-width: 0; }

.tel-gens i { display: block; width: 36px; height: 36px; border-radius: 50%; }
.tel-applis i { display: block; width: 36px; height: 36px; border-radius: 9px; }

.tel-gens u,
.tel-applis u {
  max-width: 100%;
  text-decoration: none;
  font-size: 6.5px;
  color: rgba(255, 255, 255, 0.7);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tel-groupe { margin-top: 4px; border-radius: 10px; background: #2c2c2e; overflow: hidden; }

.tel-groupe .tel-rang {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 33px;
  padding: 0 11px;
  font-size: 10.5px;
  color: rgba(255, 255, 255, 0.92);
  border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
  white-space: nowrap;
}

.tel-groupe .tel-rang i { display: flex; color: rgba(255, 255, 255, 0.8); }
.tel-groupe .tel-rang svg { width: 13px; height: 13px; }

/* -- la confirmation ------------------------------------------------------- */

.tel-dialogue {
  position: absolute;
  z-index: 4;
  left: 0;
  right: 0;
  bottom: 0;
  transform: translateY(102%);
  transition: transform 0.5s var(--glisse);
}

.tel[data-scene="dialogue"] .tel-dialogue { transform: translateY(0); }

.tel-dcorps {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px;
  border-radius: 12px;
  background: #2c2c2e;
}

.tel-dcorps i {
  display: block;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 9px;
  background-size: cover;
  background-position: center;
}

.tel-dcorps div { flex: 1 1 auto; min-width: 0; }
.tel-dcorps b { display: block; font-size: 11px; font-weight: 700; }
.tel-dcorps u { display: block; text-decoration: none; font-size: 8.5px; color: rgba(255, 255, 255, 0.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.tel-confirme { transition: background 0.12s ease-out; }

/* iOS : la feuille « Sur l'ecran d'accueil », le nom, l'interrupteur, et
   « Ajouter » en haut a droite. */
.tel--ios .tel-dialogue {
  top: 22px;
  padding: 0 12px;
  border-radius: 16px 16px 0 0;
  background: #1c1c1e;
}

.tel-dtete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 40px;
  font-size: 10px;
}

.tel-dtete s { text-decoration: none; color: #4c9fff; font-size: 9.5px; }
.tel-dtete em { font-style: normal; font-weight: 700; font-size: 10px; white-space: nowrap; }
.tel-dtete b { color: #4c9fff; font-weight: 700; font-size: 9.5px; padding: 3px 5px; margin-right: -5px; border-radius: 6px; }
.tel-dtete b.presse { background: rgba(76, 159, 255, 0.28); }

.tel-dligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
  padding: 8px 9px;
  border-radius: 12px;
  background: #2c2c2e;
  font-size: 10px;
}

.tel-dligne i { position: relative; display: block; width: 26px; height: 16px; border-radius: 8px; background: #34c759; }
.tel-dligne i::after { content: ""; position: absolute; top: 1.5px; right: 1.5px; width: 13px; height: 13px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }

.tel-clavier {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 7px 3px 12px;
  background: #2a2a2d;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tel-clavier div { display: flex; justify-content: center; gap: 3px; }
.tel-clavier b { display: block; width: 17px; height: 24px; border-radius: 4px; background: #5c5c60; box-shadow: 0 1px 0 #161618; }
.tel-clavier b.large { width: 26px; background: #3f3f43; }
.tel-clavier b.espace { width: 104px; }
.tel-clavier b.retour { width: 44px; background: #3f3f43; }

/* Android : le panneau d'installation de Chrome, et son bouton. */
.tel--android .tel-dialogue {
  padding: 6px 14px 14px;
  border-radius: 18px 18px 0 0;
  background: #2b2d30;
  box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.5);
}

.tel--android .tel-dcorps { background: none; padding: 6px 0; }
.tel--android .tel-dcorps i { border-radius: 50%; }

.tel-dboutons { display: flex; justify-content: flex-end; align-items: center; gap: 14px; margin-top: 6px; font-size: 10px; }
.tel-dboutons s { text-decoration: none; color: #a8c7fa; }
.tel-dboutons b { padding: 6px 14px; border-radius: 14px; background: #a8c7fa; color: #062e6f; font-weight: 700; }
.tel-dboutons b.presse { background: #cfe0ff; }

/* -- ce que chaque scene montre ------------------------------------------- */

.tel[data-scene="posee"] .tel-app,
.tel[data-scene="ouverte"] .tel-app { opacity: 0; }
.tel[data-scene="posee"] .tel-accueil,
.tel[data-scene="ouverte"] .tel-accueil { opacity: 1; }
.tel[data-scene="posee"] .tel-case--cible i,
.tel[data-scene="ouverte"] .tel-case--cible i { opacity: 1; transform: scale(1); }
.tel[data-scene="posee"] .tel-case--cible span,
.tel[data-scene="ouverte"] .tel-case--cible span { opacity: 1; }

/* Posee, l'application n'est plus dans le navigateur : sa barre disparait,
   comme elle disparait vraiment une fois l'icone ouverte. */
.tel[data-scene="posee"] .tel-barre,
.tel[data-scene="posee"] .tel-outils,
.tel[data-scene="ouverte"] .tel-barre,
.tel[data-scene="ouverte"] .tel-outils { opacity: 0; }

/* L'application s'ouvre depuis son icone : elle grandit depuis l'endroit exact
   ou elle vient de se poser (l'origine est calculee par le script), et
   l'icone, elle, s'evanouit en grandissant, comme le fait le systeme. */
.tel[data-scene="ouverte"] .tel-app {
  opacity: 1;
  z-index: 5;
  animation: ouvre 0.62s var(--glisse) both;
}

.tel[data-scene="ouverte"] .tel-case--cible i {
  transform: scale(1.9);
  opacity: 0;
  transition: transform 0.5s ease-in, opacity 0.3s ease-in 0.12s;
}

@keyframes ouvre {
  from { opacity: 0; transform: scale(0.16); border-radius: 30px; }
  to { opacity: 1; transform: scale(1); border-radius: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tel *, .tel { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* -- la main ---------------------------------------------------------------
 *
 * Une main, pas un point : c'est un geste qu'on montre, et un rond se lit
 * comme un curseur de souris. Trois couches emboitees, chacune pour une seule
 * chose : `.doigt` se deplace (le script), `.doigt-presse` s'enfonce (le
 * script), `.doigt-souffle` respire (ici). Toutes tournent autour du bout de
 * l'index, a 18 px, 3 px du dessin, que les marges amenent sur l'ancre.     */

.doigt {
  position: absolute;
  z-index: 5;
  left: 0;
  top: 0;
  width: 58px;
  height: 76px;
  margin: -3px 0 0 -18px;
  pointer-events: none;
  filter: drop-shadow(0 8px 12px rgba(0, 0, 0, 0.55));
  will-change: transform;
}

.doigt-presse,
.doigt-souffle { display: block; width: 100%; height: 100%; transform-origin: 18px 3px; }
.doigt svg { display: block; width: 100%; height: 100%; }

@media (prefers-reduced-motion: no-preference) {
  .doigt-souffle { animation: souffle 2.1s ease-in-out infinite alternate; }
  @keyframes souffle {
    from { transform: translate(0, 0) rotate(0); }
    to { transform: translate(0.6px, 2.2px) rotate(1.6deg); }
  }
}

/* L'onde de contact part du bout de l'index. */
.doigt-onde {
  position: absolute;
  z-index: 4;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.95);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
}

/* -- la legende, une a la fois ------------------------------------------ */

/* `align-self` et non `margin: 0 auto` : une marge automatique sur un element
   de flexbox annule l'etirement transversal, et la boite se mesure alors sur
   son contenu. Ce contenu-la est fait de spans absolus, donc de rien : la
   legende tombait a zero de large et ses mots se posaient un par ligne, sur
   le bouton d'en dessous. */
.ac-legende {
  position: relative;
  min-height: 2.9em;
  width: 100%;
  max-width: 28ch;
  align-self: center;
  text-align: center;
  font-size: 16.5px;
  line-height: 1.32;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--affiche-texte);
}

/* Une legende a la fois, vraiment : la sortante s'efface AVANT que la suivante
   n'arrive. Un fondu croise symetrique laissait, pendant presque une demi-
   seconde, deux phrases lisibles l'une par-dessus l'autre au meme endroit --
   c'est ce qu'on voit sur les captures de la premiere installation. La
   sortante part donc vite et sans delai, l'entrante attend qu'elle soit
   partie ; `visibility` la retire du rendu au lieu de la laisser a zero. */
.ac-legende span {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(7px);
  transition: opacity 0.16s ease-out, visibility 0s linear 0.16s,
              transform 0.16s var(--glisse);
}

.ac-legende .courant {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.28s ease-out 0.18s, visibility 0s linear 0.18s,
              transform 0.28s var(--glisse) 0.18s;
}

/* -- la marche a suivre en toutes lettres, quand rien ne peut etre joue --
 *
 * L'ecran des navigateurs embarques n'a pas d'animation a montrer : le geste
 * qu'il decrit se passe dans une autre application que celle-ci.            */

.ac-pas { list-style: none; margin: 0; padding: 0; max-width: 420px; align-self: center; width: 100%; }

.ac-pas li {
  display: flex;
  gap: 11px;
  align-items: baseline;
  padding: 7px 0;
  font-size: 15px;
  line-height: 1.35;
  color: var(--affiche-gris);
}

.ac-pas .n {
  flex: 0 0 20px;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.ac-pas .courant { color: var(--affiche-texte); font-weight: 600; }
.ac-pas .courant .n { opacity: 1; }

/* -- la sortie : liste de controle, puis formulaire ---------------------- */

.ac-liste { list-style: none; margin: 0; padding: 0; max-width: 420px; align-self: center; width: 100%; }

.ac-liste li {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 15px;
  line-height: 1.35;
  cursor: pointer;
}

.ac-liste li:first-child { border-top: none; }

.ac-case {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 7px;
  border: 1.5px solid var(--affiche-gris);
  position: relative;
  transition: background 0.16s ease-out, border-color 0.16s ease-out;
}

.ac-liste .coche .ac-case { background: var(--affiche-texte); border-color: var(--affiche-texte); }

.ac-liste .coche .ac-case::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 3px;
  width: 5px;
  height: 10px;
  border: solid var(--affiche-fond);
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}

.ac-volet .ac-liste { max-width: none; }
.ac-volet .ac-liste li { border-top-color: var(--trait); }
.ac-volet .ac-case { border-color: var(--gris); }
.ac-volet .coche .ac-case { background: var(--texte); border-color: var(--texte); }
.ac-volet .coche .ac-case::after { border-color: var(--fond); }

.ac-deux { display: flex; gap: 10px; width: 100%; max-width: 420px; }
.ac-deux .ac-b { flex: 1 1 0; }
.ac-b--creux { background: none; border: 1px solid var(--affiche-gris); color: var(--affiche-texte); }

.ac-saisie {
  width: 100%;
  max-width: 420px;
  align-self: center;
  box-sizing: border-box;
  padding: 13px 14px;
  border-radius: 13px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(0, 0, 0, 0.22);
  color: var(--affiche-texte);
  font: inherit;
  font-size: 16px; /* sous 16 px, iOS zoome sur le champ a la mise au point */
  resize: none;
}

.ac-saisie::placeholder { color: var(--affiche-gris); }
.ac-saisie:focus { outline: 2px solid var(--affiche-texte); outline-offset: -1px; }

.ac-note {
  margin: 0;
  max-width: 420px;
  align-self: center;
  width: 100%;
  font-size: 14px;
  line-height: 1.4;
  color: var(--affiche-gris);
}

/* Seulement a la toute premiere construction de la page.
   La classe est posee par le rendu qui cree ces elements et n'est jamais
   remise : un rendu suivant, declenche par l'arrivee du flux quelques
   centaines de millisecondes plus tard, ne doit pas rejouer l'entree sous les
   yeux. Une fenetre de temps ne suffisait pas, le flux tombait dedans. */
@media (prefers-reduced-motion: no-preference) {
  .grand.neuf,
  .jour.neuf { animation: apparait 0.26s ease-out both; }
  @keyframes apparait { from { opacity: 0; transform: translateY(8px); } }
}
