/* =============================================================================
   My Larp Wallet — moteur de rendu de maquette
   -----------------------------------------------------------------------------
   Canevas de 923 px de large = un écran iPhone de 393 pt à 2,3486x. Toutes les
   longueurs sont donc des pixels de capture, ce qui rend la maquette exportable
   à la résolution native d'un vrai screenshot.
   923 est la largeur des maquettes ENCADRÉES. Quand le wallet est l'écran du
   téléphone (app.html sous 568 px), le canevas prend la largeur de l'écran à
   2,3486 unités par point — de 845 à 1033 — pour garder la taille native de
   chaque élément (voir `NATIF` dans mockup.js). Une règle qui suppose 923 de
   large doit donc s'écrire en marges ou en pour-cent de la colonne, pas en
   largeur fixe.

   Contrairement au prototype d'origine, la mise en page est ici en FLUX et non
   en positions absolues : le nombre de jetons est variable, tout doit se
   replacer tout seul.
   ============================================================================= */

/* LA VARIABLE DU RETRAIT BAS EST DECLAREE, ET CE N'EST PAS UNE COQUETTERIE.

   `--mw-cache-bas` est ecrite par app.html a partir d'une MESURE. Sans
   declaration, c'est une propriete personnalisee libre : elle accepte
   n'importe quelle chaine, et une valeur qui n'est pas une longueur —
   « NaNpx », une chaine vide, une unite oubliee — rend invalide AU CALCUL
   chaque declaration qui la consomme. `bottom` retombe alors a `auto`, la
   feuille prend la hauteur de son contenu, et la barre d'action se retrouve
   posee en haut de l'ecran. Mesure au banc : 13 % de la hauteur, c'est-a-dire
   exactement la capture envoyee par le proprietaire.

   Declaree, la regle change du tout au tout : une valeur qui ne correspond pas
   a la syntaxe est IGNOREE, et c'est `initial-value` qui s'applique. Le pire
   cas redevient « le rendu d'avant », ce que le garde-fou de app.html visait
   deja sans pouvoir le garantir depuis l'autre bout de la chaine.

   Un moteur qui ne connait pas @property ignore ce bloc et se comporte comme
   aujourd'hui : on ne perd rien la ou on ne gagne pas. */
