/* ══════════════════════════════════════════════════════════════════════════════════════════
   Mes Garanties — feuille de style
   Reprend les jetons d'AlexIA (couleurs, rayons, écarts, élévation, échelle typographique) pour
   que les deux produits se ressemblent, mais l'application est autonome : rien n'est partagé.
   Conçue téléphone d'abord — la barre d'onglets est en bas, à portée de pouce.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  /* Fonds, textes, trait */
  --bg:#F7F6F2; --bg2:#EFEDE7; --bg3:#E8E5DE;
  --white:#FFFFFF; --text:#1C1B18; --muted:#6B6860; --subtle:#8A877F;
  --border:#DDD9D0;

  /* Accent */
  --accent:#1A4ED8; --accent-h:#1540B8; --accent-l:#EEF2FF; --accent-t:rgba(26,78,216,.08);

  /* Sémantique — quatre rôles par teinte : -d texte · plein · -b bordure · -l/-xl fond */
  --green:#16a34a; --green-d:#15803d; --green-b:#86efac; --green-l:#dcfce7; --green-xl:#f0fdf4;
  --orange:#d97706; --orange-d:#92400e; --orange-b:#fde68a; --orange-l:#fef3c7; --orange-xl:#fffbeb;
  --red:#dc2626; --red-d:#b91c1c; --red-b:#fecaca; --red-l:#fee2e2; --red-xl:#fef2f2;
  --blue:#2563eb; --blue-d:#1e40af; --blue-b:#bfdbfe; --blue-l:#dbeafe; --blue-xl:#eff6ff;
  --purple:#7c3aed; --purple-d:#7e22ce; --purple-b:#e9d5ff; --purple-l:#ede9fe;
  --sky:#0ea5e9; --sky-d:#0369a1; --sky-b:#bae6fd; --sky-l:#e0f2fe;
  --grey:#6b7280; --grey-d:#475569; --grey-b:#d1d5db; --grey-l:#e2e8f0; --grey-xl:#f1f5f9;

  /* Rayons, écarts */
  --r-xs:4px; --r-sm:8px; --r:12px; --r-lg:16px;
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px;

  /* Typographie */
  --font:'Inter',system-ui,-apple-system,sans-serif;
  --fs-2xs:10px; --fs-xs:11px; --fs-sm:12px; --fs-md:13px;
  --fs-base:14px; --fs-lg:16px; --fs-xl:20px; --fs-2xl:26px;

  /* Élévation — deux couches par cran : une proche qui dessine, une lointaine qui décolle */
  --e1:0 1px 2px rgba(28,27,24,.06),0 1px 1px rgba(28,27,24,.04);
  --e2:0 2px 4px rgba(28,27,24,.06),0 4px 8px rgba(28,27,24,.05);
  --e3:0 4px 8px rgba(28,27,24,.07),0 12px 20px rgba(28,27,24,.07);
  --e4:0 8px 16px rgba(28,27,24,.08),0 24px 48px rgba(28,27,24,.12);

  /* Gabarit */
  --tabbar:64px;

  /* Halos d'ambiance. Ils ont leurs propres jetons parce qu'un dégradé se règle à l'opacité,
     pas à la teinte : réutiliser `--accent-l` donnait un voile invisible sur le fond crème. */
  --halo-1:rgba(26,78,216,.13);
  --halo-2:rgba(124,58,237,.10);
  --halo-verrou-1:rgba(26,78,216,.20);
  --halo-verrou-2:rgba(124,58,237,.16);

  color-scheme:light;
}

:root[data-theme="dark"]{
  --bg:#12161F; --bg2:#1A1F2B; --bg3:#232938;
  --white:#1E2430; --text:#E8EAED; --muted:#9BA1AE; --subtle:#767C89;
  --border:#2E3542;

  --accent:#5B8DEF; --accent-h:#7BA4F5; --accent-l:#1C2740; --accent-t:rgba(91,141,239,.14);

  --green:#34d399; --green-d:#6ee7b7; --green-b:#1d5c45; --green-l:#13342a; --green-xl:#102620;
  --orange:#fbbf24; --orange-d:#fcd34d; --orange-b:#6b4c15; --orange-l:#3a2c10; --orange-xl:#2a2009;
  --red:#f87171; --red-d:#fca5a5; --red-b:#6e2626; --red-l:#3a1a1a; --red-xl:#2a1313;
  --blue:#60a5fa; --blue-d:#93c5fd; --blue-b:#1e3a68; --blue-l:#1b2941; --blue-xl:#141d2e;
  --purple:#a78bfa; --purple-d:#c4b5fd; --purple-b:#3f2d6b; --purple-l:#241b3d;
  --sky:#38bdf8; --sky-d:#7dd3fc; --sky-b:#0c4a6e; --sky-l:#0d2c40;
  --grey:#9ca3af; --grey-d:#cbd5e1; --grey-b:#3a4252; --grey-l:#2a3140; --grey-xl:#222835;

  /* Une ombre noire est invisible sur du bleu nuit : les crans sont redéfinis plus opaques. */
  --e1:0 1px 2px rgba(0,0,0,.34),0 1px 1px rgba(0,0,0,.30);
  --e2:0 2px 4px rgba(0,0,0,.38),0 4px 8px rgba(0,0,0,.34);
  --e3:0 4px 8px rgba(0,0,0,.42),0 12px 20px rgba(0,0,0,.40);
  --e4:0 8px 16px rgba(0,0,0,.46),0 24px 48px rgba(0,0,0,.50);

  /* La nuit, les mêmes halos éclaircissent au lieu d'assombrir : on remonte l'opacité et on
     part de teintes plus claires, sans quoi ils se noient dans le bleu nuit. */
  --halo-1:rgba(91,141,239,.16);
  --halo-2:rgba(167,139,250,.12);
  --halo-verrou-1:rgba(91,141,239,.24);
  --halo-verrou-2:rgba(167,139,250,.18);

  color-scheme:dark;
}

