04/18 fix web app responsive 3

This commit is contained in:
2026-04-18 21:00:19 -04:00
parent ab441ae289
commit 381d35be29
4 changed files with 823 additions and 85 deletions
+87 -65
View File
@@ -154,6 +154,14 @@ ul {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(208, 2, 27, 0.12);
}
/* Prevent iOS viewport auto-zoom on input focus (requires font-size >= 16px) */
@media (max-width: 768px) {
.form-group input,
.form-group select,
.form-group textarea {
font-size: 16px;
}
}
.input-with-toggle {
position: relative;
@@ -305,12 +313,13 @@ ul {
/* ── App layout (vault) ──────────────────────────────────────────── */
.vault-page {
height: 100vh;
height: 100dvh;
overflow: hidden;
}
.app-layout {
display: flex;
height: 100vh;
height: 100%;
}
/* ── Sidebar ─────────────────────────────────────────────────────── */
@@ -402,6 +411,7 @@ ul {
flex: 1;
padding: 8px 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.sidebar-section-header {
@@ -623,6 +633,8 @@ ul {
font-size: 18px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.vault-toolbar {
@@ -683,6 +695,7 @@ ul {
flex: 1;
overflow-y: auto;
padding: 12px 24px 24px;
-webkit-overflow-scrolling: touch;
}
/* Content max-width — keeps items readable on very wide screens */
@@ -763,8 +776,8 @@ ul {
}
.btn-icon {
width: 30px;
height: 30px;
width: 36px;
height: 36px;
border-radius: 6px;
display: flex;
align-items: center;
@@ -774,11 +787,19 @@ ul {
transition:
background var(--transition),
color var(--transition);
/* Expand touch target without changing visual size */
touch-action: manipulation;
}
.btn-icon:hover {
background: var(--color-bg);
color: var(--color-text);
}
@media (max-width: 768px) {
.btn-icon {
min-width: 44px;
min-height: 44px;
}
}
/* ── Spinner ─────────────────────────────────────────────────────── */
.spinner-overlay {
@@ -829,7 +850,9 @@ ul {
width: 100%;
max-width: 480px;
max-height: 90vh;
max-height: 90dvh;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: 28px;
}
@@ -932,6 +955,7 @@ ul {
flex: 1;
overflow-y: auto;
padding: 20px 24px;
-webkit-overflow-scrolling: touch;
}
/* ── Tabs ────────────────────────────────────────────────────────── */
@@ -1105,6 +1129,7 @@ ul {
display: flex;
flex-direction: column;
gap: 24px;
-webkit-overflow-scrolling: touch;
}
.sec-notice {
@@ -1416,7 +1441,7 @@ ul {
flex-shrink: 0;
}
/* Sidebar backdrop — only active on mobile */
/* Sidebar backdrop */
.sidebar-backdrop {
display: none;
position: fixed;
@@ -1428,44 +1453,47 @@ ul {
display: block;
}
/* ── Phone (≤ 640px) ─────────────────────────────────────────────── */
@media (max-width: 640px) {
/* Layout: stack topbar above main, no sidebar space in flow */
/* ── Phone + iPad portrait (≤ 768px) ───────────────────────────── */
@media (max-width: 768px) {
.app-layout {
flex-direction: column;
height: 100vh;
height: 100%;
min-height: 100dvh;
overflow: hidden;
}
/* Topbar always visible */
.mobile-topbar {
display: flex;
}
/* Sidebar slides in from the left as an overlay */
/* Sidebar: completely out of layout flow — fixed overlay only */
.sidebar {
position: fixed;
display: none !important;
position: fixed !important;
top: 0;
left: 0;
bottom: 0;
width: 260px !important; /* always full-width on mobile regardless of collapsed state */
width: 280px !important;
z-index: 90;
transform: translateX(-100%);
transition: transform 0.25s ease;
overflow-y: auto;
transition: none;
}
.sidebar.mobile-open {
transform: translateX(0);
display: flex !important;
flex-direction: column;
}
/* Show all labels inside the mobile overlay sidebar */
/* Mobile sidebar: always show full expanded state */
.sidebar .sidebar-label {
opacity: 1 !important;
max-width: none !important;
overflow: visible !important;
}
.sidebar .sidebar-section-header {
opacity: 1 !important;
height: auto !important;
padding: 12px 16px 4px !important;
pointer-events: auto !important;
}
.sidebar .sidebar-item {
justify-content: flex-start !important;
@@ -1475,18 +1503,27 @@ ul {
.sidebar .sidebar-item::after {
display: none !important;
}
/* Hide desktop collapse toggle on mobile */
.sidebar .sidebar-header {
justify-content: flex-start !important;
padding: 14px 12px !important;
overflow: hidden !important;
}
.sidebar .sidebar-header .logo-icon,
.sidebar .sidebar-header .logo-text {
opacity: 1 !important;
width: auto !important;
pointer-events: auto !important;
}
.btn-sidebar-toggle {
display: none;
display: none !important;
}
/* Main area fills everything below topbar */
.vault-main {
flex: 1;
overflow: hidden;
min-height: 0;
}
/* Tighter padding */
.vault-header {
padding: 12px 16px;
gap: 8px;
@@ -1496,7 +1533,7 @@ ul {
}
.vault-list {
padding: 8px 12px 80px;
} /* bottom pad for mobile FAB */
}
.panel-body {
padding: 16px;
}
@@ -1505,7 +1542,6 @@ ul {
gap: 16px;
}
/* Search takes full width, hide sort */
.vault-toolbar {
gap: 8px;
}
@@ -1516,33 +1552,40 @@ ul {
display: none;
}
/* FAB in header is hidden on mobile (use topbar FAB) */
.vault-header .btn-fab {
display: none;
}
/* Forms */
.form-row {
flex-direction: column;
gap: 0;
}
.modal {
padding: 20px;
}
.modal-actions {
flex-wrap: wrap;
}
/* Security stats wrap */
.modal-overlay {
padding: 0;
align-items: flex-end;
}
.modal {
max-width: 100% !important;
max-height: 92dvh;
border-radius: 16px 16px 0 0;
padding: 20px 16px;
}
.security-summary {
padding: 16px;
gap: 12px;
flex-wrap: wrap;
}
.sec-score {
font-size: 40px;
}
.sec-stats {
gap: 8px;
flex-wrap: wrap;
}
.sec-stat {
padding: 8px 12px;
@@ -1552,25 +1595,6 @@ ul {
font-size: 22px;
}
/* Modal: full-screen on phones */
.modal-overlay {
padding: 0;
align-items: flex-end;
}
.modal {
max-width: 100%;
max-height: 92vh;
border-radius: 16px 16px 0 0;
padding: 20px 16px;
}
.modal-settings {
max-width: 100%;
}
.modal-item {
max-width: 100%;
}
/* Detail label stacks above value on small screens */
.detail-field {
flex-direction: column;
gap: 4px;
@@ -1580,14 +1604,11 @@ ul {
}
}
/* ── Tablet (641px 1024px) ─────────────────────────────────────── */
@media (min-width: 641px) and (max-width: 1024px) {
/* Sidebar always shows as icon rail on tablet — user can expand with toggle */
/* ── iPad landscape / small laptop (769px 1024px) ─────────────── */
@media (min-width: 769px) and (max-width: 1024px) {
.sidebar:not(.collapsed) {
width: 200px;
}
/* Slightly tighter padding */
.vault-header {
padding: 14px 18px;
}
@@ -1601,13 +1622,9 @@ ul {
padding: 16px;
gap: 16px;
}
/* Search a bit narrower */
.search-wrapper {
max-width: 280px;
}
/* Security stats wrap gracefully */
.security-summary {
flex-wrap: wrap;
gap: 12px;
@@ -1616,13 +1633,6 @@ ul {
flex-wrap: wrap;
gap: 10px;
}
/* Form rows stay side-by-side */
.form-row {
flex-direction: row;
}
/* Modal fits tablet width */
.modal {
max-width: 460px;
}
@@ -1630,7 +1640,6 @@ ul {
/* ── Laptop (1025px 1440px) ───────────────────────────────────── */
@media (min-width: 1025px) and (max-width: 1440px) {
/* Full sidebar, comfortable padding */
.vault-header {
padding: 16px 24px;
}
@@ -1644,7 +1653,6 @@ ul {
/* ── Large PC (> 1440px) ────────────────────────────────────────── */
@media (min-width: 1441px) {
/* Wider sidebar, more generous spacing */
.sidebar:not(.collapsed) {
width: 260px;
}
@@ -1678,6 +1686,20 @@ ul {
}
}
/* ── Auth pages — phone ──────────────────────────────────────────── */
@media (max-width: 480px) {
.auth-container {
padding: 12px;
}
.auth-card {
padding: 28px 20px;
border-radius: 12px;
}
.auth-title {
font-size: 20px;
}
}
/* ── Settings — new sections (Phase 6) ──────────────────────────── */
.settings-section-danger {
border-top: 2px solid var(--color-danger, #e53e3e);
+26 -4
View File
@@ -2648,24 +2648,46 @@ const Vault = (() => {
// Mobile sidebar: hamburger opens overlay, backdrop/item-click closes it
const backdrop = document.getElementById("sidebar-backdrop");
const mobileMenuBtn = document.getElementById("btn-mobile-menu");
const mobileQuery = window.matchMedia("(max-width: 768px)");
function openMobileSidebar() {
sidebar?.classList.add("mobile-open");
backdrop?.classList.add("open");
document.body.style.overflow = "hidden";
// iOS Safari: lock scroll on <html>, not <body>
document.documentElement.style.overflow = "hidden";
}
function closeMobileSidebar() {
sidebar?.classList.remove("mobile-open");
backdrop?.classList.remove("open");
document.body.style.overflow = "";
document.documentElement.style.overflow = "";
}
mobileMenuBtn?.addEventListener("click", openMobileSidebar);
// Both click and touchstart for responsive feel on iOS
backdrop?.addEventListener("click", closeMobileSidebar);
// Close mobile sidebar whenever a nav item is clicked
backdrop?.addEventListener("touchstart", closeMobileSidebar, {
passive: true,
});
// Close mobile sidebar whenever a nav item is clicked (mobile only)
document.querySelectorAll(".sidebar-item").forEach((item) => {
item.addEventListener("click", () => {
if (window.innerWidth <= 640) closeMobileSidebar();
if (mobileQuery.matches) closeMobileSidebar();
});
});
// Close on Escape key
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && sidebar?.classList.contains("mobile-open")) {
closeMobileSidebar();
}
});
// Ensure sidebar is closed and scroll unlocked when switching to desktop
mobileQuery.addEventListener("change", (e) => {
if (!e.matches) closeMobileSidebar();
});
// Mobile FAB mirrors the desktop add-item button
document
.getElementById("btn-add-item-mobile")