/* Volet « Scanner » (identification d'une carte par caméra/photo). Le CHROME suit les
   thèmes via les variables CSS de l'app (--bg --panel --panel2 --input --line --txt
   --txt2 --mut --acc --on-acc --focus --ok/--bad/--warn --shadow --overlay). Seuls la
   scène vidéo/canvas utilisent un fond noir (#000, neutre). Miroir de collection.css. */

/* ---- bouton bascule (header) ---- */
#scan-toggle{
  position:static;z-index:3000;
  background:var(--acc);color:var(--on-acc);border:none;border-radius:24px;
  padding:11px 16px;font:700 14px/1 system-ui,Segoe UI,Roboto,sans-serif;
  cursor:pointer;box-shadow:0 6px 20px var(--shadow);display:inline-flex;gap:7px;align-items:center;
}
#scan-toggle:hover{filter:brightness(1.08)}

/* ---- volet coulissant (depuis la droite) ---- */
#scan-panel{
  position:fixed;top:0;right:0;height:100vh;width:480px;max-width:100vw;z-index:3000;
  background:var(--panel);border-left:1px solid var(--line);color:var(--txt);
  display:flex;flex-direction:column;transform:translateX(100%);
  transition:transform .22s ease;box-shadow:-8px 0 32px var(--shadow);
  font:14px/1.5 system-ui,Segoe UI,Roboto,sans-serif;
}
#scan-panel.open{transform:translateX(0)}
#scan-panel.full{width:100vw;z-index:3300}
#scan-panel.full .scan-body{max-width:900px;margin:0 auto;width:100%;box-sizing:border-box}

/* ---- en-tête ---- */
.scan-head{padding:12px 16px;border-bottom:1px solid var(--line);display:flex;gap:8px;align-items:center;flex:0 0 auto}
.scan-title{flex:1;font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#scan-close,#scan-full{background:none;border:none;color:var(--mut);line-height:1;cursor:pointer;padding:0 4px}
#scan-close{font-size:24px}
#scan-full{font-size:18px}
#scan-close:hover,#scan-full:hover{color:var(--txt)}
.scan-status{color:var(--acc);font-size:12px;min-height:16px;padding:0 16px}

/* ---- corps ---- */
/* `scrollbar-gutter:stable` : la gouttière est réservée EN PERMANENCE. Sans elle, la
   barre de défilement apparaît quand le volet de fusion s'affiche, la largeur utile perd
   ~11 px, et comme .scan-stage est en `width:100%` avec un `aspect-ratio`, sa HAUTEUR
   change — ce qui peut faire disparaître la barre, qui revient, etc. La scène se mettait
   ainsi à osciller en permanence pendant la capture. */
.scan-body{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:12px;padding:12px 16px;overflow-y:auto;scrollbar-gutter:stable}

/* ---- scène (vidéo / aperçu capturé) ---- */
/* Cadre 63:88 piloté par la HAUTEUR (height + width:auto → largeur déduite de
   l'aspect-ratio), pour rester un vrai rectangle-carte portrait (sinon width:100%
   + max-height le déforme en paysage et le guide ne correspond plus au recadrage). */
/* Le rapport est posé en JS d'après la trame réelle (layoutGuide) : la scène épouse le
   CAPTEUR. La valeur ci-dessous n'est qu'un repli avant le démarrage de la caméra.
   PIÈGE CORRIGÉ : un cadre 63:88 fixe recadrait la vidéo en `object-fit:cover` et
   n'exposait que 515×720 d'un capteur 1280×720 — 60 % de la largeur perdue AVANT la
   détection, donc autant de résolution en moins sur la carte. */
/* `flex:0 0 auto` — INDISPENSABLE, pas cosmétique. La scène est un enfant de `.scan-body`,
   qui est un conteneur flex en colonne : par défaut un enfant flex est COMPRESSIBLE
   (`flex-shrink:1`). Dès que le volet de fusion s'affichait, le contenu dépassait la
   hauteur du volet et la scène se faisait écraser — mesuré : 104 px → 1,6 px, c'est-à-dire
   l'aperçu caméra réduit à un trait. `.scan-body` ayant `overflow-y:auto`, le dépassement
   doit défiler, jamais écraser. */
.scan-stage{
  position:relative;aspect-ratio:16/9;height:auto;width:100%;max-height:34vh;margin:0 auto;
  flex:0 0 auto;
  background:#000;border:1px solid var(--line);border-radius:10px;overflow:hidden;
}
#scan-panel.full .scan-stage{max-height:52vh}
/* La vidéo remplit le cadre 63:88 (object-fit:cover) : la zone visible = le plus grand
   rectangle-carte centré de l'image, EXACTEMENT ce que l'OCR recadre. L'aperçu capturé
   (contain) montre la carte entière. */
/* `contain` et non `cover` : la scène ayant le format du capteur, rien n'est rogné —
   l'utilisateur voit EXACTEMENT ce que la détection reçoit. */
#scan-video{width:100%;height:100%;object-fit:contain;background:#000;display:block}
#scan-preview{width:100%;height:100%;object-fit:contain;background:#000;display:block}
#scan-video[hidden],#scan-preview[hidden]{display:none}
/* Guide de cadrage : cadre + zones LUES par l'OCR (nom en haut, édition/numéro en
   bas-gauche) avec libellés. Ces zones correspondent au recadrage réel. */
.scan-guide{
  position:absolute;inset:0;pointer-events:none;border-radius:10px;
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.45);
}
.scan-guide[hidden]{display:none}
.scan-guide-zone{
  position:absolute;border:2px dashed var(--acc);background:rgba(0,0,0,.18);
  display:flex;align-items:flex-start;justify-content:flex-start;
}
.scan-guide-zone span{
  font:700 10px/1.4 system-ui,Segoe UI,Roboto,sans-serif;color:var(--on-acc);
  background:var(--acc);padding:1px 6px;text-transform:uppercase;letter-spacing:.04em;
}
/* ---- gabarit CARTE : silhouette 63:88 posée et tournée par layoutGuide ---- */
/* Décrit en coordonnées de CARTE (donc debout) ; la rotation le couche d'un bloc, zones
   OCR comprises — d'où l'absence de calcul de position quand l'orientation change. */