*{box-sizing:border-box;margin:0;padding:0;}
html{-webkit-text-size-adjust:100%;}

/* ⚠️ L'attribut `hidden` ne vaut qu'un `display:none` de feuille par défaut : n'importe quelle
   règle posant un `display` explicite le bat, et l'élément reste visible. C'est ce qui faisait
   apparaître « Code oublié ? » et « Retour » sur l'écran de création, où ils n'ont rien à
   faire — tous les boutons portent `display:inline-flex`. */
[hidden]{display:none !important;}
/* Un aplat unique fait « page web » ; deux halos pâles fixés en haut donnent de la profondeur
   sans jamais gêner la lecture — ils restent sous 15 % d'opacité, ne portent aucune information
   et ne bougent pas au défilement. */
body{
  font-family:var(--font);color:var(--text);
  font-size:var(--fs-base);line-height:1.5;min-height:100vh;
  background:var(--bg);
  background-image:
    radial-gradient(90% 45% at 12% -5%, var(--halo-1) 0%, transparent 55%),
    radial-gradient(70% 35% at 100% 0%, var(--halo-2) 0%, transparent 60%);
  background-attachment:fixed;
  overscroll-behavior-y:none;
  -webkit-tap-highlight-color:transparent;
}
button,input,textarea,select{font-family:var(--font);}
button{cursor:pointer;}
a{color:var(--accent);text-decoration:none;}
img{max-width:100%;}

/* Lien d'évitement — hors écran, jamais display:none, qui le retirerait de la tabulation. */
.skip-link{position:fixed;top:8px;left:-9999px;z-index:9999;background:var(--accent);color:#fff;
  padding:10px 16px;border-radius:var(--r-sm);font-size:var(--fs-md);font-weight:600;box-shadow:var(--e2);}
.skip-link:focus{left:8px;outline:2px solid var(--white);outline-offset:2px;}

/* ─────────────────────────────────────── BARRE SUPÉRIEURE ─────────────────────────────────── */
/* Translucide et floutée : le contenu qui passe dessous reste deviné, ce qui donne la
   profondeur d'une application native. Le repli opaque couvre les navigateurs sans flou —
   sans lui, le texte passerait sur le texte. */
.topbar{
  position:sticky;top:0;z-index:100;
  background:var(--white);
  border-bottom:1px solid var(--border);
  padding:calc(env(safe-area-inset-top,0px) + var(--sp-4)) var(--sp-4) var(--sp-3);
  display:flex;align-items:flex-end;gap:var(--sp-3);
}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .topbar{
    background:color-mix(in srgb, var(--white) 78%, transparent);
    -webkit-backdrop-filter:saturate(180%) blur(16px);
    backdrop-filter:saturate(180%) blur(16px);
  }
}
.page-title{font-size:26px;font-weight:800;letter-spacing:-.7px;margin:0;flex:1;min-width:0;
  line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.topbar-actions{display:flex;gap:var(--sp-2);flex-shrink:0;}

/* ────────────────────────────────────────── BOUTONS ───────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:10px 16px;border-radius:var(--r-sm);border:1px solid transparent;
  font-size:13.5px;font-weight:600;line-height:1.2;
  transition:background .15s,border-color .15s,box-shadow .15s,color .15s;
  white-space:nowrap;
}
.btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.btn-primary{background:var(--accent);color:#fff;}
.btn-primary:hover{background:var(--accent-h);}
.btn-ghost{background:var(--white);color:var(--text);border-color:var(--border);}
.btn-ghost:hover{background:var(--bg2);}
.btn-danger{background:var(--red);color:#fff;}
.btn-danger:hover{filter:brightness(.93);}
.btn-soft{background:var(--accent-l);color:var(--accent);border-color:transparent;}
.btn-soft:hover{background:var(--accent-t);}
.btn-sm{padding:7px 12px;font-size:12.5px;}
.btn-lg{padding:14px 22px;font-size:var(--fs-lg);}
.btn-block{width:100%;}
.btn:disabled{opacity:.5;cursor:not-allowed;}
.btn-icon{
  width:38px;height:38px;padding:0;border-radius:var(--r-sm);background:var(--bg2);
  border:1px solid var(--border);font-size:var(--fs-lg);color:var(--text);
  display:inline-flex;align-items:center;justify-content:center;transition:background .12s;
}
.btn-icon:hover{background:var(--bg3);}
.btn-icon:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* ──────────────────────────────────────── CONTENEUR ───────────────────────────────────────── */
.vue{display:none;padding:var(--sp-4);
  padding-bottom:calc(var(--tabbar) + env(safe-area-inset-bottom,0px) + 90px);
  max-width:760px;margin:0 auto;}
.vue.active{display:block;}
.sect-title{font-size:var(--fs-sm);font-weight:700;text-transform:uppercase;letter-spacing:.6px;
  color:var(--muted);margin:var(--sp-5) 0 var(--sp-2);}
.sect-title:first-child{margin-top:0;}

/* ───────────────────────────────────── RECHERCHE ET FILTRES ───────────────────────────────── */
.search-wrap{position:relative;margin-bottom:var(--sp-3);}
.search-wrap .icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);
  font-size:var(--fs-lg);pointer-events:none;opacity:.75;}
