@javierfrancoleal/dsh-supervisor 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dashboard.html CHANGED
@@ -24,6 +24,8 @@ body.dark .toast{background:#e6ecf7;color:#0b1220}
24
24
  .checkpop{animation:pop .3s ease}
25
25
  @keyframes pop{0%{transform:scale(.6);opacity:0}70%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
26
26
  @keyframes flick{0%,100%{opacity:1}42%{opacity:.82}50%{opacity:1}58%{opacity:.9}}
27
+ @keyframes drawStroke{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
28
+ .mark svg path{stroke-dasharray:100;stroke-dashoffset:100;animation:drawStroke 1.6s cubic-bezier(.4,0,.2,1) forwards}
27
29
  .mark svg path:last-child{animation:flick 3.2s ease-in-out infinite;transform-origin:32px 34px}
28
30
  .person{animation:rise .3s ease backwards}
29
31
  .person:nth-child(1){animation-delay:.03s}
@@ -112,6 +114,23 @@ td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
112
114
  .wall-card{background:#1b2436;color:#fff;border-radius:16px;padding:20px;text-align:center}
113
115
  .wall-card .v{font-size:44px;font-weight:800}
114
116
  .wall-card .l{font-size:15px;opacity:.85}
117
+ .wall-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:6px 0 16px;flex-wrap:wrap}
118
+ .wall-brand{display:flex;align-items:center;gap:10px;color:#fff}
119
+ .wall-brand b{font-size:20px;display:block}
120
+ .wall-brand span{font-size:12px;opacity:.75;text-transform:uppercase;letter-spacing:.06em}
121
+ .wall-clock{text-align:right;color:#fff}
122
+ .wall-clock b{font-size:20px;display:block}
123
+ .wall-clock span{font-size:12px;opacity:.75}
124
+ .live-dot{display:flex;align-items:center;gap:7px;color:#4ade80;font-weight:800;font-size:13px;letter-spacing:.08em}
125
+ .live-dot::before{content:"";width:9px;height:9px;border-radius:50%;background:#4ade80;animation:pulse 1.6s infinite}
126
+ .tick{background:#1b2436;color:#d7e3f4;border-radius:10px;padding:8px 12px;font-size:13.5px;margin:6px 0}
127
+ .tick.dim{color:#64748b;background:none;border:1px dashed #334155}
128
+ .wall-note{color:#64748b;font-size:12px;text-align:center;margin-top:10px}
129
+ .welcome{position:relative;border-left:4px solid var(--blue);animation:rise .4s ease}
130
+ .welcome .wclose{position:absolute;top:10px;right:10px;background:none;border:none;font-size:16px;color:var(--muted);cursor:pointer}
131
+ button{transition:transform .12s ease}
132
+ button:active{transform:scale(.97)}
133
+ button:focus-visible,.pill:focus-visible,input:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
115
134
  body.wall{background:#0b1220}
116
135
  body.wall pre{max-height:40vh}
117
136
  @media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
@@ -129,7 +148,7 @@ body.wall pre{max-height:40vh}
129
148
  <main>
130
149
  <div id="loginView" class="card" style="max-width:440px;margin:26px auto">
131
150
  <div class="loginbrand">
132
- <div class="mark" style="background:none;box-shadow:none"><svg width="64" height="64" viewBox="0 0 64 64" aria-hidden="true"><defs><linearGradient id="eyeGdash" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#4D6BFE"/><stop offset="1" stop-color="#7c5cff"/></linearGradient></defs><path d="M32 14 C 14 14, 7 24.5, 7 32 C 7 39.5, 14 50, 32 50 C 50 50, 57 39.5, 57 32 C 57 24.5, 50 14, 32 14 Z" fill="none" stroke="url(#eyeGdash)" stroke-width="6" stroke-linecap="round"/><path d="M32 22.5 C 37 27.6, 39 31.2, 39 35 A 7 7 0 1 1 25 35 C 25 31.2, 27 27.6, 32 22.5 Z" fill="#FACC15"/></svg></div>
151
+ <div class="mark" style="background:none;box-shadow:none"><svg width="64" height="64" viewBox="0 0 64 64" aria-hidden="true"><defs><linearGradient id="osgd" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#4D6BFE"/><stop offset="1" stop-color="#7c5cff"/></linearGradient></defs><path pathLength="100" d="M10 32 C10 22 16 14 32 14 C48 14 54 22 54 32 C54 42 48 50 32 50 C20 50 12.5 45.2 10.5 38.5 C14 42.5 20 41 25.4 34.8 A6.6 6.6 0 0 1 38.6 34.8 C38.6 31.4 36.6 28.2 32 22.5 C27.4 28.2 25.4 31.4 25.4 34.8" fill="none" stroke="url(#osgd)" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
133
152
  <h2>Le Veilleux</h2>
134
153
  <p id="tagline">The AI works. The human decides.</p>
135
154
  </div>
@@ -147,6 +166,11 @@ body.wall pre{max-height:40vh}
147
166
  </div>
148
167
 
149
168
  <div id="ownerView" class="hidden">
169
+ <div class="card welcome" id="welcomeCard" style="display:none">
170
+ <button class="wclose" id="welcomeClose" aria-label="Close">✕</button>
171
+ <h2 id="welcomeTitle">Welcome to Le Veilleux 👁️</h2>
172
+ <p id="welcomeBody" class="note"></p>
173
+ </div>
150
174
  <div class="metrics" id="ownerMetrics"></div>
151
175
  <div class="tabs">
152
176
  <button data-tab="overview" class="active" id="tabOverview">Overview</button>
@@ -259,9 +283,17 @@ body.wall pre{max-height:40vh}
259
283
  </div>
260
284
 
261
285
  <div id="wallView" class="hidden">
262
- <div class="wall-head" id="wallHead">🏭 J.Franco Suite — Live</div>
286
+ <div class="wall-top">
287
+ <div class="wall-brand">
288
+ <svg width="34" height="34" viewBox="0 0 64 64" aria-hidden="true"><path d="M10 32 C10 22 16 14 32 14 C48 14 54 22 54 32 C54 42 48 50 32 50 C20 50 12.5 45.2 10.5 38.5 C14 42.5 20 41 25.4 34.8 A6.6 6.6 0 0 1 38.6 34.8 C38.6 31.4 36.6 28.2 32 22.5 C27.4 28.2 25.4 31.4 25.4 34.8" fill="none" stroke="#ffffff" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/></svg>
289
+ <div><b>Le Veilleux</b><span id="wallSector"></span></div>
290
+ </div>
291
+ <div class="wall-clock"><b id="wallClock">--:--</b><span id="wallDate"></span></div>
292
+ <div class="live-dot" id="wallLiveTag">LIVE</div>
293
+ </div>
263
294
  <div class="wall-grid" id="wallCards"></div>
264
- <div class="card" style="margin-top:14px"><h2 style="color:#fff" id="wallPulseTitle">Field pulse</h2><pre id="wallFeed"></pre></div>
295
+ <div class="card" style="margin-top:14px"><h2 style="color:#fff" id="wallPulseTitle">Field pulse</h2><div id="wallFeed"></div></div>
296
+ <p class="wall-note" id="wallNote">Updates every 30 s</p>
265
297
  </div>
266
298
 
267
299
  <div id="toast" class="toast"></div>
@@ -272,16 +304,16 @@ body.wall pre{max-height:40vh}
272
304
  "use strict";
273
305
  const LANG={es:"ES",en:"EN",fr:"FR",de:"DE",it:"IT",pt:"PT",zh:"中文",ja:"日本語",ko:"한국어",ar:"العربية"};
274
306
  const S={
275
- en:{login:"Log in",user:"User",password:"Password",loginBtn:"Log in",loginHint:"Accounts are managed by the business owner.",loginFailed:"Login failed.",cannotReach:"Cannot reach the supervisor server. Is it running?",workerAdded:"Worker added.",saved:"Saved.",reportSent:"Report sent.",feedbackSent:"Feedback sent.",wallOpen:"Live wallboard",logout:"Log out",overview:"Overview",field:"Field",rules:"Rules",reports:"Reports",week:"This week",feedback:"Feedback",workersActive:"Workers active",reportsTotal:"Reports total",workers:"Workers",thUser:"User",thRole:"Role",addWorker:"Add worker",userName:"User name",addBtn:"Add worker",usage:"Usage & cost",usageSub:"(per worker, estimated)",thWorker:"Worker",thSessions:"Sessions",thTokens:"Tokens",thCost:"Est. cost",panel:"Action Panel",panelNote:"Workers open the panel from their tablet or phone.",openPanel:"Open Action Panel",fieldReports:"Field reports",feedbackQueue:"Feedback queue",feedbackHint:"The agent reads this queue and resolves errors and improvements.",refresh:"Refresh",autoOn:"Auto-refresh: ON",autoOff:"Auto-refresh: OFF",rulesTitle:"Business rules",rulesHint:"These rules train the traffic light.",saveRules:"Save rules",listen:"🎙️ LISTEN",hi:"👋 ",reportTitle:"Field report",reportPh:"What happened on your shift?",sendReport:"Send report",fbTitle:"Field feedback",fbPh:"What happened? What should improve?",sendFeedback:"Send feedback",switchUser:"Switch user",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Field pulse",noActivity:"(no field activity yet)",start:"▶ START",listening:"Listening… speak now",listeningHint:"The conversation is being captured and split by person.",stopListening:"⏹ Stop listening",summaryTitle:"Conversation summary",confirm:"Confirm ✓",confirmed:"Confirmed ✓",sentNote:"Sent to kitchen & central",newConv:"New conversation",ordersTitle:"Orders — kitchen & bill",person:"Person",noSummary:"The summary will appear here as the conversation is detected.",prep:"Preparing",ready:"Ready",delivered:"Delivered",sent:"Sent",back:"Back",sayPh:"Speak or type what each person said…",sendPhrase:"Send phrase",dictate:"🎙️ Dictate",aiHint:"Speech and text go straight to the AI — the summary appears automatically.",micUnsupported:"Dictation not supported in this browser",processing:"The AI is summarizing…",sectorTab:"Sector",sectorPresets:"Sector presets",customSector:"Custom sector",saveSector:"Save sector",sectorSaved:"Sector saved.",aiSuggest:"Suggest with AI (copy prompt)",aiSectorCopied:"AI prompt copied — paste it in DeepSeek Harness.",fillBoth:"Enter your user and password.",loggingIn:"Logging in…",noOrders:"No orders yet — confirm items in the summary.",noUsage:"No usage reported yet.",noReports:"No field reports yet.",lvlEmployee:"Field",lvlLead:"Supervisor",lvlOwner:"Owner",labelPh:"Role label (e.g. Cook)",newOrder:"NEW ORDER",enableNotif:"🔔 Enable notifications",notifHint:"The kitchen tablet beeps and flashes when an order arrives.",tagline:"The AI works. The human watches, decides, reviews."},
276
- es:{login:"Iniciar sesión",user:"Usuario",password:"Contraseña",loginBtn:"Entrar",loginHint:"Las cuentas las gestiona el dueño del negocio.",loginFailed:"Datos incorrectos.",cannotReach:"No se puede contactar el servidor. ¿Está corriendo?",workerAdded:"Trabajador añadido.",saved:"Guardado.",reportSent:"Reporte enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Wallboard en vivo",logout:"Salir",overview:"Resumen",field:"Campo",rules:"Reglas",reports:"Reportes",week:"Esta semana",feedback:"Feedback",workersActive:"Trabajadores activos",reportsTotal:"Reportes totales",workers:"Trabajadores",thUser:"Usuario",thRole:"Rol",addWorker:"Añadir trabajador",userName:"Nombre de usuario",addBtn:"Añadir trabajador",usage:"Uso y coste",usageSub:"(por trabajador, estimado)",thWorker:"Trabajador",thSessions:"Sesiones",thTokens:"Tokens",thCost:"Coste est.",panel:"Panel de Acción",panelNote:"Los trabajadores abren el panel desde su tablet o teléfono.",openPanel:"Abrir Panel de Acción",fieldReports:"Reportes de campo",feedbackQueue:"Cola de feedback",feedbackHint:"El agente lee esta cola y resuelve errores y mejoras.",refresh:"Actualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Reglas del negocio",rulesHint:"Estas reglas entrenan el semáforo.",saveRules:"Guardar reglas",listen:"🎙️ ESCUCHAR",hi:"👋 ",reportTitle:"Reporte de campo",reportPh:"¿Qué pasó en tu turno?",sendReport:"Enviar reporte",fbTitle:"Feedback de campo",fbPh:"¿Qué pasó? ¿Qué debe mejorar?",sendFeedback:"Enviar feedback",switchUser:"Cambiar de usuario",wallHead:"🏭 Le Veilleux — En vivo",wallPulse:"Pulso del campo",noActivity:"(sin actividad de campo aún)",start:"▶ INICIAR",listening:"Escuchando… habla ahora",listeningHint:"La conversación se captura y divide por persona.",stopListening:"⏹ Detener",summaryTitle:"Resumen de la conversación",confirm:"Confirmar ✓",confirmed:"Confirmado ✓",sentNote:"Enviado a cocina y central",newConv:"Nueva conversación",ordersTitle:"Pedidos — cocina y cuenta",person:"Persona",noSummary:"El resumen aparecerá aquí conforme se detecta la conversación.",prep:"Preparando",ready:"Listo",delivered:"Entregado",sent:"Enviado",back:"Volver",sayPh:"Habla o escribe lo que dijo cada persona…",sendPhrase:"Enviar frase",dictate:"🎙️ Dictar",aiHint:"Voz y texto van directo a la IA — el resumen aparece solo.",micUnsupported:"Dictado no soportado en este navegador",processing:"La IA está resumiendo…",sectorTab:"Sector",sectorPresets:"Sectores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar sector",sectorSaved:"Sector guardado.",aiSuggest:"Sugerir con IA (copiar prompt)",aiSectorCopied:"Prompt de IA copiado — pégalo en DeepSeek Harness.",fillBoth:"Escribe tu usuario y contraseña.",loggingIn:"Entrando…",noOrders:"Aún no hay pedidos — confirma elementos en el resumen.",noUsage:"Aún no hay uso reportado.",noReports:"Aún no hay reportes de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dueño",labelPh:"Etiqueta de rol (ej. Cocinero)",newOrder:"NUEVO PEDIDO",enableNotif:"🔔 Activar notificaciones",notifHint:"La tablet de cocina suena y parpadea cuando llega un pedido.",tagline:"La IA trabaja. El humano vela, decide, revisa."},
277
- fr:{login:"Connexion",user:"Utilisateur",password:"Mot de passe",loginBtn:"Se connecter",loginHint:"Les comptes sont gérés par le propriétaire.",loginFailed:"Échec de connexion.",cannotReach:"Serveur injoignable. Est-il lancé ?",workerAdded:"Employé ajouté.",saved:"Enregistré.",reportSent:"Rapport envoyé.",feedbackSent:"Feedback envoyé.",wallOpen:"Tableau en direct",logout:"Déconnexion",overview:"Vue d'ensemble",field:"Terrain",rules:"Règles",reports:"Rapports",week:"Cette semaine",feedback:"Feedback",workersActive:"Employés actifs",reportsTotal:"Total rapports",workers:"Employés",thUser:"Utilisateur",thRole:"Rôle",addWorker:"Ajouter un employé",userName:"Nom d'utilisateur",addBtn:"Ajouter",usage:"Usage et coût",usageSub:"(par employé, estimé)",thWorker:"Employé",thSessions:"Sessions",thTokens:"Jetons",thCost:"Coût est.",panel:"Panneau d'action",panelNote:"Les employés ouvrent le panneau depuis leur tablette ou téléphone.",openPanel:"Ouvrir le panneau",fieldReports:"Rapports terrain",feedbackQueue:"File de feedback",feedbackHint:"L'agent lit cette file et résout erreurs et améliorations.",refresh:"Actualiser",autoOn:"Auto : ON",autoOff:"Auto : OFF",rulesTitle:"Règles du commerce",rulesHint:"Ces règles entraînent le feu tricolore.",saveRules:"Enregistrer",listen:"🎙️ ÉCOUTER",hi:"👋 ",reportTitle:"Rapport terrain",reportPh:"Que s'est-il passé pendant votre quart ?",sendReport:"Envoyer",fbTitle:"Feedback terrain",fbPh:"Que s'est-il passé ? Que faut-il améliorer ?",sendFeedback:"Envoyer",switchUser:"Changer d'utilisateur",wallHead:"🏭 Le Veilleux — En direct",wallPulse:"Pouls du terrain",noActivity:"(aucune activité)",start:"▶ DÉMARRER",listening:"Écoute… parlez maintenant",listeningHint:"La conversation est captée et répartie par personne.",stopListening:"⏹ Arrêter",summaryTitle:"Résumé de la conversation",confirm:"Confirmer ✓",confirmed:"Confirmé ✓",sentNote:"Envoyé en cuisine et au central",newConv:"Nouvelle conversation",ordersTitle:"Commandes — cuisine et addition",person:"Personne",noSummary:"Le résumé apparaîtra ici au fil de la conversation.",prep:"En préparation",ready:"Prêt",delivered:"Servi",sent:"Envoyé",back:"Retour",sayPh:"Parlez ou écrivez ce que chaque personne a dit…",sendPhrase:"Envoyer",dictate:"🎙️ Dicter",aiHint:"La voix et le texte vont directement à l’IA — le résumé apparaît seul.",micUnsupported:"Dictée non prise en charge",processing:"L’IA résume…",sectorTab:"Secteur",sectorPresets:"Secteurs prédéfinis",customSector:"Secteur personnalisé",saveSector:"Enregistrer le secteur",sectorSaved:"Secteur enregistré.",aiSuggest:"Suggérer avec l’IA (copier l’invite)",aiSectorCopied:"Invite copiée — collez-la dans DeepSeek Harness.",fillBoth:"Saisissez votre utilisateur et votre mot de passe.",loggingIn:"Connexion…",noOrders:"Aucune commande — confirmez des éléments dans le résumé.",noUsage:"Aucun usage signalé.",noReports:"Aucun rapport terrain.",lvlEmployee:"Terrain",lvlLead:"Superviseur",lvlOwner:"Propriétaire",labelPh:"Intitulé du rôle (ex. Cuisinier)",newOrder:"NOUVELLE COMMANDE",enableNotif:"🔔 Activer les notifications",notifHint:"La tablette de cuisine sonne et clignote à l'arrivée d'une commande.",tagline:"L'IA travaille. L'humain veille, décide, revoit."},
278
- de:{login:"Anmelden",user:"Benutzer",password:"Passwort",loginBtn:"Anmelden",loginHint:"Konten verwaltet der Inhaber.",loginFailed:"Anmeldung fehlgeschlagen.",cannotReach:"Server nicht erreichbar. Läuft er?",workerAdded:"Mitarbeiter hinzugefügt.",saved:"Gespeichert.",reportSent:"Bericht gesendet.",feedbackSent:"Feedback gesendet.",wallOpen:"Live-Anzeige",logout:"Abmelden",overview:"Übersicht",field:"Feld",rules:"Regeln",reports:"Berichte",week:"Diese Woche",feedback:"Feedback",workersActive:"Aktive Mitarbeiter",reportsTotal:"Berichte gesamt",workers:"Mitarbeiter",thUser:"Benutzer",thRole:"Rolle",addWorker:"Mitarbeiter hinzufügen",userName:"Benutzername",addBtn:"Hinzufügen",usage:"Nutzung & Kosten",usageSub:"(pro Mitarbeiter, geschätzt)",thWorker:"Mitarbeiter",thSessions:"Sitzungen",thTokens:"Tokens",thCost:"Kosten ca.",panel:"Aktionspanel",panelNote:"Mitarbeiter öffnen das Panel auf Tablet oder Handy.",openPanel:"Panel öffnen",fieldReports:"Feldberichte",feedbackQueue:"Feedback-Warteschlange",feedbackHint:"Der Agent liest diese Warteschlange und behebt Fehler.",refresh:"Aktualisieren",autoOn:"Auto: AN",autoOff:"Auto: AUS",rulesTitle:"Geschäftsregeln",rulesHint:"Diese Regeln trainieren die Ampel.",saveRules:"Regeln speichern",listen:"🎙️ ZUHÖREN",hi:"👋 ",reportTitle:"Feldbericht",reportPh:"Was ist in Ihrer Schicht passiert?",sendReport:"Senden",fbTitle:"Feld-Feedback",fbPh:"Was ist passiert? Was soll besser werden?",sendFeedback:"Senden",switchUser:"Benutzer wechseln",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Puls im Feld",noActivity:"(noch keine Aktivität)",start:"▶ STARTEN",listening:"Höre zu… sprich jetzt",listeningHint:"Das Gespräch wird erfasst und pro Person aufgeteilt.",stopListening:"⏹ Stopp",summaryTitle:"Gesprächsübersicht",confirm:"Bestätigen ✓",confirmed:"Bestätigt ✓",sentNote:"An Küche & Zentrale gesendet",newConv:"Neues Gespräch",ordersTitle:"Bestellungen — Küche & Rechnung",person:"Person",noSummary:"Die Übersicht erscheint hier, sobald das Gespräch erkannt wird.",prep:"In Zubereitung",ready:"Fertig",delivered:"Serviert",sent:"Gesendet",back:"Zurück",sayPh:"Sprechen oder tippen Sie, was jede Person gesagt hat…",sendPhrase:"Senden",dictate:"🎙️ Diktieren",aiHint:"Sprache und Text gehen direkt an die KI — die Übersicht erscheint automatisch.",micUnsupported:"Diktat nicht unterstützt",processing:"Die KI fasst zusammen…",sectorTab:"Branche",sectorPresets:"Branchen-Vorlagen",customSector:"Eigene Branche",saveSector:"Branche speichern",sectorSaved:"Branche gespeichert.",aiSuggest:"Mit KI vorschlagen (Prompt kopieren)",aiSectorCopied:"KI-Prompt kopiert — in DeepSeek Harness einfügen.",fillBoth:"Benutzer und Passwort eingeben.",loggingIn:"Anmeldung…",noOrders:"Noch keine Bestellungen — Elemente in der Übersicht bestätigen.",noUsage:"Noch keine Nutzung gemeldet.",noReports:"Noch keine Feldberichte.",lvlEmployee:"Feld",lvlLead:"Aufsicht",lvlOwner:"Inhaber",labelPh:"Rollenname (z. B. Koch)",newOrder:"NEUE BESTELLUNG",enableNotif:"🔔 Benachrichtigungen aktivieren",notifHint:"Das Küchen-Tablet piept und blinkt bei neuer Bestellung.",tagline:"Die KI arbeitet. Der Mensch wacht, entscheidet, prüft."},
279
- it:{login:"Accedi",user:"Utente",password:"Password",loginBtn:"Accedi",loginHint:"Gli account li gestisce il proprietario.",loginFailed:"Accesso fallito.",cannotReach:"Server non raggiungibile. È in esecuzione?",workerAdded:"Lavoratore aggiunto.",saved:"Salvato.",reportSent:"Report inviato.",feedbackSent:"Feedback inviato.",wallOpen:"Schermo live",logout:"Esci",overview:"Panoramica",field:"Campo",rules:"Regole",reports:"Report",week:"Questa settimana",feedback:"Feedback",workersActive:"Lavoratori attivi",reportsTotal:"Report totali",workers:"Lavoratori",thUser:"Utente",thRole:"Ruolo",addWorker:"Aggiungi lavoratore",userName:"Nome utente",addBtn:"Aggiungi",usage:"Uso e costi",usageSub:"(per lavoratore, stimato)",thWorker:"Lavoratore",thSessions:"Sessioni",thTokens:"Token",thCost:"Costo stim.",panel:"Pannello Azioni",panelNote:"I lavoratori aprono il pannello da tablet o telefono.",openPanel:"Apri il pannello",fieldReports:"Report di campo",feedbackQueue:"Coda feedback",feedbackHint:"L'agente legge questa coda e risolve errori e migliorie.",refresh:"Aggiorna",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regole del negozio",rulesHint:"Queste regole addestrano il semaforo.",saveRules:"Salva regole",listen:"🎙️ ASCOLTA",hi:"👋 ",reportTitle:"Report di campo",reportPh:"Cosa è successo nel tuo turno?",sendReport:"Invia",fbTitle:"Feedback di campo",fbPh:"Cosa è successo? Cosa va migliorato?",sendFeedback:"Invia",switchUser:"Cambia utente",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Battito del campo",noActivity:"(nessuna attività)",start:"▶ INIZIA",listening:"In ascolto… parla ora",listeningHint:"La conversazione viene catturata e divisa per persona.",stopListening:"⏹ Ferma",summaryTitle:"Riepilogo conversazione",confirm:"Conferma ✓",confirmed:"Confermato ✓",sentNote:"Inviato a cucina e centrale",newConv:"Nuova conversazione",ordersTitle:"Ordini — cucina e conto",person:"Persona",noSummary:"Il riepilogo apparirà qui man mano che la conversazione viene rilevata.",prep:"In preparazione",ready:"Pronto",delivered:"Servito",sent:"Inviato",back:"Indietro",sayPh:"Parla o scrivi cosa ha detto ogni persona…",sendPhrase:"Invia",dictate:"🎙️ Detta",aiHint:"Voce e testo vanno direttamente all’IA — il riepilogo appare da solo.",micUnsupported:"Dettatura non supportata",processing:"L’IA sta riassumendo…",sectorTab:"Settore",sectorPresets:"Settori predefiniti",customSector:"Settore personalizzato",saveSector:"Salva settore",sectorSaved:"Settore salvato.",aiSuggest:"Suggerisci con l’IA (copia prompt)",aiSectorCopied:"Prompt copiato — incollalo in DeepSeek Harness.",fillBoth:"Inserisci utente e password.",loggingIn:"Accesso…",noOrders:"Ancora nessun ordine — conferma elementi nel riepilogo.",noUsage:"Nessun utilizzo segnalato.",noReports:"Nessun report di campo.",lvlEmployee:"Terreno",lvlLead:"Supervisore",lvlOwner:"Proprietario",labelPh:"Etichetta ruolo (es. Cuoco)",newOrder:"NUOVO ORDINE",enableNotif:"🔔 Attiva notifiche",notifHint:"Il tablet di cucina suona e lampeggia all'arrivo di un ordine.",tagline:"L'IA lavora. L'umano veglia, decide, rivede."},
280
- pt:{login:"Entrar",user:"Usuário",password:"Senha",loginBtn:"Entrar",loginHint:"As contas são geridas pelo dono.",loginFailed:"Falha no login.",cannotReach:"Servidor inacessível. Está a correr?",workerAdded:"Trabalhador adicionado.",saved:"Guardado.",reportSent:"Relatório enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Painel ao vivo",logout:"Sair",overview:"Visão geral",field:"Campo",rules:"Regras",reports:"Relatórios",week:"Esta semana",feedback:"Feedback",workersActive:"Trabalhadores ativos",reportsTotal:"Total de relatórios",workers:"Trabalhadores",thUser:"Usuário",thRole:"Função",addWorker:"Adicionar trabalhador",userName:"Nome de usuário",addBtn:"Adicionar",usage:"Uso e custo",usageSub:"(por trabalhador, estimado)",thWorker:"Trabalhador",thSessions:"Sessões",thTokens:"Tokens",thCost:"Custo est.",panel:"Painel de Ação",panelNote:"Os trabalhadores abrem o painel no tablet ou telemóvel.",openPanel:"Abrir painel",fieldReports:"Relatórios de campo",feedbackQueue:"Fila de feedback",feedbackHint:"O agente lê esta fila e resolve erros e melhorias.",refresh:"Atualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regras do negócio",rulesHint:"Estas regras treinam o semáforo.",saveRules:"Guardar regras",listen:"🎙️ OUVIR",hi:"👋 ",reportTitle:"Relatório de campo",reportPh:"O que aconteceu no seu turno?",sendReport:"Enviar",fbTitle:"Feedback de campo",fbPh:"O que aconteceu? O que deve melhorar?",sendFeedback:"Enviar",switchUser:"Trocar de usuário",wallHead:"🏭 Le Veilleux — Ao vivo",wallPulse:"Pulso do campo",noActivity:"(sem atividade)",start:"▶ INICIAR",listening:"A ouvir… fale agora",listeningHint:"A conversa é captada e dividida por pessoa.",stopListening:"⏹ Parar",summaryTitle:"Resumo da conversa",confirm:"Confirmar ✓",confirmed:"Confirmado ✓",sentNote:"Enviado para cozinha e central",newConv:"Nova conversa",ordersTitle:"Pedidos — cozinha e conta",person:"Pessoa",noSummary:"O resumo aparece aqui conforme a conversa é detetada.",prep:"A preparar",ready:"Pronto",delivered:"Entregue",sent:"Enviado",back:"Voltar",sayPh:"Fale ou escreva o que cada pessoa disse…",sendPhrase:"Enviar",dictate:"🎙️ Ditar",aiHint:"Voz e texto vão direto à IA — o resumo aparece sozinho.",micUnsupported:"Ditado não suportado",processing:"A IA está a resumir…",sectorTab:"Setor",sectorPresets:"Setores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar setor",sectorSaved:"Setor guardado.",aiSuggest:"Sugerir com IA (copiar prompt)",aiSectorCopied:"Prompt copiado — cole no DeepSeek Harness.",fillBoth:"Digite usuário e senha.",loggingIn:"A entrar…",noOrders:"Ainda sem pedidos — confirme itens no resumo.",noUsage:"Ainda sem uso reportado.",noReports:"Ainda sem relatórios de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dono",labelPh:"Função (ex. Cozinheiro)",newOrder:"NOVO PEDIDO",enableNotif:"🔔 Ativar notificações",notifHint:"O tablet da cozinha apita e pisca quando chega um pedido.",tagline:"A IA trabalha. O humano vela, decide, revê."},
281
- zh:{login:"登录",user:"用户",password:"密码",loginBtn:"登录",loginHint:"账户由企业主管理。",loginFailed:"登录失败。",cannotReach:"无法连接服务器。它是否在运行?",workerAdded:"员工已添加。",saved:"已保存。",reportSent:"报告已发送。",feedbackSent:"反馈已发送。",wallOpen:"实时看板",logout:"退出",overview:"总览",field:"现场",rules:"规则",reports:"报告",week:"本周",feedback:"反馈",workersActive:"活跃员工",reportsTotal:"报告总数",workers:"员工",thUser:"用户",thRole:"角色",addWorker:"添加员工",userName:"用户名",addBtn:"添加",usage:"用量与成本",usageSub:"(每位员工,估算)",thWorker:"员工",thSessions:"会话",thTokens:"Token",thCost:"预估成本",panel:"操作面板",panelNote:"员工在平板或手机上打开面板。",openPanel:"打开面板",fieldReports:"现场报告",feedbackQueue:"反馈队列",feedbackHint:"智能体读取此队列并解决问题。",refresh:"刷新",autoOn:"自动:开",autoOff:"自动:关",rulesTitle:"业务规则",rulesHint:"这些规则训练红绿灯。",saveRules:"保存规则",listen:"🎙️ 聆听",hi:"👋 ",reportTitle:"现场报告",reportPh:"你的班次发生了什么?",sendReport:"发送",fbTitle:"现场反馈",fbPh:"发生了什么?什么需要改进?",sendFeedback:"发送",switchUser:"切换用户",wallHead:"🏭 Le Veilleux — 实时",wallPulse:"现场脉搏",noActivity:"(暂无现场活动)",start:"▶ 开始",listening:"正在聆听…请说话",listeningHint:"对话正在被捕捉并按人员划分。",stopListening:"⏹ 停止",summaryTitle:"对话摘要",confirm:"确认 ✓",confirmed:"已确认 ✓",sentNote:"已发送至厨房与中央系统",newConv:"新对话",ordersTitle:"订单 — 厨房与账单",person:"人员",noSummary:"随着对话被识别,摘要将显示在这里。",prep:"制作中",ready:"完成",delivered:"已送达",sent:"已发送",back:"返回",sayPh:"说出或输入每个人说的话……",sendPhrase:"发送",dictate:"🎙️ 听写",aiHint:"语音和文字直达 AI — 摘要自动出现。",micUnsupported:"此浏览器不支持听写",processing:"AI 正在总结……",sectorTab:"行业",sectorPresets:"预设行业",customSector:"自定义行业",saveSector:"保存行业",sectorSaved:"行业已保存。",aiSuggest:"用 AI 建议(复制提示)",aiSectorCopied:"AI 提示已复制 — 粘贴到 DeepSeek Harness。",fillBoth:"请输入用户名和密码。",loggingIn:"登录中……",noOrders:"暂无订单 — 请在摘要中确认项目。",noUsage:"暂无用量报告。",noReports:"暂无现场报告。",lvlEmployee:"现场",lvlLead:"主管",lvlOwner:"业主",labelPh:"角色标签(如:厨师)",newOrder:"新订单",enableNotif:"🔔 开启通知",notifHint:"新订单到达时厨房平板会响铃并闪烁。",tagline:"AI 工作,人来守护、决定、复核。"},
282
- ja:{login:"ログイン",user:"ユーザー",password:"パスワード",loginBtn:"ログイン",loginHint:"アカウントは事業主が管理します。",loginFailed:"ログイン失敗。",cannotReach:"サーバーに接続できません。起動していますか?",workerAdded:"従業員を追加しました。",saved:"保存しました。",reportSent:"報告を送信しました。",feedbackSent:"フィードバックを送信しました。",wallOpen:"ライブ掲示板",logout:"ログアウト",overview:"概要",field:"現場",rules:"ルール",reports:"報告",week:"今週",feedback:"フィードバック",workersActive:"稼働中の従業員",reportsTotal:"報告総数",workers:"従業員",thUser:"ユーザー",thRole:"役割",addWorker:"従業員を追加",userName:"ユーザー名",addBtn:"追加",usage:"利用量とコスト",usageSub:"(従業員ごと、推定)",thWorker:"従業員",thSessions:"セッション",thTokens:"トークン",thCost:"推定コスト",panel:"アクションパネル",panelNote:"従業員はタブレットやスマホでパネルを開きます。",openPanel:"パネルを開く",fieldReports:"現場報告",feedbackQueue:"フィードバック待ち行列",feedbackHint:"エージェントがこの行列を読み、問題を解決します。",refresh:"更新",autoOn:"自動: ON",autoOff:"自動: OFF",rulesTitle:"業務ルール",rulesHint:"これらのルールが信号を訓練します。",saveRules:"ルールを保存",listen:"🎙️ 聞く",hi:"👋 ",reportTitle:"現場報告",reportPh:"シフトで何がありましたか?",sendReport:"送信",fbTitle:"現場フィードバック",fbPh:"何が起きましたか?何を改善すべき?",sendFeedback:"送信",switchUser:"ユーザー切替",wallHead:"🏭 Le Veilleux — ライブ",wallPulse:"現場の鼓動",noActivity:"(まだ現場活動なし)",start:"▶ 開始",listening:"聞いています…どうぞ",listeningHint:"会話を捕捉し、人物ごとに分けています。",stopListening:"⏹ 停止",summaryTitle:"会話のまとめ",confirm:"確認 ✓",confirmed:"確認済み ✓",sentNote:"厨房と中央へ送信済み",newConv:"新しい会話",ordersTitle:"注文 — 厨房と会計",person:"人",noSummary:"会話が検出されるとここにまとめが表示されます。",prep:"調理中",ready:"完成",delivered:"提供済み",sent:"送信済み",back:"戻る",sayPh:"各人が話した内容を話すか入力…",sendPhrase:"送信",dictate:"🎙️ 音声入力",aiHint:"音声とテキストは直接AIへ — まとめは自動で表示されます。",micUnsupported:"音声入力非対応",processing:"AIが要約中…",sectorTab:"セクター",sectorPresets:"セクタープリセット",customSector:"カスタムセクター",saveSector:"セクターを保存",sectorSaved:"セクターを保存しました。",aiSuggest:"AIで提案(プロンプトをコピー)",aiSectorCopied:"AIプロンプトをコピーしました — DeepSeek Harnessに貼り付け。",fillBoth:"ユーザーとパスワードを入力してください。",loggingIn:"ログイン中…",noOrders:"まだ注文がありません — まとめで項目を確認してください。",noUsage:"まだ利用報告がありません。",noReports:"まだ現場報告がありません。",lvlEmployee:"現場",lvlLead:"監督",lvlOwner:"オーナー",labelPh:"役割名(例:調理師)",newOrder:"新規注文",enableNotif:"🔔 通知を有効化",notifHint:"注文が届くと厨房タブレットが音と点滅で知らせます。",tagline:"AIが働き、人間が見守り、決め、見直す。"},
283
- ko:{login:"로그인",user:"사용자",password:"비밀번호",loginBtn:"로그인",loginHint:"계정은 사업주가 관리합니다.",loginFailed:"로그인 실패.",cannotReach:"서버에 연결할 수 없습니다. 실행 중인가요?",workerAdded:"직원이 추가되었습니다.",saved:"저장되었습니다.",reportSent:"보고서를 보냈습니다.",feedbackSent:"피드백을 보냈습니다.",wallOpen:"라이브 보드",logout:"로그아웃",overview:"개요",field:"현장",rules:"규칙",reports:"보고서",week:"이번 주",feedback:"피드백",workersActive:"활성 직원",reportsTotal:"총 보고서",workers:"직원",thUser:"사용자",thRole:"역할",addWorker:"직원 추가",userName:"사용자 이름",addBtn:"추가",usage:"사용량 및 비용",usageSub:"(직원별, 추정)",thWorker:"직원",thSessions:"세션",thTokens:"토큰",thCost:"추정 비용",panel:"액션 패널",panelNote:"직원은 태블릿이나 휴대폰에서 패널을 엽니다.",openPanel:"패널 열기",fieldReports:"현장 보고서",feedbackQueue:"피드백 대기열",feedbackHint:"에이전트가 이 대기열을 읽고 문제를 해결합니다.",refresh:"새로고침",autoOn:"자동: ON",autoOff:"자동: OFF",rulesTitle:"사업 규칙",rulesHint:"이 규칙이 신호등을 훈련합니다.",saveRules:"규칙 저장",listen:"🎙️ 듣기",hi:"👋 ",reportTitle:"현장 보고서",reportPh:"근무 중 무슨 일이 있었나요?",sendReport:"보내기",fbTitle:"현장 피드백",fbPh:"무슨 일이 있었나요? 무엇을 개선할까요?",sendFeedback:"보내기",switchUser:"사용자 전환",wallHead:"🏭 Le Veilleux — 라이브",wallPulse:"현장의 맥박",noActivity:"(현장 활동 없음)",start:"▶ 시작",listening:"듣는 중… 말씀하세요",listeningHint:"대화를 포착하여 사람별로 나누고 있습니다.",stopListening:"⏹ 중지",summaryTitle:"대화 요약",confirm:"확인 ✓",confirmed:"확인됨 ✓",sentNote:"주방 및 중앙으로 전송됨",newConv:"새 대화",ordersTitle:"주문 — 주방 및 계산",person:"사람",noSummary:"대화가 감지되면 요약이 여기에 표시됩니다.",prep:"조리 중",ready:"완료",delivered:"서빙됨",sent:"전송됨",back:"뒤로",sayPh:"각 사람이 말한 내용을 말하거나 입력…",sendPhrase:"보내기",dictate:"🎙️ 받아쓰기",aiHint:"음성과 텍스트가 AI로 바로 전달 — 요약이 자동 표시됩니다.",micUnsupported:"받아쓰기 미지원",processing:"AI가 요약 중…",sectorTab:"업종",sectorPresets:"업종 프리셋",customSector:"사용자 정의 업종",saveSector:"업종 저장",sectorSaved:"업종이 저장되었습니다.",aiSuggest:"AI로 제안(프롬프트 복사)",aiSectorCopied:"AI 프롬프트 복사됨 — DeepSeek Harness에 붙여넣기.",fillBoth:"사용자와 비밀번호를 입력하세요.",loggingIn:"로그인 중…",noOrders:"아직 주문이 없습니다 — 요약에서 항목을 확인하세요.",noUsage:"아직 사용 보고가 없습니다.",noReports:"아직 현장 보고서가 없습니다.",lvlEmployee:"현장",lvlLead:"감독",lvlOwner:"소유주",labelPh:"역할 이름(예: 요리사)",newOrder:"새 주문",enableNotif:"🔔 알림 활성화",notifHint:"주문이 도착하면 주방 태블릿이 소리와 함께 깜박입니다.",tagline:"AI가 일하고 사람이 지키고, 결정하고, 검토합니다."},
284
- ar:{login:"تسجيل الدخول",user:"المستخدم",password:"كلمة المرور",loginBtn:"دخول",loginHint:"الحسابات يديرها صاحب العمل.",loginFailed:"فشل تسجيل الدخول.",cannotReach:"تعذر الوصول إلى الخادم. هل هو قيد التشغيل؟",workerAdded:"تمت إضافة الموظف.",saved:"تم الحفظ.",reportSent:"تم إرسال التقرير.",feedbackSent:"تم إرسال الملاحظات.",wallOpen:"اللوحة المباشرة",logout:"خروج",overview:"نظرة عامة",field:"الميدان",rules:"القواعد",reports:"التقارير",week:"هذا الأسبوع",feedback:"الملاحظات",workersActive:"موظفون نشطون",reportsTotal:"إجمالي التقارير",workers:"الموظفون",thUser:"المستخدم",thRole:"الدور",addWorker:"إضافة موظف",userName:"اسم المستخدم",addBtn:"إضافة",usage:"الاستخدام والتكلفة",usageSub:"(لكل موظف، تقديري)",thWorker:"الموظف",thSessions:"الجلسات",thTokens:"الرموز",thCost:"التكلفة التقديرية",panel:"لوحة الإجراءات",panelNote:"يفتح الموظفون اللوحة من أجهزتهم.",openPanel:"فتح اللوحة",fieldReports:"تقارير الميدان",feedbackQueue:"قائمة الملاحظات",feedbackHint:"يقرأ الوكيل هذه القائمة ويحل المشكلات.",refresh:"تحديث",autoOn:"تلقائي: ON",autoOff:"تلقائي: OFF",rulesTitle:"قواعد العمل",rulesHint:"هذه القواعد تدرّب الإشارة الضوئية.",saveRules:"حفظ القواعد",listen:"🎙️ استمع",hi:"👋 ",reportTitle:"تقرير ميداني",reportPh:"ماذا حدث في نوبتك؟",sendReport:"إرسال",fbTitle:"ملاحظات ميدانية",fbPh:"ماذا حدث؟ ما الذي يجب تحسينه؟",sendFeedback:"إرسال",switchUser:"تبديل المستخدم",wallHead:"🏭 Le Veilleux — مباشر",wallPulse:"نبض الميدان",noActivity:"(لا نشاط بعد)",start:"▶ ابدأ",listening:"أستمع… تفضل بالحديث",listeningHint:"يتم التقاط المحادثة وتقسيمها حسب الأشخاص.",stopListening:"⏹ إيقاف",summaryTitle:"ملخص المحادثة",confirm:"تأكيد ✓",confirmed:"مؤكد ✓",sentNote:"أُرسل إلى المطبخ والنظام المركزي",newConv:"محادثة جديدة",ordersTitle:"الطلبات — المطبخ والحساب",person:"شخص",noSummary:"سيظهر الملخص هنا مع اكتشاف المحادثة.",prep:"قيد التحضير",ready:"جاهز",delivered:"تم التسليم",sent:"أُرسل",back:"رجوع",sayPh:"تحدث أو اكتب ما قاله كل شخص…",sendPhrase:"إرسال",dictate:"🎙️ إملاء",aiHint:"الصوت والنص يصلان مباشرة إلى الذكاء الاصطناعي — يظهر الملخص تلقائيًا.",micUnsupported:"الإملاء غير مدعوم",processing:"الذكاء الاصطناعي يلخّص…",sectorTab:"القطاع",sectorPresets:"القطاعات المحددة مسبقًا",customSector:"قطاع مخصص",saveSector:"حفظ القطاع",sectorSaved:"تم حفظ القطاع.",aiSuggest:"اقترح بالذكاء الاصطناعي (نسخ الموجه)",aiSectorCopied:"تم نسخ الموجه — الصقه في DeepSeek Harness.",fillBoth:"أدخل المستخدم وكلمة المرور.",loggingIn:"جارٍ الدخول…",noOrders:"لا توجد طلبات بعد — أكّد العناصر في الملخص.",noUsage:"لا يوجد استخدام مُبلّغ بعد.",noReports:"لا توجد تقارير ميدانية بعد.",lvlEmployee:"الميدان",lvlLead:"مشرف",lvlOwner:"المالك",labelPh:"مسمى الدور (مثال: طباخ)",newOrder:"طلب جديد",enableNotif:"🔔 تفعيل الإشعارات",notifHint:"يصدر صوت ويومض لوح المطبخ عند وصول طلب جديد.",tagline:"الذكاء الاصطناعي يعمل، والإنسان يراقب ويقرر ويراجع."}
307
+ en:{login:"Log in",user:"User",password:"Password",loginBtn:"Log in",loginHint:"Accounts are managed by the business owner.",loginFailed:"Login failed.",cannotReach:"Cannot reach the supervisor server. Is it running?",workerAdded:"Worker added.",saved:"Saved.",reportSent:"Report sent.",feedbackSent:"Feedback sent.",wallOpen:"Live wallboard",logout:"Log out",overview:"Overview",field:"Field",rules:"Rules",reports:"Reports",week:"This week",feedback:"Feedback",workersActive:"Workers active",reportsTotal:"Reports total",workers:"Workers",thUser:"User",thRole:"Role",addWorker:"Add worker",userName:"User name",addBtn:"Add worker",usage:"Usage & cost",usageSub:"(per worker, estimated)",thWorker:"Worker",thSessions:"Sessions",thTokens:"Tokens",thCost:"Est. cost",panel:"Action Panel",panelNote:"Workers open the panel from their tablet or phone.",openPanel:"Open Action Panel",fieldReports:"Field reports",feedbackQueue:"Feedback queue",feedbackHint:"The agent reads this queue and resolves errors and improvements.",refresh:"Refresh",autoOn:"Auto-refresh: ON",autoOff:"Auto-refresh: OFF",rulesTitle:"Business rules",rulesHint:"These rules train the traffic light.",saveRules:"Save rules",listen:"🎙️ LISTEN",hi:"👋 ",reportTitle:"Field report",reportPh:"What happened on your shift?",sendReport:"Send report",fbTitle:"Field feedback",fbPh:"What happened? What should improve?",sendFeedback:"Send feedback",switchUser:"Switch user",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Field pulse",noActivity:"(no field activity yet)",start:"▶ START",listening:"Listening… speak now",listeningHint:"The conversation is being captured and split by person.",stopListening:"⏹ Stop listening",summaryTitle:"Conversation summary",confirm:"Confirm ✓",confirmed:"Confirmed ✓",sentNote:"Sent to kitchen & central",newConv:"New conversation",ordersTitle:"Orders — kitchen & bill",person:"Person",noSummary:"The summary will appear here as the conversation is detected.",prep:"Preparing",ready:"Ready",delivered:"Delivered",sent:"Sent",back:"Back",sayPh:"Speak or type what each person said…",sendPhrase:"Send phrase",dictate:"🎙️ Dictate",aiHint:"Speech and text go straight to the AI — the summary appears automatically.",micUnsupported:"Dictation not supported in this browser",processing:"The AI is summarizing…",sectorTab:"Sector",sectorPresets:"Sector presets",customSector:"Custom sector",saveSector:"Save sector",sectorSaved:"Sector saved.",aiSuggest:"Suggest with AI (copy prompt)",aiSectorCopied:"AI prompt copied — paste it in DeepSeek Harness.",fillBoth:"Enter your user and password.",loggingIn:"Logging in…",noOrders:"No orders yet — confirm items in the summary.",noUsage:"No usage reported yet.",noReports:"No field reports yet.",lvlEmployee:"Field",lvlLead:"Supervisor",lvlOwner:"Owner",labelPh:"Role label (e.g. Cook)",newOrder:"NEW ORDER",enableNotif:"🔔 Enable notifications",notifHint:"The kitchen tablet beeps and flashes when an order arrives.",tagline:"The AI works. The human watches, decides, reviews.",welcomeTitle:"Welcome to Le Veilleux 👁️",welcomeBody:"Three steps to your first live flow: 1) Add your workers. 2) Choose your sector. 3) Run a real conversation — the AI proposes, you confirm.",wallNote:"Updates every 30 s"},
308
+ es:{login:"Iniciar sesión",user:"Usuario",password:"Contraseña",loginBtn:"Entrar",loginHint:"Las cuentas las gestiona el dueño del negocio.",loginFailed:"Datos incorrectos.",cannotReach:"No se puede contactar el servidor. ¿Está corriendo?",workerAdded:"Trabajador añadido.",saved:"Guardado.",reportSent:"Reporte enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Wallboard en vivo",logout:"Salir",overview:"Resumen",field:"Campo",rules:"Reglas",reports:"Reportes",week:"Esta semana",feedback:"Feedback",workersActive:"Trabajadores activos",reportsTotal:"Reportes totales",workers:"Trabajadores",thUser:"Usuario",thRole:"Rol",addWorker:"Añadir trabajador",userName:"Nombre de usuario",addBtn:"Añadir trabajador",usage:"Uso y coste",usageSub:"(por trabajador, estimado)",thWorker:"Trabajador",thSessions:"Sesiones",thTokens:"Tokens",thCost:"Coste est.",panel:"Panel de Acción",panelNote:"Los trabajadores abren el panel desde su tablet o teléfono.",openPanel:"Abrir Panel de Acción",fieldReports:"Reportes de campo",feedbackQueue:"Cola de feedback",feedbackHint:"El agente lee esta cola y resuelve errores y mejoras.",refresh:"Actualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Reglas del negocio",rulesHint:"Estas reglas entrenan el semáforo.",saveRules:"Guardar reglas",listen:"🎙️ ESCUCHAR",hi:"👋 ",reportTitle:"Reporte de campo",reportPh:"¿Qué pasó en tu turno?",sendReport:"Enviar reporte",fbTitle:"Feedback de campo",fbPh:"¿Qué pasó? ¿Qué debe mejorar?",sendFeedback:"Enviar feedback",switchUser:"Cambiar de usuario",wallHead:"🏭 Le Veilleux — En vivo",wallPulse:"Pulso del campo",noActivity:"(sin actividad de campo aún)",start:"▶ INICIAR",listening:"Escuchando… habla ahora",listeningHint:"La conversación se captura y divide por persona.",stopListening:"⏹ Detener",summaryTitle:"Resumen de la conversación",confirm:"Confirmar ✓",confirmed:"Confirmado ✓",sentNote:"Enviado a cocina y central",newConv:"Nueva conversación",ordersTitle:"Pedidos — cocina y cuenta",person:"Persona",noSummary:"El resumen aparecerá aquí conforme se detecta la conversación.",prep:"Preparando",ready:"Listo",delivered:"Entregado",sent:"Enviado",back:"Volver",sayPh:"Habla o escribe lo que dijo cada persona…",sendPhrase:"Enviar frase",dictate:"🎙️ Dictar",aiHint:"Voz y texto van directo a la IA — el resumen aparece solo.",micUnsupported:"Dictado no soportado en este navegador",processing:"La IA está resumiendo…",sectorTab:"Sector",sectorPresets:"Sectores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar sector",sectorSaved:"Sector guardado.",aiSuggest:"Sugerir con IA (copiar prompt)",aiSectorCopied:"Prompt de IA copiado — pégalo en DeepSeek Harness.",fillBoth:"Escribe tu usuario y contraseña.",loggingIn:"Entrando…",noOrders:"Aún no hay pedidos — confirma elementos en el resumen.",noUsage:"Aún no hay uso reportado.",noReports:"Aún no hay reportes de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dueño",labelPh:"Etiqueta de rol (ej. Cocinero)",newOrder:"NUEVO PEDIDO",enableNotif:"🔔 Activar notificaciones",notifHint:"La tablet de cocina suena y parpadea cuando llega un pedido.",tagline:"La IA trabaja. El humano vela, decide, revisa.",welcomeTitle:"Bienvenido a Le Veilleux 👁️",welcomeBody:"Tres pasos para tu primer flujo en vivo: 1) Añade a tus trabajadores. 2) Elige tu sector. 3) Corre una conversación real — la IA propone, tú confirmas.",wallNote:"Se actualiza cada 30 s"},
309
+ fr:{login:"Connexion",user:"Utilisateur",password:"Mot de passe",loginBtn:"Se connecter",loginHint:"Les comptes sont gérés par le propriétaire.",loginFailed:"Échec de connexion.",cannotReach:"Serveur injoignable. Est-il lancé ?",workerAdded:"Employé ajouté.",saved:"Enregistré.",reportSent:"Rapport envoyé.",feedbackSent:"Feedback envoyé.",wallOpen:"Tableau en direct",logout:"Déconnexion",overview:"Vue d'ensemble",field:"Terrain",rules:"Règles",reports:"Rapports",week:"Cette semaine",feedback:"Feedback",workersActive:"Employés actifs",reportsTotal:"Total rapports",workers:"Employés",thUser:"Utilisateur",thRole:"Rôle",addWorker:"Ajouter un employé",userName:"Nom d'utilisateur",addBtn:"Ajouter",usage:"Usage et coût",usageSub:"(par employé, estimé)",thWorker:"Employé",thSessions:"Sessions",thTokens:"Jetons",thCost:"Coût est.",panel:"Panneau d'action",panelNote:"Les employés ouvrent le panneau depuis leur tablette ou téléphone.",openPanel:"Ouvrir le panneau",fieldReports:"Rapports terrain",feedbackQueue:"File de feedback",feedbackHint:"L'agent lit cette file et résout erreurs et améliorations.",refresh:"Actualiser",autoOn:"Auto : ON",autoOff:"Auto : OFF",rulesTitle:"Règles du commerce",rulesHint:"Ces règles entraînent le feu tricolore.",saveRules:"Enregistrer",listen:"🎙️ ÉCOUTER",hi:"👋 ",reportTitle:"Rapport terrain",reportPh:"Que s'est-il passé pendant votre quart ?",sendReport:"Envoyer",fbTitle:"Feedback terrain",fbPh:"Que s'est-il passé ? Que faut-il améliorer ?",sendFeedback:"Envoyer",switchUser:"Changer d'utilisateur",wallHead:"🏭 Le Veilleux — En direct",wallPulse:"Pouls du terrain",noActivity:"(aucune activité)",start:"▶ DÉMARRER",listening:"Écoute… parlez maintenant",listeningHint:"La conversation est captée et répartie par personne.",stopListening:"⏹ Arrêter",summaryTitle:"Résumé de la conversation",confirm:"Confirmer ✓",confirmed:"Confirmé ✓",sentNote:"Envoyé en cuisine et au central",newConv:"Nouvelle conversation",ordersTitle:"Commandes — cuisine et addition",person:"Personne",noSummary:"Le résumé apparaîtra ici au fil de la conversation.",prep:"En préparation",ready:"Prêt",delivered:"Servi",sent:"Envoyé",back:"Retour",sayPh:"Parlez ou écrivez ce que chaque personne a dit…",sendPhrase:"Envoyer",dictate:"🎙️ Dicter",aiHint:"La voix et le texte vont directement à l’IA — le résumé apparaît seul.",micUnsupported:"Dictée non prise en charge",processing:"L’IA résume…",sectorTab:"Secteur",sectorPresets:"Secteurs prédéfinis",customSector:"Secteur personnalisé",saveSector:"Enregistrer le secteur",sectorSaved:"Secteur enregistré.",aiSuggest:"Suggérer avec l’IA (copier l’invite)",aiSectorCopied:"Invite copiée — collez-la dans DeepSeek Harness.",fillBoth:"Saisissez votre utilisateur et votre mot de passe.",loggingIn:"Connexion…",noOrders:"Aucune commande — confirmez des éléments dans le résumé.",noUsage:"Aucun usage signalé.",noReports:"Aucun rapport terrain.",lvlEmployee:"Terrain",lvlLead:"Superviseur",lvlOwner:"Propriétaire",labelPh:"Intitulé du rôle (ex. Cuisinier)",newOrder:"NOUVELLE COMMANDE",enableNotif:"🔔 Activer les notifications",notifHint:"La tablette de cuisine sonne et clignote à l'arrivée d'une commande.",tagline:"L'IA travaille. L'humain veille, décide, revoit.",welcomeTitle:"Bienvenue chez Le Veilleux 👁️",welcomeBody:"Trois étapes vers votre premier flux en direct : 1) Ajoutez vos employés. 2) Choisissez votre secteur. 3) Déroulez une vraie conversation — l'IA propose, vous confirmez.",wallNote:"Mise à jour toutes les 30 s"},
310
+ de:{login:"Anmelden",user:"Benutzer",password:"Passwort",loginBtn:"Anmelden",loginHint:"Konten verwaltet der Inhaber.",loginFailed:"Anmeldung fehlgeschlagen.",cannotReach:"Server nicht erreichbar. Läuft er?",workerAdded:"Mitarbeiter hinzugefügt.",saved:"Gespeichert.",reportSent:"Bericht gesendet.",feedbackSent:"Feedback gesendet.",wallOpen:"Live-Anzeige",logout:"Abmelden",overview:"Übersicht",field:"Feld",rules:"Regeln",reports:"Berichte",week:"Diese Woche",feedback:"Feedback",workersActive:"Aktive Mitarbeiter",reportsTotal:"Berichte gesamt",workers:"Mitarbeiter",thUser:"Benutzer",thRole:"Rolle",addWorker:"Mitarbeiter hinzufügen",userName:"Benutzername",addBtn:"Hinzufügen",usage:"Nutzung & Kosten",usageSub:"(pro Mitarbeiter, geschätzt)",thWorker:"Mitarbeiter",thSessions:"Sitzungen",thTokens:"Tokens",thCost:"Kosten ca.",panel:"Aktionspanel",panelNote:"Mitarbeiter öffnen das Panel auf Tablet oder Handy.",openPanel:"Panel öffnen",fieldReports:"Feldberichte",feedbackQueue:"Feedback-Warteschlange",feedbackHint:"Der Agent liest diese Warteschlange und behebt Fehler.",refresh:"Aktualisieren",autoOn:"Auto: AN",autoOff:"Auto: AUS",rulesTitle:"Geschäftsregeln",rulesHint:"Diese Regeln trainieren die Ampel.",saveRules:"Regeln speichern",listen:"🎙️ ZUHÖREN",hi:"👋 ",reportTitle:"Feldbericht",reportPh:"Was ist in Ihrer Schicht passiert?",sendReport:"Senden",fbTitle:"Feld-Feedback",fbPh:"Was ist passiert? Was soll besser werden?",sendFeedback:"Senden",switchUser:"Benutzer wechseln",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Puls im Feld",noActivity:"(noch keine Aktivität)",start:"▶ STARTEN",listening:"Höre zu… sprich jetzt",listeningHint:"Das Gespräch wird erfasst und pro Person aufgeteilt.",stopListening:"⏹ Stopp",summaryTitle:"Gesprächsübersicht",confirm:"Bestätigen ✓",confirmed:"Bestätigt ✓",sentNote:"An Küche & Zentrale gesendet",newConv:"Neues Gespräch",ordersTitle:"Bestellungen — Küche & Rechnung",person:"Person",noSummary:"Die Übersicht erscheint hier, sobald das Gespräch erkannt wird.",prep:"In Zubereitung",ready:"Fertig",delivered:"Serviert",sent:"Gesendet",back:"Zurück",sayPh:"Sprechen oder tippen Sie, was jede Person gesagt hat…",sendPhrase:"Senden",dictate:"🎙️ Diktieren",aiHint:"Sprache und Text gehen direkt an die KI — die Übersicht erscheint automatisch.",micUnsupported:"Diktat nicht unterstützt",processing:"Die KI fasst zusammen…",sectorTab:"Branche",sectorPresets:"Branchen-Vorlagen",customSector:"Eigene Branche",saveSector:"Branche speichern",sectorSaved:"Branche gespeichert.",aiSuggest:"Mit KI vorschlagen (Prompt kopieren)",aiSectorCopied:"KI-Prompt kopiert — in DeepSeek Harness einfügen.",fillBoth:"Benutzer und Passwort eingeben.",loggingIn:"Anmeldung…",noOrders:"Noch keine Bestellungen — Elemente in der Übersicht bestätigen.",noUsage:"Noch keine Nutzung gemeldet.",noReports:"Noch keine Feldberichte.",lvlEmployee:"Feld",lvlLead:"Aufsicht",lvlOwner:"Inhaber",labelPh:"Rollenname (z. B. Koch)",newOrder:"NEUE BESTELLUNG",enableNotif:"🔔 Benachrichtigungen aktivieren",notifHint:"Das Küchen-Tablet piept und blinkt bei neuer Bestellung.",tagline:"Die KI arbeitet. Der Mensch wacht, entscheidet, prüft.",welcomeTitle:"Willkommen bei Le Veilleux 👁️",welcomeBody:"Drei Schritte zu Ihrem ersten Live-Ablauf: 1) Mitarbeiter hinzufügen. 2) Branche wählen. 3) Ein echtes Gespräch führen — die KI schlägt vor, Sie bestätigen.",wallNote:"Aktualisiert alle 30 s"},
311
+ it:{login:"Accedi",user:"Utente",password:"Password",loginBtn:"Accedi",loginHint:"Gli account li gestisce il proprietario.",loginFailed:"Accesso fallito.",cannotReach:"Server non raggiungibile. È in esecuzione?",workerAdded:"Lavoratore aggiunto.",saved:"Salvato.",reportSent:"Report inviato.",feedbackSent:"Feedback inviato.",wallOpen:"Schermo live",logout:"Esci",overview:"Panoramica",field:"Campo",rules:"Regole",reports:"Report",week:"Questa settimana",feedback:"Feedback",workersActive:"Lavoratori attivi",reportsTotal:"Report totali",workers:"Lavoratori",thUser:"Utente",thRole:"Ruolo",addWorker:"Aggiungi lavoratore",userName:"Nome utente",addBtn:"Aggiungi",usage:"Uso e costi",usageSub:"(per lavoratore, stimato)",thWorker:"Lavoratore",thSessions:"Sessioni",thTokens:"Token",thCost:"Costo stim.",panel:"Pannello Azioni",panelNote:"I lavoratori aprono il pannello da tablet o telefono.",openPanel:"Apri il pannello",fieldReports:"Report di campo",feedbackQueue:"Coda feedback",feedbackHint:"L'agente legge questa coda e risolve errori e migliorie.",refresh:"Aggiorna",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regole del negozio",rulesHint:"Queste regole addestrano il semaforo.",saveRules:"Salva regole",listen:"🎙️ ASCOLTA",hi:"👋 ",reportTitle:"Report di campo",reportPh:"Cosa è successo nel tuo turno?",sendReport:"Invia",fbTitle:"Feedback di campo",fbPh:"Cosa è successo? Cosa va migliorato?",sendFeedback:"Invia",switchUser:"Cambia utente",wallHead:"🏭 Le Veilleux — Live",wallPulse:"Battito del campo",noActivity:"(nessuna attività)",start:"▶ INIZIA",listening:"In ascolto… parla ora",listeningHint:"La conversazione viene catturata e divisa per persona.",stopListening:"⏹ Ferma",summaryTitle:"Riepilogo conversazione",confirm:"Conferma ✓",confirmed:"Confermato ✓",sentNote:"Inviato a cucina e centrale",newConv:"Nuova conversazione",ordersTitle:"Ordini — cucina e conto",person:"Persona",noSummary:"Il riepilogo apparirà qui man mano che la conversazione viene rilevata.",prep:"In preparazione",ready:"Pronto",delivered:"Servito",sent:"Inviato",back:"Indietro",sayPh:"Parla o scrivi cosa ha detto ogni persona…",sendPhrase:"Invia",dictate:"🎙️ Detta",aiHint:"Voce e testo vanno direttamente all’IA — il riepilogo appare da solo.",micUnsupported:"Dettatura non supportata",processing:"L’IA sta riassumendo…",sectorTab:"Settore",sectorPresets:"Settori predefiniti",customSector:"Settore personalizzato",saveSector:"Salva settore",sectorSaved:"Settore salvato.",aiSuggest:"Suggerisci con l’IA (copia prompt)",aiSectorCopied:"Prompt copiato — incollalo in DeepSeek Harness.",fillBoth:"Inserisci utente e password.",loggingIn:"Accesso…",noOrders:"Ancora nessun ordine — conferma elementi nel riepilogo.",noUsage:"Nessun utilizzo segnalato.",noReports:"Nessun report di campo.",lvlEmployee:"Terreno",lvlLead:"Supervisore",lvlOwner:"Proprietario",labelPh:"Etichetta ruolo (es. Cuoco)",newOrder:"NUOVO ORDINE",enableNotif:"🔔 Attiva notifiche",notifHint:"Il tablet di cucina suona e lampeggia all'arrivo di un ordine.",tagline:"L'IA lavora. L'umano veglia, decide, rivede.",welcomeTitle:"Benvenuto in Le Veilleux 👁️",welcomeBody:"Tre passi per il tuo primo flusso dal vivo: 1) Aggiungi i lavoratori. 2) Scegli il settore. 3) Svolgi una conversazione reale — l'IA propone, tu confermi.",wallNote:"Si aggiorna ogni 30 s"},
312
+ pt:{login:"Entrar",user:"Usuário",password:"Senha",loginBtn:"Entrar",loginHint:"As contas são geridas pelo dono.",loginFailed:"Falha no login.",cannotReach:"Servidor inacessível. Está a correr?",workerAdded:"Trabalhador adicionado.",saved:"Guardado.",reportSent:"Relatório enviado.",feedbackSent:"Feedback enviado.",wallOpen:"Painel ao vivo",logout:"Sair",overview:"Visão geral",field:"Campo",rules:"Regras",reports:"Relatórios",week:"Esta semana",feedback:"Feedback",workersActive:"Trabalhadores ativos",reportsTotal:"Total de relatórios",workers:"Trabalhadores",thUser:"Usuário",thRole:"Função",addWorker:"Adicionar trabalhador",userName:"Nome de usuário",addBtn:"Adicionar",usage:"Uso e custo",usageSub:"(por trabalhador, estimado)",thWorker:"Trabalhador",thSessions:"Sessões",thTokens:"Tokens",thCost:"Custo est.",panel:"Painel de Ação",panelNote:"Os trabalhadores abrem o painel no tablet ou telemóvel.",openPanel:"Abrir painel",fieldReports:"Relatórios de campo",feedbackQueue:"Fila de feedback",feedbackHint:"O agente lê esta fila e resolve erros e melhorias.",refresh:"Atualizar",autoOn:"Auto: ON",autoOff:"Auto: OFF",rulesTitle:"Regras do negócio",rulesHint:"Estas regras treinam o semáforo.",saveRules:"Guardar regras",listen:"🎙️ OUVIR",hi:"👋 ",reportTitle:"Relatório de campo",reportPh:"O que aconteceu no seu turno?",sendReport:"Enviar",fbTitle:"Feedback de campo",fbPh:"O que aconteceu? O que deve melhorar?",sendFeedback:"Enviar",switchUser:"Trocar de usuário",wallHead:"🏭 Le Veilleux — Ao vivo",wallPulse:"Pulso do campo",noActivity:"(sem atividade)",start:"▶ INICIAR",listening:"A ouvir… fale agora",listeningHint:"A conversa é captada e dividida por pessoa.",stopListening:"⏹ Parar",summaryTitle:"Resumo da conversa",confirm:"Confirmar ✓",confirmed:"Confirmado ✓",sentNote:"Enviado para cozinha e central",newConv:"Nova conversa",ordersTitle:"Pedidos — cozinha e conta",person:"Pessoa",noSummary:"O resumo aparece aqui conforme a conversa é detetada.",prep:"A preparar",ready:"Pronto",delivered:"Entregue",sent:"Enviado",back:"Voltar",sayPh:"Fale ou escreva o que cada pessoa disse…",sendPhrase:"Enviar",dictate:"🎙️ Ditar",aiHint:"Voz e texto vão direto à IA — o resumo aparece sozinho.",micUnsupported:"Ditado não suportado",processing:"A IA está a resumir…",sectorTab:"Setor",sectorPresets:"Setores predefinidos",customSector:"Sector personalizado",saveSector:"Guardar setor",sectorSaved:"Setor guardado.",aiSuggest:"Sugerir com IA (copiar prompt)",aiSectorCopied:"Prompt copiado — cole no DeepSeek Harness.",fillBoth:"Digite usuário e senha.",loggingIn:"A entrar…",noOrders:"Ainda sem pedidos — confirme itens no resumo.",noUsage:"Ainda sem uso reportado.",noReports:"Ainda sem relatórios de campo.",lvlEmployee:"Terreno",lvlLead:"Supervisor",lvlOwner:"Dono",labelPh:"Função (ex. Cozinheiro)",newOrder:"NOVO PEDIDO",enableNotif:"🔔 Ativar notificações",notifHint:"O tablet da cozinha apita e pisca quando chega um pedido.",tagline:"A IA trabalha. O humano vela, decide, revê.",welcomeTitle:"Bem-vindo ao Le Veilleux 👁️",welcomeBody:"Três passos para o seu primeiro fluxo ao vivo: 1) Adicione os trabalhadores. 2) Escolha o setor. 3) Faça uma conversa real — a IA propõe, você confirma.",wallNote:"Atualiza a cada 30 s"},
313
+ zh:{login:"登录",user:"用户",password:"密码",loginBtn:"登录",loginHint:"账户由企业主管理。",loginFailed:"登录失败。",cannotReach:"无法连接服务器。它是否在运行?",workerAdded:"员工已添加。",saved:"已保存。",reportSent:"报告已发送。",feedbackSent:"反馈已发送。",wallOpen:"实时看板",logout:"退出",overview:"总览",field:"现场",rules:"规则",reports:"报告",week:"本周",feedback:"反馈",workersActive:"活跃员工",reportsTotal:"报告总数",workers:"员工",thUser:"用户",thRole:"角色",addWorker:"添加员工",userName:"用户名",addBtn:"添加",usage:"用量与成本",usageSub:"(每位员工,估算)",thWorker:"员工",thSessions:"会话",thTokens:"Token",thCost:"预估成本",panel:"操作面板",panelNote:"员工在平板或手机上打开面板。",openPanel:"打开面板",fieldReports:"现场报告",feedbackQueue:"反馈队列",feedbackHint:"智能体读取此队列并解决问题。",refresh:"刷新",autoOn:"自动:开",autoOff:"自动:关",rulesTitle:"业务规则",rulesHint:"这些规则训练红绿灯。",saveRules:"保存规则",listen:"🎙️ 聆听",hi:"👋 ",reportTitle:"现场报告",reportPh:"你的班次发生了什么?",sendReport:"发送",fbTitle:"现场反馈",fbPh:"发生了什么?什么需要改进?",sendFeedback:"发送",switchUser:"切换用户",wallHead:"🏭 Le Veilleux — 实时",wallPulse:"现场脉搏",noActivity:"(暂无现场活动)",start:"▶ 开始",listening:"正在聆听…请说话",listeningHint:"对话正在被捕捉并按人员划分。",stopListening:"⏹ 停止",summaryTitle:"对话摘要",confirm:"确认 ✓",confirmed:"已确认 ✓",sentNote:"已发送至厨房与中央系统",newConv:"新对话",ordersTitle:"订单 — 厨房与账单",person:"人员",noSummary:"随着对话被识别,摘要将显示在这里。",prep:"制作中",ready:"完成",delivered:"已送达",sent:"已发送",back:"返回",sayPh:"说出或输入每个人说的话……",sendPhrase:"发送",dictate:"🎙️ 听写",aiHint:"语音和文字直达 AI — 摘要自动出现。",micUnsupported:"此浏览器不支持听写",processing:"AI 正在总结……",sectorTab:"行业",sectorPresets:"预设行业",customSector:"自定义行业",saveSector:"保存行业",sectorSaved:"行业已保存。",aiSuggest:"用 AI 建议(复制提示)",aiSectorCopied:"AI 提示已复制 — 粘贴到 DeepSeek Harness。",fillBoth:"请输入用户名和密码。",loggingIn:"登录中……",noOrders:"暂无订单 — 请在摘要中确认项目。",noUsage:"暂无用量报告。",noReports:"暂无现场报告。",lvlEmployee:"现场",lvlLead:"主管",lvlOwner:"业主",labelPh:"角色标签(如:厨师)",newOrder:"新订单",enableNotif:"🔔 开启通知",notifHint:"新订单到达时厨房平板会响铃并闪烁。",tagline:"AI 工作,人来守护、决定、复核。",welcomeTitle:"欢迎使用 Le Veilleux 👁️",welcomeBody:"三步开始您的第一个实时流程:1) 添加员工。2) 选择行业。3) 进行真实对话 — AI 提议,您确认。",wallNote:"每 30 秒更新"},
314
+ ja:{login:"ログイン",user:"ユーザー",password:"パスワード",loginBtn:"ログイン",loginHint:"アカウントは事業主が管理します。",loginFailed:"ログイン失敗。",cannotReach:"サーバーに接続できません。起動していますか?",workerAdded:"従業員を追加しました。",saved:"保存しました。",reportSent:"報告を送信しました。",feedbackSent:"フィードバックを送信しました。",wallOpen:"ライブ掲示板",logout:"ログアウト",overview:"概要",field:"現場",rules:"ルール",reports:"報告",week:"今週",feedback:"フィードバック",workersActive:"稼働中の従業員",reportsTotal:"報告総数",workers:"従業員",thUser:"ユーザー",thRole:"役割",addWorker:"従業員を追加",userName:"ユーザー名",addBtn:"追加",usage:"利用量とコスト",usageSub:"(従業員ごと、推定)",thWorker:"従業員",thSessions:"セッション",thTokens:"トークン",thCost:"推定コスト",panel:"アクションパネル",panelNote:"従業員はタブレットやスマホでパネルを開きます。",openPanel:"パネルを開く",fieldReports:"現場報告",feedbackQueue:"フィードバック待ち行列",feedbackHint:"エージェントがこの行列を読み、問題を解決します。",refresh:"更新",autoOn:"自動: ON",autoOff:"自動: OFF",rulesTitle:"業務ルール",rulesHint:"これらのルールが信号を訓練します。",saveRules:"ルールを保存",listen:"🎙️ 聞く",hi:"👋 ",reportTitle:"現場報告",reportPh:"シフトで何がありましたか?",sendReport:"送信",fbTitle:"現場フィードバック",fbPh:"何が起きましたか?何を改善すべき?",sendFeedback:"送信",switchUser:"ユーザー切替",wallHead:"🏭 Le Veilleux — ライブ",wallPulse:"現場の鼓動",noActivity:"(まだ現場活動なし)",start:"▶ 開始",listening:"聞いています…どうぞ",listeningHint:"会話を捕捉し、人物ごとに分けています。",stopListening:"⏹ 停止",summaryTitle:"会話のまとめ",confirm:"確認 ✓",confirmed:"確認済み ✓",sentNote:"厨房と中央へ送信済み",newConv:"新しい会話",ordersTitle:"注文 — 厨房と会計",person:"人",noSummary:"会話が検出されるとここにまとめが表示されます。",prep:"調理中",ready:"完成",delivered:"提供済み",sent:"送信済み",back:"戻る",sayPh:"各人が話した内容を話すか入力…",sendPhrase:"送信",dictate:"🎙️ 音声入力",aiHint:"音声とテキストは直接AIへ — まとめは自動で表示されます。",micUnsupported:"音声入力非対応",processing:"AIが要約中…",sectorTab:"セクター",sectorPresets:"セクタープリセット",customSector:"カスタムセクター",saveSector:"セクターを保存",sectorSaved:"セクターを保存しました。",aiSuggest:"AIで提案(プロンプトをコピー)",aiSectorCopied:"AIプロンプトをコピーしました — DeepSeek Harnessに貼り付け。",fillBoth:"ユーザーとパスワードを入力してください。",loggingIn:"ログイン中…",noOrders:"まだ注文がありません — まとめで項目を確認してください。",noUsage:"まだ利用報告がありません。",noReports:"まだ現場報告がありません。",lvlEmployee:"現場",lvlLead:"監督",lvlOwner:"オーナー",labelPh:"役割名(例:調理師)",newOrder:"新規注文",enableNotif:"🔔 通知を有効化",notifHint:"注文が届くと厨房タブレットが音と点滅で知らせます。",tagline:"AIが働き、人間が見守り、決め、見直す。",welcomeTitle:"Le Veilleux へようこそ 👁️",welcomeBody:"最初のライブフローまでの3ステップ:1) 従業員を追加。2) セクターを選択。3) 実際の会話を行う — AIが提案し、あなたが確認します。",wallNote:"30秒ごとに更新"},
315
+ ko:{login:"로그인",user:"사용자",password:"비밀번호",loginBtn:"로그인",loginHint:"계정은 사업주가 관리합니다.",loginFailed:"로그인 실패.",cannotReach:"서버에 연결할 수 없습니다. 실행 중인가요?",workerAdded:"직원이 추가되었습니다.",saved:"저장되었습니다.",reportSent:"보고서를 보냈습니다.",feedbackSent:"피드백을 보냈습니다.",wallOpen:"라이브 보드",logout:"로그아웃",overview:"개요",field:"현장",rules:"규칙",reports:"보고서",week:"이번 주",feedback:"피드백",workersActive:"활성 직원",reportsTotal:"총 보고서",workers:"직원",thUser:"사용자",thRole:"역할",addWorker:"직원 추가",userName:"사용자 이름",addBtn:"추가",usage:"사용량 및 비용",usageSub:"(직원별, 추정)",thWorker:"직원",thSessions:"세션",thTokens:"토큰",thCost:"추정 비용",panel:"액션 패널",panelNote:"직원은 태블릿이나 휴대폰에서 패널을 엽니다.",openPanel:"패널 열기",fieldReports:"현장 보고서",feedbackQueue:"피드백 대기열",feedbackHint:"에이전트가 이 대기열을 읽고 문제를 해결합니다.",refresh:"새로고침",autoOn:"자동: ON",autoOff:"자동: OFF",rulesTitle:"사업 규칙",rulesHint:"이 규칙이 신호등을 훈련합니다.",saveRules:"규칙 저장",listen:"🎙️ 듣기",hi:"👋 ",reportTitle:"현장 보고서",reportPh:"근무 중 무슨 일이 있었나요?",sendReport:"보내기",fbTitle:"현장 피드백",fbPh:"무슨 일이 있었나요? 무엇을 개선할까요?",sendFeedback:"보내기",switchUser:"사용자 전환",wallHead:"🏭 Le Veilleux — 라이브",wallPulse:"현장의 맥박",noActivity:"(현장 활동 없음)",start:"▶ 시작",listening:"듣는 중… 말씀하세요",listeningHint:"대화를 포착하여 사람별로 나누고 있습니다.",stopListening:"⏹ 중지",summaryTitle:"대화 요약",confirm:"확인 ✓",confirmed:"확인됨 ✓",sentNote:"주방 및 중앙으로 전송됨",newConv:"새 대화",ordersTitle:"주문 — 주방 및 계산",person:"사람",noSummary:"대화가 감지되면 요약이 여기에 표시됩니다.",prep:"조리 중",ready:"완료",delivered:"서빙됨",sent:"전송됨",back:"뒤로",sayPh:"각 사람이 말한 내용을 말하거나 입력…",sendPhrase:"보내기",dictate:"🎙️ 받아쓰기",aiHint:"음성과 텍스트가 AI로 바로 전달 — 요약이 자동 표시됩니다.",micUnsupported:"받아쓰기 미지원",processing:"AI가 요약 중…",sectorTab:"업종",sectorPresets:"업종 프리셋",customSector:"사용자 정의 업종",saveSector:"업종 저장",sectorSaved:"업종이 저장되었습니다.",aiSuggest:"AI로 제안(프롬프트 복사)",aiSectorCopied:"AI 프롬프트 복사됨 — DeepSeek Harness에 붙여넣기.",fillBoth:"사용자와 비밀번호를 입력하세요.",loggingIn:"로그인 중…",noOrders:"아직 주문이 없습니다 — 요약에서 항목을 확인하세요.",noUsage:"아직 사용 보고가 없습니다.",noReports:"아직 현장 보고서가 없습니다.",lvlEmployee:"현장",lvlLead:"감독",lvlOwner:"소유주",labelPh:"역할 이름(예: 요리사)",newOrder:"새 주문",enableNotif:"🔔 알림 활성화",notifHint:"주문이 도착하면 주방 태블릿이 소리와 함께 깜박입니다.",tagline:"AI가 일하고 사람이 지키고, 결정하고, 검토합니다.",welcomeTitle:"Le Veilleux에 오신 것을 환영합니다 👁️",welcomeBody:"첫 라이브 흐름까지 3단계: 1) 직원 추가. 2) 업종 선택. 3) 실제 대화 진행 — AI가 제안하고 당신이 확인합니다.",wallNote:"30초마다 업데이트"},
316
+ ar:{login:"تسجيل الدخول",user:"المستخدم",password:"كلمة المرور",loginBtn:"دخول",loginHint:"الحسابات يديرها صاحب العمل.",loginFailed:"فشل تسجيل الدخول.",cannotReach:"تعذر الوصول إلى الخادم. هل هو قيد التشغيل؟",workerAdded:"تمت إضافة الموظف.",saved:"تم الحفظ.",reportSent:"تم إرسال التقرير.",feedbackSent:"تم إرسال الملاحظات.",wallOpen:"اللوحة المباشرة",logout:"خروج",overview:"نظرة عامة",field:"الميدان",rules:"القواعد",reports:"التقارير",week:"هذا الأسبوع",feedback:"الملاحظات",workersActive:"موظفون نشطون",reportsTotal:"إجمالي التقارير",workers:"الموظفون",thUser:"المستخدم",thRole:"الدور",addWorker:"إضافة موظف",userName:"اسم المستخدم",addBtn:"إضافة",usage:"الاستخدام والتكلفة",usageSub:"(لكل موظف، تقديري)",thWorker:"الموظف",thSessions:"الجلسات",thTokens:"الرموز",thCost:"التكلفة التقديرية",panel:"لوحة الإجراءات",panelNote:"يفتح الموظفون اللوحة من أجهزتهم.",openPanel:"فتح اللوحة",fieldReports:"تقارير الميدان",feedbackQueue:"قائمة الملاحظات",feedbackHint:"يقرأ الوكيل هذه القائمة ويحل المشكلات.",refresh:"تحديث",autoOn:"تلقائي: ON",autoOff:"تلقائي: OFF",rulesTitle:"قواعد العمل",rulesHint:"هذه القواعد تدرّب الإشارة الضوئية.",saveRules:"حفظ القواعد",listen:"🎙️ استمع",hi:"👋 ",reportTitle:"تقرير ميداني",reportPh:"ماذا حدث في نوبتك؟",sendReport:"إرسال",fbTitle:"ملاحظات ميدانية",fbPh:"ماذا حدث؟ ما الذي يجب تحسينه؟",sendFeedback:"إرسال",switchUser:"تبديل المستخدم",wallHead:"🏭 Le Veilleux — مباشر",wallPulse:"نبض الميدان",noActivity:"(لا نشاط بعد)",start:"▶ ابدأ",listening:"أستمع… تفضل بالحديث",listeningHint:"يتم التقاط المحادثة وتقسيمها حسب الأشخاص.",stopListening:"⏹ إيقاف",summaryTitle:"ملخص المحادثة",confirm:"تأكيد ✓",confirmed:"مؤكد ✓",sentNote:"أُرسل إلى المطبخ والنظام المركزي",newConv:"محادثة جديدة",ordersTitle:"الطلبات — المطبخ والحساب",person:"شخص",noSummary:"سيظهر الملخص هنا مع اكتشاف المحادثة.",prep:"قيد التحضير",ready:"جاهز",delivered:"تم التسليم",sent:"أُرسل",back:"رجوع",sayPh:"تحدث أو اكتب ما قاله كل شخص…",sendPhrase:"إرسال",dictate:"🎙️ إملاء",aiHint:"الصوت والنص يصلان مباشرة إلى الذكاء الاصطناعي — يظهر الملخص تلقائيًا.",micUnsupported:"الإملاء غير مدعوم",processing:"الذكاء الاصطناعي يلخّص…",sectorTab:"القطاع",sectorPresets:"القطاعات المحددة مسبقًا",customSector:"قطاع مخصص",saveSector:"حفظ القطاع",sectorSaved:"تم حفظ القطاع.",aiSuggest:"اقترح بالذكاء الاصطناعي (نسخ الموجه)",aiSectorCopied:"تم نسخ الموجه — الصقه في DeepSeek Harness.",fillBoth:"أدخل المستخدم وكلمة المرور.",loggingIn:"جارٍ الدخول…",noOrders:"لا توجد طلبات بعد — أكّد العناصر في الملخص.",noUsage:"لا يوجد استخدام مُبلّغ بعد.",noReports:"لا توجد تقارير ميدانية بعد.",lvlEmployee:"الميدان",lvlLead:"مشرف",lvlOwner:"المالك",labelPh:"مسمى الدور (مثال: طباخ)",newOrder:"طلب جديد",enableNotif:"🔔 تفعيل الإشعارات",notifHint:"يصدر صوت ويومض لوح المطبخ عند وصول طلب جديد.",tagline:"الذكاء الاصطناعي يعمل، والإنسان يراقب ويقرر ويراجع.",welcomeTitle:"مرحبًا بك في Le Veilleux 👁️",welcomeBody:"ثلاث خطوات لأول تدفق مباشر: 1) أضف العاملين. 2) اختر القطاع. 3) أجري محادثة حقيقية — الذكاء الاصطناعي يقترح وأنت تؤكد.",wallNote:"يتحدث كل 30 ثانية"}
285
317
  };
286
318
  function haptic(){try{if(navigator.vibrate)navigator.vibrate(25);}catch(e){}if(soundOn){try{const C=window.AudioContext||window.webkitAudioContext;if(!window.__ac)window.__ac=new C();const c=window.__ac;const o=c.createOscillator(),g=c.createGain();o.frequency.value=880;o.connect(g);g.connect(c.destination);g.gain.setValueAtTime(.12,c.currentTime);g.gain.exponentialRampToValueAtTime(.001,c.currentTime+.12);o.start();o.stop(c.currentTime+.12);}catch(e){}}}
287
319
  const $=id=>document.getElementById(id);
@@ -322,6 +354,8 @@ $("notifBtn").onclick=()=>{
322
354
  function panelLinks(){const u=me?encodeURIComponent(me.name):"",r=me?encodeURIComponent(me.role):"",lb=me?encodeURIComponent(me.label||me.name):"";$("openPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);$("leadOpenPanelLink").setAttribute("href","/panel?user="+u+"&role="+r+"&label="+lb+"&lang="+cur);}
323
355
  function applyLang(){
324
356
  try{localStorage.setItem("dsh-lang",cur);}catch(e){}
357
+ $("welcomeClose").onclick=()=>{$("welcomeCard").style.display="none";try{localStorage.setItem("lv-welcome","1");}catch(e){}};
358
+ $("welcomeTitle").textContent=t("welcomeTitle");$("welcomeBody").textContent=t("welcomeBody");$("wallNote").textContent=t("wallNote");
325
359
  $("loginTitle").textContent=t("login");$("tagline").textContent=t("tagline");$("loginUser").placeholder=t("user");
326
360
  ["loginUser","loginPass"].forEach(id=>$(id).addEventListener("input",()=>$("loginError").classList.add("hidden")));$("loginPass").placeholder=t("password");
327
361
  $("loginBtn").textContent=t("loginBtn");$("loginHint").textContent=t("loginHint");$("openWall").textContent=t("wallOpen");$("logoutBtn").textContent=t("logout");
@@ -340,7 +374,7 @@ function applyLang(){
340
374
  $("stopBtn").textContent=t("stopListening");$("summaryTitle").textContent=t("summaryTitle");$("newConvBtn").textContent=t("newConv");$("toHomeBtn").textContent=t("back");
341
375
  $("reportTitle").textContent=t("reportTitle");$("reportText").placeholder=t("reportPh");$("reportBtn").textContent=t("sendReport");
342
376
  $("fbTitle").textContent=t("fbTitle");$("empFbText").placeholder=t("fbPh");$("empFbBtn").textContent=t("sendFeedback");$("switchBtn").textContent=t("switchUser");
343
- $("wallHead").textContent=t("wallHead");$("wallPulseTitle").textContent=t("wallPulse");
377
+ $("wallPulseTitle").textContent=t("wallPulse");
344
378
  $("notifBtn").textContent=t("enableNotif");$("notifHint").textContent=t("notifHint");
345
379
  $("optEmployee").textContent=t("lvlEmployee");$("optLead").textContent=t("lvlLead");$("optOwner").textContent=t("lvlOwner");$("newLabel").placeholder=t("labelPh");
346
380
  $("tabSector").textContent=t("sectorTab");$("bnavOverview").textContent=t("overview");$("bnavField").textContent=t("field");$("bnavRules").textContent=t("rules");$("bnavSector").textContent=t("sectorTab");$("sectorPresetsTitle").textContent=t("sectorPresets");$("customSectorTitle").textContent=t("customSector");$("saveSectorBtn").textContent=t("saveSector");$("aiSectorBtn").textContent=t("aiSuggest");
@@ -442,7 +476,7 @@ $("toHomeBtn").onclick=async()=>{await api("/api/live/close",{});workerFlow();};
442
476
  async function enter(){
443
477
  if(!PACK){PACK=await api("/api/sector");applyPack();}
444
478
  setWho();
445
- if(me.role==="owner"){show("ownerView");loadMetrics($("ownerMetrics"));loadUsers();loadField();loadRules();loadUsage();renderOrders();loadPresets();}
479
+ if(me.role==="owner"){show("ownerView");try{if(!localStorage.getItem("lv-welcome"))$("welcomeCard").style.display="block";}catch(e){}loadMetrics($("ownerMetrics"));loadUsers();loadField();loadRules();loadUsage();renderOrders();loadPresets();}
446
480
  else if(me.role==="lead"){show("leadView");loadMetrics($("leadMetrics"));loadLead();renderOrders();if(kitchenPoll)clearInterval(kitchenPoll);kitchenPoll=setInterval(kitchenWatch,4000);}
447
481
  else{show("employeeView");$("workerHi").textContent=t("hi")+(me.label||me.name);workerFlow();if(livePoll)clearInterval(livePoll);livePoll=setInterval(()=>{if(me&&me.role==="employee")workerFlow();},3000);}
448
482
  }
@@ -502,9 +536,11 @@ $("empFbBtn").onclick=async()=>{const r=await api("/api/feedback",{worker:me.nam
502
536
  const st=sessionStorage.getItem("dsh-sup-token");
503
537
  if(st){token=st;me=JSON.parse(sessionStorage.getItem("dsh-sup-me")||"null");(async()=>{const r=await api("/api/me");if(!r||!r.name){logout();return;}enter();})();}
504
538
  else setWho();
505
- async function wallTick(){try{const r=await (await fetch("/api/wall")).json();const cards=[[t("week"),r.reportsWeek],[t("feedback"),r.feedback],[t("workersActive"),r.workers],[t("reportsTotal"),r.reports]];$("wallCards").innerHTML=cards.map(c=>'<div class="wall-card"><div class="v">'+(c[1]===undefined?"–":c[1])+'</div><div class="l">'+c[0]+'</div></div>').join("");$("wallFeed").textContent=r.feedbackTail||t("noActivity");}catch(e){$("wallFeed").textContent=t("cannotReach");}}
539
+ async function wallTick(){try{const r=await (await fetch("/api/wall")).json();const cards=[[t("week"),r.reportsWeek],[t("ordersTitle"),r.orders],[t("feedback"),r.feedback],[t("workersActive"),r.workers],[t("reportsTotal"),r.reports]];$("wallCards").innerHTML=cards.map(c=>'<div class="wall-card"><div class="v">'+(c[1]===undefined?"–":c[1])+'</div><div class="l">'+c[0]+'</div></div>').join("");const ticks=[...(r.ordersTail||[]).map(x=>"🔔 "+x),...(r.feedbackTail||"").split("\n").filter(Boolean).slice(-4)];$("wallFeed").innerHTML=ticks.length?ticks.map(x=>'<div class="tick">'+x+'</div>').join(""):'<div class="tick dim">'+t("noActivity")+'</div>';try{const s=await (await fetch("/api/sector")).json();$("wallSector").textContent=(s&&s.id)?s.id:"";}catch(e){}}catch(e){$("wallFeed").innerHTML='<div class="tick dim">'+t("cannotReach")+'</div>';}}
540
+ function clockTick(){const d=new Date();$("wallClock").textContent=d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});$("wallDate").textContent=d.toLocaleDateString([],{weekday:"short",day:"numeric",month:"short"});}
506
541
  if(location.search.indexOf("wall=1")>=0){
507
542
  document.body.classList.add("wall");show("wallView");
543
+ clockTick();setInterval(clockTick,1000);
508
544
  wallTick();setInterval(wallTick,30000);
509
545
  }
510
546
  </script>
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@javierfrancoleal/dsh-supervisor",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "The Veilleux central control plane of the J.Franco agentic workflow suite: user accounts, the live conversation flow (listen → per-person summary → confirm → orders), telemetry, and the universal sector dashboard with 10 languages. Created by J.Franco.",
5
5
  "author": "J.Franco",
6
6
  "license": "MIT",
package/panel.html CHANGED
@@ -9,7 +9,7 @@
9
9
  <link rel="manifest" href="manifest.webmanifest">
10
10
  <link rel="apple-touch-icon" href="icons/apple-icon-180.png">
11
11
  <title>Le Veilleux — Action Panel</title>
12
- <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%234D6BFE'/%3E%3Cpath d='M32 16 C 15 16, 8.5 25.5, 8.5 32 C 8.5 38.5, 15 48, 32 48 C 49 48, 55.5 38.5, 55.5 32 C 55.5 25.5, 49 16, 32 16 Z' fill='none' stroke='%23fff' stroke-width='4.5'/%3E%3Cpath d='M32 23.5 C 36.6 28.2, 38.6 31.4, 38.6 34.8 A 6.6 6.6 0 1 1 25.4 34.8 C 25.4 31.4, 27.4 28.2, 32 23.5 Z' fill='%23FACC15'/%3E%3C/svg%3E">
12
+ <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cdefs%3E%3ClinearGradient id='f' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%234D6BFE'/%3E%3Cstop offset='1' stop-color='%237c5cff'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M10 32 C10 22 16 14 32 14 C48 14 54 22 54 32 C54 42 48 50 32 50 C20 50 12.5 45.2 10.5 38.5 C14 42.5 20 41 25.4 34.8 A6.6 6.6 0 0 1 38.6 34.8 C38.6 31.4 36.6 28.2 32 22.5 C27.4 28.2 25.4 31.4 25.4 34.8' fill='none' stroke='url(%23f)' stroke-width='6' stroke-linecap='round'/%3E%3C/svg%3E">
13
13
  <style>
14
14
  :root{--blue:#4D6BFE;--ink:#101828;--muted:#667085;--bg:#f6f7fb;--card:#fff;--line:#e3e6ee;--line2:#eef0f7;--ok:#22c55e;--bad:#ef4444}
15
15
  body.dark{--ink:#e6ecf7;--muted:#94a3b8;--bg:#0b1220;--card:#141f31;--line:#26334d;--line2:#26334d}
@@ -57,7 +57,7 @@ code{background:var(--line2);border-radius:6px;padding:2px 6px;font-size:13px}
57
57
  </head>
58
58
  <body>
59
59
  <header>
60
- <div class="logo"><svg width="26" height="26" viewBox="0 0 64 64" aria-hidden="true"><path d="M10 33c6.5-11 13-16 22-16s15.5 5 22 16c-6.5 11-13 16-22 16S16.5 44 10 33z" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/><path d="M32 24c4.2 4.2 6.2 7.4 6.2 10.4a6.2 6.2 0 1 1-12.4 0c0-3 2-6.2 6.2-10.4z" fill="#FACC15"/></svg></div>
60
+ <div class="logo"><svg width="30" height="26" viewBox="0 0 64 64" aria-hidden="true"><path d="M10 32 C10 22 16 14 32 14 C48 14 54 22 54 32 C54 42 48 50 32 50 C20 50 12.5 45.2 10.5 38.5 C14 42.5 20 41 25.4 34.8 A6.6 6.6 0 0 1 38.6 34.8 C38.6 31.4 36.6 28.2 32 22.5 C27.4 28.2 25.4 31.4 25.4 34.8" fill="none" stroke="#ffffff" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
61
61
  <div class="ht">
62
62
  <h1 id="title">DSH Assistant — Action Panel</h1>
63
63
  <p id="subtitle">J.Franco · DeepSeek Harness · Québec 🍁</p>
package/server.js CHANGED
@@ -283,7 +283,8 @@ async function api(req, res, pathname) {
283
283
  // Public wallboard feed: aggregated numbers only, no secrets.
284
284
  if (pathname === "/api/wall" && req.method === "GET") {
285
285
  const m = metrics();
286
- return send(res, 200, { ...m, feedbackTail: readFeedback(60) });
286
+ const lv = liveRead();
287
+ return send(res, 200, { ...m, orders: (lv.orders || []).length, ordersTail: (lv.orders || []).slice(-3).map((o) => (o.table ? "M" + o.table + " · " : "") + o.person + " — " + o.request), feedbackTail: readFeedback(60) });
287
288
  }
288
289
  // Live conversation flow: worker screens, per-person summary, orders to
289
290
  // the kitchen and the central system (the supervisor itself).