.scan-tpl{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  border:2px solid rgba(255,255,255,.92);border-radius:9px;
  box-shadow:0 0 0 9999px rgba(0,0,0,.28);   /* assombrit TOUT sauf la carte */
  pointer-events:none;
}
/* Repère « HAUT » : lève l'ambiguïté entre les DEUX rotations possibles d'une carte
   couchée. Sans lui, l'image redressée peut sortir à 180°, illisible pour l'OCR. */
.scan-tpl-top{
  position:absolute;top:0;left:0;right:0;height:11%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.16);border-bottom:1px dashed rgba(255,255,255,.6);
  font:800 9px/1 system-ui,Segoe UI,Roboto,sans-serif;letter-spacing:.16em;color:#fff;
}
/* Zones alignées sur CROP_NAME / CROP_BOTTOM (scan.js). Le cadre « Nom » s'arrête avant
   le coût de mana (haut-DROITE) pour ne lire que le nom (haut-GAUCHE). */
.scan-guide-name{top:4.5%;left:6%;width:66%;height:6.5%}
.scan-guide-name span{border-radius:0 0 6px 0}
.scan-guide-setcn{bottom:0.5%;left:2%;width:48%;height:9.5%;align-items:flex-end}
.scan-guide-setcn span{border-radius:0 6px 0 0}
/* Polygone détecté, redessiné à chaque trame par-dessus la vidéo. */
.scan-poly{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.scan-guide-hint{
  position:absolute;left:0;right:0;bottom:4px;text-align:center;padding:0 10px;
  font:600 11px/1.4 system-ui,Segoe UI,Roboto,sans-serif;color:#fff;
  text-shadow:0 1px 3px rgba(0,0,0,.95);
}
.scan-cam-msg{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  text-align:center;padding:20px;color:#fff;background:rgba(0,0,0,.55);font-size:13px;line-height:1.5;
}
.scan-cam-msg[hidden]{display:none}
#scan-canvas{display:none}

/* ---- contrôles (capturer / reprendre / photo) ---- */
.scan-controls{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.scan-controls button{
  background:none;border:1px solid var(--line);color:var(--txt);border-radius:6px;
  padding:9px 14px;font-size:13px;font-weight:600;cursor:pointer;
}
.scan-controls button:hover{border-color:var(--acc);color:var(--acc)}
.scan-controls button.prim{background:var(--acc);color:var(--on-acc);border-color:var(--acc)}
.scan-controls button.prim:hover{filter:brightness(1.08);color:var(--on-acc)}
.scan-controls button:disabled{opacity:.5;cursor:default;border-color:var(--line);color:var(--mut)}
.scan-filelbl{
  display:inline-block;background:none;border:1px solid var(--line);color:var(--txt);
  border-radius:6px;padding:9px 14px;font-size:13px;font-weight:600;cursor:pointer;margin-left:auto;
}
.scan-filelbl:hover{border-color:var(--acc);color:var(--acc)}

/* ---- capture continue : image hybridée en temps réel ---- */
/* Le bouton « scan continu » s'allume (accent) tant que la boucle tourne : c'est le
   seul repère indiquant que la caméra alimente l'empilement. */
#scan-cont.on{background:var(--acc);color:var(--on-acc);border-color:var(--acc)}
.scan-fuse{display:flex;flex-direction:column;gap:8px}
.scan-fuse[hidden]{display:none}
.scan-fuse-hd{display:flex;align-items:baseline;gap:8px}
.scan-fuse-lbl{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--mut);flex:1}
.scan-fuse-stat{font:600 11px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--txt2)}
/* Cadre 63:88 comme la scène vidéo : l'image hybridée EST la carte redressée. */
/* Hauteur CONTENUE : en capture continue, la scène vidéo (16:9 pleine largeur) et
   l'image hybridée doivent tenir ENSEMBLE dans le volet — à 34vh, l'hybridée passait
   sous la ligne de flottaison et le mode continu semblait sans retour visuel. */