.search-input{
  width:100%;padding:12px 40px 12px 42px;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);color:var(--text);font-size:var(--fs-lg);
  transition:border-color .12s,box-shadow .12s;
}
.search-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-t);}
.search-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:var(--bg2);
  border:none;border-radius:50%;width:26px;height:26px;color:var(--muted);font-size:var(--fs-lg);
  line-height:1;display:none;align-items:center;justify-content:center;}
.search-clear.on{display:inline-flex;}
.search-clear:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* LES FILTRES PASSENT À LA LIGNE, ils ne défilent plus. En défilement horizontal sans barre
   visible (scrollbar-width:none), la quatrième pastille — « ♾️ À vie » — était coupée par le bord
   droit sur un téléphone : 406 px de pastilles dans 343 px de large. Rien ne disait qu'il y avait
   à faire glisser, alors on lisait un défaut d'affichage, pas une invitation.
   Ils sont quatre, définis dans le code : une seconde ligne coûte 40 px et ne cache rien. */
/* Retour à la ligne, et non défilement horizontal : une pilule à demi sortie de l'écran ne se
   voit pas, et le filtre qu'elle porte reste introuvable. Deux rangées coûtent 40 px et
   montrent tout. Les 3 px de marge laissent respirer l'ombre des pilules. */
.pills{display:flex;flex-wrap:wrap;gap:var(--sp-2);
  padding:3px;margin:0 -3px var(--sp-3);}
.pill{
  flex-shrink:0;padding:8px 15px;border-radius:999px;border:1px solid var(--border);
  background:var(--white);color:var(--muted);font-size:var(--fs-md);font-weight:600;
  box-shadow:var(--e1);
  transition:background .12s,color .12s,border-color .12s,box-shadow .12s;
}
.pill:hover{background:var(--bg2);}
.pill.on{
  background:linear-gradient(135deg, var(--accent) 0%, #3f6ae0 100%);
  color:#fff;border-color:transparent;
  box-shadow:0 3px 10px var(--accent-t), 0 1px 2px rgba(28,27,24,.08);
}
.pill:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.pill .n{opacity:.65;margin-left:5px;font-weight:500;}

/* ───────────────────────────────────── CARTES DE GARANTIE ─────────────────────────────────── */
.liste{display:flex;flex-direction:column;gap:var(--sp-3);}
.gcard{
  display:flex;gap:var(--sp-3);align-items:stretch;width:100%;text-align:left;
  background:var(--white);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--e1);padding:14px;padding-left:var(--sp-5);overflow:hidden;
  position:relative;transition:box-shadow .15s,border-color .15s;
}
.gcard:hover{box-shadow:var(--e2);border-color:var(--grey-b);}
.gcard:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
/* La bande d'état en dégradé plutôt qu'un aplat : elle capte l'œil sans le retenir, et le
   statut se lit avant même d'avoir lu le nom du produit. */
