setChangingPassword(false)} width={420} height={380}>
diff --git a/frontend/src/pages/Contrasenas/ContrasenasPage.jsx b/frontend/src/pages/Contrasenas/ContrasenasPage.jsx
index 38f6f0e..b398ee4 100644
--- a/frontend/src/pages/Contrasenas/ContrasenasPage.jsx
+++ b/frontend/src/pages/Contrasenas/ContrasenasPage.jsx
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
+import { createPortal } from 'react-dom';
import {
Plus, ChevronUp, ChevronLeft, Trash2, Eye, EyeOff, Copy, Pencil, Save, X, RefreshCw, ShieldAlert,
MoreVertical, Mail, Globe, Server, Database, Cloud, Shield, Lock, Wifi, CreditCard, Building2, Printer,
@@ -76,6 +77,9 @@ export default function ContrasenasPage() {
const navigate = useNavigate();
const [locked, setLocked] = useState(true);
+ // Hueco de la barra inferior donde se muestra la cuenta regresiva (solo mientras esta desbloqueado).
+ const [footSlot, setFootSlot] = useState(null);
+ useEffect(() => { setFootSlot(document.getElementById('footbar-slot')); }, []);
const [checking, setChecking] = useState(true);
const [hasPinSet, setHasPinSet] = useState(null);
const [entries, setEntries] = useState(null);
@@ -152,8 +156,8 @@ export default function ContrasenasPage() {
useEffect(() => () => setVaultToken(null), []);
// Cierre por inactividad (3 min sin teclado/clic/toque/rueda): lo cuenta , que
- // muestra el tiempo restante junto al titulo y reinicia con cada accion del usuario, asi que
- // nunca lo saca en medio de escribir/editar una credencial.
+ // se muestra en la barra inferior (a la derecha) mientras esta desbloqueado y se reinicia con cada
+ // accion del usuario, asi que nunca lo saca en medio de escribir/editar una credencial.
function autoLockExit() {
pushToast({ tone: 'warning', message: t('vault_auto_lock_notice') });
navigate('/');
@@ -430,9 +434,9 @@ export default function ContrasenasPage() {
return (
+ {footSlot && createPortal(, footSlot)}
{t('nav_passwords')}
-
diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css
index 9bc8907..f314835 100644
--- a/frontend/src/styles/app.css
+++ b/frontend/src/styles/app.css
@@ -104,12 +104,19 @@ button { font-family: inherit; }
.content-column { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.topbar {
- height: 84px; flex: none; display: flex; align-items: center; justify-content: space-between;
+ height: 42px; flex: none; display: flex; align-items: center; justify-content: space-between;
padding: 0 16px; border-bottom: 1px solid rgb(var(--line)); background: rgb(var(--surface));
gap: 12px;
}
.topbar-left { display: flex; align-items: center; gap: 10px; }
.topbar-right { display: flex; align-items: center; gap: 10px; }
+/* Barra inferior fija: hermana del .content-area dentro de la columna flex (no flota encima), asi el
+ contenido hace scroll SOLO en el espacio que queda y nunca queda detras de ella. No toca el sidebar. */
+.footbar {
+ height: 28px; flex: none; display: flex; align-items: center; justify-content: space-between;
+ padding: 0 16px; border-top: 1px solid rgb(var(--line)); background: rgb(var(--surface));
+ font-size: .72rem; color: rgb(var(--muted));
+}
.page-title { font-size: 1.05rem; font-weight: 700; }
.content-area { flex: 1; overflow-y: auto; padding: 20px; }