/* Même raison que `.scan-stage` : sans `flex:0 0 auto`, l'image hybridée s'écrase dès que
   le résultat identifié s'ajoute sous elle. */
.scan-fuse-stage{
  position:relative;aspect-ratio:63/88;height:26vh;width:auto;max-width:100%;margin:0 auto;
  flex:0 0 auto;
  background:#000;border:1px solid var(--line);border-radius:10px;overflow:hidden;
}
.scan-fuse{flex:0 0 auto}
#scan-panel.full .scan-fuse-stage{height:40vh}
#scan-fused{width:100%;height:100%;object-fit:contain;display:block;opacity:0;transition:opacity .18s}
#scan-fused.on{opacity:1}
/* Jauge de progression vers le dernier palier d'auto-analyse. */
.scan-fuse-bar{height:4px;border-radius:2px;background:var(--input);overflow:hidden}
.scan-fuse-bar i{display:block;height:100%;width:0;background:var(--acc);transition:width .2s}
/* Hauteur RÉSERVÉE (2 lignes) : ces libellés changent à chaque trame ; sans réservation,
   chaque changement de longueur repoussait tout le contenu sous lui. */
.scan-fuse-msg{font-size:12px;color:var(--txt2);min-height:34px}
.scan-fuse-msg.warn{color:var(--warn)}
.scan-fuse-btns{display:flex;gap:8px;flex-wrap:wrap}
.scan-fuse-btns button{
  background:none;border:1px solid var(--line);color:var(--txt);border-radius:6px;
  padding:8px 14px;font-size:13px;font-weight:600;cursor:pointer;
}
.scan-fuse-btns button:hover{border-color:var(--acc);color:var(--acc)}
.scan-fuse-btns button.prim{background:var(--acc);color:var(--on-acc);border-color:var(--acc)}
.scan-fuse-btns button.prim:hover{filter:brightness(1.08);color:var(--on-acc)}
.scan-fuse-btns button:disabled{opacity:.5;cursor:default;border-color:var(--line);color:var(--mut)}

