diff --git a/controller/README.md b/controller/README.md
index bc05af8..9edb3b1 100644
--- a/controller/README.md
+++ b/controller/README.md
@@ -119,9 +119,13 @@ backups, monitoring and notifications. All Proxmox/disk operations are delegated
**unified drive view**: server-rendered registry cards enriched in place from the agent `/api/disks`
(role/durable-id/actions, joined on mount path), plus read-only **Rendszermeghajtók** and
**Nem regisztrált meghajtók** groups; agent-down degrades to a single warn note. Consequential
- actions use an in-page `.confirm-overlay` (`openDialog`), never native `confirm()`/`prompt()`.
+ actions use an in-page `.confirm-overlay` (`openDialog`) or the LIGHT inline two-step
+ (`felhomConfirm` in layout.html, v0.123.0: the trigger swaps in place to "kérdés + Igen/Mégse";
+ form buttons opt in via `data-confirm="…"`) — never native `confirm()`/`prompt()` (OS-modals
+ freeze browser automation; drill F-11).
**Enforcement:** `scripts/template_id_gate.py` (JS element-ID integrity) + `scripts/emoji_gate.py`
- (no emoji — run after any template change; the Go `TestNoEmojiInTemplates` mirrors it).
+ (no emoji) + `scripts/native_confirm_gate.py` (zero native confirm/prompt) — run after any
+ template change; the Go `TestNoEmojiInTemplates` mirrors the emoji gate.
- **Europe/Budapest timezone** — All scheduled jobs, timestamps, and UI labels use Hungarian timezone.
### Module Map
diff --git a/controller/internal/web/templates/app_info.html b/controller/internal/web/templates/app_info.html
index 9c7341c..fc2a463 100644
--- a/controller/internal/web/templates/app_info.html
+++ b/controller/internal/web/templates/app_info.html
@@ -71,7 +71,7 @@
{{range .MigrateTargets}}{{end}}
-
+
@@ -98,14 +98,15 @@ function appMigWatch(){
}
tick();
}
-function appMigrate(app,label){
+function appMigrate(btn,app,label){
var sel=document.getElementById('app-migrate-target');
var target=sel?sel.value:'';
if(!target){ alert('Válassz céltárhelyet.'); return; }
- if(!confirm('Áthelyezed a(z) '+label+' adatait ide: '+target+'?\n\nAz alkalmazás rövid időre leáll. A régi adatok csak sikeres áthelyezés után törlődnek.')) return;
- fetch('/api/storage/migrate-app',{method:'POST',headers:Object.assign({'Content-Type':'application/json'},csrfHeaders()),body:JSON.stringify({app:app,target:target})})
- .then(function(r){return r.json();}).then(function(d){ if(d.ok){ appMigWatch(); } else { alert('Hiba: '+(d.error||'ismeretlen')); } })
- .catch(function(e){ alert('Hiba: '+e); });
+ felhomConfirm(btn,'Áthelyezed a(z) '+label+' adatait ide: '+target+'? Az alkalmazás rövid időre leáll. A régi adatok csak sikeres áthelyezés után törlődnek.',function(){
+ fetch('/api/storage/migrate-app',{method:'POST',headers:Object.assign({'Content-Type':'application/json'},csrfHeaders()),body:JSON.stringify({app:app,target:target})})
+ .then(function(r){return r.json();}).then(function(d){ if(d.ok){ appMigWatch(); } else { alert('Hiba: '+(d.error||'ismeretlen')); } })
+ .catch(function(e){ alert('Hiba: '+e); });
+ });
}
(function(){ fetch('/api/storage/migrate/status').then(function(r){return r.json();}).then(function(d){ if(d.data&&d.data.job){ appMigWatch(); } }).catch(function(){}); })();
diff --git a/controller/internal/web/templates/backups.html b/controller/internal/web/templates/backups.html
index c5b0b31..860264d 100644
--- a/controller/internal/web/templates/backups.html
+++ b/controller/internal/web/templates/backups.html
@@ -182,9 +182,9 @@
{{if .Enabled}}
-
{{end}}
@@ -469,9 +469,9 @@
{{if .Tier2LastRun}}
-
{{end}}
Beállítás
@@ -673,19 +673,20 @@ function startBackupPolling() {
// Whole-guest (appliance) backup — manual trigger via the quiesce loop (controller-owned quiesce:
// stop stacks → agent vzdump → resume). Returns immediately; we poll /api/guest-backup/status.
function triggerGuestBackup() {
- if (!confirm('Elindítja a teljes rendszermentést most? A mentés ideje alatt az alkalmazások rövid időre leállhatnak.')) return;
var btn = document.getElementById('wg-backup-btn');
- var out = document.getElementById('wg-backup-result');
- btn.disabled = true;
- out.innerHTML = 'Mentés indítása…';
- fetch('/api/guest-backup/trigger', { method: 'POST', headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()) })
- .then(r => r.json())
- .then(data => {
- if (!data.ok) { out.innerHTML = '