@property --mw-cache-bas {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
/* MEME RAISON POUR LA HAUTEUR DU CLAVIER : elle est ecrite par du script, elle
   est consommee dans des `calc()`, et sans declaration une valeur du mauvais
   type rendrait INVALIDE AU CALCUL la declaration qui la lit — un rembourrage
   qui retombe a zero, une translation qui disparait, et aucun message. */
@property --mw-clavier {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

.mw {
  /* --- palette (surchargeable par le configurateur) --- */
  --mw-bg:        #000000;
  --mw-card:      #181818;
  --mw-pill:      #1c1c1c;
  --mw-accent:    rgb(179, 165, 248);
  --mw-accent-ink:#000000;
  --mw-text:      #efefef;
  --mw-dim:       #b3b3b3;
  --mw-up:        rgb(13, 234, 80);
  --mw-down:      rgb(255, 2, 42);
  --mw-chip:      #1f1f1f;

  /* --- métriques typographiques, résolues sur des captures réelles ---
     (SF Pro bascule de Text à Display au-dessus de ~27 px : ces valeurs
     tiennent compte de la bascule, ne pas les « arrondir ») */
  --mw-f-tab:     38.5px;  --mw-ls-tab:      0.6px;
  --mw-f-wallet:  42px;    --mw-ls-wallet:   0px;
  --mw-f-balance: 111px;   --mw-ls-balance:  0.4px;
  --mw-f-delta:   38.5px;  --mw-ls-delta:    1.4px;
  --mw-f-badge:   36px;    --mw-ls-badge:    1px;
  --mw-f-head:    55px;    --mw-ls-head:     0.3px;
  --mw-f-tname:   42px;    --mw-ls-tname:   -0.4px;
  --mw-f-tsub:    36.4px;  --mw-ls-tsub:     0.8px;
  --mw-f-tval:    41px;    --mw-ls-tval:    -2.1px;
  --mw-f-tchg:    37.4px;  --mw-ls-tchg:    -0.5px;
  --mw-f-search:  41.3px;  --mw-ls-search:   0.3px;
  /* Cartes Perps. Ces trois-la etaient UTILISEES sans etre definies : une
     var() sans valeur ni repli rend la declaration invalide, le font-size
     retombait donc a l'herite (16px) et « BTC 40x -3,30% » s'affichait en
     minuscule au lieu de la taille de la capture. */
  --mw-f-pname:   46px;    --mw-ls-pname:   -0.4px;
  --mw-f-plev:    34px;    --mw-ls-plev:     0px;
  --mw-f-pchg:    38px;    --mw-ls-pchg:    -0.3px;
  /* Meme cause pour le « Live » des predictions, qui sortait en blanc herite
     au lieu du rouge. Le wallet n'a qu'un rouge : celui des pertes. */
  --mw-red:       var(--mw-down);

  position: relative;
  width: 923px;
  /* Hauteur FIXE, pas min-height : c'est un écran, pas un document. Le contenu
     qui dépasse est masqué et défile ; sinon `.mw` s'étire à la hauteur du
     contenu et le dock, ancré en bas, part au milieu de nulle part. */
  height: 2000px;
  background: var(--mw-bg);
  color: var(--mw-text);
  overflow: hidden;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
               "SF Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-kerning: normal;
  font-variant-ligatures: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

/* Thème clair : on ne redéfinit que ce qui change de rôle. */
.mw[data-theme="light"] {
  --mw-bg:   #ffffff;
  --mw-card: #f2f2f4;
  --mw-pill: #ececef;
  --mw-text: #0d0d0f;
  --mw-dim:  #6a6a72;
  --mw-chip: #e4e4e8;
  --mw-accent-ink: #000000;
}

/* ------------------------------------------------------------ barre d'état */
/* Reproduite pour l'export : une maquette destinée à l'App Store en a besoin. */
/* Fond opaque et z-index propres : la barre d'état ne comptait que sur le voile
   pour masquer le contenu qui défile derrière elle. Deux protections valent
   mieux qu'une seule qui s'arrondit mal. */
/* La barre d'état DESSINÉE est retirée : sur un vrai téléphone, c'est l'iPhone
   qui affiche l'heure, le réseau et la batterie. En dessiner une seconde les
   faisait apparaître en double, avec 9:41 et 82% figés qui contredisaient les
   vraies valeurs juste au-dessus.
   La HAUTEUR, elle, reste : c'est elle qui empêche le contenu de glisser sous
   la barre du système. La retirer aurait remonté tout l'écran de 140px. */
.mw-status { position: relative; height: 140px; flex: 0 0 auto;
             background: var(--mw-bg); z-index: 3; }
/* LA BARRE DESSINEE N'EST CACHEE QUE DANS LE PRODUIT, PAS SUR LE SITE.
   Elle avait ete cachee PARTOUT le 15/09/2026, et pour une bonne raison : sur le
   telephone de l'acheteur, l'iPhone affiche deja l'heure, le reseau et la
   batterie, et en dessiner une seconde les montrait en double, avec un 9:41 et
   un 82% figes qui contredisaient les vraies valeurs deux centimetres plus haut.

   Mais cette raison n'existe QUE la. Sur l'accueil, sur /demo, sur l'ecran de
   paiement et dans les 53 illustrations publiees, le telephone est dessine dans
   un cadre, sur une page web : aucun systeme ne pose de barre par-dessus, et le
   wallet y apparaissait donc decapite, avec 140px de vide au-dessus de ses
   onglets. Un telephone sans heure ne ressemble pas a un telephone.

   `body.wallet` n'existe que dans app.html : le masquage suit donc exactement la
   frontiere « le vrai wallet » / « les maquettes du site », sans avoir a poser
   un drapeau nulle part.
   `.mw-status .r` plus bas est plus specifique et remettrait le groupe reseau en
   flex : on masque par le selecteur le plus fort plutot qu'en esperant l'ordre. */
body.wallet .mw-status > .t,
body.wallet .mw-status > .r { display: none !important; }
/* Positions mesurées sur une capture native : heure à x=117 / y=54, groupe de
   droite terminant à 77 du bord, écarts de 18, tout aligné sur une base à 82. */
.mw-status .t {
  position: absolute; left: 117px; top: 48px;
  font-size: 41px; font-weight: 600; line-height: 1;
  letter-spacing: -0.4px; color: var(--mw-text);
}
.mw-status .r {
  position: absolute; right: 77px; top: 52px;
  display: flex; align-items: flex-end; gap: 18px;
}
.mw-status svg { display: block; }
.mw-status .sig, .mw-status .wifi { margin-bottom: 1.5px; }
.mw-status .batt { position: relative; }
.mw-status .batt .pct {
  position: absolute; left: 0; top: 0; width: 59.5px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  font-size: 27px; font-weight: 650; letter-spacing: -0.6px; line-height: 1;
  color: var(--mw-bg);
}

/* -------------------------------------------------------------------- tabs */
/* Le fondu est porte par la BANDE et non par son enveloppe : le rond de
   profil vit dans l'enveloppe, en dehors de la bande, et ne doit donc pas
   etre attenue quand les onglets glissent sous lui. */
.mw-tabs-wrap { position: relative; margin-top: 17px; }
.mw-tabs-wrap > .mw-tab.is-avatar { position: absolute; left: 47px; top: 0; z-index: 2; }
/* LE FONDU SE COMPTE DEPUIS LE BORD, EN PIXELS, PAS EN POUR-CENT. Releve sur
   un canevas de 923 (92,6 % -> 68 px du bord droit), il gardait ses
   pourcentages ; depuis que le canevas suit la largeur de l'ecran (mode
   natif, 845 a 1033), un pourcentage l'aurait etire ou tasse avec elle. En
   pixels il garde la largeur relevee, et a 923 il tombe au meme dixieme. */
.mw-tabs {
  --fade: linear-gradient(to right, #000 0, #000 calc(100% - 68.3px), rgba(0,0,0,.80) calc(100% - 57.2px),
                          rgba(0,0,0,.62) calc(100% - 37.8px), rgba(0,0,0,.50) calc(100% - 18.5px),
                          rgba(0,0,0,.48) 100%);
  -webkit-mask-image: var(--fade); mask-image: var(--fade);
  position: relative;                 /* repere de offsetLeft pour cadreOnglet */
  display: flex; align-items: center; gap: 19px;
  /* 160 = 47 de marge + 94 de rond + 19 d'ecart : les onglets tombent
     exactement ou ils tombaient quand le rond etait le premier d'entre eux. */
  padding: 0 47px 0 160px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  scroll-behavior: smooth;
}
.mw-tabs::-webkit-scrollbar { display: none; }
/* Bande poussee a fond : le fondu passe a gauche, la ou le contenu sort.
   Il court jusqu'a 140px (15,2 % de 923, la fin du rond de profil) et non sur
   quelques pixels : l'onglet qui glisse dessous doit etre attenue sur TOUTE
   la largeur du rond, sinon il ressort en pleine opacite juste a cote et les
   deux pastilles, de meme couleur, se confondent en une seule forme. */
.mw[data-tab="3"] .mw-tabs {
  --fade: linear-gradient(to right, rgba(0,0,0,.40) 0, rgba(0,0,0,.52) 47.1px,
                          rgba(0,0,0,.78) 96px, #000 140.3px, #000 100%);
}
.mw-tab {
  flex: 0 0 auto; height: 94px; border-radius: 47px;
  background: var(--mw-pill); color: var(--mw-dim);
  font-size: var(--mw-f-tab); font-weight: 500; letter-spacing: var(--mw-ls-tab);
  display: flex; align-items: center; justify-content: center;
  padding: 0 33px; white-space: nowrap;
}
.mw-tab.is-active { background: var(--mw-accent); color: var(--mw-accent-ink); font-weight: 600; }
.mw-tab.is-avatar {
  width: 94px; padding: 0; overflow: hidden;
  font-size: 52px; line-height: 1; background: var(--mw-pill);
}
.mw-tab.is-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* LE GLYPHE D'AVATAR, POSE PAR `mockup.js`

   `inline-block` et non `inline` : un element en flux inline ignore purement et
   simplement `transform`, et le calage mesure par `caleDuGlyphe` ne s'appliquerait
   jamais — sans la moindre erreur pour le signaler.

   `letter-spacing: 0` parce que `.mw-tab` en herite 0,6 px : cet espace est
   ajoute APRES le caractere, il entre dans la boite que le flex centre, et il
   decale donc le glyphe visible d'un demi-espace vers la gauche. */
.mw .mw-glyphe { display: inline-block; letter-spacing: 0; }

/* ------------------------------------------------- roue de rafraîchissement */
/* Hauteur nulle et position absolue : la roue se superpose au blanc qui sépare
   la barre d'onglets du nom de portefeuille, sans jamais déplacer une seule
   ligne de la maquette. `opacity:0` par défaut — voir le commentaire de ROUE
   dans mockup.js : l'export ne doit pas la contenir. */
.mw-refresh {
  position: relative; height: 0; z-index: 2; opacity: 0; pointer-events: none;
}
.mw-refresh > span {
  position: absolute; left: 50%; top: 18px;
  width: 72px; height: 72px; margin-left: -36px;
  /* Un pas par rai, et non une rotation continue : c'est ce saut qui donne le
     mouvement caractéristique. DOUZE pas pour douze rais — les deux nombres
     doivent rester d'accord, sinon la roue glisse au lieu de sauter. */
  animation: mw-roue 1s steps(12, end) infinite;
}
/* Proportions relevées sur la capture de référence fournie par l'exploitant,
   et non déduites : 6 de large sur 24 de long dans une boîte de 72.

   LA LARGEUR EST BORNÉE PAR LA SÉPARATION, et c'est ce qui fixe le chiffre.
   Douze rais se partagent l'arc du trou central : à un rayon interne de 12, cet
   arc vaut 2·pi·12/12 = 6,3 px par rai. Un trait de 8 s'y chevauchait et la
   roue devenait un disque plein ; à 6, les rais restent distincts. Épaissir
   davantage exigerait d'agrandir le trou, donc de raccourcir les traits — ce
   qui ramènerait l'astérisque.

   Ce qui avait été raté deux fois de suite, et qu'il faut retenir : ce sont la
   LONGUEUR du trait et la petitesse du TROU CENTRAL qui font reconnaître la
   roue iOS. Le trait couvre presque les trois quarts du rayon (26 sur 36),
   il ne s'arrête pas à la moitié. Des traits courts autour d'un grand trou
   donnent un astérisque ; des traits longs autour d'un petit trou donnent une
   roue. */
.mw-refresh i {
  position: absolute; left: 50%; top: 0;
  width: 6px; height: 24px; margin-left: -3px;
  border-radius: 3px; background: var(--mw-dim);
  transform-origin: 3px 36px;
}
/* L'extinction n'est pas linéaire. Une rampe régulière donne une étoile figée
   où toutes les branches se valent ; ce qu'on veut, c'est une comète — une tête
   franche et une traîne qui s'efface vite. */
.mw-refresh i:nth-child(1){ transform: rotate(0deg); opacity: 0.13; }
.mw-refresh i:nth-child(2){ transform: rotate(30deg); opacity: 0.15; }
.mw-refresh i:nth-child(3){ transform: rotate(60deg); opacity: 0.20; }
.mw-refresh i:nth-child(4){ transform: rotate(90deg); opacity: 0.25; }
.mw-refresh i:nth-child(5){ transform: rotate(120deg); opacity: 0.32; }
.mw-refresh i:nth-child(6){ transform: rotate(150deg); opacity: 0.40; }
.mw-refresh i:nth-child(7){ transform: rotate(180deg); opacity: 0.48; }
.mw-refresh i:nth-child(8){ transform: rotate(210deg); opacity: 0.57; }
.mw-refresh i:nth-child(9){ transform: rotate(240deg); opacity: 0.67; }
.mw-refresh i:nth-child(10){ transform: rotate(270deg); opacity: 0.77; }
.mw-refresh i:nth-child(11){ transform: rotate(300deg); opacity: 0.88; }
.mw-refresh i:nth-child(12){ transform: rotate(330deg); opacity: 1.00; }
@keyframes mw-roue { to { transform: rotate(360deg); } }
/* quelqu'un qui a demandé moins d'animations n'a pas à subir une roue qui tourne */
@media (prefers-reduced-motion: reduce) {
  .mw-refresh > span { animation: none; }
}

/* ------------------------------------------------------------------ entête */
.mw-wallet {
  display: flex; align-items: center; gap: 14px;
  margin: 79px 0 0 48px;
  font-size: var(--mw-f-wallet); font-weight: 500; letter-spacing: var(--mw-ls-wallet);
  line-height: 1; color: var(--mw-dim);
}
.mw-wallet svg { display: block; position: relative; top: 2px; }

.mw-balance {
  margin: 18px 0 0 47px;
  font-size: var(--mw-f-balance); font-weight: 700; line-height: 1;
  letter-spacing: var(--mw-ls-balance); color: var(--mw-text);
  white-space: nowrap;
}

.mw-delta { display: flex; align-items: center; gap: 20px; margin: 25px 0 0 48px; }
.mw-delta .abs {
  font-size: var(--mw-f-delta); font-weight: 600; line-height: 1;
  letter-spacing: var(--mw-ls-delta);
}
.mw-delta .pct {
  height: 51px; border-radius: 18px; color: #050000;
  font-size: var(--mw-f-badge); font-weight: 600;
  letter-spacing: var(--mw-ls-badge); line-height: 1;
  display: flex; align-items: center; padding: 0 13px;
}
.mw-delta.is-up   .abs { color: var(--mw-up); }
.mw-delta.is-up   .pct { background: var(--mw-up); }
.mw-delta.is-down .abs { color: var(--mw-down); }
.mw-delta.is-down .pct { background: var(--mw-down); color: #050000; }

/* ------------------------------------------------------ liseré des cartes */
/* Mesuré sur l'app de référence : le bord est plus clair que le fond, en
   dégradé — +8 en haut, +5 sur les côtés, +2 en bas. Un filet de 1 px écran
   vaut 2,3 px de canevas. */
.mw-card { position: relative; background: var(--mw-card); }
.mw-card::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  padding: 2.3px; pointer-events: none;
  background: linear-gradient(180deg,
              rgba(255,255,255,.036) 0%,
              rgba(255,255,255,.022) 45%,
              rgba(255,255,255,.009) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.mw[data-theme="light"] .mw-card::before {
  background: linear-gradient(180deg, rgba(0,0,0,.05), rgba(0,0,0,.02));
}

/* --------------------------------------------------------------- carte Cash */
.mw-cash {
  margin: 64px 47px 0; height: 164px; border-radius: 52px;
  display: flex; align-items: center; padding: 0 49px 0 66px;
}
.mw-cash .ic { flex: 0 0 57px; width: 57px; height: 40.4px; display: block; }
.mw-cash .lb {
  flex: 1 1 auto; margin-left: 45px;
  font-size: 43px; font-weight: 600; letter-spacing: -.3px; line-height: 1;
}
.mw-cash .val { font-size: 42px; font-weight: 600; letter-spacing: -1.6px; line-height: 1; }

/* ----------------------------------------------------------------- section */
.mw-section { margin-top: 59px; }
.mw-section-head {
  display: flex; align-items: center; gap: 20px;
  padding-left: 47px; height: 70px;
  font-size: var(--mw-f-head); font-weight: 700;
  letter-spacing: var(--mw-ls-head); line-height: 1;
}
.mw-section-head svg { display: block; color: var(--mw-dim); position: relative; top: 2px; }

/* -------------------------------------------------------------- ligne jeton */
.mw-tokens { padding: 0 47px; margin-top: 32px; }
.mw-token {
  display: flex; align-items: center;
  height: 160px; border-radius: 52px; padding: 0 47px;
}
.mw-token + .mw-token { margin-top: 19px; }
.mw-token .icon {
  flex: 0 0 94px; width: 94px; height: 94px; border-radius: 50%;
  overflow: hidden; margin-right: 29px; display: block; background: var(--mw-chip);
}
.mw-token .icon svg, .mw-token .icon img { display: block; width: 100%; height: 100%; }
.mw-token .main { flex: 1 1 auto; min-width: 0; }
.mw-token .side { flex: 0 0 auto; text-align: right; position: relative; top: 1px; }

.mw-token .name {
  font-size: var(--mw-f-tname); font-weight: 600;
  letter-spacing: var(--mw-ls-tname); line-height: 1; color: var(--mw-text);
}
.mw-token .sub {
  font-size: var(--mw-f-tsub); font-weight: 400;
  letter-spacing: var(--mw-ls-tsub); line-height: 1; color: var(--mw-dim); margin-top: 15px;
}
.mw-token .val {
  font-size: var(--mw-f-tval); font-weight: 600;
  letter-spacing: var(--mw-ls-tval); line-height: 1; color: var(--mw-text);
  margin-right: 2.1px; /* compense l'approche sur un texte aligné à droite */
}
.mw-token .chg {
  font-size: var(--mw-f-tchg); font-weight: 600;
  letter-spacing: var(--mw-ls-tchg); line-height: 1; margin-top: 16px;
}
.mw-token .chg.up   { color: var(--mw-up); }
.mw-token .chg.down { color: var(--mw-down); }


/* ------------------------------------------------------ défilement interne */
/* Le contenu passe SOUS l'entête. Ordre de superposition, du fond vers le
   dessus : contenu (auto), puis voile du haut (2), puis barre d'état et
   onglets (3).
   NB : jamais de chevron ouvrant dans ces commentaires — la feuille est
   inlinée dans un SVG à l'export, où il serait lu comme une balise. */
/* Defilement natif. `.mw` est un ecran (hauteur fixe, overflow:hidden) : le
   conteneur de contenu est donc pose en absolu par-dessus toute sa surface et
   c'est LUI qui defile, pendant que la barre d'etat, les onglets et le dock —
   qui vivent en dehors — restent fixes.
   Le padding de 251px n'est pas un reglage a l'oeil : c'est le bas mesure de
   la barre d'onglets. Le passer a 330 (ou commencait le contenu) le decalait
   de 79px, parce que la marge haute de .mw-wallet s'echappait du conteneur
   par fusion de marges tant qu'il n'avait ni padding ni bordure ; le padding
   bloque cette fusion, la marge s'ajoute donc au lieu de se confondre.
   Le contenu passe SOUS la barre en defilant, comme dans une vraie app, et le
   voile du haut l'estompe. */
.mw-scroll{
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
  padding-top: 251px;
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;            /* l'indicateur iOS reste, lui */
  will-change: transform;
}
.mw-scroll::-webkit-scrollbar{ width: 0; height: 0; }
.mw-tail{ height: 260px; }          /* respiration sous la dernière carte */

.mw-topveil{
  /* Opaque jusqu'en dessous des onglets (qui finissent à 268), puis fondu :
     84% de 338px depuis -8 place la fin de l'opacité à 276. Plus court, un
     filet de contenu réapparaissait sous la barre pendant le défilement. */
  /* Déborde VOLONTAIREMENT de 8px au-dessus et sur les côtés. La maquette est
     mise à l'échelle par un facteur fractionnaire (≈0,3369) et posée à une
     position fractionnaire : le contenu défilant, promu sur sa propre couche
     par `will-change:transform`, s'arrondit alors au pixel indépendamment du
     voile, et une ligne de contenu réapparaît tout en haut. Un voile qui
     dépasse le bord ne peut plus laisser de couture ; `.mw` étant en
     overflow:hidden, ce débord ne se voit jamais. */
  /* 308 ET NON 338. Le voile part de -8 : a 338 il finissait donc au canevas 330,
     alors que la seconde rangee de « Trade » (.tk-chips) commence a 312 et celle
     d'« Explore » (.ex-cat) a 313. Leurs dix-huit premiers pixels tombaient dans
     le degrade — d'ou une pastille legerement voilee par le haut, visible sur ces
     deux ecrans et sur eux seuls, l'accueil ne posant rien d'aussi haut.
     A 308, la part opaque s'arrete au canevas 251, c'est-a-dire exactement au bas
     de la rangee d'onglets, et le degrade s'eteint a 300 — douze pixels au-dessus
     de ce que les deux ecrans dessinent. Le fondu de defilement garde ses 49 px,
     il est seulement remonte la ou il a affaire. */
  position: absolute; left: -8px; right: -8px; top: -8px; height: 308px; z-index: 2;
  background: linear-gradient(to bottom, var(--mw-bg) 0%, var(--mw-bg) 84%,
              rgba(0,0,0,0) 100%);
  pointer-events: none;
}
.mw[data-theme="light"] .mw-topveil{
  background: linear-gradient(to bottom, var(--mw-bg) 0%, var(--mw-bg) 84%,
              rgba(255,255,255,0) 100%);
}
.mw-status{ position: relative; z-index: 3; }
.mw-tabs-wrap{ position: relative; z-index: 3; }

/* Pastille discrète quand une valeur vient de changer (démo animée). */
.mw-flash{ animation: mw-flash 1.5s ease-out; }
@keyframes mw-flash{
  /* Éclat discret : à 2,1 le chiffre « sautait » à chaque révision, ce qui
     accentuait l'impression de vitesse. */
  0%   { filter: brightness(1.45); }
  100% { filter: brightness(1); }
}


/* =============================================================================
   Sections basses — Perps, Predictions, Watchlist, Explore, Support
   -----------------------------------------------------------------------------
   Reprises telles quelles du prototype vérifié au pixel, avec deux adaptations :
   les sélecteurs sont portés par `.mw` (le moteur peut être instancié plusieurs
   fois sur une page) et les variables reprennent le préfixe `--mw-`.
   Elles sont toujours rendues : ce sont elles qui donnent de la matière au
   défilement. Le drapeau `showSections` qui les conditionnait a été supprimé —
   il n'avait aucun réglage dans le panneau, et une configuration enregistrée
   avant ce changement l'aurait gardé à faux, privant définitivement ce
   compte-là des sections.
   ============================================================================= */
/* ------------------------------------------------------------------- rails */
.mw .rail{
  display:flex; gap:19px; padding:0 47px;
  overflow-x:auto; scrollbar-width:none;
}
.mw .rail::-webkit-scrollbar{ display:none; }
.mw .rail > *{ flex:0 0 auto; }
.mw .rail--perps{ margin-top:32px; margin-right:10px; }
.mw .rail--preds{ margin-top:30px; gap:38px; }

.mw .perp{
  width:376px; height:338px;
  background:var(--mw-card); border-radius:52px;
  padding:48px;
  display:flex; flex-direction:column; justify-content:space-between;
}
.mw .perp-icon{
  width:111px; height:111px; border-radius:50%;
  overflow:hidden; display:flex; align-items:center; justify-content:center;
}
.mw .perp-icon svg{ display:block; }
.mw .perp-icon--eth svg{ margin:-2px 4px 0 0; }
.mw .perp-icon--hype{ align-items:flex-start; justify-content:flex-start; }
.mw .perp-icon--hype i{ display:block; width:59px; height:59px; border-radius:50%;
                    background:#97fce4; margin:29px 0 0 -3px; }
.mw .perp-foot{ margin-bottom:3px; }
.mw .perp-row{ display:flex; align-items:center; gap:15px; }
.mw .perp-name{ font-size:var(--mw-f-pname); font-weight:700; letter-spacing:var(--mw-ls-pname); line-height:1; color:var(--mw-text); }
.mw .perp-lev{
  height:48px; border-radius:16px; background:var(--mw-chip);
  color:var(--mw-text); font-size:var(--mw-f-plev); font-weight:600;
  letter-spacing:var(--mw-ls-plev); line-height:1;
  display:flex; align-items:center; padding:0 14px;
}
.mw .perp-chg{ font-size:var(--mw-f-pchg); font-weight:500; letter-spacing:var(--mw-ls-pchg); line-height:1; margin-top:16px; }
/* Le marquage neg/pos etait pose dans le HTML depuis le debut mais aucune
   regle ne le lisait : les variations des cartes Perps sortaient en blanc
   herite alors qu'elles sont rouges sur la capture. Mesure : rgb(239,239,239). */
.mw .perp-chg.pos{ color: var(--mw-up); }
.mw .perp-chg.neg{ color: var(--mw-down); }

/* ------------------------------------------------------- carte prédiction */
.mw .pred{
  width:554px; height:319px;
  background:var(--mw-card); border-radius:38px;
  padding:39px 31px 0;
  position:relative;
}
.mw .pred-icon{ width:108px; height:108px; border-radius:50%; overflow:hidden; display:block; }
.mw .pred-icon svg{ display:block; width:100%; height:100%; }
.mw .pred-live{
  position:absolute; right:39px; top:47px;
  display:flex; align-items:center; gap:12px;
  color:var(--mw-red); font-size:37px; font-weight:600; line-height:1;
}
.mw .pred-live::before{ content:""; width:13px; height:13px; border-radius:50%; background:var(--mw-red); display:block; }
.mw .pred-title{
  position:absolute; left:31px; top:181px;
  font-size:40px; font-weight:600; letter-spacing:-.2px; line-height:1; color:var(--mw-text);
  white-space:nowrap;
}
.mw .pred-sub{
  position:absolute; left:31px; top:238px;
  font-size:37px; font-weight:400; letter-spacing:.2px; line-height:1; color:var(--mw-dim);
  white-space:nowrap;
}
.mw .pred-tickets{ position:absolute; left:38px; top:34px; width:150px; height:120px; }
.mw .pred-tickets svg{ display:block; }

/* ------------------------------------------------------------- watchlist */
.mw .watch{ padding:0 47px; margin-top:26px; }
.mw .wrow{ display:flex; align-items:center; height:164px; }
.mw .wrow-icon{
  flex:0 0 92px; width:92px; height:92px; border-radius:50%;
  overflow:hidden; margin-right:24px; display:block;
}
.mw .wrow-icon svg{ display:block; width:100%; height:100%; }
.mw .wrow-main{ flex:1 1 auto; min-width:0; }
.mw .wrow-name{ display:flex; align-items:center; gap:11px; }
.mw .wrow-sym{ font-size:42px; font-weight:700; letter-spacing:-.3px; line-height:1; color:var(--mw-text); }
.mw .wrow-mc{ font-size:37px; font-weight:400; letter-spacing:.3px; line-height:1; color:var(--mw-dim); margin-top:16px; }
.mw .wrow-side{ flex:0 0 auto; text-align:right; }
.mw .wrow-px{ font-size:41px; font-weight:600; letter-spacing:-1.4px; line-height:1; color:var(--mw-text); }
.mw .wrow-chg{ font-size:37px; font-weight:500; letter-spacing:-.4px; line-height:1; margin-top:16px; }

/* --------------------------------------------------------------- explore */
.mw .explore{ padding:0 47px; margin-top:54px; }
.mw .erow{
  display:flex; align-items:center;
  height:127px; background:var(--mw-card); border-radius:38px;
  padding-left:47px;
}
.mw .erow + .erow{ margin-top:47px; }
.mw .erow-icon{ flex:0 0 79px; width:79px; height:79px; display:flex; align-items:center; justify-content:center; margin-right:65px; }
.mw .erow-icon svg{ display:block; }
.mw .erow-title{ font-size:42px; font-weight:600; letter-spacing:-.2px; line-height:1; color:var(--mw-text); }
.mw .erow-sub{ font-size:37px; font-weight:400; letter-spacing:.2px; line-height:1; color:var(--mw-dim); margin-top:22px; }

/* --------------------------------------------------------------- support */
.mw .support-link{
  /* Étaient en absolu dans le prototype, où la section l'était aussi. En flux,
     elles s'échappaient vers le haut de l'écran : on garde les mêmes écarts. */
  margin:47px 0 0 47px;
  display:flex; align-items:center; gap:17px;
  font-size:42px; font-weight:700; letter-spacing:-.2px; line-height:1; color:var(--mw-text);
}
.mw .support-link svg{ display:block; color:var(--mw-text); position:relative; top:1px; }
.mw .disclose{
  margin:86px 0 0 47px;
  display:flex; align-items:center; gap:14px;
  font-size:36px; font-weight:400; letter-spacing:.2px; line-height:1; color:#8b8b8b;
}
.mw .disclose svg{ display:block; flex:0 0 auto; }

.mw .perp--cta{
  width:705px; padding:0; position:relative;
}
.mw .perp-cta-icon{ position:absolute; left:50px; top:47px; display:block; }
.mw .perp-cta-title{
  position:absolute; left:50px; top:196px;
  font-size:42px; font-weight:600; letter-spacing:-.2px; line-height:1; color:var(--mw-text); white-space:nowrap;
}
.mw .perp-cta-sub{
  position:absolute; left:50px; top:252px;
  font-size:37px; font-weight:400; letter-spacing:.2px; line-height:1; color:var(--mw-dim); white-space:nowrap;
}
.mw .perp-icon--hype{ overflow:visible; align-items:center; justify-content:flex-start; }
.mw .perp-icon--hype svg{ margin-left:-4px; }

.mw .support-link + .support-link{ margin-top:66px; }

/* -------------------------------------------------------------------- dock */
.mw-dock {
  position: absolute; left: 0; right: 0; bottom: 80px; height: 112px;
  display: flex; align-items: center; gap: 22px; padding: 0 47px; z-index: 4;
}
.mw-search {
  flex: 1 1 auto; height: 112px; border-radius: 56px;
  /* Nettement plus transparente qu'avant : sur la capture, la lueur orange de
     l'icone qui passe derriere traverse la pilule. A .72 elle etait bouchee. */
  background: rgba(32,32,32,.56);
  -webkit-backdrop-filter: blur(44px) saturate(170%);
          backdrop-filter: blur(44px) saturate(170%);
  display: flex; align-items: center; padding: 0 40px; gap: 24px;
  font-size: var(--mw-f-search); letter-spacing: var(--mw-ls-search);
  color: #8b8b8b; font-weight: 400;
}
.mw[data-theme="light"] .mw-search { background: rgba(0,0,0,.06); color: #77777f; }
.mw-search svg { display: block; flex: 0 0 auto; }
.mw-plus {
  flex: 0 0 112px; width: 112px; height: 112px; border-radius: 50%;
  background: var(--mw-accent); display: flex; align-items: center; justify-content: center;
  /* La croix heritait de --mw-text, donc blanche. Sur le lavande c'est l'encre
     sombre qui s'applique — exactement celle de l'onglet actif, qui est deja
     du noir sur ce meme lavande. */
  color: var(--mw-accent-ink);
}
.mw-plus svg { display: block; }

/* =============================================================================
   LE MENU DU « + »
   -----------------------------------------------------------------------------
   Tout est en pixels de CANEVAS, ancre sur `.mw-plus` juste au-dessus : la
   pastille du menu fait le meme diametre que le bouton qui l'ouvre, 112 px, et
   les deux bords droits tombent sur les 47 px de retrait du dock. Le detail du
   releve est dans le commentaire de `FAB` (mockup.js).

   L'ACCENT VIENT DE `--mw-accent`, PAS DE LA PAGE. Les copies prenaient un
   `--brand` herite de la feuille de la page, qu'il fallait rabattre a la main
   sur le lavande a la frontiere du cadre — le jour ou la page etait passee au
   violet sature, le « + » du menu avait suivi pendant que la pilule d'onglet
   active, elle, restait lavande : deux accents a deux centimetres l'un de
   l'autre dans le meme ecran. Ici la question ne se pose plus.
   ============================================================================= */
.mw-fab { position: absolute; inset: 0; z-index: 10; display: none; }
.mw[data-fab="1"] .mw-fab { display: block; }
/* LE DOCK S'EFFACE, PARCE QUE LA CROIX REMPLACE LE « + ».

   Mesure sur la capture de reference : l'interieur de l'anneau de fermeture est
   parfaitement neutre, (26,26,26), c'est-a-dire le voile et rien d'autre. Chez
   nous il tirait au mauve — (74,72,91) — parce que le « + » lavande restait
   allume dessous et traversait le flou. Le rond de fermeture n'a pas de fond
   justement parce qu'il n'a rien a cacher : il EST le « + », le temps du menu.
   La barre de recherche part avec lui, comme sur la reference ou la bande du
   bas ne montre plus aucune forme. */
.mw[data-fab="1"] .mw-dock { visibility: hidden; }
/* Le flou reprend le geste de l'app : ce qu'on quitte reste visible mais
   illisible, ce qui dit « tu es par-dessus », pas « tu as change d'ecran ».
   42 px de canevas — le rayon est mis a l'echelle avec le reste, comme celui
   de la barre de recherche juste au-dessus. */
/* PAS NOIR PUR, ET C'EST MESURE. Sur la capture de reference du 21/09/2026,
   l'ecart-type de ce qui survit au voile est le meme que chez nous (11,0 contre
   11,3) : meme opacite, meme flou. Ce qui differe, c'est le PLANCHER — 13 chez
   eux, 0 chez nous. Un voile noir sur un wallet noir donne du noir, et l'ecran
   devenait un trou ou l'on ne devinait plus rien ; le leur laisse lire la forme
   des cartes. 26 x 0,52 = 13,5 : c'est exactement le plancher releve. */
.mw-fab-voile {
  /* meme arrondi que .mw-veil ci-dessous : le voile deborde de 24 px de
     canevas sur chaque bord, `.mw` (overflow:hidden) coupe le surplus */
  position: absolute; inset: -24px;
  background: rgba(26,26,26,.52);
  -webkit-backdrop-filter: blur(42px) saturate(120%);
          backdrop-filter: blur(42px) saturate(120%);
}
.mw-fab-liste {
  position: absolute; right: 47px; bottom: 250px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 56px;
}
.mw-fab-act {
  display: flex; align-items: center; gap: 38px;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: #fff; font-family: inherit; font-weight: 700; font-size: 55px;
  line-height: 1; letter-spacing: -.7px;
  /* APPARITION MESUREE, PAS IMAGINEE. Enregistrement d'ecran de l'app de
     reference, 21/09/2026, releve image par image sur les quatre ronds :
       — elles n'arrivent PAS de cote ni d'en bas : leur centre horizontal ne
         bouge pas d'un pixel, elles apparaissent SUR PLACE ;
       — elles grandissent, depassent leur taille d'environ 3% puis se posent ;
       — le tout dure environ 155 ms, du premier pixel a la pose ;
       — et le decalage va DU BAS VERS LE HAUT, d'environ 17 ms : la rangee la
         plus proche du « + » part la premiere.
     Le depassement est dans la courbe (.34,1.3,.64,1), qui passe au-dessus de 1
     puis revient — les 3% mesures sans un troisieme point d'arret. */
  opacity: 0; transform: scale(.72);
  animation: mw-fab-entre .16s cubic-bezier(.34,1.3,.64,1) forwards;
}
/* nth-child(4) est « Trade », en bas ; nth-child(1) est « Send », en haut. */
.mw-fab-act:nth-child(4) { animation-delay: 0s }
.mw-fab-act:nth-child(3) { animation-delay: .017s }
.mw-fab-act:nth-child(2) { animation-delay: .034s }
.mw-fab-act:nth-child(1) { animation-delay: .051s }
@keyframes mw-fab-entre { to { opacity: 1; transform: none; } }
.mw-fab-act i {
  display: grid; place-items: center; width: 112px; height: 112px;
  border-radius: 50%; background: var(--mw-accent); color: var(--mw-accent-ink);
}
.mw-fab-act:active i { transform: scale(.94); }
/* LA BOITE DU « + », AU PIXEL, ET AUCUN FOND. Releve sur la capture de
   reference : l'anneau fait 112 px de diametre, centre a 47 px du bord droit et
   80 px du bas — c'est-a-dire exactement le rond du dock qu'il remplace. Et son
   interieur vaut le meme gris que ce qui l'entoure (23 contre 23-29) : il n'y a
   pas de disque, seulement un trait, si faible qu'on le devine plutot qu'on ne
   le voit. Notre pastille grise de 100 px se remarquait beaucoup trop. */
.mw-fab-fermer {
  position: absolute; right: 47px; bottom: 80px;
  display: grid; place-items: center; width: 112px; height: 112px;
  border-radius: 50%; border: 0; cursor: pointer;
  background: none; box-shadow: inset 0 0 0 2px rgba(255,255,255,.12);
  color: #fff;
}
/* Ceinture et bretelles pour l'anneau de focus : meme si le focus arrive
   autrement que par le clavier, il ne doit pas se voir. `:focus-visible` ne
   s'active qu'a la navigation clavier et garde alors un anneau NET — supprimer
   purement le contour rendrait le menu inutilisable au clavier. */
.mw-fab-act:focus, .mw-fab-fermer:focus { outline: none; }
.mw-fab-act:focus-visible, .mw-fab-fermer:focus-visible {
  outline: 5px solid var(--mw-accent); outline-offset: 9px; border-radius: 70px;
}
@media (prefers-reduced-motion: reduce) {
  .mw-fab-act { animation: none; opacity: 1; transform: none; }
}

/* Voile sous le dock. Il ETEINT le contenu, il ne le supprime pas : sur la
   capture de reference on distingue encore les formes des cartes sous la barre
   de recherche, floutees et tres assombries — pas du noir plein. Je l'avais
   rendu opaque en corrigeant l'inverse (du texte restait lisible dessous) ;
   c'etait une surcorrection, le flou est ce qui manquait.

   Le fondu passe par mask-image et non par le degrade de fond : un
   backdrop-filter s'applique a toute la boite d'un coup, et sans masque le
   flou commencerait net sur une ligne horizontale visible. Le masque fait
   entrer flou ET assombrissement ensemble.

   Repli sans backdrop-filter : le fond masque seul, soit le contenu assombri a
   18% — degrade, pas casse. */
/* LE VOILE DESCEND SOUS LE CANEVAS (25/09/2026). Pose exactement sur le bas
   (`bottom: 0`), il s'arretait sur un iPhone de l'operateur ~2 pixels physiques
   trop tot : une ligne grise #181818 — le fond des cartes, ni voile ni flou —
   entre le bas du wallet et le cadre du telephone. Releve sur sa capture :
   (7,8,9) dans le voile, (23,23,23) sur deux lignes, puis le cadre. C'est
   l'arrondi d'une couche composee (flou d'arriere-plan + masque) dans un
   canevas reduit a une echelle fractionnaire : son bord se cale vers
   l'interieur au pixel pres, le contenu dessous vers l'exterieur, et l'ecart
   depend de la largeur de l'ecran (rien a 402 ni a 440 px au simulateur).
   24 px de canevas SOUS le bas : `.mw` est en overflow:hidden et coupe le
   surplus, le bord arrondi tombe donc hors champ, quelle que soit l'echelle.
   Les paliers du masque passent en px pour ne pas bouger : 126 et 234 px
   depuis le haut, comme 42 % et 78 % de l'ancienne hauteur de 300. */
.mw-veil {
  position: absolute; left: 0; right: 0; bottom: -24px; height: 324px; z-index: 3;
  background: rgba(0,0,0,.82);
  -webkit-backdrop-filter: blur(24px) saturate(120%);
          backdrop-filter: blur(24px) saturate(120%);
  --mw-fondu: linear-gradient(to bottom, rgba(0,0,0,0) 0, rgba(0,0,0,.55) 126px,
              rgba(0,0,0,1) 234px, rgba(0,0,0,1) 100%);
  -webkit-mask-image: var(--mw-fondu); mask-image: var(--mw-fondu);
  pointer-events: none;
}
.mw[data-theme="light"] .mw-veil { background: rgba(255,255,255,.85); }



/* ------------------------------------------------------------- conteneur mis
   à l'échelle : le canevas garde ses 923 px, seul le zoom change — sauf en mode
   natif, où `fitMockup` lui donne aussi sa largeur (style en ligne). */
.mw-frame { position: relative; overflow: hidden; }
.mw-frame > .mw { transform-origin: top left; }

/* =============================================================================
   Tiroir de profil
   -----------------------------------------------------------------------------
   Il vit DERRIERE l'ecran. Ce n'est pas un panneau qui arrive par-dessus :
   c'est l'application qui glisse a droite et se retrecit, exactement comme sur
   la capture ou la bande de wallet reste visible a droite, arrondie.
   ============================================================================= */
.mw-app {
  position: absolute; inset: 0; overflow: hidden;
  background: var(--mw-bg); z-index: 2;
  transform-origin: left center;
  /* .40s ET NON .34s : mesure image par image sur un enregistrement d'ecran de
     l'app de reference, le 21/09/2026. Le bord gauche de l'application ecartee
     atteint 95% de sa course en 225ms et se pose vers 400. Notre courbe
     d'assouplissement, elle, tombait deja juste — a 25% de la duree elle rend
     0,72, la mesure aussi. Seule la duree etait courte. */
  transition: transform .40s cubic-bezier(.32,.72,0,1),
              border-radius .40s cubic-bezier(.32,.72,0,1);
}
.mw[data-drawer="1"] .mw-app {
  /* PAS DE `scale`, ET C'EST UNE MESURE, PAS UN GOUT. On reduisait l'application
     ecartee a 90%. Sur l'enregistrement, les reperes verticaux du wallet pousse
     — haut des cartes a 1233, 1520, 1617, 1851, 2085 — sont IDENTIQUES a ceux
     du wallet plein ecran. Il n'y a donc aucune reduction : c'est une
     translation pure, et la reduction nous faisait mentir de 10%.
     702px et non 710 : le bord gauche se pose a 898 sur 1180 de large, soit
     76,1% — c'est-a-dire 702 sur nos 923 de canevas. */
  transform: translateX(702px);
  border-radius: 62px;
  box-shadow: -40px 0 90px -20px rgba(0,0,0,.75);
}
/* Double role : il assombrit l'application ecartee — sur la capture, la bande
   de wallet visible est nettement eteinte, son solde n'est plus blanc — et il
   recoit la touche qui referme. En opacite plutot qu'en display, pour qu'il
   s'eteigne au meme rythme que le glissement ; pointer-events le rend inerte
   tiroir ferme, sinon il avalerait les touches destinees au wallet. */
.mw-app-voile {
  position: absolute; inset: 0; z-index: 9;
  background: rgba(0,0,0,.5); opacity: 0; pointer-events: none;
  transition: opacity .34s cubic-bezier(.32,.72,0,1);
}
.mw[data-drawer="1"] .mw-app-voile { opacity: 1; pointer-events: auto; }

.mw-drawer {
  position: absolute; left: 0; top: 0; bottom: 0; width: 710px; z-index: 1;
  padding: 185px 55px 0;
  display: flex; flex-direction: column;
  color: var(--mw-text);
}
.mw-dr-top { display: flex; align-items: center; justify-content: space-between; }
.mw-dr-ava, .mw-dr-copie {
  width: 112px; height: 112px; border-radius: 50%;
  background: var(--mw-pill); flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 52px; line-height: 1; overflow: hidden;
}
.mw-dr-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mw-dr-copie { color: var(--mw-text); }

.mw-dr-handle {
  margin-top: 46px;
  font-size: 62px; font-weight: 700; letter-spacing: -1.2px; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mw-dr-x {
  margin-top: 38px; display: flex; align-items: center; gap: 18px;
  color: var(--mw-accent); font-size: 38px; font-weight: 600; letter-spacing: -.2px;
}
.mw-dr-x svg { flex: 0 0 auto; }

.mw-dr-wallet {
  margin-top: 128px; display: flex; align-items: center; gap: 22px;
}
.mw-dr-badge {
  width: 62px; height: 62px; border-radius: 50%; flex: 0 0 auto;
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; font-weight: 600; letter-spacing: .4px;
}
.mw-dr-nom { font-size: 46px; font-weight: 600; letter-spacing: -.4px; }
.mw-dr-wallet svg { color: var(--mw-text); flex: 0 0 auto; margin-left: 4px; }

/* 44 et non 96 : mesure sur la capture, l'ecart entre le centre de la ligne
   de portefeuille et celui de « Profile » est de 152px, soit exactement un
   pas de menu. */
.mw-dr-nav { margin-top: 44px; }
.mw-dr-item {
  display: flex; align-items: center; gap: 48px; height: 152px;
  font-size: 46px; font-weight: 600; letter-spacing: -.4px; color: var(--mw-text);
}
.mw-dr-item svg { flex: 0 0 auto; }
/* Pousse le bloc bas contre le bord : « auto » sur la marge haute est ce qui
   fait le vide de la capture entre History et Settings, quel que soit le
   nombre d'entrees au-dessus. */
.mw-dr-bas { margin-top: auto; padding-bottom: 118px; }

.mw[data-theme="light"] .mw-dr-ava,
.mw[data-theme="light"] .mw-dr-copie,
.mw[data-theme="light"] .mw-dr-badge { background: rgba(0,0,0,.07); }

/* =============================================================================
   Ecran Trade
   -----------------------------------------------------------------------------
   Les deux ecrans coexistent dans le DOM et c'est le CSS qui montre l'un ou
   l'autre : basculer d'onglet ne redessine rien, donc chacun garde sa position
   de defilement, comme dans une vraie app.
   ============================================================================= */
/* visibility et non display : un conteneur passe en display:none perd son
   scrollTop, remis a zero par le navigateur. Mesure — l'ecran Trade defile a
   1200, on repasse sur l'accueil, on revient : 0. Avec visibility l'ecran
   reste dispose, donc il garde sa position, et il ne recoit ni les clics ni le
   focus tant qu'il est cache. */
.mw-ecran { visibility: hidden; }
.mw[data-tab="0"] .mw-ecran--home,
.mw[data-tab="1"] .mw-ecran--trade,
.mw[data-tab="2"] .mw-ecran--predict,
.mw[data-tab="3"] .mw-ecran--explore { visibility: visible; }
/* Pendant un glissement d'onglet, les DEUX écrans concernés sont visibles : le
   sortant et l'entrant se déplacent ensemble sous le doigt. Placée après les
   règles ci-dessus et à spécificité égale, celle-ci gagne. */
.mw .mw-ecran[data-glisse] { visibility: visible; }

/* ------------------------------------------------------------------ chips */
.mw .tk-chips {
  display: flex; gap: 19px; padding: 0 47px; margin-top: 61px;
  overflow-x: auto; scrollbar-width: none;
}
.mw .tk-chips::-webkit-scrollbar { display: none; }
.mw .chip {
  flex: 0 0 auto; display: flex; align-items: center; gap: 15px;
  height: 82px; padding: 0 30px; border-radius: 41px;
  background: var(--mw-pill); color: var(--mw-text);
  font-size: 40px; font-weight: 600; letter-spacing: -.3px; white-space: nowrap;
}
.mw .chip svg { flex: 0 0 auto; }
.mw .chip--menu { gap: 8px; padding: 0 26px 0 30px; height: 74px; border-radius: 37px;
                  font-weight: 500; color: var(--mw-text); }

/* ------------------------------------------------------------------- swap */
/* Colonne, pour que le bouton d'inversion vive DANS l'ecart entre les deux
   cartes. Il etait pose en absolu au centre du bloc, ce qui ne tombe sur la
   couture que si les deux cartes ont la meme hauteur — elles n'en ont pas.
   Et l'ecart lui-meme avait disparu : la regle .swap-carte + .swap-carte ne
   s'appliquait plus depuis que le bouton s'etait glisse entre elles. */
.mw .swap { padding: 0 47px; margin-top: 46px; display: flex; flex-direction: column; }
.mw .swap-carte {
  background: var(--mw-card); border-radius: 44px; padding: 44px 42px 38px;
}

.mw .swap-tete {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 42px; font-weight: 500; color: var(--mw-dim); letter-spacing: -.2px;
}
.mw .swap-regl {
  width: 74px; height: 74px; border-radius: 50%; background: var(--mw-pill);
  display: flex; align-items: center; justify-content: center; color: var(--mw-text);
}
.mw .swap-ligne {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; margin-top: 34px;
}
.mw .swap-val { font-size: 72px; font-weight: 500; line-height: 1; color: #5c5c5c; }
.mw .swap-jeton {
  flex: 0 0 auto; display: flex; align-items: center; gap: 14px;
  height: 74px; padding: 0 18px 0 8px; border-radius: 37px;
  background: var(--mw-pill); color: var(--mw-text);
  font-size: 44px; font-weight: 600; letter-spacing: -.4px;
}
.mw .swap-jeton-ic {
  width: 58px; height: 58px; border-radius: 50%; overflow: hidden;
  background: #0e0e0e; display: block; flex: 0 0 auto;
}
.mw .swap-jeton-ic svg { display: block; width: 100%; height: 100%; }
.mw .swap-jeton-ic--cash { background: var(--mw-accent); padding: 9px; }
.mw .swap-pied {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 30px; color: var(--mw-dim);
  font-size: 40px; font-weight: 400; letter-spacing: .2px;
}
.mw .swap-pied--droite { justify-content: flex-end; }
/* 88 de haut avec -18 de marge en haut et en bas : sa contribution nette a la
   colonne est de 88-36 = 52px, soit exactement l'ecart voulu entre les cartes,
   et son centre tombe au milieu de cet ecart quelles que soient leurs
   hauteurs. */
.mw .swap-inverse {
  align-self: center; position: relative; margin: -18px 0;
  width: 88px; height: 88px; border-radius: 50%; z-index: 2;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; justify-content: center;
}

/* ------------------------------------------------------- liste des jetons */
.mw .tk-titre {
  padding: 0 47px; margin-top: 100px;
  font-size: 55px; font-weight: 700; letter-spacing: var(--mw-ls-head); line-height: 1;
}
.mw .tk-filtres { display: flex; gap: 19px; padding: 0 47px; margin-top: 46px; }
.mw .tk-liste { margin-top: 2px; }
.mw .tk-icon { position: relative; overflow: visible; }
.mw .tk-icon > svg { border-radius: 50%; }
/* Deux jetons de la capture ne sont pas ronds mais carres a coins adoucis :
   leur illustration remplit le carre. Ces regles arrivent apres celles de
   .wrow-icon, a specificite egale — c'est ce qui leur permet de gagner. */
.mw .tk-icon--carre, .mw .tk-icon--carre > svg { border-radius: 18px; }
.mw .tk-rang {
  position: absolute; left: -4px; bottom: -4px; width: 40px; height: 40px;
  display: block;
}
.mw .tk-rang svg { display: block; width: 100%; height: 100%; }
.mw .tk-verif { flex: 0 0 auto; }
.mw .wrow-chg.pos { color: var(--mw-up); }
.mw .wrow-chg.neg { color: var(--mw-down); }

/* =============================================================================
   Ecran Predict
   ============================================================================= */
.mw .pr-titre {
  display: flex; align-items: center; gap: 14px;
  padding: 0 47px; margin-top: 62px;
  font-size: 55px; font-weight: 700; letter-spacing: var(--mw-ls-head); line-height: 1;
  color: var(--mw-text);
}
.mw .pr-titre svg { flex: 0 0 auto; }
.mw .pr-h2 {
  padding: 0 47px; margin-top: 96px;
  font-size: 55px; font-weight: 700; letter-spacing: var(--mw-ls-head); line-height: 1;
}

/* ------------------------------------------------------------- Up or Down */
.mw .pr-ud {
  margin: 44px 47px 0; background: var(--mw-card); border-radius: 44px;
  padding: 44px 40px 40px;
}
.mw .pr-ud-tete { display: flex; align-items: flex-start; gap: 26px; }
.mw .pr-ud-ic { width: 90px; height: 90px; border-radius: 50%; overflow: hidden; flex: 0 0 auto; }
.mw .pr-ud-ic svg { display: block; width: 100%; height: 100%; }
.mw .pr-ud-txt { flex: 1 1 auto; min-width: 0; }
.mw .pr-ud-px { font-size: 50px; font-weight: 600; letter-spacing: -1px; line-height: 1; }
.mw .pr-ud-px sup { font-size: .68em; vertical-align: super; letter-spacing: -.5px; }
.mw .pr-ud-cible { margin-top: 16px; font-size: 42px; color: var(--mw-dim); letter-spacing: -.2px; }
.mw .pr-ud-chrono { flex: 0 0 auto; font-size: 44px; font-weight: 500; letter-spacing: -.4px; }

.mw .pr-ud-graph { height: 250px; margin-top: 42px; }
.mw .pr-ud-graph svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* Le seuil : trait pointille sur toute la largeur, le chevron pose dessus au
   centre et l'etiquette du prix cible calee a droite. Le trait passe DERRIERE,
   d'ou le fond de carte repris sur les deux elements poses dessus. */
.mw .pr-ud-seuil {
  position: relative; height: 62px; margin-top: 26px;
  display: flex; align-items: center; justify-content: flex-end;
}
.mw .pr-ud-seuil::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  border-top: 4px dashed #4a4a4a;
}
.mw .pr-ud-chev {
  position: absolute; left: 50%; transform: translateX(-50%);
  background: var(--mw-card); padding: 0 14px; box-sizing: content-box;
}
.mw .pr-ud-etiq {
  position: relative; background: #d9d9d9; color: #101010;
  font-size: 40px; font-weight: 500; letter-spacing: -.3px;
  padding: 12px 26px; border-radius: 999px;
}

.mw .pr-ud-boutons { display: flex; gap: 26px; margin-top: 34px; }
.mw .pr-ud-b {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 16px;
  height: 84px; border-radius: 42px; background: var(--mw-pill);
  font-size: 44px; font-weight: 500; letter-spacing: -.4px; color: var(--mw-text);
}

/* --------------------------------------------------------- 5 Minute Markets */
.mw .pr-grille {
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px;
  padding: 0 47px; margin-top: 46px;
}
.mw .pr-mini { background: var(--mw-card); border-radius: 36px; padding: 38px 36px 36px; }
.mw .pr-mini-ic {
  width: 92px; height: 92px; border-radius: 50%; overflow: hidden; display: block;
  background: #0b0b0b;
}
.mw .pr-mini-ic svg { display: block; width: 100%; height: 100%; }
.mw .pr-mini-ic--eth { background: #6f7bf0; padding: 18px 24px; }
.mw .pr-mini-sym { margin-top: 38px; font-size: 46px; font-weight: 700; letter-spacing: -.4px; }
.mw .pr-mini-sub { margin-top: 18px; font-size: 40px; color: var(--mw-dim); }

/* ------------------------------------------------------- cartes de marche */
.mw .pr-marche {
  margin: 40px 47px 0; background: var(--mw-card); border-radius: 40px; padding: 38px 34px 34px;
}
.mw .pr-m-tete { display: flex; align-items: center; gap: 26px; }
.mw .pr-m-tete--nu { display: block; }
.mw .pr-m-titre {
  /* 42 et non 44 : a 44, « Nasdaq 100 Year-End 2026 Close » passait a la
     ligne alors qu'il tient sur une seule sur la capture. */
  font-size: 42px; font-weight: 600; letter-spacing: -.4px; line-height: 1.3; color: var(--mw-text);
}
.mw .pr-ic {
  width: 76px; height: 76px; border-radius: 20px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
}
.mw .pr-ic svg { width: 62%; height: 62%; display: block; }

.mw .pr-opt { display: flex; align-items: center; gap: 26px; height: 126px; }
.mw .pr-ava {
  width: 68px; height: 68px; border-radius: 18px; overflow: hidden; flex: 0 0 auto; display: block;
}
.mw .pr-ava--rond { border-radius: 50%; }
.mw .pr-ava svg { display: block; width: 100%; height: 100%; }
.mw .pr-opt-nom {
  flex: 1 1 auto; min-width: 0; font-size: 44px; font-weight: 500; letter-spacing: -.4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mw .pr-pct {
  flex: 0 0 auto; min-width: 148px; text-align: center;
  background: var(--mw-pill); color: var(--mw-dim);
  font-size: 40px; font-weight: 500; padding: 16px 0; border-radius: 22px;
}
.mw .pr-plus {
  margin-top: 16px; height: 84px; border-radius: 42px; background: var(--mw-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 42px; font-weight: 600; letter-spacing: -.3px;
}

.mw .pr-avis {
  padding: 0 47px; margin-top: 74px;
  font-size: 40px; line-height: 1.42; color: var(--mw-dim); letter-spacing: -.2px;
}
.mw .pr-avis a { color: var(--mw-accent); }

/* =============================================================================
   Ecran Explore
   ============================================================================= */
.mw .ex-cat { display: flex; gap: 22px; padding: 0 47px; margin-top: 62px;
              overflow-x: auto; scrollbar-width: none; }
.mw .ex-cat::-webkit-scrollbar { display: none; }
.mw .ex-chip { height: 102px; border-radius: 51px; padding: 0 34px 0 17px; gap: 22px; font-size: 44px; }
.mw .ex-cat-ic {
  width: 68px; height: 68px; border-radius: 20px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
}
.mw .ex-cat-ic svg { width: 64%; height: 64%; display: block; }

.mw .ex-carte {
  margin: 40px 47px 0; background: var(--mw-card); border-radius: 40px; padding: 0 34px;
}

/* ------------------------------------------------------- What's Happening */
.mw .ex-newsbloc { padding: 0 47px; margin-top: 44px; }
.mw .ex-news + .ex-news { margin-top: 56px; }
.mw .ex-news-src { font-size: 40px; color: var(--mw-dim); letter-spacing: -.2px; }
.mw .ex-news-titre {
  margin-top: 26px; font-size: 40px; font-weight: 500; line-height: 1.32;
  letter-spacing: -.4px; color: var(--mw-text);
}
.mw .ex-marque { margin-top: 26px; display: flex; align-items: center; gap: 22px;
                 font-size: 42px; font-weight: 700; color: var(--mw-down); }
.mw .ex-var { font-weight: 600; }

/* ------------------------------------------------------------- Top Traders */
.mw .ex-trow, .mw .ex-srow, .mw .ex-lrow { display: flex; align-items: center; height: 168px; }
.mw .ex-trow-ic, .mw .ex-srow-ic, .mw .ex-lrow-ic {
  position: relative; flex: 0 0 92px; width: 92px; height: 92px; margin-right: 26px;
  display: block;
}
.mw .ex-trow-ic > svg, .mw .ex-srow-ic > svg, .mw .ex-lrow-ic > svg,
.mw .ex-ava { display: block; width: 100%; height: 100%; border-radius: 50%; }
.mw .ex-srow-ic > svg { border-radius: 26px; }
.mw .ex-ava--lettre {
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 46px; font-weight: 500;
}
.mw .ex-trow-main, .mw .ex-srow-main { flex: 1 1 auto; min-width: 0; }
.mw .ex-trow-nom { font-size: 44px; font-weight: 700; letter-spacing: -.4px; }
.mw .ex-trow-pct { margin-top: 14px; font-size: 44px; font-weight: 500; color: var(--mw-up); letter-spacing: -.4px; }
.mw .ex-follow {
  flex: 0 0 auto; height: 76px; padding: 0 38px; border-radius: 38px;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; font-size: 40px; font-weight: 600;
}

/* ---------------------------------------------------------- Trending Sites */
.mw .ex-srow-nom { font-size: 46px; font-weight: 600; letter-spacing: -.4px; }
.mw .ex-srow-cat { margin-top: 14px; font-size: 42px; color: var(--mw-dim); }
.mw .ex-lien {
  flex: 0 0 auto; width: 76px; height: 76px; border-radius: 22px;
  background: var(--mw-pill); color: var(--mw-text);
  display: flex; align-items: center; justify-content: center;
}

/* ------------------------------------------------------------------ Learn */
.mw .ex-lrow-titre { font-size: 46px; font-weight: 600; letter-spacing: -.4px; }
.mw .ex-lrow-sub { margin-top: 14px; font-size: 42px; color: var(--mw-dim); }

/* =============================================================================
   Feuilles du tiroir — Profile, Chats, Watchlist, History
   -----------------------------------------------------------------------------
   Sorties de l'ecran par translation, jamais en display:none : un conteneur
   retire du flux perd son scrollTop, et une feuille qu'on rouvre doit se
   retrouver ou on l'avait laissee.
   ============================================================================= */
.mw-feuille {
  position: absolute; inset: 0; z-index: 6;
  /* LE BAS DE LA FEUILLE S'ARRETE AU BAS DE CE QU'ON VOIT.

     La maquette a un rapport fixe : sur un iPhone de 393 pt de large elle
     mesure 851 px de haut, alors que Safari n'en laisse voir que ~750 — sa
     barre d'adresse mange le reste. Le bas de la maquette passe donc DERRIERE
     cette barre, et avec lui tout ce qui s'y colle : la barre d'action de la
     fiche d'un jeton (`.je-pied`, sticky bottom:0) semblait posee au milieu de
     nulle part, et la fin d'une feuille etait inatteignable.

     La longhand doit rester APRES `inset` — a specificite egale, c'est la
     derniere declaration qui gagne, et `inset` remettrait le bas a zero.

     `0px` par defaut, et c'est le point important : sans la variable — app
     posee sur l'ecran d'accueil, moteur monte ailleurs, script en panne — on
     retombe EXACTEMENT sur le rendu d'avant. La variable est posee par
     app.html, en pixels de canevas, et vaut zero des qu'il n'y a rien de
     cache. */
  /* LE PLAFOND EST ICI AUSSI, ET PAS SEULEMENT DANS LE SCRIPT QUI ECRIT LA
     VARIABLE. app.html borne deja sa mesure a 260 px de canevas, mais un garde-
     fou qui ne vit que du cote de l'ecrivain ne protege personne du jour ou un
     autre appelant, une version en cache ou une mesure aberrante ecrit autre
     chose : le CSS, lui, obeit sans discuter. `clamp` rend l'echouage
     impossible, quelle que soit la valeur recue — au pire la feuille perd 10 %
     de sa hauteur, jamais le quart ni la moitie. */
  bottom: clamp(0px, var(--mw-cache-bas, 0px), 200px);
  background: var(--mw-bg); color: var(--mw-text);
  overflow-y: auto; overflow-x: hidden; scrollbar-width: none;
  overscroll-behavior: contain;
  transform: translateY(100%); visibility: hidden;
  transition: transform .36s cubic-bezier(.32,.72,0,1), visibility 0s .36s;
}
.mw-feuille::-webkit-scrollbar { width: 0; }
.mw[data-feuille="profile"]   .mw-feuille[data-feuille="profile"],
.mw[data-feuille="chats"]     .mw-feuille[data-feuille="chats"],
.mw[data-feuille="watchlist"] .mw-feuille[data-feuille="watchlist"],
.mw[data-feuille="history"]   .mw-feuille[data-feuille="history"],
.mw[data-feuille="tokens"]    .mw-feuille[data-feuille="tokens"],
.mw[data-feuille="token"]     .mw-feuille[data-feuille="token"],
.mw[data-feuille="perps"]     .mw-feuille[data-feuille="perps"],
.mw[data-feuille="search"]    .mw-feuille[data-feuille="search"],
.mw[data-feuille="cash"]      .mw-feuille[data-feuille="cash"],
.mw[data-feuille="comptes"]   .mw-feuille[data-feuille="comptes"],
.mw[data-feuille="gerer"]     .mw-feuille[data-feuille="gerer"],
.mw[data-feuille="avatar"]    .mw-feuille[data-feuille="avatar"],
/* « Receive » MANQUAIT A CETTE LISTE, et c'est tout le defaut : la feuille
   etait rendue, sa bascule fonctionnait au banc, et le bouton du menu posait
   bien `data-feuille="receive"` — mais aucune regle ne la faisait remonter,
   donc elle restait a `translateY(100%)`, hors champ. Rien ne s'ouvrait, et
   rien n'echouait non plus : c'est exactement la panne qu'un banc de la
   bascule ne pouvait pas voir.
   Une enumeration ne se relit pas a l'oeil a chaque ajout : `tools/feuilles_check.py`
   la compare desormais aux feuilles rendues par mockup.js, et la pre-poussee
   refuse un ecran qui ne pourrait pas s'ouvrir. */
.mw[data-feuille="receive"]   .mw-feuille[data-feuille="receive"],
.mw[data-feuille="send"]      .mw-feuille[data-feuille="send"],
.mw[data-feuille="trade"]     .mw-feuille[data-feuille="trade"] {
  transform: none; visibility: visible;
  transition: transform .36s cubic-bezier(.32,.72,0,1), visibility 0s;
}
/* Plein ecran (Profile, Chats) : la croix remplace la poignee. */
.mw .fe--plein { padding: 150px 47px 0; }
/* Demi-feuille (Watchlist, History, Comptes) : poignee en haut, comme une
   feuille iOS.

   LE DEGAGEMENT DU HAUT N'EST PAS DECORATIF. Ces feuilles couvrent tout l'ecran
   (`inset: 0` sur .mw-feuille), pas seulement le bas : sans padding, la poignee
   se retrouvait a 34 px du bord et l'en-tete a 77 — c'est-a-dire SOUS la barre
   d'etat de l'iPhone, la croix collee a l'heure. Les onglets de l'accueil, eux,
   commencent a 157. On aligne donc l'en-tete sur cette meme ligne, et la
   poignee se pose juste au-dessus. */
.mw .fe--sheet { padding: 80px 47px 0; }
.mw .fe--sheet .fe-tete { margin-top: 30px; }

/* LA POIGNEE FERME LA FEUILLE, ET ELLE DOIT DONC SE TOUCHER.
   Elle mesure 78 x 9 au canevas, soit environ deux pixels de haut sur la
   demonstration d'ordinateur : c'etait la SEULE sortie de ces feuilles a la
   souris — Echap marche, mais rien ne le dit, et on ne devine pas une touche.
   Constat du proprietaire sur /demo : « je viens d'ouvrir ca et je ne peux pas
   le fermer ».
   On lui donne donc une zone de prehension a sa mesure : toute la bande du haut
   de la feuille, invisible, portee par un pseudo-element. Le trait dessine ne
   bouge pas d'un pixel — c'est la cible qui grandit, pas le decor.
   Les debords lateraux sont rognes par `overflow-x: hidden` de `.mw-feuille` :
   ils ne fabriquent donc aucune barre de defilement. Et `bottom` s'arrete bien
   avant l'element suivant, qui commence 58 px plus bas. */
.mw .fe-poignee {
  display: block; width: 83px; height: 12px; border-radius: 6px;
  background: #4a4a4a; margin: 34px auto 0;
  position: relative; cursor: pointer;
}
.mw .fe-poignee::after {
  content: ""; position: absolute; left: -500px; right: -500px;
  top: -34px; bottom: -34px;
}
.mw .fe-tete { display: flex; align-items: center; gap: 30px; }
.mw .fe-tete-txt { display: flex; flex-direction: column; gap: 6px; }
.mw .fe-tete-sub { font-size: 40px; color: var(--mw-dim); letter-spacing: -.2px; }
.mw .fe-x {
  flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-text);
  display: flex; align-items: center; justify-content: center;
}
.mw .fe-titre-l { font-size: 50px; font-weight: 700; letter-spacing: -.8px; }
.mw .fe-titre {
  margin-top: 34px; font-size: 74px; font-weight: 800; letter-spacing: -1.6px; line-height: 1.05;
}
.mw .fe-titre--haut { margin-top: 78px; }
.mw .fe-chapo {
  margin-top: 26px; font-size: 45px; line-height: 1.34; color: var(--mw-text);
  letter-spacing: -.4px;
}
.mw .fe-rond {
  width: 110px; height: 110px; border-radius: 50%; margin-top: 58px;
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
}
.mw .fe-h2 { margin-top: 78px; font-size: 55px; font-weight: 700; letter-spacing: -.6px; }
.mw .fe-h2--serre { margin-top: 44px; }

/* ------------------------------------------------------------------ profil */
.mw .fe-moi { display: flex; align-items: center; gap: 36px; margin-top: 44px; }
.mw .fe-ava {
  flex: 0 0 152px; width: 152px; height: 152px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 60px; font-weight: 500;
}
.mw .fe-ava--av { font-size: 84px; overflow: hidden; }
.mw .fe-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mw .fe-stats { flex: 1 1 auto; display: flex; justify-content: space-between; gap: 24px; }
.mw .fe-stats > div { display: flex; flex-direction: column; gap: 14px; }
.mw .fe-stat-l { font-size: 40px; color: var(--mw-dim); letter-spacing: -.2px; }
.mw .fe-stat-v { font-size: 46px; font-weight: 600; letter-spacing: -.4px; }
.mw .fe-boutons { display: flex; gap: 26px; margin-top: 52px; }
.mw .fe-bouton {
  flex: 1 1 0; height: 104px; border-radius: 52px; background: var(--mw-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 44px; font-weight: 600; letter-spacing: -.4px;
}
.mw .fe-act { margin-top: 44px; }
.mw .fe-act-tete { display: flex; align-items: flex-start; gap: 22px; }
.mw .fe-act-n {
  flex: 0 0 60px; width: 60px; height: 60px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 32px; font-weight: 600;
}
.mw .fe-act-txt { flex: 1 1 auto; min-width: 0; }
.mw .fe-act-l { font-size: 44px; line-height: 1.28; letter-spacing: -.4px; }
.mw .fe-act-l b { font-weight: 700; }
.mw .fe-act-h { display: block; margin-top: 10px; font-size: 40px; color: var(--mw-dim); }
.mw .fe-act-plus { flex: 0 0 auto; font-size: 46px; color: var(--mw-dim); line-height: .6; }
.mw .fe-carte {
  margin-top: 26px; background: var(--mw-card); border-radius: 40px; padding: 34px 30px 26px;
}
.mw .fe-carte-tete { display: flex; align-items: center; gap: 26px; }
.mw .fe-carte-ic { width: 90px; height: 90px; border-radius: 50%; overflow: hidden; flex: 0 0 auto; }
.mw .fe-carte-ic svg { display: block; width: 100%; height: 100%; }
.mw .fe-carte-nom { flex: 1 1 auto; font-size: 46px; font-weight: 700; letter-spacing: -.4px; }
.mw .fe-buy {
  flex: 0 0 auto; height: 80px; padding: 0 42px; border-radius: 40px;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; font-size: 42px; font-weight: 600;
}
.mw .fe-vide {
  display: flex; flex-direction: column; align-items: center; gap: 26px;
  padding: 46px 40px 40px; text-align: center;
  font-size: 42px; line-height: 1.32; color: var(--mw-dim);
}
.mw .fe-carte-pied {
  display: flex; gap: 34px; padding-top: 18px; color: var(--mw-dim);
}

/* ------------------------------------------------------------------- chats */
.mw .fe-rail { display: flex; gap: 26px; margin-top: 30px; }
.mw .fe-carte--tend { flex: 0 0 88%; margin-top: 0; padding: 8px 30px; }
.mw .fe-carte--coupee { flex: 0 0 88%; height: 100px; }
.mw .fe-trow { display: flex; align-items: center; gap: 26px; height: 156px; }
.mw .fe-trow-ic { flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%; overflow: hidden; }
.mw .fe-trow-ic svg { display: block; width: 100%; height: 100%; }
.mw .fe-trow-main { flex: 1 1 auto; min-width: 0; }
.mw .fe-trow-nom { font-size: 46px; font-weight: 700; letter-spacing: -.4px; }
.mw .fe-trow-mc { margin-top: 12px; font-size: 42px; font-weight: 600; }
.mw .fe-trow-mc span { color: var(--mw-dim); font-weight: 400; }
.mw .fe-gens {
  flex: 0 0 auto; display: flex; align-items: center; gap: 14px;
  font-size: 44px; font-weight: 600; color: var(--mw-text);
}
.mw .fe-gens svg { color: var(--mw-dim); }
.mw .fe-neant {
  display: flex; flex-direction: column; align-items: center; gap: 30px;
  margin-top: 96px; font-size: 44px; color: var(--mw-dim);
}

/* --------------------------------------------------------- watchlist / historique */
.mw .fe-chips { display: flex; gap: 22px; margin-top: 40px; overflow-x: auto; scrollbar-width: none; }
.mw .fe-chips::-webkit-scrollbar { display: none; }
.mw .fe-chip { height: 88px; padding: 0 36px; border-radius: 44px; font-size: 44px; font-weight: 600; }
.mw .fe-chip.is-on { background: #f2f2f2; color: #101010; }
.mw .fe-chip--actif { background: var(--mw-accent); color: var(--mw-accent-ink); }
.mw .fe-watch { padding: 0; margin-top: 26px; }
.mw .fe-mois { margin-top: 46px; font-size: 50px; font-weight: 700; letter-spacing: -.6px; }
.mw .fe-hist { margin-top: 18px; }
.mw .fe-hrow { display: flex; align-items: center; gap: 26px; height: 152px; }
.mw .fe-hrow-ic { flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%; overflow: hidden; }
.mw .fe-hrow-ic svg { display: block; width: 100%; height: 100%; }
.mw .fe-hrow-main { flex: 1 1 auto; min-width: 0; }
.mw .fe-hrow-t { font-size: 46px; font-weight: 600; letter-spacing: -.4px; }
.mw .fe-hrow-s { margin-top: 12px; font-size: 42px; color: var(--mw-dim); }
.mw .fe-hrow-v { flex: 0 0 auto; font-size: 44px; font-weight: 600; color: var(--mw-up); }

/* ------------------------------------------ feuille « Tokens » et fiche jeton */
.mw .fe-barre { display: flex; align-items: center; gap: 30px; margin-top: 34px; }
.mw .fe-barre .fe-titre-l { flex: 1 1 auto; }
.mw .fe-regl {
  flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-text);
  display: flex; align-items: center; justify-content: center;
}
.mw .fe-tot {
  margin-top: 44px; font-size: var(--mw-f-balance); font-weight: 700;
  letter-spacing: var(--mw-ls-balance); line-height: 1;
}
.mw .fe-tot-delta {
  display: flex; align-items: center; gap: 26px; margin-top: 30px;
  font-size: var(--mw-f-delta); font-weight: 600; letter-spacing: var(--mw-ls-delta);
}
.mw .fe-tot-delta .pct { padding: 10px 18px; border-radius: 14px; color: var(--mw-accent-ink); }
.mw .fe-tot-delta.is-up   { color: var(--mw-up); }
.mw .fe-tot-delta.is-down { color: var(--mw-down); }
.mw .fe-tot-delta.is-up   .pct { background: var(--mw-up); }
.mw .fe-tot-delta.is-down .pct { background: var(--mw-down); }
.mw .fe-liste { margin-top: 46px; }

/* ------------------------------------------------------------- fiche jeton */
/* Deux couleurs INDEPENDANTES : la courbe suit le sens de la plage tracee, la
   variation suit son propre signe. Les lier peignait « +0,91% » en rouge parce
   que la courbe des 24 dernieres heures descendait. */
.mw .je-graph { color: var(--mw-up); }
.mw .je-graph.est-bas { color: var(--mw-down); }
.mw .fe-barre--jeton .je-ic {
  flex: 1 1 auto; width: 92px; height: 92px; max-width: 92px;
  border-radius: 50%; overflow: hidden; margin-right: auto;
}
.mw .fe-barre--jeton .je-ic svg, .mw .fe-barre--jeton .je-ic img { display: block; width: 100%; height: 100%; }
.mw .je-nom {
  display: flex; align-items: center; gap: 18px; margin-top: 40px;
  font-size: 74px; font-weight: 800; letter-spacing: -1.6px; line-height: 1;
  color: var(--mw-text);
}
.mw .je-nom svg { color: var(--mw-dim); }
.mw .je-px {
  margin-top: 18px; font-size: 74px; font-weight: 800;
  letter-spacing: -1.6px; line-height: 1; color: var(--mw-text);
}
.mw .je-var { margin-top: 22px; font-size: 46px; font-weight: 600; letter-spacing: -.4px;
              color: var(--mw-up); }
.mw .je-var.est-bas { color: var(--mw-down); }

.mw .je-graph { height: 300px; margin: 66px 0 0; }
.mw .je-graph svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* =============================================================================
   LE BALAYAGE DE LA COURBE
   -----------------------------------------------------------------------------
   Poser le doigt sur le graphe montre l'instant vise : une verticale, un point
   sur la courbe, une bulle d'heure, et le cours du haut qui prend la valeur de
   cet instant. Ce qui vient APRES s'eteint, ce qui vient avant garde sa couleur.

   `touch-action: none` est indispensable : sans lui, iOS reserve le geste au
   defilement et aucun `pointermove` n'arrive. C'est aussi pour cela que le
   glissement de feuille de `brancheGestes` laisse passer ce qui commence ici —
   deux gestes ne peuvent pas se partager un meme doigt.
   ============================================================================= */
.mw .je-graph { position: relative; touch-action: none; }
/* UNE APP NE SE SELECTIONNE PAS, ET RIEN NE L'INTERDISAIT ICI. Constate au
   simulateur le 22/09/2026 : un appui prolonge sur la courbe faisait selectionner
   le texte de la bulle d'heure, et iOS affichait sa loupe et son menu PAR-DESSUS
   le telephone, debordant du cadre. Le defaut n'etait pas propre au graphe — la
   maquette entiere se selectionnait, ce qu'aucune application native ne fait.
   Les champs de saisie, eux, gardent leur selection : on y tape. */
.mw { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.mw input, .mw textarea,
/* ET CE QUI DEVIENT EDITABLE SUR PLACE — mais PAS pour la raison que ce
   commentaire donnait d'abord, et la correction vaut d'etre ecrite.

   LA LIGNE. Le @ ne s'edite pas dans un champ : `app.html` pose
   `contentEditable` sur « Username » (Profil > Manage Profile). L'exception du
   dessus, qui ne nomme que `input` et `textarea`, ne la couvrait donc pas.

   CE QUE J'AI CRU, ET QUI EST FAUX. J'ai ecrit ici que le curseur ne se posait
   nulle part et que taper n'ecrivait nulle part. Mesure au simulateur iPhone 17,
   iOS 27, sur les DEUX versions de cette feuille : sans la regle, le champ prend
   quand meme le focus, la selection posee par le script tient, le clavier
   s'ouvre et la frappe arrive. Les deux moteurs forcent `-webkit-user-modify:
   read-write` sur un hote d'edition, quoi que dise `user-select`. Ma mesure
   d'origine avait ete prise dans un document SANS FOCUS, ou Chromium refuse de
   deplacer `activeElement` — un artefact de banc, pas un defaut du produit.

   CE QUI EST VRAI, ET MESURE. Sans la regle, un appui long DANS le champ ne
   donne RIEN : ni poignees de selection, ni menu. Avec elle, iOS affiche ses
   deux poignees bleues puis « Couper / Copier / Coller ». Autrement dit, sans
   elle on ne peut que tout reecrire : ni poser un curseur a la main, ni corriger
   une lettre, ni COLLER un @ qu'on vient de copier ailleurs. C'est cela que la
   regle repare, et c'est assez pour la garder. */
.mw [contenteditable="true"] {
  -webkit-user-select: auto; user-select: auto; -webkit-touch-callout: default;
}
/* Rien ne se voit au repos : ces trois-la n'existent que sous le doigt. */
.mw .je-regle, .mw .je-curseur { opacity: 0; }
.mw .je-graph.est-scrute .je-regle, .mw .je-graph.est-scrute .je-curseur { opacity: 1; }
.mw .je-regle { stroke: #6f6f6f; stroke-width: 2; }
/* Le trait complet s'eteint sous le doigt ; `.je-avant` garde la couleur. */
.mw .je-graph.est-scrute .je-trait { stroke: #4a4a4a; }
.mw .je-avant { stroke: currentColor; }
.mw .je-base { stroke: #3a3a3a; stroke-width: 2; stroke-dasharray: 6 10; }
.mw .je-instant {
  position: absolute; top: 6px; transform: translateX(-50%);
  padding: 12px 26px; border-radius: 34px; background: #2a2a2a; color: #f2f2f2;
  font-size: 36px; font-weight: 600; letter-spacing: -.2px; line-height: 1;
  white-space: nowrap; opacity: 0; pointer-events: none;
}
.mw .je-graph.est-scrute .je-instant { opacity: 1; }

.mw .je-plages { display: flex; align-items: center; gap: 12px; margin-top: 62px; }
.mw .je-plage {
  flex: 1 1 0; justify-content: center; height: 78px; padding: 0;
  border-radius: 39px; background: none; color: var(--mw-dim);
  font-size: 42px; font-weight: 600; letter-spacing: .4px;
}
.mw .je-plage.is-on { background: #f2f2f2; color: #101010; }
.mw .je-bougies { flex: 0 0 auto; padding-left: 10px; color: var(--mw-text); display: flex; }

.mw .je-h2 { margin-top: 74px; color: var(--mw-text); }
.mw .je-pos { display: flex; align-items: center; gap: 26px; height: 164px; color: var(--mw-text); }
.mw .je-pos-ic { flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%; overflow: hidden; }
.mw .je-pos-ic svg, .mw .je-pos-ic img { display: block; width: 100%; height: 100%; }
.mw .je-pos-main { flex: 1 1 auto; min-width: 0; }
.mw .je-pos-t { display: flex; align-items: baseline; gap: 14px; font-size: 46px; letter-spacing: -.4px; }
.mw .je-pos-t b { font-weight: 700; }
.mw .je-pos-t span { color: var(--mw-dim); font-weight: 400; }
.mw .je-pos-q { margin-top: 12px; font-size: 42px; color: var(--mw-dim); }
.mw .je-pos-side { flex: 0 0 auto; text-align: right; }
.mw .je-pos-v { font-size: 46px; font-weight: 600; letter-spacing: -.6px; }
.mw .je-pos-d { margin-top: 12px; font-size: 42px; font-weight: 500; color: var(--mw-up); }
.mw .je-pos-d.est-bas { color: var(--mw-down); }
.mw .je-pos > svg { color: var(--mw-dim); flex: 0 0 auto; }

.mw .je-chat { display: flex; align-items: center; margin-top: 46px; color: var(--mw-text); }
.mw .je-chat-t {
  flex: 1 1 auto; display: flex; align-items: center; gap: 14px;
  font-size: 55px; font-weight: 700; letter-spacing: -.6px;
}
.mw .je-chat-n { flex: 0 0 auto; font-size: 44px; font-weight: 500; color: var(--mw-up); }
.mw .je-tail { height: 220px; }

/* Barre d'action collée en bas, comme sur la capture.

   ELLE N'EST PLUS `sticky`, ET C'EST LA CORRECTION. Collée en `sticky` dans la
   feuille qui défile, sa position dépendait du défilement, de la hauteur du
   contenu et du comportement de `position: sticky` sous un ancêtre
   `transform: scale()` — combinaison fragile sur WebKit. D'où le défaut signalé
   deux fois : la barre posée au milieu de l'écran, par-dessus la courbe, le
   contenu continuant dessous. Le banc Chromium ne l'a jamais reproduit, ce qui
   est la signature d'un défaut de moteur et non de mise en page.

   Ancrée au canevas, elle est là où on la met, partout, toujours. Voir le
   commentaire de `renderMockup` pour le détail. */
.mw .je-pied, .mw .pe-pied {
  position: absolute; left: 0; right: 0; z-index: 7;
  bottom: clamp(0px, var(--mw-cache-bas, 0px), 200px);
  display: flex; align-items: center; gap: 26px;
  padding: 22px 47px calc(52px + env(safe-area-inset-bottom));
  background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, var(--mw-bg) 34%);
  /* SORTIE PAR TRANSLATION SEULE, SANS `visibility`. `.mw` est en
     `overflow: hidden` : une barre poussée sous le bas du canevas est déjà hors
     de vue. Une transition retardée sur `visibility` avait été écrite en plus —
     et mesurée fausse au banc : la barre du jeton restait visible sur la
     feuille « tokens », celle des perps restait visible une fois la feuille
     fermée, et un aller-retour entre deux feuilles laissait la barre du jeton à
     la fois « visible » et encore translatée hors du canevas. Deux propriétés
     d'état qui se transitionnent à des rythmes différents, c'est deux états à
     lire là où un seul suffit. `pointer-events` suit le transform, pour qu'une
     barre hors champ n'attrape aucun doigt. */
  transform: translateY(130%); pointer-events: none;
  transition: transform .36s cubic-bezier(.32,.72,0,1);
}
.mw[data-feuille="token"] .je-pied,
.mw[data-feuille="perps"] .pe-pied { transform: none; pointer-events: auto; }
.mw .je-cap {
  flex: 1 1 auto; height: 112px; border-radius: 56px; background: var(--mw-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 44px; font-weight: 600; color: var(--mw-text); letter-spacing: -.4px;
}
.mw .je-cap span { color: var(--mw-dim); font-weight: 400; margin-left: 12px; }
.mw .je-trade {
  flex: 0 0 auto; height: 112px; padding: 0 62px; border-radius: 56px;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; font-size: 46px; font-weight: 700;
}

/* ------------------------------------------------------------ feuille Perps */
.mw .pe-tot { margin-top: 40px; }
.mw .pe-carte { margin-top: 46px; background: var(--mw-card); border-radius: 40px; padding: 34px 30px; }
.mw .pe-fonds {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  font-size: 46px; font-weight: 500; letter-spacing: -.4px; color: var(--mw-text);
}
.mw .pe-fonds svg { color: var(--mw-dim); vertical-align: -4px; margin-left: 8px; }
.mw .pe-fonds-v { font-weight: 600; }
.mw .pe-add {
  display: flex; align-items: center; justify-content: center;
  height: 96px; margin-top: 30px; border-radius: 48px;
  background: var(--mw-pill); color: var(--mw-text);
  font-size: 46px; font-weight: 600; letter-spacing: -.4px;
}
.mw .pe-promo { position: relative; display: flex; align-items: center; gap: 20px; padding: 40px 30px 34px; }
.mw .pe-promo-x { position: absolute; right: 30px; top: 30px; color: var(--mw-dim); }
.mw .pe-promo-txt { flex: 1 1 auto; min-width: 0; }
.mw .pe-promo-k {
  font-size: 36px; font-weight: 700; letter-spacing: 2px; color: var(--mw-dim);
}
.mw .pe-promo-t {
  margin-top: 18px; font-size: 50px; font-weight: 600; line-height: 1.24;
  letter-spacing: -.5px; color: var(--mw-text); max-width: 86%;
}
.mw .pe-promo-l {
  margin-top: 26px; display: flex; align-items: center; gap: 12px;
  font-size: 46px; font-weight: 600; color: var(--mw-accent);
}
.mw .pe-promo-ill { flex: 0 0 200px; width: 200px; align-self: center; margin-right: -8px; }

.mw .pe-titre { margin-top: 74px; }
/* DEUX rangees qui defilent lateralement, pas un retour a la ligne libre :
   sur la capture la quatrieme pastille de chaque rangee est coupee par le
   bord, ce qui n'arrive qu'avec un defilement horizontal. En flex-wrap on
   obtenait trois rangees completes, ce qui n'est pas la meme mise en page. */
.mw .pe-chips {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto);
  justify-content: start; gap: 20px; margin-top: 36px;
  overflow-x: auto; scrollbar-width: none;
}
.mw .pe-chips::-webkit-scrollbar { display: none; }
.mw .pe-chip { height: 86px; padding: 0 30px; border-radius: 43px; gap: 16px; font-size: 44px; }

.mw .pe-liste { margin-top: 22px; }
.mw .pe-row { display: flex; align-items: center; height: 158px; }
.mw .pe-row-ic {
  position: relative; flex: 0 0 92px; width: 92px; height: 92px; margin-right: 26px;
  display: block; overflow: visible;
}
.mw .pe-row-ic > svg, .mw .pe-row-ic > img { display: block; width: 100%; height: 100%; border-radius: 50%; }
.mw .pe-row-main { flex: 1 1 auto; min-width: 0; }
.mw .pe-row-t { display: flex; align-items: center; gap: 18px; }
.mw .pe-row-s { font-size: 46px; font-weight: 700; letter-spacing: -.4px; }
.mw .pe-lev {
  height: 52px; padding: 0 16px; border-radius: 16px; background: var(--mw-chip);
  display: flex; align-items: center; font-size: 36px; font-weight: 600;
}
.mw .pe-row-v { margin-top: 14px; font-size: 42px; color: var(--mw-dim); }
.mw .pe-row-side { flex: 0 0 auto; text-align: right; }
.mw .pe-tail { height: 240px; }

/* Long / Short : même barre ancrée que celle de la fiche d'un jeton, réglée
   avec elle plus haut dans cette feuille. Elle souffrait exactement du même
   défaut, pour exactement la même raison — elle n'avait simplement jamais été
   signalée, la feuille Perps étant moins visitée. */
.mw .pe-long, .mw .pe-short {
  flex: 1 1 0; height: 112px; border-radius: 56px;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 46px; font-weight: 700; letter-spacing: -.4px;
}

/* --------------------------------------------------------------- recherche */
/* Un vrai champ, pas un texte : sans lui aucun clavier ne s'ouvre. Il est
   dessine pour se confondre avec la pastille qui l'entoure. */
.mw .mw-search-champ {
  flex: 1 1 auto; min-width: 0; width: 100%;
  background: none; border: 0; outline: none; padding: 0;
  color: var(--mw-text); font: inherit; letter-spacing: inherit;
  -webkit-appearance: none; appearance: none;
}
.mw .mw-search-champ::placeholder { color: #8b8b8b; opacity: 1; }
.mw .mw-search-champ::-webkit-search-cancel-button { display: none; }

/* Le « + » devient une croix : c'est la MEME pastille tournee d'un quart de
   tour, donc le passage de l'une a l'autre se fait sans a-coup. */
.mw-fermer-recherche {
  flex: 0 0 112px; width: 112px; height: 112px; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff;
  display: none; align-items: center; justify-content: center;
}
.mw-fermer-recherche svg { transform: rotate(45deg); }
.mw[data-feuille="search"] .mw-plus { display: none; }
.mw[data-feuille="search"] .mw-fermer-recherche { display: flex; }

/* Le dock passe AU-DESSUS de la feuille pendant la recherche : sur la capture
   le champ flotte sur la liste, il n'est pas recouvert par elle. */
.mw[data-feuille="search"] .mw-dock { z-index: 8; }
.mw[data-feuille="search"] .mw-veil { z-index: 7; }
/* Remonte avec le clavier. La variable est posee par le script, qui seul
   connait la hauteur reellement occupee — elle varie avec la langue, la barre
   de suggestions et le clavier choisi. */
.mw .mw-dock, .mw .mw-veil { transition: transform .22s ease-out; }
.mw[data-feuille="search"] .mw-dock,
.mw[data-feuille="search"] .mw-veil { transform: translateY(calc(var(--mw-clavier, 0px) * -1)); }

/* ET LES DEUX FEUILLES QUI ONT UN CHAMP EN BAS. « Send » et « Trade » sont des
   colonnes fermees — `overflow: hidden`, le champ en dernier enfant, la liste
   en `flex: 1 1 auto` — et rien au-dessus d'elles ne defile : la scene est
   `position: fixed`. Le champ qu'on vient de toucher se retrouvait donc DERRIERE
   le clavier, sans aucun moyen de le faire remonter. Seule la recherche etait
   compensee.
   Un rembourrage bas, pas une translation : la boite de contenu retrecit par le
   bas, la liste prend le retrait (elle est la seule extensible) et le champ
   monte exactement de la hauteur du clavier — sans jamais sortir de la feuille,
   ce qu'une translation ferait des que le clavier est haut.
   Le plafond est ici ET dans le script : une variable ecrite par du JS doit
   etre bornee la ou elle est LUE, sinon la mise en page depend du bon vouloir
   d'une ligne de code. 1400 canevas = 70 % de la hauteur, bien au-dela de tout
   clavier reel. */
.mw[data-feuille="send"] .fe--envoyer,
.mw[data-feuille="trade"] .fe--troc {
  padding-bottom: calc(80px + min(var(--mw-clavier, 0px), 1400px));
}

.mw .fe--recherche { padding-top: 0; }
.mw .re-bloc { margin-top: 54px; }
.mw .re-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; }
.mw .re-h2 { margin-top: 0; }
.mw .re-vider { font-size: 46px; font-weight: 500; color: var(--mw-dim); letter-spacing: -.4px; }
.mw .re-liste { margin-top: 10px; }
.mw .re-row { height: 156px; }
/* De quoi ne jamais laisser la derniere ligne sous le champ de recherche. */
/* Le mot n'apparait QUE si le filtre ne laisse rien : une liste vide sans
   phrase se lit comme un ecran casse. Meme geste que `.en-rien` du Send. */
.mw .re-rien {
  display: none; margin: 62px 0 0; color: var(--mw-dim);
  font-weight: 500; font-size: 40px; line-height: 1;
}
.mw .fe--recherche.est-vide .re-rien { display: block; }
/* Les surfaces qu'on vient de brancher le disent au curseur : sur ordinateur,
   une main est la seule facon de savoir qu'on peut appuyer. */
.mw .ca-row, .mw .je-trade, .mw .pe-long, .mw .pe-short,
.mw .rc-bouton, .mw .co-qr { cursor: pointer; }
.mw .re-tail { height: 300px; }

/* Etat vide de la courbe, salon et « About » de la fiche. */
.mw .je-vide {
  display: flex; flex-direction: column; align-items: center; gap: 26px;
  height: 300px; justify-content: center; margin-top: 66px;
  font-size: 42px; color: var(--mw-dim); text-align: center;
}
/* =============================================================================
   `hidden` DOIT CACHER, MEME EN FLEX
   -----------------------------------------------------------------------------
   `[hidden] { display: none }` vient de la feuille du NAVIGATEUR, et dans la
   cascade une declaration d'AUTEUR la bat toujours — la specificite n'y change
   rien. Toute ligne de la maquette posee en `display: flex` restait donc a
   l'ecran une fois marquee `hidden` : le filtre de la recherche marquait les
   lignes sans en cacher une seule, et celui de « Send » faisait pareil depuis
   bien plus longtemps. Les deux donnaient l'illusion de marcher, parce que le
   cas « aucune correspondance » repliait le bloc entier, lui, et affichait sa
   phrase.

   `!important` n'est pas un raccourci ici : c'est la seule facon de dire que
   l'attribut l'emporte sur le dessin, ce que la feuille du navigateur ne peut
   pas faire. Le depot connaissait deja ce piege — app.html le documente deux
   fois, pour `.cpt` et pour `.pwa` — mais la maquette, elle, n'avait rien.

   La regle est GLOBALE a la maquette exprès : la poser ligne par ligne, c'est
   la reposer a chaque nouvelle liste, et l'oublier une fois. */
.mw [hidden] { display: none !important; }

.mw .je-vide[hidden], .mw .je-graph[hidden],
.mw .je-pos[hidden], .mw .je-pos-titre[hidden] { display: none; }
.mw .je-sym {
  font-size: 46px; font-weight: 500; color: var(--mw-dim);
  letter-spacing: -.4px; margin-left: 16px;
}
.mw .je-sym:empty { display: none; }
.mw .je-bulle {
  display: flex; align-items: center; gap: 26px; margin-top: 30px;
  background: var(--mw-card); border-radius: 36px; padding: 30px 34px;
}
.mw .je-bulle-a {
  flex: 0 0 66px; width: 66px; height: 66px; border-radius: 50%;
  background: var(--mw-pill); display: flex; align-items: center;
  justify-content: center; font-size: 34px;
}
.mw .je-bulle-t {
  min-width: 0; font-size: 44px; color: var(--mw-text); letter-spacing: -.4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mw .je-about {
  display: flex; align-items: center; gap: 12px; margin-top: 56px;
  font-size: 55px; font-weight: 700; letter-spacing: -.6px; color: var(--mw-text);
}
.mw .je-about b { font-weight: 700; }

/* ------------------------------------------------------------- feuille Cash */
.mw .ca-vide { flex: 1 1 auto; }
.mw .ca-tete { display: flex; align-items: flex-start; justify-content: space-between; gap: 30px; margin-top: 62px; }
.mw .ca-txt { min-width: 0; }
.mw .ca-titre, .mw .ca-solde {
  font-size: 86px; font-weight: 800; letter-spacing: -2px; line-height: 1.06;
}
.mw .ca-carte { flex: 0 0 258px; width: 258px; height: 164px; display: block; }
.mw .ca-h2 { margin-top: 96px; font-size: 62px; font-weight: 800; letter-spacing: -1px; }
.mw .ca-liste { margin-top: 26px; }
.mw .ca-row { display: flex; align-items: center; gap: 30px; height: 150px; }
.mw .ca-row-ic {
  flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%;
  background: var(--mw-card); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
}
.mw .ca-row-t { font-size: 50px; font-weight: 600; letter-spacing: -.5px; }
.mw .ca-row-s { margin-top: 12px; font-size: 44px; color: var(--mw-dim); letter-spacing: -.2px; }

/* --------------------------------------------------------- feuille Comptes */
.mw .co-liste { margin-top: 34px; display: flex; flex-direction: column; gap: 26px; }
.mw .co-row {
  display: flex; align-items: center; gap: 26px;
  background: var(--mw-card); border-radius: 40px; padding: 26px 26px 26px 30px;
}
.mw .co-ini {
  position: relative; flex: 0 0 96px; width: 96px; height: 96px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 42px; font-weight: 500; letter-spacing: .6px;
}
/* La coche est un BADGE pose sur la pastille, pas une icone dedans : cadree
   plus au centre elle mordait sur les initiales et les deux devenaient
   illisibles. L'anneau de la couleur de la carte la detache du disque. */
.mw .co-coche {
  position: absolute; right: -6px; bottom: -6px; width: 38px; height: 38px;
  border-radius: 50%; background: var(--mw-accent); color: #0b0b0d;
  box-shadow: 0 0 0 6px var(--mw-card);
  display: flex; align-items: center; justify-content: center;
}
.mw .co-coche svg { width: 62%; height: 62%; display: block; }
.mw .co-main { flex: 1 1 auto; min-width: 0; }
.mw .co-nom { font-size: 50px; font-weight: 700; letter-spacing: -.5px; }
.mw .co-tot { margin-top: 12px; font-size: 46px; font-weight: 500; color: var(--mw-text); }
.mw .co-act {
  flex: 0 0 88px; width: 88px; height: 88px; border-radius: 26px;
  background: var(--mw-pill); color: var(--mw-text);
  display: flex; align-items: center; justify-content: center;
}


/* =============================================================================
   Feuille « Manage Profile »
   -----------------------------------------------------------------------------
   Seul l'avatar y est vivant ; les deux cartes de lignes sont decoratives comme
   le reste de la maquette. Elles reprennent donc la carte des feuilles
   existantes (.fe-carte) plutot qu'un nouveau fond.
   ============================================================================= */
/* Contrairement a tous les autres ronds d'avatar du fichier, celui-ci n'est PAS
   en overflow:hidden : le badge crayon deborde volontairement du disque et un
   overflow le rognerait. C'est donc l'image elle-meme qui porte son arrondi. */
.mw .gp-ava {
  position: relative; width: 240px; height: 240px; border-radius: 50%;
  margin: 56px auto 0; background: var(--mw-pill); color: var(--mw-dim);
  display: flex; align-items: center; justify-content: center;
  font-size: 132px; line-height: 1;
}
.mw .gp-ava img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
/* Meme construction que .co-coche : un badge POSE sur la pastille, detache par
   un anneau — de la couleur du fond de la feuille, pas d'une carte. Il chevauche
   le bord du disque, d'ou l'ancrage a 2px et non a l'interieur. */
.mw .gp-crayon {
  position: absolute; right: 2px; bottom: 2px; width: 72px; height: 72px;
  border-radius: 50%; background: var(--mw-accent); color: var(--mw-accent-ink);
  box-shadow: 0 0 0 8px var(--mw-bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 34px; line-height: 1;
}
.mw .gp-crayon svg { display: block; width: 52%; height: 52%; }

.mw .gp-carte {
  margin-top: 26px; background: var(--mw-card); border-radius: 40px; padding: 0 34px;
}
.mw .gp-ligne {
  display: flex; align-items: center; justify-content: space-between; gap: 26px;
  height: 122px; font-size: 46px; font-weight: 500; letter-spacing: -.4px;
}
/* Le filet ne separe QUE deux lignes voisines : pose sur la premiere, il
   doublerait le bord arrondi de la carte. */
.mw .gp-ligne + .gp-ligne { border-top: 3px solid rgba(255,255,255,.08); }
.mw[data-theme="light"] .gp-ligne + .gp-ligne { border-top-color: rgba(0,0,0,.10); }
.mw .gp-lib {
  flex: 1 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mw .gp-val {
  flex: 0 1 auto; min-width: 0; color: var(--mw-dim); font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* LA MEME LIGNE, PENDANT QU'ON L'EDITE. Deux choses la rendaient intenable.

   Vide, elle n'avait aucune largeur : un @ jamais choisi rend `.gp-val` vide,
   donc une boite de 0x0 — mesure au simulateur iPhone, `boite: [552,1045,0,0]`.
   Le curseur se posait bien, mais dans une fente invisible : rien ne disait
   qu'on etait en train d'ecrire. `min-width` lui donne de quoi se voir.

   Et `overflow: hidden` coupait ce qu'on tapait des que ca depassait la
   largeur restante : on ecrivait dans une fenetre qui ne suit pas le curseur.
   Pendant l'edition seulement, on rend la coupe a la ligne interdite mais le
   depassement visible. Au repos, la ligne garde ses points de suspension. */
.mw .gp-val[contenteditable="true"] {
  flex: 0 1 auto; min-width: 180px; overflow: visible; text-overflow: clip;
  color: var(--mw-text); outline: none;
}
.mw .gp-ligne svg { flex: 0 0 auto; color: var(--mw-dim); }
/* .fe--sheet pose un padding en raccourci qui met le bas a zero ; cette
   longhand doit donc rester APRES lui dans la feuille. Sans elle, la derniere
   carte colle au bord bas de l'ecran. */
.mw .fe--gerer { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }

/* =============================================================================
   Feuille « Select Avatar »
   ============================================================================= */
/* Colonne flexible pour que « Save » se pose au BAS de la feuille quel que soit
   le nombre d'emojis : la feuille est en position absolue inset:0, sa hauteur
   est donc connue et margin-top:auto absorbe tout le vide restant.
   Les enfants sont figes en flex:0 0 auto — sinon, le jour ou la grille
   depasserait la hauteur de l'ecran, flex les comprimerait au lieu de laisser
   defiler. */
.mw .fe--avatar {
  display: flex; flex-direction: column;
  padding-bottom: calc(62px + env(safe-area-inset-bottom));
}
.mw .fe--avatar > * { flex: 0 0 auto; }

/* Le chevron reprend exactement la pastille de la croix : c'est la meme place
   dans l'en-tete. Classe a part parce que la croix, elle, est cablee sur la
   fermeture de toute feuille — ici on veut seulement revenir en arriere. */
.mw .av-retour {
  flex: 0 0 92px; width: 92px; height: 92px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-text);
  display: flex; align-items: center; justify-content: center;
}
.mw .av-apercu {
  width: 300px; height: 300px; border-radius: 50%; margin: 62px auto 0;
  background: var(--mw-pill); color: var(--mw-dim); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 162px; line-height: 1;
}
.mw .av-apercu img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 7 colonnes en 1fr : sur les 829 px utiles il reste ~96 px par case, soit des
   cibles tactiles tres au-dessus du minimum. aspect-ratio plutot qu'une hauteur
   ecrite en dur, pour que les cases restent carrees si la marge laterale de la
   feuille bouge un jour. */
.mw .av-grille {
  /* 62 et non 86 : avec neuf rangees, la feuille depassait de 14 px et se
     mettait a defiler pour rien. Ce qu'on rogne ici, le vide sous la grille le
     rend en ecart avant « Save ». */
  margin: 62px 0 70px;
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 26px;
}
.mw .av-emo {
  aspect-ratio: 1; border-radius: 28px; background: var(--mw-pill);
  display: flex; align-items: center; justify-content: center;
  font-size: 54px; line-height: 1;
}
/* Le lavande plein, comme l'onglet actif. Sur un emoji — glyphe en couleur —
   une couleur de texte ne changerait rien : seul le fond peut dire lequel est
   choisi. */
.mw .av-emo.est-choisi { background: var(--mw-accent); }

/* margin-top:auto colle le bouton en bas ; la marge basse de la grille garantit
   l'ecart minimal le jour ou il n'y a plus de vide a absorber. */
.mw .av-save {
  margin-top: auto; height: 112px; border-radius: 56px;
  background: var(--mw-accent); color: var(--mw-accent-ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 46px; font-weight: 700; letter-spacing: -.4px;
}


/* ========================================================== app installee
   iOS 27 ET LA BARRE D'ETAT. Depuis Safari 26, iOS peint un flou « Liquid
   Glass » dans la zone de la barre d'etat d'une app posee sur l'ecran
   d'accueil ; iOS 27 en a fait un lavis franc. Il est dessine PAR LE SYSTEME,
   AU-DESSUS de la webview : rien dans la page ne l'atteint. Son seul
   declencheur est `black-translucent`, que app.html a donc quitte.

   CE BLOC EST LA CONTREPARTIE. La webview commence desormais SOUS une barre
   opaque de 59pt. `.mw-status` est une bande VIDE de 140px de canevas — soit
   59,6pt a l'echelle d'un iPhone 14 Pro — qui n'existait que pour empecher le
   contenu de passer sous cette barre. Le systeme fait maintenant le travail :
   la garder ajouterait un second trou de la meme taille, et la rangee
   d'onglets descendrait de 59pt. On la met donc a zero, et app.html raccourcit
   le canevas de 140px en meme temps : le contenu retombe au MEME pixel
   d'ecran qu'avant, et la capture est identique.

   LES DEUX AUTRES VALEURS EN DEPENDENT, et les oublier casserait le
   defilement. Elles sont ecrites ici par leur soustraction, pas par leur
   resultat, pour qu'on voie d'ou elles viennent :
     - `.mw-scroll` commence sous la barre d'onglets, mesuree a 251px ;
     - `.mw-topveil` est opaque jusqu'en dessous de ces memes onglets, 338px.
   Les onglets remontant de 140px, les deux remontent de 140px.

   Ce bloc est en FIN de feuille a dessein — regle du projet : une surcharge
   posee au milieu se fait ecraser par une regle plus bas a specificite egale. */
/* PLUS AUCUNE DETECTION D'APP INSTALLEE, ET C'EST LE POINT DE CE PASSAGE.
   Ces trois regles etaient conditionnees a une classe `html.installe` posee par
   un JS qui interrogeait navigator.standalone et display-mode. Mesure sur le
   telephone du proprietaire : deux captures prises a neuf minutes d'ecart, de
   part et d'autre d'une relance ET d'une reinstallation, sont IDENTIQUES AU
   PIXEL. La detection ne repond donc pas sur iOS 27, et une correction qui
   depend d'elle n'est pas une correction, c'est un pari.

   Le declencheur est desormais une CERTITUDE et non une question : `body.wallet`
   n'existe que dans app.html, et sous 900px cette page affiche le wallet en
   plein ecran. Dans ce cas-la — installe ou dans Safari — la bande d'etat vide
   de 140px n'a plus de role : ou bien iOS a rentre la webview sous sa propre
   barre opaque, ou bien Safari dessine deja sa barre au-dessus. Elle se retire
   donc sans condition.
   L'accueil, /demo et /subscribe ne portent pas `body.wallet` : ils gardent la
   bande, donc le canevas de 2000, donc les 53 illustrations publiees aussi. */
/* LA BANDE REPASSE A ZERO : LA WEBVIEW EST DE NOUVEAU ENCASTREE.

   Elle etait revenue a 140 le temps d'essayer `viewport-fit=cover` +
   `black-translucent`, qui etaient la condition `insets.top > 0` du chemin
   « color extension » de WebKit. Le chemin n'a pas fonctionne sur l'appareil, et
   la pleine page a coute cher : l'ecran d'attente lavande s'est mis a porter le
   voile systeme sur 220px de canevas au lieu de rien. Mesure et details en tete
   de app.html.

   Sans `cover`, iOS encastre la webview sous sa propre barre. Le telephone
   dessine deja l'heure au-dessus : un second trou de la meme taille ferait
   descendre la rangee d'onglets de 59 pt pour rien. Elle repart donc a zero, et
   la rangee remonte au canevas 17 — soit 7 px CSS sous la barre, la meme place
   qu'occupe la rangee de l'application de reference.

   CE QUI RESTE DU VOILE DANS CETTE CONFIGURATION : les 35 pt qui suivent la
   barre, soit le canevas 0 a 82. La rangee est dedans. C'est le defaut connu,
   et le seul levier mesure qui l'annule est de la faire commencer sous le
   canevas 82 — au prix de 34 px CSS de noir en plus. Le proprietaire a tranche
   contre ce prix ; `height: 80px` ici le remettrait. */
@media (max-width: 899px) {
  body.wallet .mw-status  { height: 0; }
  body.wallet .mw-scroll  { padding-top: calc(251px - 140px); }
  body.wallet .mw-topveil { height: calc(308px - 140px); }
  /* LE TIROIR AUSSI, ET IL AVAIT ETE OUBLIE. Il n'est pas dans `.mw-app` : son
     rembourrage de 185 lui est propre, donc la mise a zero de `.mw-status` ne
     l'atteignait pas, et lui seul restait 140 px trop bas.
     Mesure du 21/09/2026, les deux captures superposees : AU CANEVAS le tiroir
     etait deja juste — rond d'avatar a 185 chez nous contre 186 dans
     l'application de reference. Tout l'ecart venait de l'ECRAN : la reference
     est une app native qui dessine sous la barre d'etat, notre webview est
     encastree 138 px plus bas. Pour tomber au meme endroit A L'ECRAN, il faut
     donc remonter le contenu d'autant — exactement ce que font les trois regles
     au-dessus pour l'ecran principal.
     Verification : 185 - 140 = 45 au canevas, plus 138 d'encastrement, soit 183
     a l'ecran contre 186 releves sur la reference. */
  body.wallet .mw-drawer  { padding-top: calc(185px - 140px); }
  /* « Send » ET « Trade » POUR LA MEME RAISON. Leur rembourrage de 157 vient
     d'une mesure faite sur l'application de reference, qui dessine sous la barre
     d'etat : son en-tete tombe au canevas 157 et l'ecran commence au premier
     pixel. Notre webview commence 138 px plus bas, donc le meme 157 mettait
     l'en-tete a 295 A L'ECRAN. Mesure du 21/09/2026 sur « Send » : au canevas
     nous etions a 204 contre 205 pour la reference — deja juste — mais a
     l'ecran 137 px trop bas.
     Ces deux feuilles seules : les autres n'ont pas de rembourrage haut fige,
     ou se replient deja d'elles-memes, comme « Receive ». */
  body.wallet .fe--envoyer,
  body.wallet .fe--troc   { padding-top: calc(157px - 140px); }
  /* ET LE BAS, POUR « Send » SEULEMENT. Son champ de recherche est colle au bas
     de la feuille ; le canevas s'arretant 80 px plus haut que le bas de l'ecran
     — les 34 pt de la barre d'accueil —, il tombait 78 px trop haut. Mesure :
     bas du champ a l'ecran 1841 contre 1919 pour la reference.
     « Trade » n'en a PAS besoin : sa colonne se replie deja d'elle-meme, et son
     clavier finit a 1834 contre 1836 pour la reference. Lui soustraire ces 80
     l'aurait pousse 80 px trop bas. */
  body.wallet .fe--envoyer { padding-bottom: calc(80px - 80px); }
  /* « RECEIVE » AUSSI, ET ELLE AVAIT ETE LAISSEE DE COTE parce qu'elle « se
     repliait d'elle-meme » — ce qui etait une autre facon de dire que sa carte
     rapetissait. Maintenant que la colonne tient juste, elle a le meme besoin
     que « Send » et « Trade » : remonter de 138 px pour tomber au meme endroit
     A L'ECRAN que l'application de reference, qui dessine sous la barre d'etat.
     Le rembourrage de 123 n'y suffit pas — 123 - 140 serait negatif — donc les
     15 qui manquent sortent de la marge de la poignee : 0 + 19 = 19 au canevas,
     plus 138 d'encastrement, soit 157 a l'ecran, exactement le releve.
     Et le compte tombe juste de l'autre bout : la colonne fait 1999, moins ces
     138, soit 1861 — la hauteur meme du canevas sur cet appareil. Rien ne plie. */
  body.wallet .fe--recevoir { padding-top: 0; }
  body.wallet .fe--recevoir .fe-poignee { margin-top: 19px; }
  /* ET LE BAS DANS L'AUTRE SENS, POUR LA MEME RAISON. La webview est encastree
     des DEUX cotes : 59 pt en haut, 34 pt en bas pour la barre d'accueil. Le
     bloc du bas est colle au bas du canevas, qui s'arrete donc 80 px de canevas
     plus haut que le bas de l'ECRAN — 34 pt x 1783/759 = 80. Sans cette
     soustraction, « Settings » et « Help & Support » remontaient de 80 px et
     passaient de dix pixels de la reference a quatre-vingt-dix. */
  body.wallet .mw-dr-bas  { padding-bottom: calc(118px - 80px); }
}


/* ========================================================= feuille « Receive »
   TOUTES LES VALEURS SONT DES MESURES, relevees le 21/09/2026 au decodeur sur les
   deux captures de reference. Elles font 923 x 2000 — exactement notre canevas —
   donc chaque nombre s'y transpose au pixel, sans conversion :
     poignee          x 420  y 157   83 x 12
     titre            x 51   y 216   hauteur de capitale 37
     bascule          x 47   y 300   829 x 95,  rayon 47,5, fond #1c1c1c
       pastille active         400 x 75, rayon 37,5, fond #e4e4e4, encre noire
     carte du QR      x 47   y 576   829 x 834, rayon 56, fond #1c1c1c
     legende          y 1494  hauteur 30
     bouton primaire  x 47   y 1671  829 x 113, rayon 56,5, fond = notre accent
     bouton secondaire       y 1807  829 x 113, fond #111111
   Rythme vertical mesure : titre->bascule 48, bascule->carte 181, carte->legende
   84, legende->bouton 147, entre boutons 23, dernier bouton->bas 80.
   Le 47 lateral n'est pas une valeur nouvelle : c'est exactement le rembourrage
   maison des feuilles, `.mw .fe--sheet { padding: 80px 47px 0 }`. On ne le
   redeclare donc pas.
   Ce bloc est en FIN de feuille : regle du projet, une surcharge posee au milieu
   se fait ecraser par une regle plus bas a specificite egale. */
/* LA FEUILLE SE PLIE A LA HAUTEUR DU CANEVAS, ELLE NE LA SUPPOSE PLUS.
   Toutes les valeurs de ce bloc ont ete relevees sur une reference de 2000 px de
   haut. Un iPhone dont la webview est encastree n'en offre que 1783, et la
   feuille debordait alors de 530 px : « Copy Address » commencait au canevas
   1804 pour un canevas qui s'arrete a 1783, et « Share » etait entierement hors
   de l'ecran. Mesure au banc en 393 x 759.
   On la met donc en colonne flexible, comme l'ecran « Trade » : les deux grandes
   respirations et la carte du QR sont les seuls elements a `flex-shrink`, et ils
   absorbent la difference. Le titre, la bascule, la legende et les deux boutons
   gardent leur taille mesuree — ce sont eux qu'on lit.
   Les respirations plient TROIS FOIS plus vite que la carte : sur un ecran
   court, mieux vaut resserrer les blancs que rapetisser le QR. */
/* LA COLONNE TIENT, ET C'EST NOUVEAU. Elle demandait 2368 px de haut pour un
   canevas de 2000 — 1860 sur le telephone, ou la webview est encastree. Les
   respirations pliaient donc jusqu'a la corde et la carte du QR avec elles :
   mesuree a 656 x 651 sur l'appareil contre 833 x 829 sur la reference, soit un
   QR ampute d'un cinquieme. Deux excedents l'expliquaient :
     — `.rc-jeu--carte` (181) ET `.rc-carte { margin-top: 181px }` posaient DEUX
       FOIS le meme ecart, 362 au lieu des 184 releves ;
     — le titre trainait la marge de 78 de `.fe-h2`, plus une respiration de 100,
       soit 178 entre la poignee et lui, contre 49 sur la reference.
   La colonne totalise maintenant 1999. Elle n'a plus rien a rendre, et la carte
   ne plie plus du tout. */
.mw .fe--recevoir {
  display: flex; flex-direction: column; overflow: hidden;
  padding: 123px 47px 79px;
}
/* LA QUEUE DE DEFILEMENT N'A PLUS DE ROLE ICI, ET ELLE COUTAIT CHER. `.mw-tail`
   reserve de quoi faire defiler une feuille jusqu'au bout ; cette colonne ne
   defile pas. Laissee en place, elle prenait 150 px que la carte du QR devait
   ceder : mesuree a 484 au lieu de 834, pour 231 px de vide sous les boutons. */
.mw .fe--recevoir .mw-tail { display: none; }
.rc-jeu--carte { flex: 0 3 183px; }
.rc-jeu--actions { flex: 0 3 125px; }
/* LES BLANCS DE L'EN-TETE PLIENT AUSSI. Laisses en rembourrage rigide, ils
   coutaient 148 px que la carte du QR devait ceder : mesuree a 592 au lieu de
   834. En respirations, la reduction se repartit et la carte garde sa taille. */
.rc-jeu--tete { flex: 0 3 38px; }
.rc-jeu--bascule { flex: 0 3 39px; }
.rc-tete { display: flex; align-items: center; gap: 16px; padding: 0; flex: 0 0 auto; }
/* `margin-top: 0` ET NON UN OUBLI : `.fe-h2` en pose 78, qui ont leur sens la
   ou ce titre ouvre une section au milieu d'une feuille. Ici il ouvre la feuille
   elle-meme, et la respiration au-dessus de lui est deja posee par `.rc-jeu--tete`.
   La taille passe de 55 a 48 : l'encre du mot « Receive » fait 165 x 35 sur la
   reference contre 193 x 40 chez nous. */
/* `.mw .rc-titre` ET NON `.rc-titre` : `.mw .fe-h2` vaut (0,2,0) et gagnait
   malgre sa position plus haute dans la feuille. Verifie par style calcule, pas
   par lecture : la police restait a 55 et la marge a 78. */
.mw .rc-titre { flex: 1; font-size: 48px; line-height: 1.15; margin-top: 0; }
/* L'AIDE N'EXISTE QU'EN « Cash », et ce n'est pas un oubli de l'autre etat :
   mesure faite, la zone entiere plafonne a une luminance de 7 en Tokens — le
   bouton est ABSENT, pas assombri. */
.rc-aide {
  display: none; place-items: center; width: 94px; height: 94px; flex: 0 0 auto;
  border-radius: 50%; background: #131313; color: #f6f6f6;
}
.mw[data-recevoir="cash"] .rc-aide { display: grid; }

.rc-bascule {
  flex: 0 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  height: 93px; padding: 10px; border-radius: 47.5px; background: #1c1c1c;
  box-sizing: border-box;
}
.rc-onglet {
  border: 0; margin: 0; cursor: pointer; border-radius: 37.5px;
  background: none; color: #b4b4b4;
  font: 600 40px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  transition: background .18s, color .18s;
}
/* L'ETAT VIT SUR `.mw`, PAS SUR LE BOUTON. `renderMockup` remplace l'element a
   chaque redessin : une classe posee sur un bouton disparaitrait avec lui, et
   l'onglet choisi serait perdu des la premiere frappe dans les reglages.
   Mesure : seule la COULEUR change entre actif et inactif, pas la graisse — le
   nombre de pixels de glyphe est le meme des deux cotes. */
.mw:not([data-recevoir="cash"]) .rc-onglet[data-recevoir="tokens"],
.mw[data-recevoir="cash"] .rc-onglet[data-recevoir="cash"] {
  background: #e4e4e4; color: #000;
}

.rc-carte {
  /* `flex: 0 0 auto` : ELLE NE PLIE PLUS. C'est le seul bloc de cette feuille
     qu'on regarde vraiment ; ce sont les respirations qui doivent rendre la
     place, et elles en ont 385 a donner. `margin-top` retire : l'ecart au-dessus
     est pose une seule fois, par `.rc-jeu--carte`. */
  /* LARGEUR DE LA COLONNE, ET NON 829 EN DUR : 829, c'est 923 moins les deux
     marges de 47. Le canevas plein ecran fait de 845 a 1033 de large (mode
     natif, mockup.js) : a 881 la carte debordait de 42 de chaque cote de sa
     colonne, a 1033 elle laissait deux gouttieres de 102. Le rapport releve
     (829 x 833) est garde par `aspect-ratio` ; a 923, rien ne bouge. */
  flex: 0 0 auto; width: 100%; height: auto; aspect-ratio: 829 / 833;
  align-self: center; position: relative;
  border-radius: 56px; background: #1c1c1c;
  display: grid; place-items: center;
}
/* La matrice occupe 730 x 730 dans une carte de 829 x 834 : 49,5 de marge
   horizontale, 52 de verticale. */
.rc-qr { position: absolute; inset: 52px 49.5px; display: grid; place-items: center; color: #fff; }
.rc-qr--cash { display: none; }
.mw[data-recevoir="cash"] .rc-qr--tokens { display: none; }
.mw[data-recevoir="cash"] .rc-qr--cash { display: grid; }
.qr-trame { width: 100%; height: 100%; display: block; }
/* LA FENETRE CENTRALE N'EST PAS UNE PLAQUE PLUS CLAIRE. Echantillon pris dans la
   fenetre hors glyphe : (28,28,28) — exactement le fond de la carte. Ce disque
   porte donc la meme couleur ; c'est un degagement, pas un cartouche. */
.rc-logo {
  position: absolute; display: grid; place-items: center;
  /* EN PART DU QR, PAS EN PIXELS : 150 de cote, 30 de marge et 34 d'arrondi
     releves sur une matrice de 730 (canevas de 923). Depuis que la carte suit
     la largeur de la colonne (mode natif, 845 a 1033 de canevas), la matrice
     fait de 652 a 840 : en pixels fixes, la pastille mordait sur le premier
     anneau de points a 881 (fenetre de 132,5 pour 150) et flottait dans une
     fenetre trop grande a 1033. Les pour-cent sont ceux de `.rc-qr`, son bloc
     conteneur ; `padding` en pour-cent se compte sur la largeur, comme voulu.
     A 923 : 150 x 150, marge 30, arrondi 34 — rien ne bouge. */
  width: 20.548%; height: auto; aspect-ratio: 1 / 1;
  border-radius: 22.667%; background: #1c1c1c;
  padding: 4.1096%; box-sizing: border-box;
}
.rc-logo svg { width: 100%; height: 100%; display: block; }
/* LE SIGLE EST BLANC DANS LE QR, ET COLORE AILLEURS. Sur la reference il est en
   aplat blanc ; dans la liste des jetons, c'est le degrade de la marque. Plutot
   que de dessiner un second sigle a tenir a jour, on eteint celui-la : `brightness(0)`
   le rend noir quelle que soit son oeuvre d'origine — degrade compris — et
   `invert(1)` le repasse en blanc. La forme, elle, ne bouge pas d'un pixel. */
.rc-logo:not(.rc-logo--duo) svg { filter: brightness(0) invert(1); }
/* LE SIGLE DE SOLANA PORTE DESORMAIS SON DISQUE NOIR (tokens.js, `solanaSvg`) :
   le filtre du dessus le passerait en blanc avec le sigle, et le QR aurait en
   son centre une pastille blanche pleine au lieu des trois barres. Le disque
   n'a pas de role ici — la fenetre du QR est deja un degagement du fond de la
   carte — donc il s'efface. */
.rc-logo .sol-disque { display: none; }

.rc-legende {
  flex: 0 0 auto; margin: 62px 0 0; display: flex; align-items: center; gap: 14px;
  color: var(--mw-text); font-size: 42px; font-weight: 600;
}
.rc-legende .rc-sep, .rc-legende .rc-adr { color: #b3b3b3; font-weight: 500; }
.rc-legende svg { margin-left: auto; }
.rc-legende--cash { display: none; }
.mw[data-recevoir="cash"] .rc-legende--tokens { display: none; }
.mw[data-recevoir="cash"] .rc-legende--cash { display: flex; }

.rc-actions { flex: 0 0 auto; display: grid; gap: 23px; margin-top: 0; }
.rc-bouton {
  height: 113px; border: 0; cursor: pointer; border-radius: 56.5px;
  background: #111111; color: #efefef;
  font: 700 46px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
}
.rc-bouton--plein { background: var(--mw-accent); color: #000; font-size: 48px; }


/* ============================================= feuilles « Send » et « Trade »
   TOUTES LES VALEURS SONT DES MESURES, relevees le 21/09/2026 au decodeur sur
   les deux captures de reference. Elles font 1179 x 2556, soit exactement le
   rapport de notre canevas : a l'echelle 923/1179 chaque nombre s'y transpose.

   SEND                                     TRADE
     en-tete      y 157   hauteur 94          en-tete      y 157   hauteur 94
     titre                capitale 34         titre                centre
     rond « + »   x 782   diametre 94         carte 1      y 366   829 x 329  r52
     « Accounts » y 320   capitale 23         carte 2      y 723   829 x 329  r52
     pastille     x 47    diametre 84,5       rond d'echange  centre 461,5 / 709, ø 75
     nom          x 160,5 capitale 31         pilules      y 1188  113 de haut, r56,5
     adresse              hauteur 27,4                     x 55,6  247 de large, ecart 36
     pas entre lignes     151                 clavier      colonnes 178,5 / 461,5 / 743,5
     champ        y 1808  829 x 113  r56,5                 lignes 1375,5 / 1507 / 1638,5 / 1770
     rond de scan centre 815 / 1864,8, ø 75   fond des cartes #131313
     fond du champ #171717                    pastille de jeton  290,5 x 84,6  r42,3
                                              rond d'echange : #b3a5f9 — notre accent

   LE ROND D'ECHANGE EST DEJA A NOTRE COULEUR. Mesure faite, la reference le peint
   en #b3a5f9 ; notre accent vaut #b3a5f8. Ce n'est pas une coincidence a
   preserver mais une valeur a NE PAS FIGER : on ecrit `var(--mw-accent)`, donc
   le rond suit le wallet. La regle du projet ne change pas d'un iota — le wallet
   reste lavande, et c'est justement la variable qui le garantit.

   LA RESPIRATION SE COMPRIME, LE CONTENU NON. Le releve totalise 2001 px de
   haut ; un telephone dont la fenetre est plus courte donne un canevas de ~1783.
   Les deux `\.tr-jeu` sont les seuls elements a `flex-shrink: 1` : ils absorbent
   la difference, et cartes, pilules et clavier gardent leur taille mesuree. Sans
   eux, l'ecran deborderait et le clavier finirait sous le bord.

   Ce bloc est en FIN de feuille : regle du projet, une surcharge posee au milieu
   se fait ecraser par une regle plus bas a specificite egale. */

.mw .fe--envoyer, .mw .fe--troc {
  padding: 157px 47px 80px;
  display: flex; flex-direction: column; overflow: hidden;
}

/* ------------------------------------------------------------------- Send */
.en-barre { display: flex; align-items: center; gap: 30px; flex: 0 0 92px; }
.en-titre { font-size: 46px; font-weight: 700; letter-spacing: -.8px; }
.en-plus {
  margin-left: auto; flex: 0 0 94px; width: 94px; height: 94px; border-radius: 50%;
  background: var(--mw-pill); color: var(--mw-text); display: grid; place-items: center;
}
.en-label {
  margin: 70px 0 0 5px; flex: 0 0 auto;
  font: 700 32px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.3px; color: var(--mw-text);
}
.en-liste { margin-top: 78px; flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: none; }
.en-liste::-webkit-scrollbar { width: 0; }

.en-ligne {
  display: flex; align-items: center; gap: 29px; width: 100%; text-align: left;
  border: 0; background: none; padding: 0; margin: 0 0 66.5px; cursor: pointer;
  color: inherit; font: inherit;
}
.en-ligne:last-child { margin-bottom: 0; }
.en-ligne:active { opacity: .55; }
.en-ava {
  flex: 0 0 84.5px; width: 84.5px; height: 84.5px; border-radius: 50%;
  background: #1c1c1c; color: #b4b4b4; display: grid; place-items: center;
  /* 40 et non 34 : sur la reference « L1 » fait 29,7 de capitale pour 32,9 de
     large dans un rond de 84,5. A 34 la pastille paraissait vide. */
  font: 700 40px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -1px;
}
.en-txt { display: flex; flex-direction: column; min-width: 0; }
.en-nom {
  font: 700 41px/46px -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.6px; color: #eeeeee;
}
.en-adr {
  font: 400 37px/38.5px -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.2px; color: #b4b4b4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Le mot n'apparait QUE si le filtre ne laisse rien : une liste vide sans
   phrase se lit comme un ecran casse. */
.en-rien {
  display: none; margin: 0; flex: 0 0 auto; color: var(--mw-dim);
  font: 500 40px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
}
.fe--envoyer.est-vide .en-rien { display: block; }

.en-champ {
  flex: 0 0 113px; margin-top: 30px; border-radius: 56.5px; background: #171717;
  display: flex; align-items: center; gap: 27px; padding: 0 23.5px 0 39px;
}
.en-loupe { color: #b4b4b4; display: grid; place-items: center; flex: 0 0 auto; }
.en-saisie {
  flex: 1 1 auto; min-width: 0; border: 0; background: none; outline: none; color: #eeeeee;
  font: 500 42px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.3px;
}
.en-saisie::placeholder { color: #6e6e6e; }
.en-scan {
  flex: 0 0 75px; width: 75px; height: 75px; border-radius: 50%;
  background: #1f1f1f; color: #eeeeee; display: grid; place-items: center;
}

/* ------------------------------------------------------------------ Trade */
.tr-barre { display: grid; grid-template-columns: 92px 1fr 92px; align-items: center; flex: 0 0 92px; }
.tr-titre { text-align: center; font-size: 44px; font-weight: 600; letter-spacing: -.5px; }
.tr-regl {
  width: 92px; height: 92px; border-radius: 50%; background: var(--mw-pill);
  color: var(--mw-text); display: grid; place-items: center;
}

.tr-jeu--haut { flex: 0 1 117.4px; }
.tr-jeu--bas  { flex: 0 1 136.4px; }

.tr-carte {
  flex: 0 0 329px; position: relative; border-radius: 52px; background: #131313;
  box-sizing: border-box;
}
.tr-lab {
  position: absolute; left: 50px; top: 52px; color: #b4b4b4;
  font: 500 35px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.3px;
}
.tr-mid {
  position: absolute; left: 50px; right: 47px; top: 122px; height: 85px;
  display: flex; align-items: center; gap: 24px;
}
.tr-montant {
  flex: 1 1 auto; min-width: 0; color: #eeeeee;
  font: 500 76px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -2px; font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tr-montant.est-vide { color: #6e6e6e; }
.tr-carte.est-trop .tr-montant { color: #ff6f6f; }

.tr-choix { flex: 0 0 auto; position: relative; cursor: pointer; }
.tr-opt {
  display: none; align-items: center; gap: 17px; height: 84.6px; border-radius: 42.3px;
  background: #161616; padding: 0 22px 0 11px; color: #eeeeee;
}
.tr-opt.est-choisi { display: flex; }
.tr-ic { width: 62px; height: 62px; flex: 0 0 62px; display: grid; place-items: center; }
.tr-ic svg, .tr-ic img { width: 100%; height: 100%; display: block; border-radius: 50%; }
.tr-sym {
  font: 700 42px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.5px; white-space: nowrap;
}
.tr-badge { color: var(--mw-accent); display: grid; place-items: center; flex: 0 0 auto; }
.tr-choix .chev, .tr-opt svg:last-child { flex: 0 0 auto; }
.tr-choix:active { opacity: .6; }

/* `bottom` mesure la BOITE, pas l'encre : avec 49 le banc posait le texte 4 px
   trop haut, parce que la ligne fait 44 (la hauteur du bouton) pour 35 de texte. */
.tr-bas {
  position: absolute; left: 50px; right: 47px; bottom: 44px;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
}
.tr-note {
  margin-left: auto; color: #b4b4b4;
  font: 500 35px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.3px; font-variant-numeric: tabular-nums;
}
.tr-unite {
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer; color: #b4b4b4;
  display: grid; place-items: center; width: 44px; height: 44px;
}
.tr-unite:active { opacity: .5; }
.fe--troc[data-mode="usd"] .tr-unite { color: var(--mw-accent); }

/* LE ROND DEBORDE SUR LES DEUX CARTES, DONC IL PASSE AU-DESSUS. Sans z-index,
   la carte du bas — qui vient apres dans le document — lui coupait le tiers
   inferieur : mesure faite a la capture, pas deduite. */
.tr-entre { flex: 0 0 27.6px; position: relative; z-index: 2; }
.tr-echange {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 75px; height: 75px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: var(--mw-accent); color: #151221; display: grid; place-items: center;
}
.tr-echange:active { transform: translate(-50%, -50%) scale(.9); }

/* LA RANGEE EST DITE EN TOUTES LETTRES : 113. Sans `grid-template-rows`, sa
   hauteur ne venait que du `flex-basis` du conteneur, que WebKit ne transmet
   pas a une piste `auto` : dans Safari (simulateur iPhone, iOS 27, avant comme
   apres le 28/09/2026) les trois pilules sortaient a la hauteur de leur texte,
   ~45 au lieu de 113 — des traits, plus des boutons. Chromium, lui, etirait :
   le banc ne l'avait jamais vu. */
.tr-parts {
  flex: 0 0 113px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 36px;
  grid-template-rows: 113px;
  margin: 0 8.6px;
}
.tr-part {
  border: 0; border-radius: 56.5px; background: #131313; color: #eeeeee; cursor: pointer;
  font: 600 44px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  letter-spacing: -.4px;
}
.tr-part:active { background: #1f1f1f; }

.tr-clavier {
  flex: 0 0 526px; display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 131.5px; margin: 8.65px -9.4px 0;
}
.tr-touche {
  border: 0; background: none; padding: 0; cursor: pointer; color: #eeeeee;
  display: grid; place-items: center; border-radius: 40px;
  font: 400 56px/1 -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
  font-variant-numeric: tabular-nums;
}
.tr-touche:active { background: #1a1a1a; }


/* UN NOM DE JETON LONG SE COUPE, IL NE DEBORDE PLUS (28/09/2026).
   La ligne a une hauteur fixe (160) : un nom ou une quantite qui passait a la
   ligne descendait sur la ligne suivante — « Wrapped Staked Ether » sur quatre
   lignes, par-dessus Ethereum. Le defaut existait deja a 923 de large ; en
   taille native, un iPhone de 375 pt n'a que 881 de canevas et le rencontre
   plus tot. On fait comme l'app de reference : une ligne, et des points de
   suspension. Les montants, a droite, ne se coupent jamais : c'est le nom qui
   cede (`.main` a deja `min-width: 0`).
   `line-height: 1` et `overflow: hidden` rogneraient les jambages (g, p, y) et
   le haut des capitales accentuees : le rembourrage vertical leur rend la
   place, la marge negative la reprend, et la ligne ne bouge pas d'un pixel.
   `.main` passe en colonne flexible POUR CETTE RAISON : en flux de blocs, la
   marge negative du nom et la marge positive du dessous FUSIONNERAIENT (15 -
   6 = 9 au lieu de 15) ; entre deux elements flexibles, elles s'additionnent
   sans fusion, et la colonne garde exactement 42 + 15 + 36,4.
   Le point de coupe suit la largeur laissee par les montants, qui changent
   avec les cours (toutes les 4 s) : un nom coupe peut gagner ou perdre une
   lettre d'un tick a l'autre, comme dans l'app de reference. `tabular-nums`
   l'aurait fige, mais au prix du dessin de TOUS les montants, releves en
   chiffres proportionnels sur la reference : on ne le pose pas. */
.mw-token .main { display: flex; flex-direction: column; }
.mw-token .name, .mw-token .sub {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-block: .14em; margin-block: -.14em;
}
.mw-token .sub { margin-top: calc(15px - .14em); }


/* =============================================================================
   PLEIN ECRAN : LES BOUTONS DU BAS RESTENT EN BAS (28/09/2026)
   -----------------------------------------------------------------------------
   Depuis que le wallet garde sa taille native (mockup.js, `NATIF`), un
   telephone plus HAUT a aussi un canevas plus haut : 2020 dans l'app installee
   sur un Pro Max, contre 1783 sur un iPhone de 393 pt. Les colonnes de
   « Trade » et de « Receive » avaient ete reglees pour 1783 : leurs
   respirations savent PLIER, pas grandir. Sur un Pro Max, le pave numerique et
   les boutons « Copy Address » / « Share » finissaient donc 240 unites
   au-dessus du bas — 100 pt de noir sous eux, la ou la reference les pose
   contre le bas (releve : dernier bouton -> bas 80).
   Une seule respiration grandit dans chaque colonne, celle qui separe le haut
   du bas : tout ce qui est au-dessus garde sa place mesuree, tout ce qui est
   en dessous reste colle au bas. A 1783 (app installee, iPhone de 393 pt), la
   colonne de Receive totalise exactement le canevas et ne bouge pas ; celle de
   Trade laissait 7 unites libres SOUS le pave, qui passent maintenant au-dessus :
   le pave descend de 7 unites (2,8 px) et sa derniere touche finit a 80 du bas
   au lieu de 87 — la valeur relevee sur la reference. C'est le seul element
   qui bouge sur l'iPhone de reference, et il bouge vers elle.
   SEULEMENT PLEIN ECRAN (`body.wallet`, sous 568 px, meme requete que
   app.html) : les maquettes encadrees gardent leur colonne au pixel. */
@media (max-width: 567px) {
  body.wallet .tr-jeu--bas { flex-grow: 1; }
  body.wallet .rc-jeu--actions { flex-grow: 1; }
}

/* THEME CLAIR : LES COULEURS ECRITES EN DUR (28/09/2026). Les feuilles Recevoir,
   Envoyer et Trade (ajoutees le 21/09) portent des couleurs relevees sur la
   reference SOMBRE (#eeeeee, #b4b4b4…). Le theme clair ne change que les
   variables (.mw[data-theme="light"], en tete de feuille) et ne les atteignait
   pas : sur le fond de feuille devenu blanc, le pave du Trade sortait a 1,16:1
   (gris clair sur blanc), les noms de comptes de l'Envoi blanc sur blanc, la
   croix de la recherche invisible, la pastille choisie de la Watchlist et de la
   fiche jeton plus claire que les autres. Chaque regle ci-dessous est bornee au
   theme clair et plus precise que celle qu'elle remplace : le sombre ne bouge
   pas d'un pixel. Pas de surcharge generale de .tr-montant / .tr-unite : a
   precision egale elle effacerait leurs etats rouge (montant trop grand) et
   accent (saisie en dollars). Releve : audit du rendu du kit affilie. */
.mw[data-theme="light"] .tr-touche { color: var(--mw-text); }
.mw[data-theme="light"] .tr-touche:active { background: var(--mw-pill); }
.mw[data-theme="light"] .en-nom { color: var(--mw-text); }
.mw[data-theme="light"] .en-adr,
.mw[data-theme="light"] .rc-legende .rc-sep,
.mw[data-theme="light"] .rc-legende .rc-adr { color: var(--mw-dim); }
.mw[data-theme="light"] .en-ava { background: var(--mw-pill); color: var(--mw-dim); }
.mw[data-theme="light"] .mw-fermer-recherche { background: var(--mw-pill); color: var(--mw-text); }
.mw[data-theme="light"] .fe-chip.is-on,
.mw[data-theme="light"] .je-plage.is-on { background: var(--mw-text); color: var(--mw-bg); }