/* ---- résultat identifié ---- */
.scan-result:empty{display:none}
.scan-res-title{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--mut);margin-bottom:8px;display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
/* Confiance du vote OCR. En `--ok` quand la carte retenue a la majorité absolue,
   en `--warn` sinon : une identification à 1 voix sur 3 mérite un coup d'œil. */
.scan-vote{font-size:10px;font-weight:700;color:var(--ok);text-transform:none;letter-spacing:0}
.scan-vote.weak{color:var(--warn)}
.scan-res-card{display:flex;gap:12px;align-items:flex-start}
.scan-res-img{width:120px;flex:0 0 auto;border-radius:8px;border:1px solid var(--line);background:var(--panel2)}
.scan-res-ph{width:120px;aspect-ratio:63/88}
.scan-res-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}
.scan-res-nm{font-size:16px;font-weight:700;color:var(--txt);line-height:1.25}
.scan-res-id{font-size:15px;color:var(--txt);letter-spacing:.02em;display:flex;align-items:center;gap:6px}
.scan-res-id b{font-weight:800;color:var(--acc)}
/* Édition incertaine : badge « ? » (l'impression exacte n'a pas pu être déterminée). */
.scan-ed-q{
  display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
  border-radius:50%;background:var(--warn-bg,var(--panel2));color:var(--warn);
  border:1px solid var(--warn);font-weight:800;font-size:14px;line-height:1;cursor:help;
}
.scan-res-meta{font-size:12px;color:var(--txt2);text-transform:capitalize}
.scan-res-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px}
.scan-res-actions button{
  background:none;border:1px solid var(--line);color:var(--txt);border-radius:6px;
  padding:8px 12px;font-size:12px;font-weight:600;cursor:pointer;
}
.scan-res-actions button:hover{border-color:var(--acc);color:var(--acc)}
.scan-res-actions button.prim{background:var(--acc);color:var(--on-acc);border-color:var(--acc)}
.scan-res-actions button.prim:hover{filter:brightness(1.08);color:var(--on-acc)}
.scan-res-actions button:disabled{opacity:.6;cursor:default}

/* candidats (liste de choix quand plusieurs correspondances) */
.scan-cands-lbl{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--mut);margin:12px 0 6px}
.scan-cands{display:flex;gap:8px;flex-wrap:wrap}
.scan-cand{
  width:78px;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;gap:3px;
  background:none;border:1px solid transparent;border-radius:8px;padding:4px;cursor:pointer;
}
.scan-cand:hover{border-color:var(--acc);background:var(--input)}
.scan-cand.on{border-color:var(--acc);background:var(--input)}
.scan-cand img{width:70px;border-radius:5px;border:1px solid var(--line);background:var(--panel2)}
.scan-cand-nm{font-size:10px;color:var(--txt2);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70px}

/* ---- repli manuel / assisté ---- */
.scan-manual{display:flex;flex-direction:column;gap:10px}
.scan-manual-note{font-size:13px;color:var(--warn)}
.scan-manual-title{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--mut)}
.scan-flds{display:flex;flex-direction:column;gap:8px}
.scan-flds input{
  background:var(--input);border:1px solid var(--line);color:var(--txt);border-radius:6px;
  padding:9px 10px;font-size:14px;width:100%;box-sizing:border-box;
}
.scan-flds input:focus{outline:none;border-color:var(--acc)}
#scan-resolve{
  align-self:flex-start;background:var(--acc);color:var(--on-acc);border:1px solid var(--acc);
  border-radius:6px;padding:9px 16px;font-size:13px;font-weight:700;cursor:pointer;
}
#scan-resolve:hover{filter:brightness(1.08)}

