Files
photobooth/frontend/index.html
Jules 05f78f731d Surprise : precharger image + animation fade in/out + attente chargement
Evite le freeze percu : image prechargee au boot, fade 200ms,
attente img.onload si pas encore prete, re-precharge apres affichage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-17 19:09:53 +02:00

1156 lines
64 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Photobooth</title>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="google" content="notranslate">
<meta http-equiv="Content-Language" content="fr">
<link rel="stylesheet" href="/css/style.css?v=16">
<link rel="stylesheet" href="/css/themes.css?v=2">
</head>
<body>
<div id="app">
<!-- Bandeau erreur imprimante (tous écrans) -->
<div id="printer-erreur" class="printer-erreur cache">
<span class="printer-erreur-icon">&#128424;</span>
<span id="printer-erreur-msg">Problème imprimante</span>
<button onclick="document.getElementById('printer-erreur').classList.add('cache')">&#10005;</button>
</div>
<!-- Overlay erreur equipement (camera/imprimante) -->
<div id="erreur-equipement" class="erreur-overlay cache">
<div class="erreur-icon" id="erreur-equip-icon">&#128247;</div>
<div class="erreur-titre" id="erreur-equip-titre">Preparation en cours</div>
<div class="erreur-msg" id="erreur-equip-msg">L'appareil photo se prepare, un instant...</div>
<div class="erreur-spinner" id="erreur-equip-spinner"></div>
<div class="erreur-steps cache" id="erreur-equip-steps"></div>
<div id="erreur-equip-actions" style="display:flex;gap:1rem;flex-wrap:wrap;justify-content:center">
<button class="erreur-btn erreur-btn-primaire cache" id="erreur-equip-btn-retry" onclick="erreurEquipRetry()">Reessayer</button>
<button class="erreur-btn erreur-btn-secondaire cache" id="erreur-equip-btn-video" onclick="erreurEquipVideo()">Voir l'aide video</button>
<button class="erreur-btn erreur-btn-secondaire cache" id="erreur-equip-btn-restart" onclick="erreurEquipRestart()">Redemarrer la borne</button>
<button class="erreur-btn erreur-btn-secondaire" id="erreur-equip-btn-accueil" onclick="fermerErreurEquipement()">Retour accueil</button>
</div>
</div>
<!-- Ecran d'accueil -->
<section id="ecran-accueil" class="ecran actif">
<!-- Fond video/gif en boucle -->
<video id="accueil-video" class="accueil-media cache" muted loop playsinline></video>
<img id="accueil-gif" class="accueil-media cache">
<div class="accueil-contenu">
<img id="accueil-logo" class="accueil-logo cache" src="" alt="">
<h1 id="nom-evenement">Photobooth</h1>
<p class="accueil-instruction">Touchez pour commencer</p>
<div id="accueil-animation-defaut" class="accueil-animation">
<div class="cercle-pulse"></div>
</div>
</div>
<div id="compteur-accueil" class="compteur-accueil cache">
<span id="compteur-restant">400</span> / <span id="compteur-limite">400</span>
</div>
<!-- Booth : QR discret en bas a gauche -->
<div id="booth-info" class="booth-info cache">
<img id="booth-qr" class="booth-qr" src="">
</div>
<!-- Icone admin coin bas-droit -->
<div id="btn-admin" class="btn-admin" onclick="ouvrirAdmin()">&#9881;</div>
<!-- Icone photostation coin bas-gauche (visible seulement si installée) -->
<div id="btn-photostation" class="btn-photostation cache" onclick="ouvrirPhotostation()">&#128444;</div>
</section>
<!-- Choix du mode -->
<section id="ecran-mode" class="ecran">
<h2>Choisissez votre mode</h2>
<div class="grille-modes">
<button class="btn-mode" data-mode="simple">
<div class="mode-icone mode-icone-large">&#128247;</div>
<span>Photo</span>
</button>
<button class="btn-mode" data-mode="multi" id="btn-multi">
<div class="mode-icone mode-icone-large">&#127902;</div>
<span>Pellicule</span>
</button>
</div>
<button class="btn-retour" onclick="allerA('accueil')">Retour</button>
</section>
<!-- Choix de cadre avant capture -->
<section id="ecran-cadre-choix" class="ecran">
<h2>Choisissez un cadre</h2>
<div id="grille-cadres-choix" class="grille-cadres-choix">
<div class="cadre-choix-item cadre-choix-aucun" onclick="lancerSansCadre()">
<div class="cadre-choix-vide"></div>
<span>Sans cadre</span>
</div>
</div>
<button class="btn-retour" onclick="allerA('mode')">Retour</button>
</section>
<!-- Compte a rebours + Capture -->
<section id="ecran-capture" class="ecran">
<div id="preview-live" class="preview-live">
<img id="img-preview" src="" alt="Preview">
<img id="cadre-overlay-live" class="cadre-overlay cache" src="" alt="">
<div id="cadre-guide-recadrage" class="cadre-guide-recadrage cache"></div>
<div id="preview-erreur-camera" class="preview-erreur-camera cache">
<div class="preview-erreur-icon">&#128247;</div>
<p>Appareil photo deconnecte</p>
<span>Reconnexion en cours...</span>
</div>
</div>
<div id="compte-a-rebours" class="compte-a-rebours cache">
<span id="chiffre-car">3</span>
</div>
<div id="flash-blanc" class="flash-blanc cache"></div>
<div id="surprise-overlay" class="surprise-overlay cache"></div>
<div id="capture-en-cours" class="capture-en-cours cache">
<div class="capture-spinner"></div>
<span>Capture en cours...</span>
</div>
<div class="capture-info">
<span id="capture-compteur"></span>
</div>
</section>
<!-- Preview photo + Filtres -->
<section id="ecran-preview" class="ecran">
<div class="preview-photo-container">
<img id="photo-resultat" src="" alt="Photo">
<img id="cadre-overlay-preview" class="cadre-overlay cache" src="" alt="">
</div>
<div id="barre-filtres" class="barre-filtres">
</div>
<div id="barre-overlays" class="barre-overlays cache">
</div>
<div id="barre-fonds" class="barre-fonds cache">
</div>
<div class="preview-actions">
<button class="btn-action" onclick="allerA('partage')">Valider</button>
<button class="btn-secondaire" onclick="recommencer()">Reprendre</button>
</div>
</section>
<!-- Partage -->
<section id="ecran-partage" class="ecran">
<h2>Partagez votre photo !</h2>
<div class="photo-miniature">
<img id="photo-partage" src="" alt="Photo">
<img id="cadre-overlay-partage" class="cadre-overlay cache" src="" alt="">
</div>
<div class="grille-partage">
<button class="btn-partage" id="btn-imprimer" onclick="ouvrirImpression()">
<div class="partage-icone">&#128424;</div>
<span>Imprimer</span>
</button>
<button class="btn-partage" id="btn-email" onclick="ouvrirEmail()">
<div class="partage-icone">&#128231;</div>
<span>Email</span>
</button>
<button class="btn-partage" id="btn-qr" onclick="afficherQR()">
<div class="partage-icone">&#128274;</div>
<span>QR Code</span>
</button>
</div>
<div id="popup-qr" class="popup-qr cache">
<img id="qr-photo" class="qr-photo-img" src="">
<p class="qr-label">Scannez pour voir votre photo</p>
<button class="btn-secondaire" onclick="fermerQR()">Fermer</button>
</div>
<div id="form-impression" class="form-impression cache">
<div class="exemplaires-choix">
<button class="btn-exemplaire" onclick="changerExemplaires(-1)">-</button>
<span id="nb-exemplaires">1</span>
<button class="btn-exemplaire" onclick="changerExemplaires(1)">+</button>
</div>
<span class="exemplaires-label">exemplaire(s)</span>
<button class="btn-action" onclick="lancerImpression()">Imprimer</button>
<button class="btn-secondaire" onclick="fermerImpression()">Annuler</button>
</div>
<div id="form-email" class="form-email cache">
<input type="email" id="input-email" placeholder="votre@email.com" autocomplete="off" readonly>
<div id="email-suggestions" class="email-suggestions"></div>
<div class="clavier-virtuel" id="clavier-email">
<div class="clavier-ligne">
<button onclick="clavierTape('1')">1</button>
<button onclick="clavierTape('2')">2</button>
<button onclick="clavierTape('3')">3</button>
<button onclick="clavierTape('4')">4</button>
<button onclick="clavierTape('5')">5</button>
<button onclick="clavierTape('6')">6</button>
<button onclick="clavierTape('7')">7</button>
<button onclick="clavierTape('8')">8</button>
<button onclick="clavierTape('9')">9</button>
<button onclick="clavierTape('0')">0</button>
</div>
<div class="clavier-ligne">
<button onclick="clavierTape('a')">a</button>
<button onclick="clavierTape('z')">z</button>
<button onclick="clavierTape('e')">e</button>
<button onclick="clavierTape('r')">r</button>
<button onclick="clavierTape('t')">t</button>
<button onclick="clavierTape('y')">y</button>
<button onclick="clavierTape('u')">u</button>
<button onclick="clavierTape('i')">i</button>
<button onclick="clavierTape('o')">o</button>
<button onclick="clavierTape('p')">p</button>
</div>
<div class="clavier-ligne">
<button onclick="clavierTape('q')">q</button>
<button onclick="clavierTape('s')">s</button>
<button onclick="clavierTape('d')">d</button>
<button onclick="clavierTape('f')">f</button>
<button onclick="clavierTape('g')">g</button>
<button onclick="clavierTape('h')">h</button>
<button onclick="clavierTape('j')">j</button>
<button onclick="clavierTape('k')">k</button>
<button onclick="clavierTape('l')">l</button>
<button onclick="clavierTape('m')">m</button>
</div>
<div class="clavier-ligne">
<button onclick="clavierTape('w')">w</button>
<button onclick="clavierTape('x')">x</button>
<button onclick="clavierTape('c')">c</button>
<button onclick="clavierTape('v')">v</button>
<button onclick="clavierTape('b')">b</button>
<button onclick="clavierTape('n')">n</button>
<button onclick="clavierTape('@')">@</button>
<button onclick="clavierTape('.')">.</button>
<button onclick="clavierTape('-')">-</button>
<button onclick="clavierTape('_')">_</button>
</div>
<div class="clavier-ligne clavier-speciales">
<button class="clavier-wide" onclick="clavierEffacer()">&#9003;</button>
<button class="clavier-wide" onclick="clavierTape('@gmail.com')">@gmail</button>
<button class="clavier-wide" onclick="clavierTape('@hotmail.com')">@hotmail</button>
<button class="clavier-wide" onclick="clavierTape('@outlook.com')">@outlook</button>
<button class="clavier-wide" onclick="clavierTape('@yahoo.fr')">@yahoo</button>
</div>
<div class="clavier-ligne clavier-speciales">
<button class="clavier-wide" onclick="clavierTape('@icloud.com')">@icloud</button>
<button class="clavier-wide" onclick="clavierTape('@orange.fr')">@orange</button>
<button class="clavier-wide" onclick="clavierTape('@free.fr')">@free</button>
<button class="clavier-wide" onclick="clavierTape('@sfr.fr')">@sfr</button>
<button class="clavier-wide" onclick="clavierTape('@laposte.net')">@laposte</button>
</div>
</div>
<div style="display:flex;gap:1rem;margin-top:0.5rem">
<button class="btn-action" onclick="envoyerEmail()">Envoyer</button>
<button class="btn-secondaire" onclick="fermerEmail()">Annuler</button>
</div>
</div>
<div id="zone-qr" class="zone-qr cache">
<img id="img-qr" src="" alt="QR Code">
</div>
<div id="statut-partage" class="statut-partage cache"></div>
<div class="partage-bas">
<button class="btn-action" id="btn-terminer" onclick="allerA('accueil')">Terminer</button>
<button class="btn-secondaire" onclick="recommencer()">Nouvelle photo</button>
</div>
</section>
<!-- Galerie -->
<section id="ecran-galerie" class="ecran">
<h2>Galerie</h2>
<div id="grille-galerie" class="grille-galerie"></div>
<button class="btn-retour" onclick="allerA('accueil')">Retour</button>
</section>
<!-- Choix admin : wizard ou parametres -->
<section id="ecran-admin-choix" class="ecran" onclick="event.stopPropagation()">
<h2>Administration</h2>
<div class="grille-modes">
<button class="btn-mode" onclick="ouvrirWizard()">
<div class="mode-icone mode-icone-large">&#9889;</div>
<span>Nouvel evenement</span>
</button>
<button class="btn-mode" onclick="allerA('admin')">
<div class="mode-icone mode-icone-large">&#9881;</div>
<span>Parametres</span>
</button>
</div>
<div style="display:flex;gap:1rem;margin-top:1rem">
<button class="btn-secondaire" onclick="location.reload()">Recharger</button>
<button class="btn-secondaire" onclick="quitterNavigateur()">Quitter</button>
</div>
<button class="btn-retour" onclick="allerA('accueil')">Retour</button>
</section>
<!-- Wizard evenement -->
<section id="ecran-wizard" class="ecran">
<div class="wizard-header">
<button class="btn-fermer" onclick="allerA('accueil')">&times;</button>
<div class="wizard-progress" id="wizard-progress"></div>
</div>
<!-- Etape 1 : Nom -->
<div class="wizard-step actif" data-step="1">
<h2>Nom de l'evenement</h2>
<input type="text" id="wiz-nom" class="wizard-input" placeholder="Mariage Julie & Thomas" autocomplete="off">
<button class="wizard-btn-next" onclick="wizardSuivant()">Suivant</button>
</div>
<!-- Etape 2 : Theme -->
<div class="wizard-step" data-step="2">
<h2>Theme visuel</h2>
<div class="wizard-choix">
<button class="wizard-card" data-val="base" onclick="wizardChoisir(this, 'theme')">
<div class="wizard-card-icon" style="background:#1a1a2e;color:#e91e63">&#9790;</div>
<span>Sombre</span>
</button>
<button class="wizard-card" data-val="sikapics" onclick="wizardChoisir(this, 'theme')">
<div class="wizard-card-icon" style="background:#fbe7e8;color:#c31f48">&#10047;</div>
<span>SikaPics</span>
</button>
<button class="wizard-card" data-val="viking" onclick="wizardChoisir(this, 'theme')">
<div class="wizard-card-icon" style="background:#2b1810;color:#b08d57">&#9876;</div>
<span>Viking</span>
</button>
</div>
<button class="wizard-btn-next" onclick="wizardSuivant()">Suivant</button>
</div>
<!-- Etape 3 : Modes photo -->
<div class="wizard-step" data-step="3">
<h2>Modes photo</h2>
<div class="wizard-choix">
<button class="wizard-card wizard-toggle actif" data-val="simple" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#128247;</div>
<span>Photo</span>
</button>
<button class="wizard-card wizard-toggle actif" data-val="multi" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#127902;</div>
<span>Pellicule</span>
</button>
</div>
<button class="wizard-btn-next" onclick="wizardSuivant()">Suivant</button>
</div>
<!-- Etape 4 : Nombre de photos pellicule -->
<div class="wizard-step" data-step="4">
<h2>Photos par pellicule</h2>
<div class="wizard-nombre">
<button class="wizard-nb-btn" onclick="wizardNbPhotos(-1)">-</button>
<span id="wiz-nb-photos" class="wizard-nb-val">4</span>
<button class="wizard-nb-btn" onclick="wizardNbPhotos(1)">+</button>
</div>
<button class="wizard-btn-next" onclick="wizardSuivant()">Suivant</button>
</div>
<!-- Etape 5 : Fonctions partage -->
<div class="wizard-step" data-step="5">
<h2>Partage</h2>
<div class="wizard-choix wizard-choix-wrap">
<button class="wizard-card wizard-toggle" data-val="impression" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#128424;</div>
<span>Impression</span>
</button>
<button class="wizard-card wizard-toggle" data-val="email" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#9993;</div>
<span>Email</span>
</button>
<button class="wizard-card wizard-toggle" data-val="galerie_live" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#127760;</div>
<span>Galerie live</span>
</button>
<button class="wizard-card wizard-toggle" data-val="qr" onclick="wizardToggle(this)">
<div class="wizard-card-icon">&#9641;</div>
<span>QR Code</span>
</button>
</div>
<button class="wizard-btn-next" onclick="wizardSuivant()">Suivant</button>
</div>
<!-- Etape 6 : Resume -->
<div class="wizard-step" data-step="6">
<h2>C'est pret !</h2>
<div id="wiz-resume" class="wizard-resume"></div>
<button class="wizard-btn-next wizard-btn-go" onclick="wizardTerminer()">Lancer le photobooth</button>
<button class="btn-secondaire" onclick="allerA('admin')">Parametres avances</button>
</div>
</section>
<!-- Menu Admin / Backoffice (avance) -->
<section id="ecran-admin" class="ecran">
<div class="admin-header">
<h2>Parametres avances</h2>
<button class="btn-fermer" onclick="allerA('accueil')">&times;</button>
</div>
<div class="admin-contenu">
<div class="admin-rubriques">
<button class="rubrique actif" data-rubrique="general" onclick="changerRubrique('general')">General</button>
<button class="rubrique" data-rubrique="evenement" onclick="changerRubrique('evenement')">Evenement</button>
</div>
<div class="admin-onglets" id="onglets-general">
<button class="onglet actif" data-onglet="materiel">Materiel</button>
<button class="onglet" data-onglet="compteur-admin">Compteur</button>
<button class="onglet" data-onglet="consommables-admin" onclick="chargerConsommables()">Consommables</button>
<button class="onglet" data-onglet="fonctions">Fonctions</button>
<button class="onglet" data-onglet="personnalisation">Personnalisation</button>
<button class="onglet" data-onglet="videos-admin" onclick="chargerVideosAdmin()">Videos</button>
<button class="onglet" data-onglet="eclairage" onclick="demarrerEclairageLive();demarrerEclairageLiveExt()">Eclairage</button>
<button class="onglet" data-onglet="wifi" onclick="chargerWifi()">WiFi</button>
<button class="onglet" data-onglet="diagnostic" onclick="chargerDiagnostic()">Diagnostic</button>
<button class="onglet" data-onglet="infos" onclick="chargerInfosSysteme()">Infos</button>
</div>
<div class="admin-onglets cache" id="onglets-evenement">
<button class="onglet" data-onglet="evenement">Config</button>
<button class="onglet" data-onglet="destinations-admin">Destinations</button>
<button class="onglet" data-onglet="surprise-admin">Surprise</button>
<button class="onglet" data-onglet="admin-galerie" onclick="chargerAdminGalerie()">Galerie</button>
</div>
<!-- Panneau Materiel (Camera + Imprimante) -->
<div class="admin-panneau actif" id="panneau-materiel">
<h3>Appareil photo</h3>
<div class="champ">
<label>Statut</label>
<span id="admin-camera-statut" class="statut-badge">--</span>
<button class="btn-secondaire btn-petit" onclick="reconnecterCamera()">Reconnecter</button>
</div>
<div class="champ">
<label>Appareil detecte</label>
<select id="admin-appareil"><option value="">Detection...</option></select>
</div>
<div class="champ">
<label>Compte a rebours (secondes)</label>
<input type="number" id="admin-car" min="1" max="10" value="3">
</div>
<div class="champ">
<label class="toggle"><input type="checkbox" id="tog-flash-integre" checked><span class="toggle-slider"></span> Flash intégré Canon (décocher = flash Off)</label>
</div>
<h3>Imprimante</h3>
<div class="champ">
<label>Imprimante</label>
<select id="admin-imprimante"><option value="">Detection...</option></select>
<button class="btn-secondaire btn-petit" onclick="rafraichirImprimantes()">Rafraichir</button>
</div>
<div class="champ">
<label>Format papier</label>
<select id="admin-format-papier">
<option value="15x20">15&times;20 cm</option>
<option value="10x15">10&times;15 cm</option>
<option value="10x15-2up">10&times;15 cm &mdash; 2 strips</option>
</select>
</div>
<div class="champ">
<label>Orientation photo</label>
<div class="radio-group">
<label><input type="radio" name="admin-orientation" value="portrait"> Portrait</label>
<label><input type="radio" name="admin-orientation" value="paysage"> Paysage</label>
</div>
</div>
<div class="champ">
<label>Nombre max d'exemplaires</label>
<input type="number" id="admin-copies-max" min="1" max="20" value="5">
</div>
<div class="champ">
<label class="toggle"><input type="checkbox" id="tog-rembobinage-ruban"><span class="toggle-slider"></span> Rembobinage ruban (economise le ruban sur les petits formats)</label>
</div>
<button class="btn-action" onclick="sauvegarderMateriel()">Sauvegarder</button>
<div class="champ" style="margin-top:1rem;display:flex;gap:0.8rem;flex-wrap:wrap">
<button class="btn-danger" onclick="evacuerBourrage()">&#9888; Annuler jobs</button>
<button class="btn-secondaire" onclick="resetUsb()">&#8635; Réinit. USB</button>
<button class="btn-secondaire" onclick="couperPapier()">&#9988; Couper papier</button>
</div>
<div id="imprimante-statut-detail" class="champ" style="display:none">
<div id="imprimante-erreur-msg" style="background:rgba(244,67,54,0.1);border-radius:8px;padding:0.8rem;color:#f44336;font-size:0.85rem;margin-top:0.5rem"></div>
</div>
</div>
<!-- Panneau Compteur -->
<div class="admin-panneau" id="panneau-compteur-admin">
<h3>Compteur de photos</h3>
<div class="champ">
<label class="toggle"><input type="checkbox" id="tog-compteur-actif"><span class="toggle-slider"></span> Compteur actif</label>
</div>
<div class="compteur-display">
<div class="compteur-gros">
<span id="admin-compteur-restant" class="compteur-nombre">400</span>
<span class="compteur-sep">/</span>
<span id="admin-compteur-limite-display" class="compteur-nombre petit">400</span>
</div>
<span class="compteur-label">photos restantes</span>
<span id="admin-compteur-detail" class="compteur-label" style="font-size:0.7em;opacity:0.7;margin-top:2px"></span>
</div>
<div class="champ">
<label>Limite evenement (0 = pas de limite)</label>
<input type="number" id="admin-compteur-limite" min="1" max="9999" value="400">
</div>
<div class="champ-row">
<button class="btn-action" onclick="sauvegarderCompteur()">Sauvegarder</button>
<button class="btn-danger" onclick="resetCompteur()">Remettre a zero</button>
</div>
</div>
<!-- Panneau Consommables -->
<div class="admin-panneau" id="panneau-consommables-admin">
<h3>Suivi consommables</h3>
<p class="aide">Suivez l'usure du papier et du ruban. Reinitalisez quand vous changez une bobine.</p>
<div class="conso-grid">
<div class="conso-card">
<div class="conso-icon">&#128196;</div>
<div class="conso-titre">Papier</div>
<div class="conso-barre-fond"><div class="conso-barre conso-barre-papier" id="conso-barre-papier"></div></div>
<div class="conso-chiffres"><span id="conso-papier-restant">--</span> / <span id="conso-papier-cap">--</span> feuilles</div>
<button class="btn-secondaire btn-petit" onclick="resetConsommable('papier')">Bobine changee</button>
</div>
<div class="conso-card">
<div class="conso-icon">&#127912;</div>
<div class="conso-titre">Ruban</div>
<div class="conso-barre-fond"><div class="conso-barre conso-barre-ruban" id="conso-barre-ruban"></div></div>
<div class="conso-chiffres"><span id="conso-ruban-restant">--</span> / <span id="conso-ruban-cap">--</span> poses</div>
<button class="btn-secondaire btn-petit" onclick="resetConsommable('ruban')">Ruban change</button>
</div>
<div class="conso-card">
<div class="conso-icon">&#128247;</div>
<div class="conso-titre">Photos sorties</div>
<div class="conso-gros" id="conso-photos">--</div>
</div>
<div class="conso-card" id="conso-card-perdues">
<div class="conso-icon">&#9888;</div>
<div class="conso-titre">Poses perdues</div>
<div class="conso-gros" id="conso-perdues" style="color:#fb8c00">--</div>
<div class="conso-chiffres">ruban gaspille sans rembobinage</div>
</div>
</div>
<h3 style="margin-top:1.5rem">Capacites</h3>
<div class="champ">
<label>Capacite papier (feuilles par bobine)</label>
<input type="number" id="conso-cap-papier" min="1" max="9999" value="400">
</div>
<div class="champ">
<label>Capacite ruban (poses par bobine)</label>
<input type="number" id="conso-cap-ruban" min="1" max="9999" value="400">
</div>
<button class="btn-action" onclick="sauvegarderCapacites()">Sauvegarder capacites</button>
<button class="btn-danger" style="margin-top:0.5rem" onclick="resetConsommable('tout')">Tout reinitialiser</button>
<div class="conso-diag" id="conso-diagnostic" style="margin-top:1.5rem"></div>
</div>
<!-- Panneau Destinations -->
<div class="admin-panneau" id="panneau-destinations-admin">
<h3>Ou sauvegarder les photos ?</h3>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-dest-memoire" checked><span class="toggle-slider"></span> Memoire interne</label>
<label class="toggle"><input type="checkbox" id="tog-dest-usb"><span class="toggle-slider"></span> Cle USB</label>
</div>
<div id="dest-usb-details" class="sous-config cache">
<div class="champ">
<label>Chemin USB</label>
<div class="champ-row">
<select id="admin-chemin-usb"><option value="/media/usb">/media/usb</option></select>
<button class="btn-secondaire btn-petit" onclick="detecterUSB()">Detecter</button>
</div>
</div>
</div>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-dest-ftp"><span class="toggle-slider"></span> Serveur FTP</label>
</div>
<div id="dest-ftp-details" class="sous-config cache">
<div class="champ"><label>Hote FTP</label><input type="text" id="admin-ftp-host" placeholder="ftp.exemple.com"></div>
<div class="champ"><label>Port</label><input type="number" id="admin-ftp-port" value="21"></div>
<div class="champ"><label>Utilisateur</label><input type="text" id="admin-ftp-user"></div>
<div class="champ"><label>Mot de passe</label><input type="password" id="admin-ftp-pass"></div>
<div class="champ"><label>Chemin distant</label><input type="text" id="admin-ftp-chemin" value="/photobooth"></div>
</div>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-dest-galerie"><span class="toggle-slider"></span> Galerie en ligne</label>
</div>
<div id="dest-galerie-details" class="sous-config cache">
<div class="champ"><label>URL du serveur</label><input type="text" id="admin-booth-url" placeholder="https://booth.copydev.fr" value="https://booth.copydev.fr"></div>
<div class="champ"><label>Cle API</label><input type="text" id="admin-booth-apikey" placeholder="booth-photobooth-2026" value="booth-photobooth-2026"></div>
<div class="champ"><label>ID evenement</label><input type="text" id="admin-booth-eventid" placeholder="auto" value=""></div>
<div class="champ">
<label>Code invites : <span id="admin-booth-password" style="font-size:1.5rem;font-weight:bold;letter-spacing:4px">--</span></label>
</div>
<button class="btn-action" onclick="sauvegarderBooth()">Sauvegarder</button>
<button class="btn-secondaire" onclick="regenererBoothPassword()">Nouveau code</button>
<button class="btn-secondaire" onclick="imprimerFlyerQR()">&#128424; Imprimer flyer QR</button>
</div>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-dest-email-auto"><span class="toggle-slider"></span> Email automatique</label>
</div>
<h3>Quelles photos sauvegarder ?</h3>
<div class="radio-groupe">
<label class="radio"><input type="radio" name="sauv-mode" id="sauv-tout" value="tout" checked><span class="radio-mark"></span> Toutes les photos</label>
<label class="radio"><input type="radio" name="sauv-mode" id="sauv-imprimees" value="imprimees"><span class="radio-mark"></span> Uniquement les photos imprimees</label>
</div>
<button class="btn-action" onclick="sauvegarderDestinations()">Sauvegarder</button>
</div>
<!-- Panneau Personnalisation (Cadres + Fonds + Animations) -->
<div class="admin-panneau" id="panneau-personnalisation">
<h3>Cadres d'impression</h3>
<p class="aide">Selectionnez un cadre PNG par format. Le cadre est applique sur chaque impression. Laissez vide pour imprimer sans cadre.</p>
<div class="cadres-formats">
<div class="cadres-format-bloc" id="cadres-bloc-strip">
<h4>Strip (5&times;15 cm)</h4>
<div class="cadres-liste" id="cadres-liste-strip"></div>
<div class="champ cadres-upload">
<input type="file" id="input-cadre-strip" accept=".png" class="input-fichier">
<button class="btn-secondaire btn-petit" onclick="uploaderCadreFormat('strip')">Importer</button>
</div>
</div>
<div class="cadres-format-bloc" id="cadres-bloc-10x15">
<h4>10&times;15 cm</h4>
<div class="cadres-liste" id="cadres-liste-10x15"></div>
<div class="champ cadres-upload">
<input type="file" id="input-cadre-10x15" accept=".png" class="input-fichier">
<button class="btn-secondaire btn-petit" onclick="uploaderCadreFormat('10x15')">Importer</button>
</div>
</div>
<div class="cadres-format-bloc" id="cadres-bloc-15x20">
<h4>15&times;20 cm</h4>
<div class="cadres-liste" id="cadres-liste-15x20"></div>
<div class="champ cadres-upload">
<input type="file" id="input-cadre-15x20" accept=".png" class="input-fichier">
<button class="btn-secondaire btn-petit" onclick="uploaderCadreFormat('15x20')">Importer</button>
</div>
</div>
</div>
<h3>Cadres / Overlays photo</h3>
<p class="aide">Cochez les cadres a proposer aux utilisateurs en live.</p>
<div id="liste-cadres" class="liste-cadres">
<p class="texte-secondaire">Aucun cadre importe</p>
</div>
<div class="champ">
<input type="file" id="input-cadre" accept=".png" class="input-fichier">
<button class="btn-action" onclick="uploaderCadre()">Importer un cadre</button>
</div>
<h3>Fonds (chroma key)</h3>
<p class="aide">Importez des images de fond pour le mode fond vert.</p>
<div id="liste-fonds" class="liste-fonds">
<p class="texte-secondaire">Aucun fond importe</p>
</div>
<div class="champ">
<input type="file" id="input-fond" accept=".jpg,.jpeg,.png" class="input-fichier">
<button class="btn-action" onclick="uploaderFond()">Importer un fond</button>
</div>
<h3>Animations 3-2-1</h3>
<p class="aide">Si plusieurs sont cochees, une sera choisie au hasard.</p>
<div id="liste-animations" class="liste-animations">
</div>
<h4>Animations personnalisees (video/GIF)</h4>
<div id="liste-animations-custom" class="liste-animations">
</div>
<div class="champ">
<input type="file" id="input-animation" accept=".gif,.mp4,.webm" class="input-fichier">
<button class="btn-action" onclick="uploaderAnimation()">Importer</button>
</div>
<div class="animation-preview">
<h4>Apercu</h4>
<div id="preview-animation" class="preview-animation-box">
<span id="preview-anim-chiffre" class="anim-chiffre">3</span>
<video id="preview-anim-video" class="preview-anim-video cache" muted playsinline></video>
</div>
<button class="btn-secondaire" onclick="testerAnimationPreview()">Tester</button>
</div>
</div>
<!-- Panneau Evenement -->
<div class="admin-panneau" id="panneau-evenement">
<h3>Evenements</h3>
<div class="champ-row" style="margin-bottom:1rem">
<input type="text" id="input-nouveau-event" placeholder="Nom du nouvel evenement" style="flex:1">
<button class="btn-action btn-petit" onclick="creerEvenementAdmin()">Creer</button>
</div>
<div id="liste-evenements"></div>
<h3 id="titre-event-detail" class="cache">Configuration evenement</h3>
<div id="detail-evenement" class="cache">
<div class="champ">
<label>Theme visuel</label>
<select id="admin-theme" onchange="changerTheme(this.value)">
<option value="base">Base (Sombre moderne)</option>
<option value="sikapics">SikaPics (Rose elegant)</option>
<option value="viking">Viking Celte (Bois & Bronze)</option>
</select>
</div>
<div class="champ">
<label>Nom de l'evenement</label>
<input type="text" id="admin-nom-event" placeholder="Mon Evenement">
</div>
<div class="champ">
<label>Video/GIF d'accueil (boucle)</label>
<div class="champ-row">
<select id="admin-media-accueil">
<option value="">Aucun (animation par defaut)</option>
</select>
<button class="btn-secondaire btn-petit" onclick="rafraichirMediaAccueil()">Rafraichir</button>
</div>
<input type="file" id="input-media-accueil" accept=".gif,.mp4,.webm" class="input-fichier">
<button class="btn-secondaire btn-petit" onclick="uploaderMediaAccueil()">Importer</button>
</div>
<div class="champ">
<label>Couleur primaire</label>
<input type="color" id="admin-couleur-primaire" value="#e91e63">
</div>
<div class="champ">
<label>Couleur secondaire</label>
<input type="color" id="admin-couleur-secondaire" value="#ffffff">
</div>
<div class="champ">
<label>Date de fin (impression bloquee apres)</label>
<input type="date" id="admin-date-fin">
</div>
<div class="champ-row">
<button class="btn-action" onclick="sauvegarderEvenement()">Sauvegarder</button>
<button class="btn-danger" id="btn-terminer-event" onclick="terminerEvenement()">Terminer l'evenement</button>
</div>
<div id="badge-event-termine" class="cache" style="background:#f44336;color:#fff;padding:8px 16px;border-radius:8px;text-align:center;font-weight:bold;margin-top:8px">Evenement termine — impression desactivee</div>
<div class="champ" id="lien-galerie-event" style="display:none">
<label>Galerie en ligne</label>
<a id="url-galerie-event" href="#" target="_blank" class="btn-secondaire btn-petit" style="text-decoration:none;display:inline-block">Ouvrir la galerie</a>
</div>
<h3>Formats d'impression</h3>
<p class="aide">Formats papier disponibles pour cet evenement.</p>
<div class="toggle-groupe" id="event-formats-toggles">
<label class="toggle"><input type="checkbox" id="tog-event-fmt-10x15"><span class="toggle-slider"></span> 10&times;15 cm</label>
<label class="toggle"><input type="checkbox" id="tog-event-fmt-15x20"><span class="toggle-slider"></span> 15&times;20 cm</label>
<label class="toggle"><input type="checkbox" id="tog-event-fmt-strip"><span class="toggle-slider"></span> Strip / Pellicule</label>
</div>
<h3>Cadre evenement</h3>
<p class="aide">Cadre specifique a cet evenement. Applique sur tous les formats sauf strips.</p>
<div id="cadres-event-formats"></div>
</div>
</div>
<!-- Panneau Fonctions (toggles + email + booth + galerie + systeme) -->
<div class="admin-panneau" id="panneau-fonctions">
<h3>Modes photo</h3>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-photo-simple" checked><span class="toggle-slider"></span> Photo simple</label>
<label class="toggle"><input type="checkbox" id="tog-multi-shot"><span class="toggle-slider"></span> Pellicule (multi-shot)</label>
<label class="toggle"><input type="checkbox" id="tog-filtres"><span class="toggle-slider"></span> Filtres</label>
<label class="toggle"><input type="checkbox" id="tog-overlays"><span class="toggle-slider"></span> Overlays / Cadres</label>
<label class="toggle"><input type="checkbox" id="tog-chroma-key"><span class="toggle-slider"></span> Chroma key (fond vert)</label>
</div>
<h3>Partage</h3>
<div class="toggle-groupe">
<label class="toggle"><input type="checkbox" id="tog-impression"><span class="toggle-slider"></span> Impression</label>
<label class="toggle"><input type="checkbox" id="tog-email"><span class="toggle-slider"></span> Email</label>
<label class="toggle"><input type="checkbox" id="tog-qr-code"><span class="toggle-slider"></span> QR Code</label>
<label class="toggle"><input type="checkbox" id="tog-galerie"><span class="toggle-slider"></span> Galerie locale</label>
</div>
<h3>Email SMTP</h3>
<div class="champ"><label>Serveur SMTP</label><input type="text" id="admin-smtp-host" placeholder="smtp.gmail.com"></div>
<div class="champ"><label>Port</label><input type="number" id="admin-smtp-port" value="587"></div>
<div class="champ"><label>Utilisateur</label><input type="text" id="admin-smtp-user" placeholder="user@gmail.com"></div>
<div class="champ"><label>Mot de passe</label><input type="password" id="admin-smtp-pass"></div>
<div class="champ"><label>Expediteur</label><input type="text" id="admin-expediteur" placeholder="photobooth@event.com"></div>
<button class="btn-action" onclick="sauvegarderEmail()">Sauvegarder email</button>
<h3>Galerie locale</h3>
<div class="champ">
<label>Photos prises : <span id="admin-nb-photos">0</span> | Exports : <span id="admin-nb-exports">0</span></label>
</div>
<div class="champ">
<label>URL galerie en ligne</label>
<input type="text" id="admin-url-galerie" placeholder="https://...">
</div>
<button class="btn-action" onclick="sauvegarderGalerie()">Sauvegarder URL</button>
<button class="btn-danger" onclick="confirmerViderGalerie()">Vider toute la galerie</button>
<h3>Systeme</h3>
<button class="btn-action" onclick="location.reload()">Mettre a jour l'affichage</button>
<button class="btn-secondaire" onclick="quitterNavigateur()">Quitter le navigateur</button>
<button class="btn-danger" onclick="confirmerRedemarrage()">Redemarrer le systeme</button>
<button class="btn-danger" onclick="confirmerExtinction()">Eteindre le systeme</button>
</div>
<!-- Panneau WiFi -->
<div class="admin-panneau" id="panneau-wifi">
<div class="wifi-statut" id="wifi-statut">
<div class="wifi-statut-icon" id="wifi-statut-icon">&#128246;</div>
<div class="wifi-statut-info">
<div id="wifi-ssid" class="wifi-ssid">--</div>
<div id="wifi-detail" class="wifi-detail">Non connecté</div>
</div>
<div id="wifi-signal-bars" class="wifi-signal-bars"></div>
</div>
<div class="champ-row" style="margin:1rem 0">
<button class="btn-action" onclick="scannerWifi()">&#128269; Scanner les réseaux</button>
</div>
<div id="wifi-scan-loading" class="cache" style="text-align:center;padding:1rem;color:#888">
<div class="capture-spinner" style="display:inline-block;width:24px;height:24px"></div>
Recherche en cours...
</div>
<div id="wifi-liste-reseaux" class="wifi-liste"></div>
<h3 style="margin-top:1.5rem">Réseaux enregistrés</h3>
<div id="wifi-liste-enregistres" class="wifi-liste"></div>
</div>
<!-- Popup saisie mot de passe WiFi -->
<div id="popup-wifi-mdp" class="popup-overlay cache">
<div class="popup-box popup-box-pave" style="max-width:600px">
<h3 id="wifi-mdp-titre">Mot de passe WiFi</h3>
<input type="text" id="wifi-mdp-input" placeholder="Mot de passe" autocomplete="off" readonly style="font-size:1.1rem;padding:.8rem;width:100%;border-radius:8px;border:1px solid rgba(255,255,255,.15);background:rgba(255,255,255,.05);color:#fff;margin-bottom:.5rem">
<div id="wifi-mdp-erreur" class="mdp-erreur cache">Echec connexion</div>
<div class="clavier-virtuel" id="clavier-wifi">
<div class="clavier-ligne">
<button onclick="wifiTape('1')">1</button>
<button onclick="wifiTape('2')">2</button>
<button onclick="wifiTape('3')">3</button>
<button onclick="wifiTape('4')">4</button>
<button onclick="wifiTape('5')">5</button>
<button onclick="wifiTape('6')">6</button>
<button onclick="wifiTape('7')">7</button>
<button onclick="wifiTape('8')">8</button>
<button onclick="wifiTape('9')">9</button>
<button onclick="wifiTape('0')">0</button>
</div>
<div class="clavier-ligne" id="wifi-kb-row1">
<button onclick="wifiTape('a')">a</button>
<button onclick="wifiTape('z')">z</button>
<button onclick="wifiTape('e')">e</button>
<button onclick="wifiTape('r')">r</button>
<button onclick="wifiTape('t')">t</button>
<button onclick="wifiTape('y')">y</button>
<button onclick="wifiTape('u')">u</button>
<button onclick="wifiTape('i')">i</button>
<button onclick="wifiTape('o')">o</button>
<button onclick="wifiTape('p')">p</button>
</div>
<div class="clavier-ligne" id="wifi-kb-row2">
<button onclick="wifiTape('q')">q</button>
<button onclick="wifiTape('s')">s</button>
<button onclick="wifiTape('d')">d</button>
<button onclick="wifiTape('f')">f</button>
<button onclick="wifiTape('g')">g</button>
<button onclick="wifiTape('h')">h</button>
<button onclick="wifiTape('j')">j</button>
<button onclick="wifiTape('k')">k</button>
<button onclick="wifiTape('l')">l</button>
<button onclick="wifiTape('m')">m</button>
</div>
<div class="clavier-ligne" id="wifi-kb-row3">
<button onclick="wifiTape('w')">w</button>
<button onclick="wifiTape('x')">x</button>
<button onclick="wifiTape('c')">c</button>
<button onclick="wifiTape('v')">v</button>
<button onclick="wifiTape('b')">b</button>
<button onclick="wifiTape('n')">n</button>
<button onclick="wifiTape('!')">!</button>
<button onclick="wifiTape('.')">.</button>
<button onclick="wifiTape('-')">-</button>
<button onclick="wifiTape('_')">_</button>
</div>
<div class="clavier-ligne clavier-speciales">
<button class="clavier-wide" onclick="wifiToggleMaj()" id="wifi-btn-maj">&#8679; MAJ</button>
<button class="clavier-wide clavier-espace" onclick="wifiTape(' ')">Espace</button>
<button class="clavier-wide" onclick="wifiEffacer()">&#9003;</button>
</div>
<div class="clavier-ligne clavier-speciales">
<button onclick="wifiTape('@')">@</button>
<button onclick="wifiTape('#')">#</button>
<button onclick="wifiTape('$')">$</button>
<button onclick="wifiTape('%')">%</button>
<button onclick="wifiTape('&')">&amp;</button>
<button onclick="wifiTape('*')">*</button>
<button onclick="wifiTape('+')" >+</button>
<button onclick="wifiTape('=')">=</button>
<button onclick="wifiTape('/')">/</button>
<button onclick="wifiTape('?')">?</button>
</div>
</div>
<div style="display:flex;gap:1rem;margin-top:.8rem">
<button class="btn-action" onclick="validerWifiMdp()" id="wifi-btn-connecter">Connecter</button>
<button class="btn-secondaire" onclick="fermerPopupWifi()">Annuler</button>
</div>
</div>
</div>
<!-- Panneau Galerie admin -->
<div class="admin-panneau" id="panneau-admin-galerie">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;flex-wrap:wrap;gap:0.5rem">
<h3 style="margin:0">Photos</h3>
<div style="display:flex;gap:0.5rem;align-items:center">
<span id="admin-galerie-selection" style="font-size:0.85rem;color:#aaa"></span>
<button class="btn-action btn-petit" onclick="adminGalerieSelectAll()">Tout selectionner</button>
<button class="btn-action btn-petit" onclick="adminGalerieDeselectAll()">Deselectionner</button>
<button class="btn-secondaire btn-petit" onclick="adminGalerieImprimer()">Imprimer selection</button>
</div>
</div>
<div id="admin-galerie-grille" class="grille-galerie" style="max-height:60vh;overflow-y:auto"></div>
</div>
<div class="admin-panneau" id="panneau-eclairage">
<div style="display:flex;gap:1rem;align-items:flex-start;flex-wrap:wrap">
<div style="flex:1;min-width:280px">
<img id="eclairage-preview" style="width:100%;border-radius:8px;background:#111" alt="Preview">
</div>
<div style="flex:0 0 200px;text-align:center">
<div id="eclairage-score-box" style="font-size:3rem;font-weight:800;padding:1.5rem;border-radius:16px;background:#222;margin-bottom:1rem">--</div>
<div id="eclairage-action" style="font-size:1.2rem;font-weight:600;margin-bottom:.5rem">--</div>
<div id="eclairage-visages" style="font-size:.9rem;color:#aaa">--</div>
</div>
</div>
<h3 style="margin-top:1.5rem">Relais</h3>
<div id="relais-status" style="margin-bottom:1rem;padding:0.5rem;background:#111;border-radius:6px;font-size:0.85rem;color:#aaa">Non connecte</div>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-bottom:1rem">
<button class="btn-action btn-petit" onclick="relaisAction('projecteurs','on')">Projecteurs ON</button>
<button class="btn-secondaire btn-petit" onclick="relaisAction('projecteurs','off')">Projecteurs OFF</button>
<button class="btn-danger btn-petit" onclick="relaisAction('canon/power-cycle','on')">Power-cycle Canon</button>
<button class="btn-danger btn-petit" style="background:#b71c1c" onclick="relaisAction('canon/hard-reset','on')">Hard Reset Canon</button>
</div>
<h4>Eclairage automatique</h4>
<div class="champ">
<label class="toggle"><input type="checkbox" id="tog-eclairage-auto"><span class="toggle-slider"></span> Allumer les projecteurs automatiquement selon la luminosite</label>
</div>
<div class="champ">
<label>Seuil projecteur 1 (score &lt;)</label>
<input type="number" id="relais-seuil-proj1" min="0" max="100" value="45" step="5">
<span style="font-size:0.75rem;color:#888">1 seul projecteur s'allume</span>
</div>
<div class="champ">
<label>Seuil projecteur 2 (score &lt;)</label>
<input type="number" id="relais-seuil-proj2" min="0" max="100" value="30" step="5">
<span style="font-size:0.75rem;color:#888">Les 2 projecteurs s'allument</span>
</div>
<div class="champ">
<label>Seuil extinction (score &gt;)</label>
<input type="number" id="relais-seuil-off" min="0" max="100" value="65" step="5">
<span style="font-size:0.75rem;color:#888">Projecteurs s'eteignent</span>
</div>
<h4 style="margin-top:1.5rem">Veille</h4>
<div class="champ">
<label>Eteindre les projecteurs apres (minutes d'inactivite)</label>
<input type="number" id="relais-veille-delai" min="0" max="60" value="0" step="1">
<span style="font-size:0.75rem;color:#888">0 = jamais. Les projecteurs se rallument quand un utilisateur touche l'ecran</span>
</div>
<button class="btn-action" onclick="sauvegarderRelaisConfig()">Sauvegarder</button>
</div>
<!-- Panneau Diagnostic -->
<div class="admin-panneau" id="panneau-diagnostic">
<h3>Sante du systeme</h3>
<div class="diag-cards" id="diag-sante">
<div class="diag-card" id="diag-camera">
<div class="diag-icon">&#128247;</div>
<div class="diag-label">Camera</div>
<div class="diag-status" id="diag-camera-status">--</div>
</div>
<div class="diag-card" id="diag-imprimante">
<div class="diag-icon">&#128424;</div>
<div class="diag-label">Imprimante</div>
<div class="diag-status" id="diag-imp-status">--</div>
</div>
<div class="diag-card" id="diag-relais">
<div class="diag-icon">&#128268;</div>
<div class="diag-label">Relais</div>
<div class="diag-status" id="diag-relais-status">--</div>
</div>
<div class="diag-card" id="diag-systeme">
<div class="diag-icon">&#128187;</div>
<div class="diag-label">Systeme</div>
<div class="diag-status" id="diag-sys-status">--</div>
</div>
</div>
<h3 style="margin-top:1.5rem">Actions</h3>
<div class="diag-actions">
<button class="btn-action" onclick="diagReconnecterCamera()">&#128247; Reconnecter camera</button>
<button class="btn-action" onclick="diagReactiverImprimante()">&#128424; Reactiver imprimante</button>
<button class="btn-secondaire" onclick="diagRedemarrerBackend()">&#8635; Redemarrer backend</button>
<button class="btn-secondaire" onclick="diagRefreshChromium()">&#127760; Recharger navigateur</button>
<button class="btn-danger" onclick="if(confirm('Redemarrer la borne ?'))diagRedemarrerSysteme()">&#9888; Redemarrer la borne</button>
</div>
<h3 style="margin-top:1.5rem">Logs backend <button class="btn-secondaire btn-petit" onclick="chargerLogs()" style="margin-left:0.5rem">&#8635; Actualiser</button></h3>
<div id="diag-logs" class="diag-logs">Appuyer sur Actualiser...</div>
<h3 style="margin-top:1.5rem">Peripheriques USB <button class="btn-secondaire btn-petit" onclick="chargerUsb()" style="margin-left:0.5rem">&#8635;</button></h3>
<div id="diag-usb" class="diag-usb">--</div>
</div>
<div class="admin-panneau" id="panneau-infos">
<div class="infos-systeme-header">
<h3>Informations systeme</h3>
<button class="btn-action btn-petit" onclick="chargerInfosSysteme()">&#8635; Actualiser</button>
</div>
<div id="infos-systeme-contenu" class="infos-systeme-contenu">
<p class="infos-chargement">Chargement...</p>
</div>
<div class="infos-systeme-header" style="margin-top:1.5rem">
<h3>Diagnostic camera</h3>
<button class="btn-action btn-petit" onclick="chargerDiagCamera()">&#8635; Tester</button>
</div>
<div id="diag-camera-contenu" style="font-family:monospace;font-size:0.75rem;background:#111;color:#0f0;padding:0.75rem;border-radius:6px;white-space:pre-wrap;max-height:300px;overflow-y:auto">
Appuyer sur Tester...
</div>
<div class="admin-panneau" id="panneau-videos-admin">
<h3>Videos didactiques</h3>
<p class="aide">Chaque situation peut contenir plusieurs etapes video. L'operateur verra les videos en sequence : chaque etape boucle jusqu'a validation avant de passer a la suivante.</p>
<div id="video-situations-liste"></div>
<div style="margin-top:1rem;padding:0.75rem;background:#1a1a2e;border-radius:8px;border:1px dashed #444">
<h4 style="margin:0 0 0.5rem">Ajouter une situation</h4>
<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap">
<input type="text" id="nouvelle-situation-label" placeholder="Nom de la situation" style="flex:1;min-width:150px;padding:0.4rem 0.6rem;border-radius:6px;border:1px solid #555;background:#111;color:#fff">
<button class="btn-action btn-petit" onclick="creerSituation()">+ Ajouter</button>
</div>
</div>
<h4 style="margin-top:1.5rem">Apercu</h4>
<video id="video-situation-preview" style="width:100%;max-height:300px;border-radius:8px;background:#111" controls></video>
<div style="margin-top:1rem">
<button class="btn-action" onclick="lancerWizardDepuisAdmin()">&#9654; Tester le wizard sur le booth</button>
</div>
</div>
<div class="admin-panneau" id="panneau-surprise-admin">
<h3>Photo / Video surprise</h3>
<p class="aide">Media affiche sur l'ecran ~1 seconde avant la prise de photo pour surprendre et provoquer un sourire.</p>
<div class="champ">
<label class="toggle"><input type="checkbox" id="tog-surprise-actif"><span class="toggle-slider"></span> Surprise active</label>
</div>
<div class="champ">
<label>Type de surprise</label>
<div class="radio-group">
<label><input type="radio" name="surprise-type" value="photo" checked> Photo</label>
<label><input type="radio" name="surprise-type" value="video"> Video</label>
</div>
</div>
<div class="champ">
<label>Media actuel</label>
<div id="surprise-current">Aucun media configure</div>
</div>
<div class="champ">
<input type="file" id="input-surprise-media" accept=".jpg,.jpeg,.png,.gif,.mp4,.webm" class="input-fichier">
<button class="btn-action" onclick="uploaderSurprise()">Importer</button>
<button class="btn-danger btn-petit" onclick="supprimerSurprise()">Supprimer</button>
</div>
<div class="champ">
<label>Delai avant capture (ms)</label>
<input type="number" id="admin-surprise-delai" min="500" max="3000" value="1000" step="100">
</div>
<button class="btn-action" onclick="sauvegarderSurprise()">Sauvegarder</button>
<h4 style="margin-top:1.5rem">Apercu</h4>
<div id="surprise-preview" style="width:100%;max-height:300px;border-radius:8px;background:#111;display:flex;align-items:center;justify-content:center;min-height:150px;color:#666">
Aucun apercu
</div>
</div>
</div>
</div>
</section>
<!-- Wizard video didactique plein ecran -->
<div id="wizard-video" class="popup-overlay cache" style="z-index:9999;background:rgba(0,0,0,0.97);display:flex;flex-direction:column;align-items:center;justify-content:center">
<div id="wizard-titre" style="color:#fff;font-size:1.8rem;font-weight:700;margin-bottom:0.3rem;text-align:center"></div>
<div id="wizard-etape-info" style="color:#aaa;font-size:1rem;margin-bottom:1rem"></div>
<video id="wizard-video-player" muted playsinline loop style="width:90%;max-height:65vh;border-radius:12px;background:#000"></video>
<div id="wizard-etape-label" style="color:#ccc;font-size:1.1rem;margin-top:0.8rem;text-align:center;min-height:1.5rem"></div>
<button id="wizard-btn-ok" onclick="wizardEtapeSuivante()" style="margin-top:1.5rem;padding:1.2rem 3rem;font-size:1.5rem;font-weight:700;border:none;border-radius:16px;background:#4caf50;color:#fff;cursor:pointer;min-width:280px">OK, c'est bon !</button>
<button onclick="fermerWizard()" style="margin-top:0.8rem;padding:0.6rem 1.5rem;font-size:0.9rem;border:none;border-radius:8px;background:#333;color:#aaa;cursor:pointer">Quitter</button>
</div>
<!-- Popup sélection cadre impression -->
<div id="popup-cadre-impression" class="popup-overlay cache">
<div class="popup-box popup-box-cadre">
<h3>Cadre d'impression</h3>
<div id="grille-cadres-impression" class="grille-cadres-choix grille-cadres-popup"></div>
<div class="popup-actions">
<button class="btn-action" onclick="confirmerCadreImpression()">Confirmer</button>
<button class="btn-secondaire" onclick="annulerCadreImpression()">Annuler</button>
</div>
</div>
</div>
<!-- Popup PIN photostation -->
<div id="popup-pin-photostation" class="popup-overlay cache">
<div class="popup-box popup-box-pave">
<h3>Station d'impression</h3>
<p class="aide">Entrez le code PIN</p>
<div id="pin-photostation-affichage" class="mdp-affichage" style="font-size:2rem;letter-spacing:0.5rem;margin:1rem 0">&#9675;&#9675;&#9675;&#9675;</div>
<div id="pin-photostation-erreur" class="mdp-erreur cache">Code incorrect</div>
<div class="pave-numerique">
<button class="pave-touche" onclick="pinPhotostationTouche('1')">1</button>
<button class="pave-touche" onclick="pinPhotostationTouche('2')">2</button>
<button class="pave-touche" onclick="pinPhotostationTouche('3')">3</button>
<button class="pave-touche" onclick="pinPhotostationTouche('4')">4</button>
<button class="pave-touche" onclick="pinPhotostationTouche('5')">5</button>
<button class="pave-touche" onclick="pinPhotostationTouche('6')">6</button>
<button class="pave-touche" onclick="pinPhotostationTouche('7')">7</button>
<button class="pave-touche" onclick="pinPhotostationTouche('8')">8</button>
<button class="pave-touche" onclick="pinPhotostationTouche('9')">9</button>
<button class="pave-touche" onclick="pinPhotostationEffacer()">&#8592;</button>
<button class="pave-touche" onclick="pinPhotostationTouche('0')">0</button>
<button class="pave-touche" onclick="fermerPopupPhotostation()">&#10005;</button>
</div>
</div>
</div>
<!-- Popup mot de passe admin -->
<div id="popup-mdp" class="popup-overlay cache">
<div class="popup-box popup-box-pave">
<h3>Acces administration</h3>
<input type="password" id="input-mdp-admin" placeholder="&#9679;&#9679;&#9679;&#9679;" inputmode="none" autocomplete="off" readonly>
<div class="pave-numerique">
<button class="pave-touche" onclick="paveTouche('1')">1</button>
<button class="pave-touche" onclick="paveTouche('2')">2</button>
<button class="pave-touche" onclick="paveTouche('3')">3</button>
<button class="pave-touche" onclick="paveTouche('4')">4</button>
<button class="pave-touche" onclick="paveTouche('5')">5</button>
<button class="pave-touche" onclick="paveTouche('6')">6</button>
<button class="pave-touche" onclick="paveTouche('7')">7</button>
<button class="pave-touche" onclick="paveTouche('8')">8</button>
<button class="pave-touche" onclick="paveTouche('9')">9</button>
<button class="pave-touche pave-effacer" onclick="paveEffacer()">&#9003;</button>
<button class="pave-touche" onclick="paveTouche('0')">0</button>
<button class="pave-touche pave-valider" onclick="validerMdpAdmin()">&#10003;</button>
</div>
<p id="mdp-erreur" class="mdp-erreur cache">Mot de passe incorrect</p>
<button class="btn-secondaire" onclick="fermerPopupMdp()">Annuler</button>
</div>
</div>
</div>
<!-- Ecran de pause (deconnexion backend) -->
<div id="ecran-pause" style="display:none;position:fixed;inset:0;z-index:9999;background:#0a0a0f;flex-direction:column;align-items:center;justify-content:center;text-align:center">
<div style="font-size:6rem;animation:pause-bob 2s ease-in-out infinite">&#9749;</div>
<h1 style="color:#fff;font-size:2.2rem;margin:1rem 0 .5rem;font-weight:700">Petite pause...</h1>
<p style="color:#888;font-size:1.2rem;max-width:400px;line-height:1.5">Le photobooth revient dans un instant.<br>Pas de panique, on s'occupe de tout !</p>
<div style="margin-top:2rem;display:flex;gap:8px">
<span class="pause-dot" style="width:12px;height:12px;border-radius:50%;background:#e91e63;animation:pause-dot .6s ease-in-out infinite"></span>
<span class="pause-dot" style="width:12px;height:12px;border-radius:50%;background:#e91e63;animation:pause-dot .6s ease-in-out .2s infinite"></span>
<span class="pause-dot" style="width:12px;height:12px;border-radius:50%;background:#e91e63;animation:pause-dot .6s ease-in-out .4s infinite"></span>
</div>
<p id="pause-status" style="color:#555;font-size:.85rem;margin-top:2rem">Reconnexion en cours...</p>
</div>
<style>
@keyframes pause-bob { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-20px)} }
@keyframes pause-dot { 0%,100%{opacity:.2;transform:scale(.8)} 50%{opacity:1;transform:scale(1.2)} }
</style>
<script src="/js/websocket.js?v=16"></script>
<script src="/js/app.js?v=25"></script>
<script src="/js/camera.js?v=21"></script>
<script src="/js/effects.js?v=4"></script>
<script src="/js/gallery.js?v=5"></script>
<script src="/js/share.js?v=9"></script>
<script src="/js/admin.js?v=17"></script>
</body>
</html>