/* ============================================================
   VANE — jetons de design
   Extraits par l'API Figma du fichier « Vanevc Bot », frames des 8 ecrans.
   Toutes les valeurs ci-dessous sont relevees, aucune n'est estimee.

   Police : Manrope uniquement (decision client 2026-08-13). Le melange de
   polices de la maquette etait un accident d'export Figma.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap');

:root {
  /* ---- Marque ------------------------------------------------ */
  --vane-red:            #E12325;
  --vane-red-deep:       #8F0808;
  --vane-red-bright:     #F21313;
  --vane-red-mid:        #DC2222;
  --vane-red-soft:       #EB7778;

  /* Degrades releves tels quels dans la maquette */
  --grad-brand:      linear-gradient(180deg, #E12325 0%, #8F0808 100%);
  --grad-balance:    radial-gradient(118% 128% at 6% 112%,
                       #FF6E6F 0%, #E35153 13%, #A73335 27%,
                       #6B1819 44%, #3A1516 66%, #271111 100%);
  /* Releve colonne par colonne : uni #B71415, traverse d'un voile clair
     (#E4A7A7) vers 48 %. Ce n'est pas le degrade vif que j'avais mis. */
  /* Degrade HORIZONTAL, releve a six abscisses hors du texte : le bouton
     perd un tiers de sa luminosite de gauche a droite. Je l'avais fait
     uniforme, puis vertical — les deux etaient faux. */
  --grad-cta:        linear-gradient(90deg,
                       #DF2324 0%, #D61F21 12%, #CD1B1D 23%,
                       #A10D0E 77%, #980A0B 88%, #900707 100%);
  /* Releve colonne par colonne sur l'export : #BABABA en haut, #9F9F9F en
     bas. La valeur precedente (#E9E9E9) rendait la carte bien trop claire. */
  --grad-card-metal: linear-gradient(180deg, #BCBCBC 0%, #9E9E9E 100%);
  --grad-surface:    linear-gradient(180deg, #5A5A5A 0%, #383838 100%);
  --grad-glow:       linear-gradient(180deg, #E12325 0%, #FFFFFF 100%);

  /* ---- Surfaces ---------------------------------------------- */
  --bg:              #080808;   /* releve en 6 points, pas #000000 */
  --surface:         #151515;
  --surface-2:       #1B1B1A;
  --surface-3:       #393838;
  --hairline:        rgba(255, 255, 255, 0.10);
  --texture-veil:    rgba(255, 255, 255, 0.02);

  /* ---- Texte (5 couleurs, releve exhaustif) ------------------- */
  --text:            #FFFFFF;
  --text-muted:      #ABABAB;   /* releve sur 4 elements, pas #979592 */
  --text-dim:        #8A8A8A;
  --text-invert:     #000000;
  --link:            #007AFF;   /* bleu systeme iOS */
  --danger:          #FF3B30;

  /* ---- Bordures ---------------------------------------------- */
  --border:          rgba(255, 255, 255, 0.10);
  --border-strong:   #FFFFFF;
  --border-selected: var(--vane-red-bright);   /* 1.5px sur l'element choisi */

  /* ---- Rayons (valeurs relevees) ------------------------------ */
  --r-xs:   5px;
  --r-sm:   8px;
  --r-md:  12px;
  --r-lg:  16px;
  --r-xl:  24px;
  --r-2xl: 32px;
  --r-pill: 999px;

  /* ---- Typographie -------------------------------------------
     Une seule famille. La graisse porte la hierarchie, selon le
     bareme fixe par le client :
       titres / gros montants -> 700-800
       texte courant          -> 500-600
       labels / petits textes -> 400
     Les tailles sont celles relevees dans la maquette.          */
  --font: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --fs-10: 10px;   --fs-11: 11px;   --fs-12: 12px;   --fs-13: 13px;
  --fs-14: 14px;   --fs-16: 16px;   --fs-17: 17px;   --fs-18: 18px;
  --fs-20: 20px;   --fs-24: 24px;   --fs-25: 25px;   --fs-26: 26px;
  --fs-36: 36px;

  --fw-label:  400;
  --fw-body:   500;
  --fw-strong: 600;
  --fw-title:  700;
  --fw-hero:   800;

  /* ---- Gabarit ------------------------------------------------ */
  /* La maquette est dessinee en 402 px, mais une mini-app Telegram tourne
     de 320 (SE 1re gen) a 430 px (Pro Max). Ces trois valeurs etaient
     FIGEES : sur un Android de 360 la mise en page debordait. */
  --screen-w:  min(402px, 100vw);
  --gutter:    16px;
  /* La gouttiere reste a 16 px sur TOUS les telephones : le contenu
     grandit avec l ecran au lieu de rester fige a 370, ce qui laissait
     30 px de vide sur un Pro Max. */
  --content-w: min(calc(100vw - 32px), 398px);
}

/* ============================================================
   Base
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

/* L'attribut `hidden` doit gagner contre tout `display` d'auteur.
   Sans ca, `.list { display:grid }` le neutralise et deux vues se
   superposent — vu en recette sur l'onglet My Cards. */
[hidden] { display: none !important; }


html, body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-weight: var(--fw-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  /* Le fond occupe tout l'ecran. Plafonner le CORPS a 402 px laissait
     deux bandes noires sur les cotes des que le telephone etait plus
     large — tres visibles des qu'une surface coloree touche le bord. */
  width: 100%;
  margin-inline: auto;
  min-height: 100svh;
  /* Ancre `.vane-glow` : sans ca il se positionne par rapport au bloc
     conteneur initial et echappe au decoupage ci-dessous. */
  position: relative;
}

/* `.vane-glow` est en `position:absolute` par rapport au bloc conteneur
   initial et mesure 559 px de large : sans cette regle il etend le document
   a 481 px et la mini-app scrolle horizontalement sur les quatre pages.
   `clip` plutot que `hidden` : il coupe sans creer de conteneur de
   defilement, donc `position:sticky` et le defilement vertical survivent. */
html, body { overflow-x: clip; }

/* Echelle typographique — a appliquer, jamais a redefinir localement. */
.t-hero    { font-size: var(--fs-36); font-weight: var(--fw-hero);   letter-spacing: -0.02em; }
.t-amount  { font-size: var(--fs-25); font-weight: var(--fw-title);  letter-spacing: -0.01em; }
.t-title   { font-size: var(--fs-20); font-weight: var(--fw-title); }
.t-section { font-size: var(--fs-16); font-weight: var(--fw-title); }
.t-body    { font-size: var(--fs-14); font-weight: var(--fw-body); }
.t-sub     { font-size: var(--fs-13); font-weight: var(--fw-body);  color: var(--text-muted); }
.t-label   { font-size: var(--fs-12); font-weight: var(--fw-label); color: var(--text-muted); }
.t-micro   { font-size: var(--fs-10); font-weight: var(--fw-label); color: var(--text-dim);
             letter-spacing: 0.04em; text-transform: uppercase; }

/* La texture kanji : image, jamais 2 473 vecteurs (95 Ko en PNG contre 808 en SVG). */
.vane-texture {
  background-image: url('assets/texture-kanji.png');
  background-size: 411px auto;
  background-repeat: repeat;
}


/* ============================================================
   VANE — coquille commune + ecran 1 (achat de carte)
   Geometrie relevee sur la frame Figma 54:16758 (402x1264).
   Contenu a 370px, gouttiere 16px, rythme vertical 12/16/20.
   ============================================================ */

/* ---- Halo rouge en haut de page (Ellipse 242 : 559x136 @ -168,-53) ---- */
.vane-glow {
  position: absolute;
  top: -53px;
  left: 50%;
  width: 559px;
  height: 136px;
  margin-left: -279px;
  background: #7A2928;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.9;
  pointer-events: none;
  z-index: 0;
}

.vane-page {
  position: relative;
  z-index: 1;
  padding-bottom: 19px;               /* barre d'accueil iOS (mesure : 43 px sous le bouton) */
}

.wrap { width: var(--content-w); margin-inline: auto; }

/* ---- Barre d'etat simulee (402x47) ---------------------------- */
.statusbar {
  height: 47px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22px 0 28px;
  font-size: var(--fs-16);
  font-weight: var(--fw-strong);
}
.statusbar .icons { display: flex; align-items: center; gap: 6px; opacity: 0.95; }

/* ---- En-tete : logo + langue + portefeuille (370x44 @ y63) ----- */
.appbar {
  height: 44px;
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.appbar .logo { width: 97px; height: 36px; display: block; }   /* mesure : 91x30 */

.lang {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  background: #270D0D;                   /* releve, pas #1E1414 */
  border: 1px solid rgba(255, 255, 255, 0.34);   /* bordure claire, relevee */
  font-size: var(--fs-13);
  font-weight: var(--fw-body);                   /* pas de gras dans la maquette */
  color: var(--text);
  cursor: pointer;
}
.lang > svg:first-child {
  width: 22px; height: 22px; padding: 3px;
  border-radius: 5px; background: var(--vane-red);
  color: #fff; flex: none;
}
.appbar .right { display: flex; align-items: center; gap: 10px; }

.wallet-btn {
  width: 34px; height: 34px;             /* mesure : 31 px de rouge */
  /* Six points releves en travers du bouton : #FFA6A6 au bord gauche,
     puis #FF5F5F, #B92C2C, #711818, #3D0F0F, #250E0E a droite. */
  background: radial-gradient(78% 110% at 0% 38%,
    #FFB8B8 0%, #FF5F5F 20%, #B92C2C 40%, #711818 60%,
    #3D0F0F 80%, #250E0E 100%);
  border-radius: 50%;
  display: grid; place-items: center;
  border: 0;
  cursor: pointer;
  text-decoration: none;
}
.wallet-btn svg { width: 24px; height: 24px; color: #fff; }

/* ---- Carte de solde (370x87, r16, fond noir + degrade rouge) --- */
.balance {
  position: relative;
  height: 87px;
  margin-top: 16px;
  border-radius: var(--r-lg);
  background: var(--grad-balance);
  border: 1px solid rgba(255, 255, 255, 0.4);   /* lisere releve sur 4 cotes */
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
}
.balance::after {                      /* torii en filigrane, cote droit */
  content: '';
  position: absolute;
  right: -68px; top: 50%;
  width: 220px; height: 310px;           /* torii 2,6x trop petit et trop a gauche */
  transform: translateY(-50%);
  background: url('assets/solde-torii.png') center/contain no-repeat;
  opacity: 0.18;
  pointer-events: none;
}
.balance .label {
  font-size: var(--fs-12);
  font-weight: var(--fw-label);
  color: rgba(255, 255, 255, 0.72);
  text-transform: capitalize;
}
.balance .amount {
  font-size: var(--fs-25);
  font-weight: var(--fw-title);
  letter-spacing: -0.01em;
  margin-top: 4px;
}
.balance .amount .cur {
  font-size: var(--fs-14);
  font-weight: var(--fw-body);
  margin-left: 6px;
  opacity: 0.9;
}
/* Le « + » n'est pas pose sur un cercle net mais sur une TACHE D'ENCRE
   blanche aux bords dechiquetes. Detouree depuis l'export @2x (cle sur la
   blancheur, trou du « + » rebouche par remplissage depuis l'exterieur). */
.balance .add {
  position: relative;
  flex: 0 0 auto;
  width: 54px; height: 54px;
  border: 0;
  background: url('assets/tache-encre.png') center / contain no-repeat;
  color: var(--vane-red);
  display: grid; place-items: center;
  text-decoration: none;
  cursor: pointer;
  font-size: 0;                          /* le « + » textuel est remplace ci-dessous */
}
.balance .add::after {
  content: '';
  width: 22px; height: 22px;
  border: 1.6px solid var(--vane-red);
  border-radius: 50%;
  background:
    linear-gradient(var(--vane-red), var(--vane-red)) center / 10px 1.6px no-repeat,
    linear-gradient(var(--vane-red), var(--vane-red)) center / 1.6px 10px no-repeat;
}

/* ---- Onglets (370x48, r51, #151515 + texture kanji) ------------ */
.tabs {
  position: relative;
  height: 48px;
  margin-top: 12px;                      /* mesure : 12 px sous la carte de solde */
  border-radius: 51px;
  background: var(--surface);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  overflow: hidden;
}
.tabs::before {                        /* la texture, en image */
  content: '';
  position: absolute; inset: 0;
  background-image: url('assets/texture-kanji.png');
  background-size: 411px auto;
  opacity: 0.5;
  pointer-events: none;
}
.tabs a {
  position: relative;
  z-index: 1;
  height: 37px;                          /* mesure sur l'export, pas 32 */
  margin: 0 8px;
  border-radius: var(--r-pill);
  display: grid; place-items: center;
  font-size: var(--fs-12);
  font-weight: var(--fw-strong);
  color: var(--text-muted);
  text-decoration: none;
}
.tabs a.on {
  background: var(--surface-3);
  color: var(--text);
}
/* Branche de cerisier, a cheval sur le bord gauche de l'onglet actif.
   L'API images de Figma refusant d'exporter (429 persistant), la branche a
   ete detouree depuis l'export @2x de l'ecran 2 : cle sur la saturation
   (tige brune) combinee a la luminance (fleurs claires). */
.tabs a.on::before {
  content: '';
  position: absolute;
  left: 4px; top: 50%;
  width: 22px; height: 32px;
  transform: translateY(-50%);
  background: url('assets/branche-cerisier.png') center / contain no-repeat;
  pointer-events: none;
}

/* ---- Visuel de carte (370x167, r16, degrade metal) ------------- */
/* Hauteur 167 px. Les elements sont places explicitement plutot que
   repartis par le flux : la maquette donne leurs coordonnees relatives
   au haut de la carte (titre 17, puce 45, numero 98, pied 140). */
.cardface {
  position: relative;
  height: 167px;
  margin-top: 20px;
  border-radius: var(--r-lg);
  background: var(--grad-card-metal);
  color: var(--text-invert);
  overflow: hidden;
  padding: 11px 18px 16px;
}
.cardface .pan  { position: absolute; left: 18px; top: 98px; }
.cardface .foot { position: absolute; left: 18px; right: 18px; bottom: 17px; }
.cardface .brand { font-size: var(--fs-18); font-weight: var(--fw-hero); }
.cardface .puce {
  position: absolute; left: 2px; top: 53px;   /* mesure : or a x=44, y=342 */
  width: 133px; height: 37px; z-index: 2;
  background: url('assets/carte-puce.png') left center / contain no-repeat;
  pointer-events: none;
}
.cardface .pan   { font-size: var(--fs-18); font-weight: var(--fw-strong); letter-spacing: 0.04em; }
.cardface .membre { display: inline-flex; align-items: center; gap: 6px; }
.cardface .foot  { display: flex; align-items: center; gap: 10px; font-size: var(--fs-11); font-weight: var(--fw-body); }
.cardface .kanji { display: none; }   /* cuit dans le detourage du samourai */
.cardface .kanji-inutilise {
  position: absolute; right: 14px; top: 8px;
  font-size: 42px; font-weight: 800; line-height: 1.02;
  text-align: center;
  z-index: 2;
}
/* Le samourai occupe la moitie droite de la carte, decoupe en fondu.
   z-index 0 : il passe DERRIERE le kanji, comme dans la maquette. */
.cardface::after {
  content: '';
  position: absolute;
  right: 0; bottom: 0;
  width: 150px; height: 155px;
  z-index: 0;
  /* Detoure directement depuis la carte de l'export : mon ancien asset
     avait un cadrage different (rapport 0,79 contre 1,05) et ne pouvait
     pas couvrir les 162 px de large de la maquette. Le kanji est compris
     dans le detourage, il passe par-dessus le samourai. */
  background: url('assets/carte-samourai.png') right bottom / contain no-repeat;
  pointer-events: none;
}
.cardface > * { position: relative; z-index: 1; }

/* ---- Titres de section ---------------------------------------- */
.sec-title {
  margin: 20px 0 16px;
  font-size: var(--fs-12);
  font-weight: var(--fw-title);
  color: var(--text);
}

/* ---- Bloc choix de carte (370x253, r16, #151515) --------------- */
.panel {
  border-radius: var(--r-lg);
  background: var(--surface);
  padding: 16px;
}
.card-opt {
  display: flex; align-items: center; gap: 12px;
  border-radius: var(--r-md);
  background:
    radial-gradient(78% 135% at 97% 120%,
      rgba(228, 44, 46, 0.46) 0%, rgba(228, 44, 46, 0.16) 40%, rgba(228, 44, 46, 0) 74%),
    #272727;
  padding: 14px 14px;                    /* mesure : 61 px de haut */
}
/* Pastille ronde du logo. Relevee sur l'export Figma : ~43 px, fond
   #4F3B3B et bord #4A3939 — mais ces deux valeurs sont le RESULTAT d'un
   blanc translucide pose sur le degrade rouge de la carte (le meme point
   hors pastille vaut #151515, et le rapport n'est pas constant entre les
   canaux : ce n'est donc pas une couleur pleine). On reproduit la cause,
   pas la consequence, pour que la pastille suive le degrade comme dans la
   maquette. */
.card-opt .net {
  width: 43px; height: 43px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.card-opt .net svg { display: block; }   /* mesure : 43x41, pas de disque sombre */
.card-opt .net img { width: 43px; height: 41px; object-fit: contain; }
.card-opt .txt { flex: 1; }
.card-opt .txt b { display: block; font-size: var(--fs-14); font-weight: var(--fw-title); }
.card-opt .txt span { font-size: var(--fs-11); font-weight: var(--fw-label); color: rgba(255,255,255,0.8); }
.card-opt .check {
  position: relative;
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
}
.card-opt .check::before {                /* la tache, grisee */
  content: '';
  position: absolute; inset: 0;
  background: url('assets/tache-encre.png') center / contain no-repeat;
  opacity: 0.60;
}
.card-opt .check svg {
  position: relative; z-index: 1;         /* net, par-dessus la tache */
  width: 16px; height: 16px;
  border-radius: 50%; background: #fff; padding: 2px;
}

.feature-list { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 12px; }
.feature-list li { display: flex; align-items: center; gap: 12px; font-size: var(--fs-13); font-weight: var(--fw-body); }
.feature-list .ok { width: 22px; height: 22px; flex: none; }

.fee-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px dashed rgba(255,255,255,0.18);
  font-size: var(--fs-13);
}
.fee-row .k { color: var(--text-muted); font-weight: var(--fw-label); }
.fee-row .v { font-weight: var(--fw-strong); }

/* ---- Montant choisi (370x86, r16) ------------------------------ */
.amount-box {
  position: relative;
  height: 86px;
  border-radius: var(--r-lg);
  /* Releve sur l'export : #151515 uni, avec une lueur rouge sur le seul bord
     GAUCHE (#812828 a x=18, #281616 a x=90, puis plat). Le rouge plein
     precedent etait une invention, comme sur la ligne « Vane Standard ». */
  background:
    radial-gradient(46% 132% at -3% 50%,
      rgba(196, 56, 58, 0.66) 0%, rgba(150, 30, 32, 0.20) 38%, rgba(120, 22, 24, 0) 72%),
    #151515;
  overflow: hidden;
  padding: 16px 18px;
  display: flex; align-items: center; justify-content: space-between;
}
.amount-box .k { font-size: var(--fs-12); font-weight: var(--fw-label); color: rgba(255,255,255,0.85); }
.amount-box .v { font-size: var(--fs-26); font-weight: var(--fw-title); margin-top: 6px; }
.amount-box .cur {
  border: 1px solid rgba(255, 255, 255, 0.30);   /* discret, pas absent */
  border-radius: var(--r-pill);
  padding: 6px 15px;
  font-size: var(--fs-12); font-weight: var(--fw-body);
  color: var(--text);
}

/* ---- Pastilles de montant (369x36 @ y904) ---------------------- */
.chips { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 12px; }
.chips button {
  height: 36px;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid transparent;
  color: var(--text-muted);
  font-family: var(--font);
  font-size: var(--fs-13);
  font-weight: var(--fw-body);
  cursor: pointer;
}
.chips button.on {
  /* Corps #151515 comme les pastilles inactives, PLUS une lueur radiale
     ancree sur le bord GAUCHE a 35 % de la hauteur. Mon degrade lineaire
     n'atteignait jamais le neutre. */
  background-color: #151515;
  background-image: radial-gradient(60% 150% at 0% 35%,
    #FFD1D1 0%, #FF8585 14%, #FF5C5C 22%, #A42525 32%,
    #5C1818 44%, #2C1616 56%, #151515 80%);
  border-color: #EA5758;                 /* contour releve, moins sature */
  border-width: 1.5px;
  color: var(--text);
  font-weight: var(--fw-title);
}

/* ---- Recapitulatif (370x198, r16) ------------------------------ */
.summary { margin-top: 20px; }
.summary .row { display: flex; justify-content: space-between; font-size: var(--fs-13); padding: 6px 0; }
.summary .row .k { color: var(--text-muted); font-weight: var(--fw-label); }
.summary .row .v { font-weight: var(--fw-strong); }
.summary .sep { border-top: 1px dashed rgba(255,255,255,0.18); margin: 6px 0; }
.summary .total { display: flex; justify-content: space-between; align-items: baseline;
                  padding-top: 6px; font-size: var(--fs-16); font-weight: var(--fw-title); }
.summary .total .v { font-size: var(--fs-18); font-weight: var(--fw-hero); }
.summary .row .v { font-weight: var(--fw-title); }
.summary .total .k { font-size: var(--fs-16); font-weight: var(--fw-title); }
.summary .total .v { font-size: var(--fs-20); font-weight: var(--fw-hero); }

/* ---- Action principale (370x48, r207) -------------------------- */
/* Graisse 600 relevee, pas 700. */
.cta {
  font-weight: var(--fw-strong);
  width: 100%; height: 48px;
  margin-top: 16px;
  border: 0; border-radius: var(--r-pill);
  background: var(--grad-cta);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-14);
  font-weight: var(--fw-title);
  cursor: pointer;
}
.cta[disabled] { opacity: 0.5; cursor: not-allowed; }

/* ---- Barre d'accueil iOS --------------------------------------- */
.home-indicator {
  width: 140px; height: 5px;
  margin: 18px auto 0;
  border-radius: var(--r-pill);
  background: #fff;
}

/* ============================================================
   LISTES DE CARTES — ecrans 2 et 3, plus les etats 4, 5 et 6.
   Geometrie relevee sur les frames 127:32300 et 196:2748.
   ============================================================ */

.list { margin-top: 10px; display: grid; gap: 12px; }

/* ---- Ecran 2 : ligne « Top Up » (370x144, r12) -----------------
   Le haut de la carte est une ENCOCHE : un bandeau metallique dont le
   corps sombre remonte a gauche (21 px sous le bord) et redescend a
   droite (36 px), avec une courbe en S entre les deux.

   Ce bandeau est un degrade a double voile — clair en haut a gauche,
   sombre au milieu, vif en bas a droite. Le reproduire en CSS donnerait
   une approximation ; il est donc pose en image, exactement comme la
   texture kanji (arbitrage §5 de SPEC-8-ECRANS.md). Mesures relevees sur
   l'export @2x, pas estimees.

   Deux etats : carte active -> bandeau rouge et texte blanc ; carte
   fermee -> bandeau mauve grise et texte eteint. */
.card-row {
  position: relative;
  height: 136px;
  border-radius: var(--r-md);
  background: #1F1F1F url('assets/bandeau-carte-eteint.png') top left / var(--content-w) 28px no-repeat;
  padding: 21px 18px 12px;
  overflow: hidden;
  cursor: pointer;
}
/* La carte active porte un bandeau plus epais (36 px contre 28) : c'est
   la carte mise en avant. Mesure relevee sur l'export, pas un choix. */
.card-row.actif {
  box-shadow: 0 0 10px rgba(235, 119, 120, 0.18);   /* portee 9 px relevee */
  height: 144px;
  background-image: url('assets/bandeau-carte-actif.png');
  background-size: var(--content-w) 36px;
  padding-top: 29px;
}

.card-row .name { font-size: 17px; font-weight: var(--fw-title); color: #A5A5A5; }
.card-row.actif .name { color: var(--text); }

.card-row .pan  { margin-top: 14px; font-size: 16px; font-weight: var(--fw-body);
                  letter-spacing: 0.08em; color: rgba(255,255,255,.9); }

/* Separateur en pointilles (#353535 releve sur l'export), pas un trait plein. */
.card-row .foot { display: flex; align-items: center; justify-content: space-between;
                  margin-top: 13px; padding-top: 11px;
                  /* Tirets 6/4 releves. `border: dashed` donne 3/2, non pilotable. */
                  border-top: 0;
                  background: repeating-linear-gradient(90deg,
                    #353535 0 6px, rgba(0,0,0,0) 6px 10px) top left / 100% 1px no-repeat; }

.card-row .amount { font-size: var(--fs-12); font-weight: var(--fw-title); color: #A5A5A5; }
.card-row.actif .amount { color: var(--text); }

/* Pastille d'etat, commune aux deux ecrans.
   Dans la maquette le LIBELLE reste clair et seule la PASTILLE porte la
   couleur — verte si active, rouge si fermee. Colorer le libelle (ce que
   faisait la version precedente) etait une invention. */
.state { display: inline-flex; align-items: center; gap: 6px;
         font-size: var(--fs-11); font-weight: var(--fw-body);
         color: rgba(255, 255, 255, 0.86); }
.state::before { content: ''; width: 5px; height: 5px; border-radius: 50%; }
.state.on::before  { background: #41DC22; }
.state.off::before { background: #DC2222; }
.card-row:not(.actif) .state { color: #FFFFFF; }   /* le libelle reste blanc */

/* ---- Ecran 3 : carte detaillee (370x174, r12) ----------------- */
.card-item {
  position: relative;
  height: 174px;                         /* mesure : pas 186 - 12 de gouttiere */
  border-radius: var(--r-md);
  background: #000;
  border: 1px solid rgba(255, 255, 255, 0.38);   /* lisere clair, pas --hairline */
  padding: 16px 16px 14px;
  overflow: hidden;
}
.card-item::after {                      /* halo rouge : cotes + bas */
  content: '';
  position: absolute; inset: 0; border-radius: inherit;
  /* Le foyer n'est pas centre : releve sur l'export, le point le plus vif
     est en BAS A GAUCHE (#E45D5E vers x=65), avec une remontee plus faible
     vers x=335. La montee commence aux deux tiers de la hauteur. */
  background:
    radial-gradient(50% 20% at 50% 0%,
      rgba(238, 150, 150, 0.80) 0%, rgba(190, 80, 82, 0.35) 38%, rgba(140, 30, 32, 0) 100%),
    radial-gradient(62% 52% at 17% 103%,
      rgba(255, 150, 150, 1) 0%, rgba(226, 84, 86, 0.72) 34%, rgba(160, 32, 34, 0) 74%),
    radial-gradient(50% 44% at 90% 103%,
      rgba(206, 56, 59, 0.70) 0%, rgba(150, 28, 30, 0) 72%),
    radial-gradient(130% 40% at 50% 106%,
      rgba(158, 30, 32, 0.70) 0%, rgba(120, 20, 22, 0) 76%);
  pointer-events: none;
}
.card-item > * { position: relative; z-index: 1; }
.card-item .name    { font-size: var(--fs-13); font-weight: var(--fw-title); }
.card-item .created { margin-top: 10px; font-size: var(--fs-11); font-weight: var(--fw-label);
                      color: var(--text-muted); }
.card-item .balance-chip {
  position: absolute; top: 20px; right: 16px;
  width: 72px; height: 40px; border-radius: 9px;
  background: #000; border: 1px solid rgba(255, 255, 255, 0.36);
  display: grid; place-items: center;
  font-size: var(--fs-14); font-weight: var(--fw-title);
  z-index: 2;
}
.card-item .mid { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.card-item .badge {
  height: 26px; padding: 0 9px; border-radius: var(--r-sm);   /* r=8 releve */
  background: rgba(255, 255, 255, 0.20);
  border: 0;                             /* la maquette n'a AUCUNE bordure */
  color: rgba(255, 255, 255, 0.88);
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-11); font-weight: var(--fw-body);
}
.card-item .badge::before {
  content: ''; width: 4px; height: 4px; border-radius: 50%; background: #41DC22;
}
.card-item .badge.off::before { background: var(--danger); }
.card-item .pan { font-size: var(--fs-12); letter-spacing: .08em; }
.card-item .view {
  margin-top: 14px; height: 40px; width: 100px;
  border: 0; border-radius: var(--r-pill);   /* pilule pleine, r=20 releve */
  background: #fff; color: #000;
  font-family: var(--font); font-size: var(--fs-13); font-weight: var(--fw-title);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer;
}

/* ---- Bouton « Create New Card » (370x48) ---------------------- */
.create-card {
  width: 100%; height: 48px; margin-top: 16px;
  border: 0; border-radius: var(--r-pill);
  background: var(--grad-cta); color: var(--text);
  font-family: var(--font); font-size: var(--fs-13); font-weight: var(--fw-title);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer;
}

/* ---- Ecran 4 : chargement ------------------------------------- */
/* La maquette ne montre NI en-tete, NI solde, NI onglets pendant le
   chargement : c'est un plein ecran. Voir `.en-chargement` plus bas. */
.loading { padding: 0; text-align: center; }
.loading .visual { width: 285px; height: 151px; margin: 0 auto 14px;
                   background: url('assets/cartes-duo.png') center/contain no-repeat; }
.loading .msg { font-size: var(--fs-20); font-weight: var(--fw-title); }
.loading .sub { margin-top: 8px; font-size: var(--fs-12); color: #ABABAB; }
.loading .bar { width: 210px; height: 20px; margin: 12px auto 0; border-radius: var(--r-pill);
                background: var(--surface); overflow: hidden; }
.loading .bar i { display: block; height: 100%; width: 61.5%; border-radius: inherit;
                  /* Remplissage FIGE a 61,5 % dans la maquette, et le degrade
                     s'ECLAIRCIT vers la droite. Mon animation etait inventee. */
                  background: linear-gradient(90deg, var(--vane-red-mid) 0%, var(--vane-red-bright) 100%); }
@keyframes vane-slide { 0% { transform: translateX(-100%);} 100% { transform: translateX(250%);} }

/* ---- Ecrans 5 et 6 : etats vides ------------------------------ */
.empty { padding: 75px 0 0; text-align: center; }
.empty--soleil { padding-top: 45px; }   /* mesure propre a l ecran 5 */
.empty .halo {
  width: 285px; height: 151px; margin: 0 auto 26px;
  background: url('assets/cartes-duo.png') center/contain no-repeat;
  /* Le drop-shadow etait une invention : la maquette a un champ radial
     ambiant large, pas une ombre portee collee a l'illustration. */
  filter: none;
}
.empty { position: relative; }
.empty:not(.empty--soleil)::before {
  content: '';
  position: absolute; z-index: -1; pointer-events: none;
  top: -140px; left: 50%;
  width: 600px; height: 600px; margin-left: -300px;
  background: radial-gradient(circle, rgba(235,119,120,0.22) 0%, rgba(235,119,120,0) 62%);
}
/* Ecran 5 : la maquette pose les cartes sur un soleil rouge avec des
   eclats, la ou l'ecran 6 n'a que le duo de cartes. Deux illustrations
   distinctes, verifiees sur les exports. */
.empty--soleil .halo {
  width: 345px; height: 230px; margin: 0 auto 18px;
  background-image: url('assets/cartes-soleil.png');
  filter: none;
}

.empty h3  { margin: 0; font-size: var(--fs-20); font-weight: var(--fw-title); }
.empty p   { margin: 10px 0 0; font-size: var(--fs-12); font-weight: var(--fw-label);
             color: var(--text-muted); }
.empty .cta { width: auto; min-width: 136px; padding: 0 26px; margin-top: 16px; height: 44px; }

/* ============================================================
   ECRANS 7 et 8 — ajout de fonds, puis choix de la cryptomonnaie.
   L'ecran 8 est l'ecran 7 avec une feuille modale par-dessus :
   meme page, un etat de plus. Geometrie : frames 249:17069 / 252:18649.
   ============================================================ */

/* ---- Barre de retour + titre (34x34 @ y63, titre @ y117) ------- */
.backbar { margin-top: 16px; }
.back-btn {
  position: relative; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%;
  /* Le rond est TRANSPARENT dans la maquette : le degrade de l'entete le
     traverse. Je l'avais rempli de noir plein. */
  background: transparent; border: 1px solid rgba(255, 255, 255, 0.53);   /* anneau mesure a 160 sur fond 53 */
  display: grid; place-items: center; cursor: pointer;
}
.back-btn svg { width: 20px; height: 20px; color: #fff; }
.page-title { margin-top: 20px; }
.page-title h1 { margin: 0; font-size: var(--fs-13); font-weight: var(--fw-title); }
.page-title p  { margin: 8px 0 0; font-size: var(--fs-11); font-weight: var(--fw-label);
                 color: var(--text-muted); }

/* ---- Montant saisi (centre, @ y238-306) ------------------------ */
.amount-display { margin-top: 68px; text-align: center; }
.amount-display .k {
  font-size: var(--fs-10); font-weight: var(--fw-label);
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
}
.amount-display .v {
  margin-top: 12px;
  font-size: var(--fs-36); font-weight: var(--fw-label); letter-spacing: -0.02em;
}
.amount-display .v .caret {
  display: inline-block; width: 1px; height: 30px; margin-left: 2px;
  background: #FFFFFF; vertical-align: -4px;
  animation: vane-blink 1s steps(1) infinite;
}
@keyframes vane-blink { 50% { opacity: 0; } }
.amount-display .bal { margin-top: 14px; font-size: var(--fs-10);
                       font-weight: var(--fw-label); color: var(--text-muted); }

/* ---- Clavier numerique iOS (402x291 @ y583, touches 126x47) ---- */
.keypad {
  margin-top: 28px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px 6px;
}
.keypad button {
  height: 47px;
  border: 0; border-radius: var(--r-xs);
  background: #646464;
  color: #fff;
  font-family: var(--font);
  font-size: var(--fs-25); font-weight: var(--fw-label);
  cursor: pointer;
}
.keypad button:active { background: #7a7a7a; }
.keypad button.ghost { background: transparent; font-size: var(--fs-20); }

/* ---- Feuille modale du choix de crypto (402x601 @ y273) -------- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(59, 59, 59, 0.55);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.sheet {
  position: fixed; left: 50%; bottom: 0; z-index: 41;
  width: min(100%, 402px); height: 601px;
  transform: translateX(-50%);
  background: #0C0C0C;                   /* releve sur l'export */
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: 16px var(--gutter) 30px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.38);   /* lisere d'arete */
  overflow-y: auto;
}
.sheet .grip {
  width: 44px; height: 6px; margin: 0 auto 22px;
  border-radius: var(--r-pill); background: #6E6E6E;
}
.sheet h2 { margin: 0; font-size: 16px; font-weight: var(--fw-title); }
.sheet .hint { margin: 8px 0 20px; font-size: 12px;
               font-weight: var(--fw-label); color: #B2B2B2; }

/* Une ligne crypto : 370x62, espacement 74 -> 12 de gouttiere. */
.crypto-row {
  height: 62px;
  margin-bottom: 12px;                   /* pas de 74 releve */
  padding: 0 14px;
  display: flex; align-items: center; gap: 12px;
  background: #181818;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: var(--r-md);
  cursor: pointer;
}
.crypto-row.on {
  /* La bordure rouge etait une INVENTION : la maquette garde le meme filet
     que les autres lignes. En revanche elle a une lueur exterieure et un
     remplissage qui s'eteint vers le bas. */
  border-color: rgba(255, 255, 255, 0.10);
  box-shadow: 0 -10px 28px rgba(225, 35, 37, 0.20);
  background: linear-gradient(180deg, #211818 0%, #251818 29%, #1C1818 71%, #181818 94%);
}
.crypto-row .sym {
  width: 46px; height: 46px; flex: none;
  background-size: contain; background-repeat: no-repeat; background-position: center;
}
.crypto-row .txt { flex: 1; }
.crypto-row .txt b { display: block; font-size: 14px; font-weight: var(--fw-title);
                     text-transform: uppercase; }
.crypto-row .txt span { font-size: 12px; font-weight: var(--fw-label);
                        color: #B2B2B2; }
.crypto-row .go { width: 20px; height: 20px; color: #B1B1B1; }


/* ============================================================
   Ecran 7 — ajouter des fonds.
   Releve sur l'export : le groupe bas (montants rapides, bouton,
   clavier) est plaque contre le bas de l'ecran, pas colle sous la
   saisie. Il manquait 110 px de respiration au milieu.
   ============================================================ */
.ecran-fonds { display: flex; flex-direction: column; min-height: 100svh; }
.ecran-fonds .wrap { flex: 1; display: flex; flex-direction: column; }
.ecran-fonds .bas { margin-top: auto; margin-bottom: 25px; }
.ecran-fonds .bas .cta { margin-top: 10px; }

/* Le libelle est en casse normale dans la maquette, pas en capitales. */
/* Position verifiee texte par texte contre la maquette :
   « Enter Amount » a y=238, « €50 » a 263, la ligne de solde a 306.
   Le 143 px precedent venait d'une mesure par blocs qui appariait mon
   libelle avec la ligne de solde de la maquette — 69 px de trop. */
.ecran-fonds .amount-display { margin-top: 74px; }
.ecran-fonds .amount-display .k {
  font-size: var(--fs-12); letter-spacing: 0; text-transform: none;
}
/* Interlignes releves sur la maquette : libelle 238-246, montant 263-290,
   solde 306-315 — soit 17 px puis 16 px d ecart. J avais 28 et 28. */
.ecran-fonds .amount-display .v   { margin-top: 1px; }
.ecran-fonds .amount-display .bal { margin-top: 2px; font-size: var(--fs-12); color: #FFFFFF; }
.ecran-fonds .page-title { margin-top: 16px; }
.ecran-fonds .page-title h1 { font-size: var(--fs-16); }

/* Clavier iOS : chaque touche porte ses lettres sous le chiffre. */
/* Bande de fond pleine largeur sous le clavier, absente chez moi. */
.ecran-fonds .keypad {
  background: #131313;
  margin-left: -10px; margin-right: -10px;
  padding: 6px 0 0;
}
.keypad { gap: 7px 6px; }
.keypad button {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0;
  line-height: 1.05;
}
.keypad button small {
  font-size: 9px; font-weight: var(--fw-strong);
  letter-spacing: 0.36em; opacity: 1; margin-top: 1px;
}
.keypad button.ghost { font-size: var(--fs-20); letter-spacing: 0.1em; }


/* ============================================================
   Ecran 4 — chargement plein ecran.
   La maquette masque la coquille : ni logo, ni carte de solde, ni
   onglets. Le bloc est centre verticalement.
   ============================================================ */
.en-chargement .appbar,
.en-chargement .balance,
.en-chargement .tabs { display: none; }
.en-chargement .wrap > :not(#viewCreating) { display: none !important; }
.en-chargement .lancement { display: none !important; }
.en-chargement .home-indicator { display: none; }
.en-chargement #viewCreating {
  display: flex !important;
  position: fixed;
  inset: 0;
  z-index: 300;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0 24px;
  min-height: 100dvh;
  min-height: 100svh;
  background: #080808;
}
.en-chargement .vane-page { display: flex; flex-direction: column; min-height: 100svh; }
.en-chargement .wrap { flex: 1; display: flex; flex-direction: column; justify-content: center;
                       padding-bottom: 0; }


/* ============================================================
   Fondu de bas d'ecran — le « brouillard » de la maquette.
   Absent de mon integration : la 4e carte descendait a pleine
   luminosite jusqu'au bord. Mesure par regression sur la carte 4
   comparee a la carte 3 (contenu identique) : alpha = 0 a y=791,
   plein a y=844, soit 84 px de haut, opacite pleine a 64 %.
   ============================================================ */
/* Reserve aux ecrans de liste : l'ecran 1 se termine sur son bouton. */
.vane-page:has(.list)::after {
  content: '';
  position: fixed;
  left: 50%; bottom: 0;
  transform: translateX(-50%);
  width: 100%;
  height: 84px;
  background: linear-gradient(180deg, rgba(8,8,8,0) 0%, #080808 64%, #080808 100%);
  pointer-events: none;
  z-index: 5;
}

/* La barre d'accueil etait POUSSEE HORS CHAMP par le flux quand la liste
   deborde. `absolute` dans un `.vane-page` d'au moins 100svh : elle tombe
   au bas du viewport sur un ecran court, ET au bas de la page sur l'ecran 1
   qui est long. `fixed` la collait au viewport, donc au milieu de la page. */
.vane-page { position: relative; min-height: 100svh; }
.home-indicator {
  position: absolute;
  left: 50%; bottom: 7px;
  transform: translateX(-50%);
  margin: 0;
  width: 133px; height: 5px;
  z-index: 10;
}

/* Halo de fond de l'ecran de chargement : plus haut et plus etale que le
   halo standard (ajustement par moindres carres, rmse 1,95 sur 97). */
.en-chargement .vane-glow { top: -160px; height: 340px; filter: blur(80px); }

/* ============================================================
   Ecran 5 — aucune carte.
   La maquette ne contient AUCUN bouton rouge sous le sous-titre :
   zero pixel sature sur toute la bande. Le mien etait une invention.
   ============================================================ */
.empty--soleil .cta { display: none; }

/* Lueur rouge ambiante derriere l'illustration, absente du PNG. */
.empty--soleil .halo { position: relative; margin: 0 auto 34px; }
.empty--soleil .halo::before {
  content: '';
  position: absolute; z-index: -1;
  left: 50%; top: 85px;
  width: 160px; height: 140px;
  margin: -70px 0 0 -80px;
  background: #692E31;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
}

/* ============================================================
   Ecran 3 — la barre « Creer une nouvelle carte » est FLOTTANTE
   dans la maquette : elle recouvre la 3e carte, a 30 px du bas.
   Chez moi elle suivait le flux et tombait hors de l'ecran.
   Un voile degrade la precede, comme sur l'ecran 2.
   ============================================================ */
.ecran-cartes #cardsList { margin-top: 20px; }
.ecran-cartes .wrap { padding-bottom: 96px; }
.vane-page:has(.list) .wrap { padding-bottom: 96px; }   /* mesure propre a l'ecran 3 */

.ecran-cartes .create-card {
  position: fixed;
  left: 50%; bottom: 30px;
  transform: translateX(-50%);
  width: var(--content-w);
  height: 48px;
  margin-top: 0;
  z-index: 20;
}
/* Le voile n'appartient qu'a l'ecran 3 : l'ecran 2 partage l'id #viewList
   et heritait d'un second fondu par-dessus le sien. */
.ecran-cartes #viewList::after {
  content: '';
  position: fixed;
  left: 50%; bottom: 0;
  transform: translateX(-50%);
  width: 100%;
  height: 112px;
  background: linear-gradient(180deg, rgba(8,8,8,0) 0%, #080808 40%);
  pointer-events: none;
  z-index: 10;
}


/* ============================================================
   Ecran « Details de la carte » — frames 477:577 / 479:3342.
   Toutes les coordonnees sont relevees sur le noeud Figma :
   rond de retour 34x34 a (16,63) · titre a y=74 · panneau 370x340
   rayon 16 a y=117 · libelles a x=34 · deux pilules 180x48 a y=473
   avec 10 px d'ecart · lueur #EB7778.
   ============================================================ */
.ecran-details .details-tete,
.ecran-depot .details-tete {
  position: relative;
  height: 34px;
  margin-top: 16px;
  display: flex; align-items: center;
}
.ecran-details .details-tete h1,
.ecran-depot .details-tete h1 {
  position: absolute; left: 0; right: 0;
  margin: 0; text-align: center;
  pointer-events: none;
  font-size: var(--fs-16); font-weight: var(--fw-title);
}

.details-panneau {
  position: relative;
  margin-top: 20px;
  height: 340px;
  padding: 15px 18px;   /* libelle mesure a y=137, panneau a y=117 */
  border-radius: var(--r-lg);
  /* Bordure relevee sur les 4 cotes : #9B3B3B a gauche, #753B3C a droite,
     #6B5252 en bas, #321C1C en haut. J'avais un filet blanc a 14 % qui
     disparaissait completement sur le bord gauche. */
  border: 1px solid transparent;
  background:
    linear-gradient(#000, #000) padding-box,
    linear-gradient(135deg, #9B3B3B 0%, #8A4040 30%, #753B3C 62%, #6B5252 100%) border-box;
  overflow: hidden;
}
.details-panneau::before {
  /* Le foyer est a GAUCHE (pic #862F2F vers x=86) et couvre tout le
     panneau, plus sature que ce que j'avais mis. */
  content: '';
  position: absolute; z-index: 0; pointer-events: none;
  inset: 0;
  /* Profil vertical releve a x=110 : pic #DC4243 vers 36 % de la hauteur,
     sombre au-dessus (#240D0D) comme en dessous (#231515), coins a #150F0F.
     Ma bande horizontale n avait aucune chute verticale : elle noyait tout
     le panneau. C est une ELLIPSE. */
  background: radial-gradient(64% 38% at 24% 34%,
    #DC4243 0%, #C93B3C 14%, #A93031 30%, #7B2324 48%,
    #4E1A1A 68%, #2A1414 84%, #180F0F 100%);
}
.details-panneau::after {                  /* torii en filigrane, comme le solde */
  content: '';
  position: absolute; z-index: 0; pointer-events: none;
  /* Le torii DEBORDE le panneau, qui le rogne a droite, et il est GRIS
     translucide — pas un petit motif rouge centre. Ma mesure precedente
     ne captait que sa partie la plus contrastee. */
  right: -26px; top: 0;
  width: 214px; height: 264px;
  background: url('assets/solde-torii.png') center / contain no-repeat;
  filter: grayscale(1) brightness(2.4);
  opacity: 0.30;
}
.details-panneau > * { position: relative; z-index: 1; }

.details-panneau .champ { display: flex; flex-direction: column; gap: 8px; }   /* ecart libelle/valeur mesure a 25 px */
.details-panneau .champ + .champ,
.details-panneau .champ-double + .champ { margin-top: 20px; }
.details-panneau .champ .k {
  font-size: var(--fs-12); font-weight: var(--fw-label);
  color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;
}
.details-panneau .champ .v { font-size: var(--fs-14); font-weight: var(--fw-body); }
.details-panneau .champ-double { display: flex; gap: 0; margin-top: 20px; }
.details-panneau .champ-double .champ { flex: 0 0 128px; }
.details-panneau .champ-double .champ + .champ { margin-top: 0; }
.details-panneau .champ:first-child .v { font-size: var(--fs-16); letter-spacing: 0.02em; }

.details-panneau .sep {
  margin: 20px 0 0;
  height: 1px;
  background: repeating-linear-gradient(90deg,
    rgba(255,255,255,0.09) 0 6px, rgba(0,0,0,0) 6px 10px);   /* la maquette n'a pas de trait net */
}

/* Deux pilules de 180x48, 10 px d'ecart. */
.details-actions {
  margin-top: 20px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.pilule {
  height: 48px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, 0.14);
  /* Releve a six abscisses : #3E2929 a gauche, #1D1919 a droite. Elle est
     REMPLIE, pas evidee comme je l'avais faite. */
  background: linear-gradient(90deg,
    #402A2A 0%, #392727 22%, #332425 44%, #2A1F20 66%, #231C1C 84%, #1D1919 100%);
  color: var(--text);
  font-family: var(--font); font-size: var(--fs-14); font-weight: var(--fw-strong);
  cursor: pointer;
}
.pilule.pleine { background: #FFFFFF; color: #000000; border-color: #FFFFFF; }


/* ============================================================
   Ecran de depot crypto — frames 258:18822 / 394:27276.
   Coordonnees relevees sur le noeud : carte du QR 260x258 rayon 6
   a (71,145) · libelles a x=16 · valeurs a x=29 · panneau de
   remarque 370x87 rayon 12 a y=621.
   ============================================================ */
.qr-carte {
  width: min(260px, 100%); aspect-ratio: 260 / 258;
  margin: 34px auto 0;
  border-radius: 6px;
  background: #FFFFFF;
  display: grid; place-items: center;
}
.qr-carte img { width: 226px; height: 221px; display: block; object-fit: contain; }

.depot-champ { margin-top: 26px; }
.depot-champ .k {
  display: block;
  font-size: var(--fs-12); font-weight: var(--fw-label);
  color: var(--text-muted);
}
.depot-champ .boite {
  position: relative;
  margin-top: 8px;
  min-height: 57px;
  padding: 9px 52px 9px 13px;
  border-radius: var(--r-sm);
  background: #141414;                   /* releve, pas le fond de page */
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.depot-champ .v {
  display: block;
  font-size: var(--fs-14); font-weight: var(--fw-strong);
  word-break: break-all;
}
.depot-champ .note {
  display: block; margin-top: 3px;
  font-size: var(--fs-12); font-weight: var(--fw-label);
  color: var(--text-muted);
}
.depot-champ .copie {
  position: absolute; right: 10px; top: 50%;
  transform: translateY(-50%);
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-xs);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  cursor: pointer;
}
.depot-champ .copie svg { width: 17px; height: 17px; }
.depot-champ .copie.fait { background: #2ED573; color: #000; }

.depot-remarque {
  position: relative;
  margin-top: 30px;
  min-height: 87px;
  padding: 16px 92px 16px 16px;
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: #1F0B0B;                    /* releve : teinte rouge, pas un gris */
  overflow: hidden;
}
.depot-remarque::after {                  /* le visuel 72x72 a x=299 */
  content: '';
  /* Ce sont des DIAMANTS ETHEREUM, pas des cartes. Detoures de la
     reference du depot : x 305..385, y 630..701. */
  position: absolute; right: 0; top: 5px;
  width: 86px; height: 78px;
  background: url('assets/note-icone.png') center / contain no-repeat;
  opacity: 1;
  pointer-events: none;
}
.depot-remarque b { display: block; font-size: var(--fs-14); font-weight: var(--fw-title); }
.depot-remarque p {
  margin: 6px 0 0;
  font-size: var(--fs-12); font-weight: var(--fw-label);
  color: var(--text-muted); line-height: 1.45;
}


/* ============================================================
   Ecran de lancement — frames 480:3456 / 482:6163.
   Releve : fond #080808, logo 193x80 a (104,397), soit exactement
   centre dans les deux axes. Aucun texte, donc aucune traduction.
   ============================================================ */
.lancement.seul { position: absolute; }
.lancement {
  position: fixed; inset: 0; z-index: 60;
  /* Releve colonne par colonne : halo rouge en haut (#6A2523 au pic vers
     10 % de la hauteur), eteint sur #080808 des la mi-hauteur. Le logo
     est GRIS metal, pas rouge : c'est un autre asset. */
  /* Releve tous les 75 px : #6B2423 a y=50, #662322 a 125, #491A1A a 200,
     #241010 a 275, #0F0A0A a 350. Mon degrade mourait des y=225. */
  background:
    /* Assombrissement lateral : #541E1D aux bords contre #6E2524 au centre. */
    radial-gradient(58% 30% at 50% 6%, rgba(0,0,0,0) 0%, rgba(0,0,0,0.10) 100%),
    /* Arrets verticaux poses aux six ordonnees mesurees. */
    linear-gradient(180deg,
      #6E2524 0%, #6B2423 5.7%, #662322 14.3%, #491A1A 22.9%,
      #241010 31.5%, #0F0A0A 40%, #080808 48.6%, #080808 100%);
  display: flex; flex-direction: column; align-items: center;
}
.lancement .statusbar { width: 100%; flex: none; position: absolute; top: 0; left: 0; }
.lancement img {
  width: 180px; height: 69px; object-fit: contain;
  margin: auto;                          /* centre sur les 874 px, pas sous la barre */
}


/* Carte choisie dans l'onglet Recharger : la selection doit se voir. */
.card-row.choisie { outline: 1.5px solid var(--vane-red-bright); outline-offset: -1px; }
#topupPanel { margin-top: 22px; padding-bottom: 24px; }
#topupPanel .sec-title { margin-top: 0; }


/* ============================================================
   Barre d'etat et barre d'accueil : DECOR DE MAQUETTE.
   Dans une mini-app Telegram, l'heure, le reseau, le wifi, la batterie
   et l'indicateur d'accueil sont dessines par LE TELEPHONE, au-dessus
   de la page. Les dessiner ici les DOUBLE, avec une heure figee a 9:41.
   Son app d'origine n'en dessine aucune — verifie dans son depot.

   Elles restent dans le HTML parce que sans elles tout le rendu remonte
   de 47 px et aucune comparaison au pixel avec la maquette ne tient.
   Elles ne s'affichent donc QUE si le document porte la classe `maquette`,
   posee par l'apercu et par le script de capture. En production, rien.
   ============================================================ */
.statusbar,
.home-indicator { display: none; }
body.maquette .statusbar { display: flex; }
body.maquette .home-indicator { display: block; }


/* ============================================================
   Les deux animations du fichier Figma, avec leurs parametres
   exacts lus dans les donnees de prototype :

     ecran de chargement — Group 2085665937 (l'illustration des
       deux cartes, 247x148 a 77,264) : 900 ms, EASE_IN_AND_OUT,
       declencheur AFTER_TIMEOUT quasi immediat -> elle BOUCLE.

     ecran de lancement — le Logo (193x80 a 104,397) :
       500 ms, EASE_IN, une seule fois a l'ouverture.

   Les durees et les courbes sont relevees, pas choisies. Ce que
   Figma ne dit pas, c'est QUELLE propriete bouge : `CHANGE_TO`
   interpole vers une variante dont je n'ai pas le contenu.
   Le mouvement ci-dessous est donc une proposition ; les timings,
   eux, sont ceux du fichier.
   ============================================================ */

@keyframes vane-cartes-flottent {
  0%   { transform: translateY(0)      rotate(0deg); }
  50%  { transform: translateY(-7px)   rotate(-1.2deg); }
  100% { transform: translateY(0)      rotate(0deg); }
}
.loading .visual {
  animation: vane-cartes-flottent 1800ms ease-in-out infinite;
}

@keyframes vane-logo-entre {
  from { opacity: 0; transform: scale(0.88); }
  to   { opacity: 1; transform: scale(1); }
}
.lancement img {
  animation: vane-logo-entre 500ms ease-in both;
}

/* Un utilisateur qui a demande moins de mouvement n'en recoit aucun. */
@media (prefers-reduced-motion: reduce) {
  .loading .visual,
  .lancement img { animation: none; }
}


/* ============================================================
   Bouton « + » du solde.
   Le fichier Figma ne declare AUCUNE animation dessus : chaque
   element de sa zone a ete sonde, on n'y trouve qu'un componentId
   sur l'icone, qui est une reference de composant.

   L'owner en veut une. On reprend donc le seul vocabulaire que le
   fichier utilise pour un element qui boucle : 900 ms EASE_IN_AND_OUT,
   comme l'illustration de l'ecran de chargement. La tache d'encre
   respire, le « + » reste net.
   ============================================================ */
@keyframes vane-encre-respire {
  0%   { transform: scale(1)     rotate(0deg); }
  50%  { transform: scale(1.055) rotate(2.5deg); }
  100% { transform: scale(1)     rotate(0deg); }
}
.balance .add {
  animation: vane-encre-respire 1800ms ease-in-out infinite;
  transform-origin: 50% 50%;
}
.balance .add::after {
  /* Le « + » ne suit pas la respiration : il resterait illisible. */
  animation: vane-encre-respire 1800ms ease-in-out infinite reverse;
}
.balance .add:active { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .balance .add,
  .balance .add::after { animation: none; }
}


/* Saisie libre du montant : le champ doit etre invisible en tant que
   champ — meme corps, meme graisse, meme couleur que le texte qu'il
   remplace. Seul le curseur trahit qu'on peut ecrire. */
.amount-box .v { display: inline-flex; align-items: baseline; }
.amount-box .v .sym { font: inherit; }
.amount-box .saisie {
  font: inherit; color: inherit;
  background: none; border: 0; padding: 0; margin: 0;
  width: 5ch; min-width: 2ch;
  caret-color: var(--vane-red-bright);
  outline: none;
  font-variant-numeric: tabular-nums;
}
.amount-box .saisie:focus-visible { box-shadow: 0 2px 0 var(--vane-red-bright); }


/* Notice de confirmation, posee au-dessus de tout. */
.vane-notice {
  position: fixed; z-index: 90;
  left: 50%; bottom: 26px;
  transform: translate(-50%, 14px);
  width: min(calc(100vw - 32px), 398px);
  padding: 13px 16px;
  border-radius: var(--r-md);
  background: #171312;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 260ms ease-out, transform 260ms ease-out;
  pointer-events: none;
}
.vane-notice.vue { opacity: 1; transform: translate(-50%, 0); }
.vane-notice b {
  display: block;
  font-size: var(--fs-14); font-weight: var(--fw-title);
}
.vane-notice span {
  display: block; margin-top: 3px;
  font-size: var(--fs-12); font-weight: var(--fw-label);
  color: var(--text-muted);
}
@media (prefers-reduced-motion: reduce) {
  .vane-notice { transition: none; }
}


/* Ecran de chargement des details : tant qu'il tient, le detail est masque. */
body:not(.chargement) .ecran-details #viewLoading { display: none; }
body.chargement .ecran-details .details-panneau,
body.chargement .ecran-details .details-actions,
body.chargement .ecran-details .details-note { display: none; }



/* Montant de recharge saisissable : le champ doit etre indiscernable du
   texte qu'il remplace — meme corps, meme graisse, meme couleur. Seul le
   curseur rouge indique qu'on peut ecrire. */
.amount-box .v.saisie { display: flex; align-items: baseline; gap: 1px; }
.amount-box .v.saisie .dev { font: inherit; color: inherit; }
.amount-box .v.saisie input {
  font: inherit; color: inherit;
  background: none; border: 0; padding: 0; margin: 0;
  width: 5ch; min-width: 0;
  font-variant-numeric: tabular-nums;
  caret-color: var(--vane-red);
  outline: none;
  -moz-appearance: textfield;
}
.amount-box .v.saisie input::-webkit-outer-spin-button,
.amount-box .v.saisie input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }


/* ------------------------------------------------------------------
   Bouton « + » — cale sur la reference Figma, mesuree sur 12 exports
   qui donnent tous les MEMES valeurs : tache blanche 45x45, cercle
   rouge 20x20, cercle centre dans la tache (ecart +0,5 px).

   Trois ecarts corriges d'un coup :
   1. la tache faisait ~56 px au lieu de 45  -> background-size explicite
   2. le cercle faisait ~24 px au lieu de 20 -> taille + box-sizing
   3. le cercle tombait 8 px trop bas.

   Le 3 n'etait pas un probleme de centrage mais de STRUCTURE : la boite
   est une grille, et elle contient DEUX elements — le texte « + » et le
   ::after. La grille les empilait donc sur deux lignes, poussant le
   cercle en seconde ligne. Le sortir du flux avec inset+margin:auto le
   centre sur la boite entiere, et ne touche pas a `transform` — que
   l'animation de respiration s'approprie (elle avait deja efface une
   premiere tentative de recentrage par translateY).
   ------------------------------------------------------------------ */
.balance .add {
  /* 46 et non 45 : `background-size` dimensionne le PNG ENTIER (92x93),
     alors que le blanc n'en occupe que 90x91. 45 x 92/90 = 46,0 -> le
     blanc rendu tombe pile sur les 45 px de la reference. */
  background-size: 46px 46px;
}
.balance .add::after {
  position: absolute;
  inset: 0;
  margin: auto;
  box-sizing: border-box;
  width: 20px; height: 20px;
  border-width: 1.5px;
  background:
    linear-gradient(var(--vane-red), var(--vane-red)) center / 9px 1.5px no-repeat,
    linear-gradient(var(--vane-red), var(--vane-red)) center / 1.5px 9px no-repeat;
}