.gcard::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:5px;
  background:linear-gradient(180deg, var(--grey-b) 0%, var(--grey-l) 100%);
}
.gcard.s-ok::before{background:linear-gradient(180deg,#22c55e 0%,#16a34a 100%);}
.gcard.s-bientot::before{background:linear-gradient(180deg,#f59e0b 0%,#d97706 100%);}
.gcard.s-expire::before{background:linear-gradient(180deg,#ef4444 0%,#dc2626 100%);}
.gcard.s-avie::before{background:linear-gradient(180deg,#a78bfa 0%,#7c3aed 100%);}

.gcard-vignette{
  width:58px;height:58px;flex-shrink:0;border-radius:var(--r);background:var(--bg2);
  display:flex;align-items:center;justify-content:center;font-size:28px;overflow:hidden;
  border:1px solid var(--border);
  box-shadow:inset 0 1px 3px rgba(28,27,24,.06);
}
.gcard-vignette img{width:100%;height:100%;object-fit:cover;}
.gcard-corps{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.gcard-titre{font-size:var(--fs-lg);font-weight:700;line-height:1.3;letter-spacing:-.2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.gcard-sous{font-size:var(--fs-md);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.gcard-bas{display:flex;align-items:center;gap:var(--sp-2);margin-top:6px;flex-wrap:wrap;}

.badge{
  display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:999px;
  font-size:var(--fs-xs);font-weight:700;letter-spacing:.2px;white-space:nowrap;
}
.b-green{background:var(--green-l);color:var(--green-d);}
.b-orange{background:var(--orange-l);color:var(--orange-d);}
.b-red{background:var(--red-l);color:var(--red-d);}
.b-blue{background:var(--blue-l);color:var(--blue-d);}
.b-purple{background:var(--purple-l);color:var(--purple-d);}
.b-gray{background:var(--grey-l);color:var(--grey-d);}

.gcard-prix{font-size:var(--fs-md);color:var(--subtle);font-weight:600;margin-left:auto;}

/* Barre de vie de la garantie */
.jauge{height:4px;border-radius:999px;background:var(--bg3);overflow:hidden;margin-top:6px;}
.jauge > i{display:block;height:100%;border-radius:999px;background:var(--green);
  transition:width .4s ease;}
.jauge.w > i{background:var(--orange);}
.jauge.d > i{background:var(--red);}

/* ─────────────────────────────────────── BANDEAU D'ALERTE ─────────────────────────────────── */
.alerte{
  display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--orange-xl);border:1px solid var(--orange-b);border-radius:var(--r);
  margin-bottom:var(--sp-4);font-size:var(--fs-md);color:var(--orange-d);
}
.alerte .txt{flex:1;min-width:0;}
.alerte strong{font-weight:700;}
.info-box{padding:var(--sp-3) var(--sp-4);background:var(--blue-xl);border:1px solid var(--blue-b);
  border-radius:var(--r);font-size:var(--fs-md);color:var(--blue-d);}
.err-box{padding:var(--sp-3) var(--sp-4);background:var(--red-xl);border:1px solid var(--red-b);
  border-radius:var(--r);font-size:var(--fs-md);color:var(--red-d);}

/* ──────────────────────────────────────── ÉCRAN VIDE ──────────────────────────────────────── */
.vide{text-align:center;padding:var(--sp-6) var(--sp-4);}
.vide-icone{font-size:56px;line-height:1;margin-bottom:var(--sp-3);}
.vide-titre{font-size:var(--fs-lg);font-weight:700;margin-bottom:var(--sp-2);}
.vide-texte{font-size:var(--fs-md);color:var(--muted);max-width:340px;margin:0 auto var(--sp-4);}

/* ──────────────────────────────────────── FORMULAIRES ─────────────────────────────────────── */
.form-group{margin-bottom:var(--sp-4);}
.form-label{display:block;font-size:var(--fs-md);font-weight:600;margin-bottom:6px;color:var(--text);}
.form-label .opt{font-weight:500;color:var(--subtle);font-size:var(--fs-sm);}
.form-input,.form-select,.form-textarea{
  width:100%;padding:11px 12px;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--white);color:var(--text);font-size:var(--fs-lg);
  transition:border-color .12s,box-shadow .12s;
}
.form-input:focus,.form-select:focus,.form-textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-t);
}
.form-textarea{min-height:76px;resize:vertical;font-size:var(--fs-base);}
/* ⚠️ iOS — « Date d'achat » dépassait du formulaire par la droite. `width:100%` ne suffit pas sur
   un champ `date` : Safari lui donne un contrôle natif qui garde SA largeur minimale, et un
   élément remplaçable ne se réduit pas en dessous de sa taille intrinsèque tant qu'on ne l'y
   autorise pas. D'où les trois déclarations, et pas une de moins :
     • `appearance:none`  retire la chrome native qui impose cette largeur (le sélecteur de date
       s'ouvre toujours à la tape — seule l'apparence du contrôle change) ;
     • `min-width:0`      lève le plancher de largeur intrinsèque ;
     • `max-width:100%`   le borne quoi qu'il arrive.
   Invisible sous Chrome de bureau, où le champ tenait déjà dans sa colonne : c'est pourquoi le
   défaut ne se voyait qu'au téléphone. */
.form-input[type="date"]{-webkit-appearance:none;appearance:none;min-width:0;max-width:100%;}
.form-select{appearance:none;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%236B6860' stroke-width='1.6' d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:11px;
  padding-right:34px;}
.row-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3);}
.aide{font-size:var(--fs-sm);color:var(--muted);margin-top:5px;}
.req{color:var(--red);}

/* Choix rapides de durée */
.choix{display:flex;flex-wrap:wrap;gap:var(--sp-2);}
.choix button{
  padding:9px 14px;border-radius:var(--r-sm);border:1px solid var(--border);background:var(--white);
  color:var(--text);font-size:var(--fs-md);font-weight:600;
  transition:background .12s,border-color .12s,color .12s;
}
.choix button:hover{background:var(--bg2);}
.choix button.on{background:var(--accent);border-color:var(--accent);color:#fff;}
.choix button:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* Grille des catégories */
.cats{display:grid;grid-template-columns:repeat(auto-fill,minmax(82px,1fr));gap:var(--sp-2);}
.cat{
  display:flex;flex-direction:column;align-items:center;gap:4px;padding:10px 4px;
  border:1px solid var(--border);border-radius:var(--r-sm);background:var(--white);
  font-size:var(--fs-xs);font-weight:600;color:var(--muted);
  transition:background .12s,border-color .12s,color .12s;
}
.cat .e{font-size:24px;line-height:1;}
.cat:hover{background:var(--bg2);}
.cat.on{border-color:var(--accent);background:var(--accent-l);color:var(--accent);}
.cat:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* ───────────────────────────────────────── PHOTOS ─────────────────────────────────────────── */
.photos{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:var(--sp-2);}
.photo{position:relative;aspect-ratio:3/4;border-radius:var(--r-sm);overflow:hidden;
  border:1px solid var(--border);background:var(--bg2);}
.photo img{width:100%;height:100%;object-fit:cover;display:block;}
.photo > button.ouvre{position:absolute;inset:0;background:none;border:none;padding:0;}
.photo-del{
  position:absolute;top:4px;right:4px;width:26px;height:26px;border-radius:50%;
  background:rgba(0,0,0,.6);color:#fff;border:none;font-size:var(--fs-base);line-height:1;
  display:flex;align-items:center;justify-content:center;
}
.photo-del:focus-visible{outline:2px solid #fff;outline-offset:1px;}
.photo-add{
  aspect-ratio:3/4;border:2px dashed var(--border);border-radius:var(--r-sm);background:var(--bg2);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  color:var(--muted);font-size:var(--fs-sm);font-weight:600;
  transition:border-color .12s,background .12s;
}
.photo-add:hover{border-color:var(--accent);background:var(--accent-l);}
.photo-add .e{font-size:26px;}
.photo-add:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* ──────────────────────────────────────── BARRE D'ONGLETS ─────────────────────────────────── */
.tabbar{
  position:fixed;left:0;right:0;bottom:0;z-index:200;background:var(--white);
  border-top:1px solid var(--border);display:flex;
  padding-bottom:env(safe-area-inset-bottom,0px);
  box-shadow:0 -1px 3px rgba(28,27,24,.04);
}
.tab{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:10px 2px 8px;background:none;border:none;color:var(--muted);position:relative;
  font-size:var(--fs-2xs);font-weight:600;transition:color .15s;min-height:var(--tabbar);
}
.tab .e{font-size:22px;line-height:1;transition:transform .22s cubic-bezier(.34,1.56,.64,1);}
.tab.on{color:var(--accent);}
.tab.on .e{transform:translateY(-2px) scale(1.12);}
/* Un trait court sous l'onglet actif : la couleur seule ne suffit pas à dire « vous êtes ici »
   pour qui distingue mal le bleu du gris. */
.tab::after{
  content:'';position:absolute;top:4px;left:50%;transform:translateX(-50%) scaleX(0);
  width:26px;height:3px;border-radius:999px;background:var(--accent);
  transition:transform .22s cubic-bezier(.34,1.56,.64,1);
}
.tab.on::after{transform:translateX(-50%) scaleX(1);}
.tab:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-sm);}
.tab-pastille{position:absolute;top:6px;left:50%;margin-left:6px;background:var(--red);color:#fff;
  border-radius:999px;font-size:var(--fs-2xs);font-weight:700;padding:1px 5px;min-width:16px;
  line-height:1.4;}

/* Bouton flottant de scan */
.fab{
  position:fixed;right:var(--sp-4);z-index:210;
  bottom:calc(var(--tabbar) + env(safe-area-inset-bottom,0px) + var(--sp-4));
  height:58px;padding:0 var(--sp-5);border-radius:999px;border:none;
  background:linear-gradient(135deg,#1A4ED8 0%,#3f6ae0 100%);color:#fff;
  font-size:var(--fs-lg);font-weight:700;display:inline-flex;align-items:center;gap:var(--sp-2);
  box-shadow:0 6px 18px rgba(26,78,216,.34),0 2px 6px rgba(28,27,24,.14);
  transition:box-shadow .15s,filter .15s;
}
.fab:hover{filter:brightness(1.05);box-shadow:0 8px 24px rgba(26,78,216,.42),0 3px 8px rgba(28,27,24,.16);}
.fab:focus-visible{outline:2px solid var(--accent);outline-offset:3px;}
.fab .e{font-size:24px;}

/* ───────────────────────────────────────── FENÊTRES ───────────────────────────────────────── */
.modal-overlay{
  position:fixed;inset:0;z-index:500;background:rgba(28,27,24,.5);
  display:none;align-items:flex-end;justify-content:center;
}
.modal-overlay.on{display:flex;}
.modal{
  background:var(--bg);width:100%;max-width:640px;max-height:94vh;
  border-radius:var(--r-lg) var(--r-lg) 0 0;box-shadow:var(--e4);
  display:flex;flex-direction:column;animation:monte .2s ease-out;
}
.modal:focus{outline:none;}
@keyframes monte{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
.modal-header{
  display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-4);
  border-bottom:1px solid var(--border);background:var(--white);
  border-radius:var(--r-lg) var(--r-lg) 0 0;flex-shrink:0;
}
.modal-title{font-size:var(--fs-lg);font-weight:700;flex:1;min-width:0;margin:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.modal-body{padding:var(--sp-4);overflow-y:auto;flex:1;-webkit-overflow-scrolling:touch;}
.modal-footer{
  padding:var(--sp-3) var(--sp-4);
  padding-bottom:calc(var(--sp-3) + env(safe-area-inset-bottom,0px));
  border-top:1px solid var(--border);background:var(--white);display:flex;gap:var(--sp-2);flex-shrink:0;
}
.modal-footer .btn{flex:1;}

/* ─────────────────────────────────────── FICHE DÉTAIL ─────────────────────────────────────── */
.fiche-tete{display:flex;gap:var(--sp-3);align-items:flex-start;margin-bottom:var(--sp-4);}
.fiche-emoji{font-size:44px;line-height:1;flex-shrink:0;}
.fiche-nom{font-size:var(--fs-xl);font-weight:800;line-height:1.2;margin-bottom:4px;}
.fiche-sous{font-size:var(--fs-md);color:var(--muted);}

/* Le compte à rebours est ce qu'on vient chercher : il occupe la fiche, et sa couleur suffit à
   répondre avant même qu'on ait lu le chiffre. */
.compte{
  text-align:center;padding:var(--sp-6) var(--sp-4);border-radius:var(--r-lg);
  margin-bottom:var(--sp-4);position:relative;overflow:hidden;
  border:1px solid var(--border);background:var(--white);
  box-shadow:var(--e1);
}
/* Un liseré supérieur de la couleur de l'état : la même grammaire que la bande des cartes. */
.compte::before{
  content:'';position:absolute;top:0;left:0;right:0;height:4px;background:var(--grey-b);
}
.compte.ok::before{background:linear-gradient(90deg,#22c55e,#16a34a);}
.compte.bientot::before{background:linear-gradient(90deg,#f59e0b,#d97706);}
.compte.expire::before{background:linear-gradient(90deg,#ef4444,#dc2626);}
.compte.avie::before{background:linear-gradient(90deg,#a78bfa,#7c3aed);}
.compte.ok{background:var(--green-xl);border-color:var(--green-b);}
.compte.bientot{background:var(--orange-xl);border-color:var(--orange-b);}
.compte.expire{background:var(--red-xl);border-color:var(--red-b);}
.compte.avie{background:var(--purple-l);border-color:var(--purple-b);}
.compte-nb{font-size:40px;font-weight:800;line-height:1;letter-spacing:-1px;}
.compte.ok .compte-nb,.compte.ok .compte-txt{color:var(--green-d);}
.compte.bientot .compte-nb,.compte.bientot .compte-txt{color:var(--orange-d);}
.compte.expire .compte-nb,.compte.expire .compte-txt{color:var(--red-d);}
.compte.avie .compte-nb,.compte.avie .compte-txt{color:var(--purple-d);}
.compte-txt{font-size:var(--fs-md);font-weight:600;margin-top:6px;}
.compte-date{font-size:var(--fs-sm);color:var(--muted);margin-top:var(--sp-2);}

.detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3);margin-bottom:var(--sp-4);}
.detail-item{background:var(--white);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:var(--sp-3);}
.detail-item .label{display:block;font-size:var(--fs-xs);font-weight:700;text-transform:uppercase;
  letter-spacing:.5px;color:var(--subtle);margin-bottom:3px;}
.detail-item .val{font-size:var(--fs-base);font-weight:600;overflow-wrap:break-word;}
.detail-item.full{grid-column:1 / -1;}
.detail-item .val.libre{font-weight:400;white-space:pre-wrap;}

.actions-grille{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-2);
  margin-bottom:var(--sp-4);}

/* Visionneuse plein écran */
.viewer{position:fixed;inset:0;z-index:10000;background:rgba(0,0,0,.94);display:none;
  align-items:center;justify-content:center;flex-direction:column;}
.viewer.on{display:flex;}
.viewer img{max-width:100%;max-height:80vh;object-fit:contain;}
.viewer-fermer{position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);right:12px;
  width:42px;height:42px;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;border:none;
  font-size:var(--fs-xl);display:flex;align-items:center;justify-content:center;}
.viewer-nav{display:flex;gap:var(--sp-4);margin-top:var(--sp-4);align-items:center;}
.viewer-nav button{width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.16);
  color:#fff;border:none;font-size:var(--fs-xl);}
.viewer-nav span{color:#fff;font-size:var(--fs-md);min-width:52px;text-align:center;}

/* ──────────────────────────────────── STATISTIQUES ────────────────────────────────────────── */
.tuiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-3);
  margin-bottom:var(--sp-5);}
/* Les vignettes du résumé sont le seul endroit où l'on REGARDE un chiffre au lieu de lire :
   elles peuvent donc se permettre un relief que les listes n'auraient pas. */
.tuile{
  background:linear-gradient(170deg, var(--white) 0%, var(--bg) 190%);
  border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--sp-4);box-shadow:var(--e1), inset 0 1px 0 rgba(255,255,255,.7);
  position:relative;overflow:hidden;
  transition:box-shadow .15s,transform .15s;
}
.tuile::before{
  content:'';position:absolute;inset:0 auto 0 0;width:3px;
  background:linear-gradient(180deg, var(--accent) 0%, var(--sky) 100%);
  opacity:.9;
}
.tuile:hover{box-shadow:var(--e2), inset 0 1px 0 rgba(255,255,255,.7);transform:translateY(-2px);}
.tuile-e{font-size:24px;line-height:1;margin-bottom:var(--sp-2);}
.tuile-nb{font-size:30px;font-weight:800;line-height:1.05;letter-spacing:-1px;}
.tuile-lib{font-size:var(--fs-sm);color:var(--muted);margin-top:6px;font-weight:600;}

.barres{display:flex;flex-direction:column;gap:var(--sp-3);}
.barre-ligne{display:flex;align-items:center;gap:var(--sp-3);}
.barre-nom{font-size:var(--fs-md);font-weight:600;width:112px;flex-shrink:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.barre-piste{flex:1;min-width:0;height:20px;background:var(--bg2);border-radius:999px;
  overflow:hidden;box-shadow:inset 0 1px 2px rgba(28,27,24,.05);}
.barre-piste > i{display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg, var(--accent) 0%, var(--sky) 180%);
  transition:width .4s ease;}
/* Assez large pour « 3290 CHF » d'un seul tenant : à 60 px le montant se coupait en deux
   lignes et décalait toute la rangée. */
.barre-val{font-size:var(--fs-md);font-weight:700;width:82px;text-align:right;flex-shrink:0;
  white-space:nowrap;}

/* ───────────────────────────────────────── RÉGLAGES ───────────────────────────────────────── */
.reglage{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--white);border:1px solid var(--border);border-radius:var(--r);
  margin-bottom:var(--sp-2);}
.reglage .e{font-size:22px;flex-shrink:0;}
.reglage-txt{flex:1;min-width:0;}
.reglage-nom{display:block;font-size:var(--fs-base);font-weight:600;color:var(--text);}
.reglage-aide{display:block;font-size:var(--fs-sm);color:var(--muted);margin-top:2px;}
.reglage .form-select,.reglage .form-input{width:auto;min-width:96px;flex-shrink:0;
  font-size:var(--fs-base);padding:8px 10px;}
.reglage .form-select{padding-right:30px;}
button.reglage{width:100%;text-align:left;}
button.reglage:hover{background:var(--bg2);}
button.reglage:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* Interrupteur */
.switch{position:relative;width:46px;height:26px;flex-shrink:0;background:var(--grey-b);
  border-radius:999px;border:none;transition:background .15s;}
.switch::after{content:'';position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:#fff;box-shadow:var(--e1);transition:transform .2s;}
.switch.on{background:var(--accent);}
.switch.on::after{transform:translateX(20px);}
.switch:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

/* ──────────────────────────────────────── NOTIFICATIONS ───────────────────────────────────── */
#toasts{position:fixed;left:var(--sp-3);right:var(--sp-3);z-index:9100;
  bottom:calc(var(--tabbar) + env(safe-area-inset-bottom,0px) + var(--sp-3));
  display:flex;flex-direction:column;gap:var(--sp-2);pointer-events:none;align-items:center;}
.toast{
  pointer-events:auto;background:var(--text);color:var(--bg);border-radius:var(--r-sm);
  padding:12px var(--sp-4);font-size:var(--fs-md);font-weight:600;box-shadow:var(--e3);
  display:flex;align-items:center;gap:var(--sp-3);max-width:520px;width:100%;
  animation:monte .2s ease-out;
}
.toast.ok{background:var(--green-d);color:#fff;}
.toast.warn{background:var(--orange-d);color:#fff;}
.toast.err{background:var(--red-d);color:#fff;}
.toast .txt{flex:1;min-width:0;}
.toast button{background:rgba(255,255,255,.2);color:inherit;border:none;border-radius:var(--r-xs);
  padding:6px 12px;font-size:var(--fs-sm);font-weight:700;flex-shrink:0;}
.toast button:focus-visible{outline:2px solid currentColor;outline-offset:1px;}

/* ─────────────────────────────────────── VERROUILLAGE ─────────────────────────────────────── */

/* Au-dessus de tout, y compris des fenêtres : rien ne doit rester lisible derrière.
   Deux halos radiaux posés sur un dégradé donnent de la profondeur sans image à charger —
   c'est le seul écran où l'on ne lit rien, donc le seul où le décor se justifie. */
.verrou{
  position:fixed;inset:0;z-index:20000;
  background:
    radial-gradient(120% 80% at 50% -10%, var(--halo-verrou-1) 0%, transparent 58%),
    radial-gradient(95% 65% at 108% 104%, var(--halo-verrou-2) 0%, transparent 62%),
    linear-gradient(170deg, var(--bg) 0%, var(--bg2) 100%);
  display:flex;align-items:center;justify-content:center;
  padding:calc(env(safe-area-inset-top,0px) + var(--sp-5)) var(--sp-5)
          calc(env(safe-area-inset-bottom,0px) + var(--sp-5));
  overflow-y:auto;
}
.verrou[hidden]{display:none;}
/* Empêche la page de défiler derrière l'écran de code, sur un téléphone où le clavier
   redimensionne la fenêtre. */
body.verrouille{overflow:hidden;}

.verrou-boite{
  width:100%;max-width:340px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-3);
}

/* Le logo de l'application plutôt qu'un émoji : c'est la même image que sur l'écran d'accueil
   du téléphone, et la reconnaître rassure avant de taper un code. Le halo l'assoit sur le fond. */
.verrou-logo{
  width:88px;height:88px;border-radius:26px;overflow:hidden;
  margin-bottom:var(--sp-1);
  box-shadow:0 12px 32px rgba(26,78,216,.28), 0 2px 8px rgba(28,27,24,.12),
             inset 0 1px 0 rgba(255,255,255,.4);
}
.verrou-logo img{width:100%;height:100%;display:block;}

.verrou-titre{font-size:28px;font-weight:800;margin:0;letter-spacing:-.6px;line-height:1.15;}
.verrou-sous{font-size:var(--fs-lg);color:var(--muted);margin:0;line-height:1.35;}

.points{display:flex;gap:14px;justify-content:center;margin:var(--sp-3) 0 0;min-height:20px;}
.point{
  width:15px;height:15px;border-radius:50%;background:transparent;
  border:2px solid var(--grey-b);
  transition:background .18s cubic-bezier(.34,1.56,.64,1),
             border-color .18s, transform .18s cubic-bezier(.34,1.56,.64,1);
}
.point.plein{
  background:var(--accent);border-color:var(--accent);transform:scale(1.25);
  box-shadow:0 2px 8px var(--accent-t);
}

/* Un code refusé se signale par un mouvement, comme sur un téléphone : c'est plus rapide à
   comprendre qu'une ligne de texte, et le texte reste là pour qui ne l'a pas vu. */
@keyframes secousse{
  0%,100%{transform:translateX(0)}
  15%,45%,75%{transform:translateX(-7px)}
  30%,60%,90%{transform:translateX(7px)}
}
.points.refus{animation:secousse .42s ease-in-out;}

/* Code montré. Les chiffres tiennent dans la hauteur des points (20 px) pour que rien ne saute
   quand on bascule de l'un à l'autre, et `tabular-nums` les garde alignés — sinon un « 1 » plus
   étroit décale toute la ligne à chaque touche. */
/* ⚠️ MÊME LARGEUR QUE LES POINTS, au pixel : 6 × 15 px + 5 × 14 px d'écart = 160 px dans les deux
   états. Ce n'est pas de la coquetterie — la rangée est l'élément le plus LARGE de l'écran de
   code, et c'est donc ELLE qui fixe la largeur du bloc, donc celle du pavé, dont les touches sont
   en `aspect-ratio:1`. Un écart de 10 px au lieu de 14 rétrécissait la rangée de 20 px, les
   touches de 6 px, et le pavé entier remontait de 12 px sous le pouce à chaque bascule.
   D'où `min-width` sur le chiffre et AUCUN `gap` propre à l'état « vus ». */
.chiffre{min-width:15px;text-align:center;font-size:20px;line-height:20px;font-weight:700;
  color:var(--text);font-variant-numeric:tabular-nums;}
.verrou-oeil{
  display:inline-flex;align-items:center;gap:6px;margin:var(--sp-3) auto 0;
  padding:6px 12px;border-radius:999px;border:1px solid var(--border);background:var(--white);
  color:var(--muted);font-size:var(--fs-sm);font-weight:600;
  transition:background .12s,color .12s,border-color .12s;
}
.verrou-oeil:hover{background:var(--bg2);color:var(--text);}
.verrou-oeil:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}

.verrou-msg{min-height:22px;font-size:var(--fs-md);font-weight:600;line-height:1.35;
  margin-top:var(--sp-2);}
.verrou-msg.err{color:var(--red-d);}
.verrou-msg.info{color:var(--muted);font-weight:500;}

.pave{
  display:grid;grid-template-columns:repeat(3,1fr);gap:14px;
  width:100%;max-width:272px;margin:var(--sp-2) auto 0;
}
.pave.bloque{opacity:.35;pointer-events:none;}
.touche{
  aspect-ratio:1;border-radius:50%;border:1px solid var(--border);
  background:linear-gradient(180deg, var(--white) 0%, var(--bg) 160%);
  color:var(--text);font-size:26px;font-weight:600;letter-spacing:-.5px;
  display:flex;align-items:center;justify-content:center;
  transition:transform .09s cubic-bezier(.34,1.56,.64,1),
             background .12s, box-shadow .12s, border-color .12s;
  box-shadow:var(--e1), inset 0 1px 0 rgba(255,255,255,.6);
}
.touche:hover{background:var(--bg2);}
/* Le rebond au relâchement donne le retour qu'un vrai bouton donnerait sous le doigt. */
.touche:active{transform:scale(.9);background:var(--accent-l);border-color:var(--accent);
  box-shadow:0 0 0 4px var(--accent-t);}
.touche:focus-visible{outline:2px solid var(--accent);outline-offset:3px;}
.touche[data-touche="eff"]{background:transparent;border-color:transparent;box-shadow:none;
  font-size:22px;color:var(--muted);}
.touche[data-touche="eff"]:active{background:var(--bg3);box-shadow:none;}

.verrou-rester{
  display:flex;align-items:center;gap:10px;justify-content:center;
  font-size:var(--fs-md);color:var(--text);cursor:pointer;
  margin-top:var(--sp-4);padding:10px 16px;border-radius:999px;
  background:var(--white);border:1px solid var(--border);box-shadow:var(--e1);
  transition:border-color .12s,background .12s;
}
.verrou-rester:hover{background:var(--bg2);}
.verrou-rester:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-t);}
.verrou-rester input{width:18px;height:18px;accent-color:var(--accent);flex-shrink:0;}
#verrou-zone-secours{width:100%;}

/* Sur un écran de téléphone court (ou clavier ouvert), le décor cède la place au pavé. */
@media(max-height:680px){
  .verrou-logo{width:60px;height:60px;border-radius:18px;}
  .verrou-titre{font-size:22px;}
  .verrou-sous{font-size:var(--fs-base);}
  .pave{gap:10px;max-width:248px;}
  .touche{font-size:22px;}
}

/* La clé de secours se lit pour être recopiée : espacée, en groupes, jamais en une masse. */
.cle-secours{
  display:flex;flex-wrap:wrap;gap:var(--sp-2);justify-content:center;
  padding:var(--sp-4);background:var(--bg2);border:1px solid var(--border);
  border-radius:var(--r);
}
.cle-secours span{
  font-size:var(--fs-xl);font-weight:700;letter-spacing:2px;
  padding:6px 10px;background:var(--white);border:1px solid var(--border);
  border-radius:var(--r-sm);
}

/* ─────────────────────────────────────────── DIVERS ───────────────────────────────────────── */
.spinner{width:28px;height:28px;border:3px solid var(--border);border-top-color:var(--accent);
  border-radius:50%;animation:tourne .7s linear infinite;margin:0 auto;}
@keyframes tourne{to{transform:rotate(360deg)}}
.page-load{padding:var(--sp-6);text-align:center;}
.hint{font-size:var(--fs-sm);color:var(--muted);text-align:center;margin-top:var(--sp-3);}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}

/* Écran large : le contenu respire, la barre d'onglets se recentre */
@media(min-width:768px){
  .vue{padding:var(--sp-5);padding-bottom:calc(var(--tabbar) + 100px);}
  .detail-grid{grid-template-columns:repeat(3,1fr);}
  .modal-overlay{align-items:center;padding:var(--sp-4);}
  .modal{border-radius:var(--r-lg);max-height:88vh;}
  .tabbar{max-width:760px;margin:0 auto;border-radius:var(--r-lg) var(--r-lg) 0 0;
    border:1px solid var(--border);border-bottom:none;}
  .fab{right:calc(50% - 380px + var(--sp-4));}
}
@media(max-width:560px){
  .detail-grid{grid-template-columns:1fr 1fr;}
  .row-2{grid-template-columns:1fr;}
  .fab{padding:0 var(--sp-4);}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;}
  /* L'ombre et la teinte d'état restent : ce sont des informations, pas des animations. */
}

@media print{
  .tabbar,.fab,.topbar-actions,#toasts,.modal-footer{display:none !important;}
  body{background:#fff;}
}