/* ---- texte OCR brut (petit, discret, sélectionnable) ---- */
.scan-raw{
  margin-top:auto;padding:8px 10px;background:var(--panel2);border:1px solid var(--line);
  border-radius:6px;font-size:11px;color:var(--mut);
}
.scan-raw[hidden]{display:none}
.scan-raw-lbl{display:block;text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px}
.scan-raw-txt{
  font:12px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--txt2);
  white-space:pre-wrap;word-break:break-word;user-select:text;
}

/* Image de résultat CLIQUABLE (→ sélecteur d'impression) + zoomée au survol. */
.scan-res-img[role="button"]{cursor:pointer;transition:box-shadow .12s,transform .12s}
.scan-res-img[role="button"]:hover{box-shadow:0 0 0 2px var(--acc);transform:translateY(-1px)}
.scan-res-img[role="button"]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--acc)}

/* Bouton crayon (édition textuelle) : compact, dans la rangée d'actions. */
.scan-edit-btn{line-height:1;padding:8px 10px !important}

/* ---- sélecteur d'impression (modal) ---- */
.scan-modal-overlay{
  position:fixed;inset:0;z-index:3950;display:flex;align-items:center;justify-content:center;
  background:var(--overlay);padding:20px;
  font:14px/1.5 system-ui,Segoe UI,Roboto,sans-serif;
}
.scan-modal{
  width:min(560px,100%);max-height:calc(100vh - 40px);overflow:auto;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  padding:18px 18px 14px;color:var(--txt);box-shadow:0 18px 60px var(--shadow);
}
.scan-modal-hd{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:16px;font-weight:700;margin-bottom:12px}
.scan-modal-x{background:none;border:none;color:var(--mut);font-size:22px;line-height:1;cursor:pointer;padding:0 2px}
.scan-modal-x:hover{color:var(--txt)}
.scan-modal-btns{display:flex;gap:8px;justify-content:flex-end;margin-top:6px;flex-wrap:wrap}
.scan-modal-btns button{
  background:none;border:1px solid var(--line);color:var(--txt);border-radius:6px;
  padding:8px 14px;font-size:13px;font-weight:600;cursor:pointer;
}
.scan-modal-btns button:hover{border-color:var(--acc);color:var(--acc)}
.scan-pick-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px;
  max-height:60vh;overflow-y:auto;margin-bottom:12px;padding:2px;
}
.scan-pick-empty{grid-column:1/-1;text-align:center;color:var(--mut);padding:24px 0;font-size:13px}
.scan-pick-item{
  display:flex;flex-direction:column;align-items:center;gap:4px;cursor:pointer;
  border:1px solid transparent;border-radius:8px;padding:4px;
}
.scan-pick-item:hover{border-color:var(--acc);background:var(--input)}
.scan-pick-item img{width:100%;border-radius:6px;border:1px solid var(--line);background:var(--panel2)}
.scan-pick-nm{font-size:11px;color:var(--txt);text-align:center;line-height:1.2}
.scan-pick-meta{font-size:11px;color:var(--txt2);text-align:center;line-height:1.2}
.scan-pick-meta b{color:var(--txt)}

/* Aperçu magnifié DÉDIÉ au picker (au-dessus du modal 3950, sous le menu thème 4000). */
#scan-pickzoom{position:fixed;display:none;z-index:3990;pointer-events:none;width:300px}
#scan-pickzoom img{width:100%;display:block;border-radius:12px;box-shadow:0 12px 44px var(--shadow)}
.scan-pickzoom-info{
  margin-top:6px;background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:6px 10px;box-shadow:0 8px 28px var(--shadow);
}
.scan-pz-set{font-size:12px;color:var(--txt)}
.scan-pz-set b{color:var(--txt)}
.scan-pz-sub{font-size:11px;color:var(--mut);margin-top:2px}

@media (max-width:520px){
  #scan-panel{width:100vw}
}
