<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title | default(value="Backup codes") }}</title>
<script>window.tailwind = { config: { darkMode: 'class' } };</script>
<script src="{{ tailwind_src | safe }}"></script>
<script>
(function () {
try {
var stored = localStorage.getItem('adminx-theme');
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if ((stored || (prefersDark ? 'dark' : 'light')) === 'dark') document.documentElement.classList.add('dark');
} catch (_) {}
})();
</script>
</head>
<body class="h-full bg-slate-50 text-slate-900 dark:bg-slate-950 dark:text-slate-100 selection:bg-indigo-200/50 dark:selection:bg-indigo-400/30">
<div class="flex items-center justify-center min-h-screen px-4 py-10">
<div class="bg-white dark:bg-gray-800 p-8 rounded-xl shadow-lg w-full max-w-md border border-gray-200 dark:border-gray-700">
<div class="text-center mb-8">
<div class="mx-auto w-16 h-16 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-full flex items-center justify-center mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">Two-factor auth enabled</h2>
<p class="text-gray-600 dark:text-gray-400 mt-2">
Save these one-time backup codes somewhere safe. Each works once if you lose your authenticator.
<span class="font-semibold text-gray-800 dark:text-gray-200">They won't be shown again.</span>
</p>
</div>
<div id="codes" class="grid grid-cols-2 gap-2 mb-4">
{% for code in backup_codes %}
<code class="backup-code text-center bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg px-3 py-2 text-sm text-gray-800 dark:text-gray-200 tracking-widest">{{ code }}</code>
{% endfor %}
</div>
<div class="flex gap-3 mb-6">
<button type="button" id="copy-btn"
class="flex-1 flex justify-center items-center gap-2 py-2.5 px-4 rounded-lg text-sm font-medium border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
Copy
</button>
<button type="button" id="download-btn"
class="flex-1 flex justify-center items-center gap-2 py-2.5 px-4 rounded-lg text-sm font-medium border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
Download
</button>
</div>
<a href="{{ mount | safe }}"
class="w-full flex justify-center items-center py-3 px-4 rounded-lg shadow-sm text-sm font-medium text-white bg-gradient-to-r from-indigo-600 to-fuchsia-600 hover:from-indigo-700 hover:to-fuchsia-700 transition-all duration-200">
I've saved them — continue
</a>
</div>
</div>
<script>
(function () {
var codes = Array.prototype.map.call(
document.querySelectorAll('.backup-code'),
function (el) { return el.textContent.trim(); }
);
var text = codes.join('\n') + '\n';
var copyBtn = document.getElementById('copy-btn');
copyBtn.addEventListener('click', function () {
var done = function () {
var original = copyBtn.innerHTML;
copyBtn.textContent = 'Copied!';
setTimeout(function () { copyBtn.innerHTML = original; }, 1500);
};
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(done, fallbackCopy);
} else { fallbackCopy(); }
function fallbackCopy() {
var ta = document.createElement('textarea');
ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.select();
try { document.execCommand('copy'); done(); } catch (e) {}
document.body.removeChild(ta);
}
});
document.getElementById('download-btn').addEventListener('click', function () {
var blob = new Blob([text], { type: 'text/plain' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url; a.download = 'adminx-backup-codes.txt';
document.body.appendChild(a); a.click(); document.body.removeChild(a);
URL.revokeObjectURL(url);
});
})();
</script>
</body>
</html>