Files
PassKeeper/app/static/css/app.css
T
2026-04-18 15:04:42 -04:00

1707 lines
34 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── Reset & base ──────────────────────────────────────────────────── */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--color-bg: #f4f5f7;
--color-surface: #ffffff;
--color-primary: #d0021b;
--color-primary-dark: #a80016;
--color-text: #1a1a2e;
--color-text-muted: #6b7280;
--color-border: #e2e4e9;
--color-sidebar-bg: #1e2235;
--color-sidebar-text: #c8ccd8;
--color-sidebar-hover: #2d3250;
--color-sidebar-active: #d0021b;
--radius: 8px;
--shadow: 0 1px 4px rgba(0, 0, 0, 0.08), 0 2px 12px rgba(0, 0, 0, 0.05);
--transition: 150ms ease;
}
html,
body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
color: var(--color-text);
background: var(--color-bg);
}
a {
color: var(--color-primary);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
button {
cursor: pointer;
font: inherit;
border: none;
background: none;
}
input,
select,
textarea {
font: inherit;
}
ul {
list-style: none;
}
/* ── Utilities ───────────────────────────────────────────────────── */
.hidden {
display: none !important;
}
/* ── Auth pages ──────────────────────────────────────────────────── */
.auth-page {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: var(--color-bg);
}
.auth-container {
width: 100%;
max-width: 420px;
padding: 16px;
}
.auth-card {
background: var(--color-surface);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 40px 36px;
}
@media (max-width: 480px) {
.auth-container {
padding: 12px;
}
.auth-card {
padding: 28px 20px;
border-radius: 12px;
}
.auth-title {
font-size: 20px;
}
}
.auth-logo {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 28px;
}
.auth-logo .logo-icon {
font-size: 28px;
}
.auth-logo .logo-text {
font-size: 20px;
font-weight: 700;
color: var(--color-text);
}
.auth-title {
font-size: 22px;
font-weight: 600;
margin-bottom: 24px;
}
.auth-footer {
margin-top: 20px;
text-align: center;
color: var(--color-text-muted);
}
/* ── Form elements ──────────────────────────────────────────────── */
.form-group {
margin-bottom: 16px;
}
.form-group label {
display: block;
margin-bottom: 6px;
font-weight: 500;
color: var(--color-text);
}
.form-group label .hint {
font-weight: 400;
color: var(--color-text-muted);
font-size: 12px;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 9px 12px;
border: 1px solid var(--color-border);
border-radius: var(--radius);
background: var(--color-surface);
color: var(--color-text);
transition: border-color var(--transition);
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(208, 2, 27, 0.12);
}
.input-with-toggle {
position: relative;
}
.input-with-toggle input {
padding-right: 40px;
}
.btn-show-pass {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
font-size: 16px;
opacity: 0.6;
transition: opacity var(--transition);
}
.btn-show-pass:hover {
opacity: 1;
}
.form-error {
color: #c00;
background: #fff0f0;
border: 1px solid #fcc;
border-radius: var(--radius);
padding: 8px 12px;
margin-bottom: 12px;
font-size: 13px;
}
/* Buttons */
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--color-primary);
color: #fff;
padding: 10px 20px;
border-radius: var(--radius);
font-weight: 600;
transition: background var(--transition);
}
.btn-primary:hover {
background: var(--color-primary-dark);
}
.btn-primary:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.btn-full {
width: 100%;
}
.btn-secondary {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--color-border);
color: var(--color-text);
padding: 10px 20px;
border-radius: var(--radius);
font-weight: 500;
transition: background var(--transition);
}
.btn-secondary:hover {
background: #d1d5dc;
}
.btn-text {
background: none;
border: none;
color: inherit;
padding: 0;
}
/* Notices */
.notice-success {
background: #e8f5e9;
border: 1px solid #a5d6a7;
color: #2e7d32;
border-radius: var(--radius);
padding: 10px 14px;
margin-bottom: 16px;
font-size: 13px;
}
.notice-info {
background: #e3f2fd;
border: 1px solid #90caf9;
color: #1565c0;
border-radius: var(--radius);
padding: 10px 14px;
margin-bottom: 16px;
font-size: 13px;
}
/* ── Password Generator modal ────────────────────────────────────────── */
.gen-opt {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
font-size: 13px;
}
.gen-opt input[type="checkbox"] {
width: 15px;
height: 15px;
accent-color: var(--color-primary);
cursor: pointer;
}
#gen-output {
letter-spacing: 0.5px;
font-family: "Courier New", monospace;
}
/* Launch (open URL) button — distinct colour so it reads as navigation */
.btn-icon[data-action="launch"] {
color: #1a73e8;
}
.btn-icon[data-action="launch"]:hover {
background: #e8f0fe;
color: #1558b0;
}
/* Password strength */
.password-strength {
margin-top: 6px;
font-size: 12px;
font-weight: 500;
}
.strength-1 {
color: #c62828;
}
.strength-2 {
color: #e65100;
}
.strength-3 {
color: #f57f17;
}
.strength-4 {
color: #2e7d32;
}
.strength-5 {
color: #1b5e20;
}
/* ── App layout (vault) ──────────────────────────────────────────── */
.vault-page {
height: 100vh;
overflow: hidden;
}
.app-layout {
display: flex;
height: 100vh;
}
/* ── Sidebar ─────────────────────────────────────────────────────── */
.sidebar {
width: 240px;
flex-shrink: 0;
background: var(--color-sidebar-bg);
color: var(--color-sidebar-text);
display: flex;
flex-direction: column;
overflow: hidden;
transition: width 0.22s ease;
}
.sidebar.collapsed {
width: 72px;
}
/* Sidebar must not clip its children when collapsed — tooltips need to escape */
.sidebar.collapsed .sidebar-nav,
.sidebar.collapsed .sidebar-footer {
overflow: visible;
}
.sidebar-header {
display: flex;
align-items: center;
gap: 8px;
padding: 14px 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
flex-shrink: 0;
min-height: 56px;
overflow: hidden;
}
/* When collapsed: centre the toggle button, hide everything else */
.sidebar.collapsed .sidebar-header {
justify-content: center;
padding: 14px 0;
overflow: visible;
}
.sidebar-header .logo-icon {
font-size: 22px;
flex-shrink: 0;
transition: opacity 0.15s ease;
}
.sidebar-header .logo-text {
font-size: 16px;
font-weight: 700;
color: #fff;
flex: 1;
white-space: nowrap;
overflow: hidden;
transition: opacity 0.15s ease;
}
.sidebar.collapsed .sidebar-header .logo-icon,
.sidebar.collapsed .sidebar-header .logo-text {
opacity: 0;
width: 0;
pointer-events: none;
}
/* Toggle button — always visible, always clickable */
.btn-sidebar-toggle {
background: none;
border: none;
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
cursor: pointer;
padding: 6px 8px;
border-radius: 4px;
line-height: 1;
flex-shrink: 0;
transition:
color var(--transition),
transform 0.22s ease;
margin-left: auto;
z-index: 10;
}
.btn-sidebar-toggle:hover {
color: #fff;
background: rgba(255, 255, 255, 0.12);
}
.sidebar.collapsed .btn-sidebar-toggle {
transform: rotate(180deg);
margin-left: 0;
}
.sidebar-nav {
flex: 1;
padding: 8px 0;
overflow-y: auto;
}
.sidebar-section-header {
padding: 12px 16px 4px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.35);
white-space: nowrap;
overflow: hidden;
transition: opacity 0.15s ease;
}
.sidebar.collapsed .sidebar-section-header {
opacity: 0;
pointer-events: none;
height: 0;
padding: 0;
}
.sidebar-item {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 16px;
border-radius: 0;
color: var(--color-sidebar-text);
cursor: pointer;
transition: background var(--transition);
font-size: 14px;
width: 100%;
text-align: left;
position: relative;
white-space: nowrap;
overflow: hidden;
}
.sidebar-item:hover {
background: var(--color-sidebar-hover);
}
.sidebar-item.active {
background: var(--color-sidebar-active);
color: #fff;
}
.sidebar-icon {
font-size: 20px;
flex-shrink: 0;
width: 22px;
text-align: center;
}
/* Labels — fade out when collapsed; use max-width so icon stays visible */
.sidebar-label {
transition:
opacity 0.15s ease,
max-width 0.22s ease;
max-width: 200px;
overflow: hidden;
}
.sidebar.collapsed .sidebar-label {
opacity: 0;
max-width: 0;
}
.sidebar.collapsed .sidebar-item {
justify-content: center;
padding: 10px 0;
overflow: visible;
}
/* Tooltip — appears to the right of the 72px rail */
.sidebar.collapsed .sidebar-item::after {
content: attr(data-tooltip);
position: fixed;
left: 80px;
background: #111827;
color: #fff;
font-size: 12px;
padding: 5px 10px;
border-radius: 5px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.12s ease;
z-index: 1000;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.sidebar.collapsed .sidebar-item:hover::after {
opacity: 1;
}
.sidebar-footer {
padding: 12px 0;
border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.folder-item {
justify-content: space-between;
}
.folder-label {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
cursor: pointer;
}
.btn-delete-folder {
background: none;
border: none;
cursor: pointer;
font-size: 13px;
opacity: 0;
color: rgba(255, 255, 255, 0.6);
transition:
opacity var(--transition),
color var(--transition);
padding: 2px 4px;
border-radius: 4px;
flex-shrink: 0;
}
.folder-item:hover .btn-delete-folder {
opacity: 1;
}
.btn-delete-folder:hover {
color: #ff6b6b;
}
.btn-new-folder {
float: right;
margin-right: 4px;
background: none;
border: none;
color: rgba(255, 255, 255, 0.5);
font-size: 16px;
line-height: 1;
cursor: pointer;
padding: 0 4px;
transition: color var(--transition);
}
.btn-new-folder:hover {
color: #fff;
}
.new-folder-row {
padding: 4px 10px 4px 16px;
}
.new-folder-row form {
display: flex;
align-items: center;
gap: 4px;
}
.new-folder-row input {
flex: 1;
padding: 5px 8px;
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.1);
color: #fff;
font-size: 13px;
}
.new-folder-row input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.new-folder-row input:focus {
outline: none;
border-color: rgba(255, 255, 255, 0.5);
}
.new-folder-row .btn-icon {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
}
.new-folder-row .btn-icon:hover {
color: #fff;
background: rgba(255, 255, 255, 0.1);
}
/* ── Vault main ──────────────────────────────────────────────────── */
.vault-main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background: var(--color-bg);
}
#view-vault,
#view-security {
display: flex;
flex-direction: column;
flex: 1;
overflow: hidden;
min-height: 0;
position: relative;
}
#view-vault.hidden,
#view-security.hidden {
display: none;
}
.vault-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 24px;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
gap: 16px;
}
.vault-title {
font-size: 18px;
font-weight: 600;
white-space: nowrap;
}
.vault-toolbar {
display: flex;
align-items: center;
gap: 12px;
flex: 1;
justify-content: flex-end;
}
.search-wrapper {
display: flex;
align-items: center;
background: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: 20px;
padding: 6px 14px;
gap: 8px;
flex: 1;
max-width: 360px;
}
.search-icon {
color: var(--color-text-muted);
}
#search-input {
border: none;
background: none;
outline: none;
flex: 1;
font-size: 14px;
}
.btn-fab {
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--color-primary);
color: #fff;
font-size: 24px;
font-weight: 300;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 8px rgba(208, 2, 27, 0.35);
transition:
background var(--transition),
box-shadow var(--transition);
flex-shrink: 0;
}
.btn-fab:hover {
background: var(--color-primary-dark);
box-shadow: 0 4px 14px rgba(208, 2, 27, 0.45);
}
/* ── Vault list ──────────────────────────────────────────────────── */
.vault-list {
flex: 1;
overflow-y: auto;
padding: 12px 24px 24px;
}
.vault-group-header {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-text-muted);
padding: 16px 0 6px;
border-bottom: 1px solid var(--color-border);
margin-bottom: 4px;
}
.vault-empty {
text-align: center;
color: var(--color-text-muted);
padding: 60px 0;
font-size: 15px;
}
.vault-item {
display: flex;
align-items: center;
gap: 12px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 12px 14px;
margin-bottom: 6px;
cursor: pointer;
transition:
box-shadow var(--transition),
border-color var(--transition);
}
.vault-item:hover {
box-shadow: var(--shadow);
border-color: #c9ccd4;
}
.item-icon {
font-size: 22px;
flex-shrink: 0;
}
.item-info {
flex: 1;
min-width: 0;
}
.item-name {
display: block;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-sub {
display: block;
font-size: 12px;
color: var(--color-text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-actions {
display: flex;
gap: 4px;
opacity: 0;
transition: opacity var(--transition);
}
.vault-item:hover .item-actions {
opacity: 1;
}
.btn-icon {
width: 30px;
height: 30px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
color: var(--color-text-muted);
transition:
background var(--transition),
color var(--transition);
}
.btn-icon:hover {
background: var(--color-bg);
color: var(--color-text);
}
/* ── Spinner ─────────────────────────────────────────────────────── */
.spinner-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.7);
z-index: 10;
}
.spinner-overlay.hidden {
display: none;
}
.spinner {
width: 36px;
height: 36px;
border: 3px solid var(--color-border);
border-top-color: var(--color-primary);
border-radius: 50%;
animation: spin 0.7s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* ── Modal ───────────────────────────────────────────────────────── */
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
display: none;
align-items: center;
justify-content: center;
z-index: 100;
padding: 16px;
}
.modal-overlay.open {
display: flex;
}
.modal {
background: var(--color-surface);
border-radius: var(--radius);
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 480px;
max-height: 90vh;
overflow-y: auto;
padding: 28px;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.modal-header h3 {
font-size: 18px;
font-weight: 600;
}
.btn-close {
font-size: 18px;
color: var(--color-text-muted);
padding: 4px;
border-radius: 4px;
}
.btn-close:hover {
background: var(--color-bg);
color: var(--color-text);
}
.modal-actions {
display: flex;
gap: 10px;
justify-content: flex-end;
margin-top: 20px;
}
.required {
color: var(--color-primary);
}
/* ── Toast ───────────────────────────────────────────────────────── */
.toast {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%) translateY(20px);
background: #1a1a2e;
color: #fff;
padding: 10px 20px;
border-radius: 20px;
font-size: 14px;
font-weight: 500;
opacity: 0;
transition:
opacity 0.25s,
transform 0.25s;
pointer-events: none;
z-index: 200;
white-space: nowrap;
}
.toast.show {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
.toast.toast-error {
background: #c00;
}
/* ── Unlock overlay ──────────────────────────────────────────────── */
.modal-unlock {
max-width: 380px;
}
.unlock-logo {
margin-bottom: 16px;
}
.unlock-title {
margin-bottom: 4px;
}
.unlock-subtitle {
color: var(--color-text-muted);
font-size: 13px;
margin-bottom: 20px;
}
.btn-link {
padding: 10px 20px;
border-radius: var(--radius);
text-decoration: none;
}
/* ── Auth step hint ─────────────────────────────────────────────── */
.auth-step-hint {
color: var(--color-text-muted);
font-size: 13px;
margin-bottom: 16px;
}
#mfa-code {
font-size: 22px;
letter-spacing: 0.2em;
text-align: center;
}
/* ── Panel body (sharing / emergency) ───────────────────────────── */
.panel-body {
flex: 1;
overflow-y: auto;
padding: 20px 24px;
}
/* ── Tabs ────────────────────────────────────────────────────────── */
.panel-tabs {
display: flex;
gap: 4px;
margin-bottom: 16px;
border-bottom: 2px solid var(--color-border);
padding-bottom: 0;
}
.tab-btn {
padding: 8px 16px;
border-radius: 6px 6px 0 0;
font-size: 13px;
font-weight: 500;
color: var(--color-text-muted);
border-bottom: 2px solid transparent;
margin-bottom: -2px;
transition:
color var(--transition),
border-color var(--transition);
}
.tab-btn:hover {
color: var(--color-text);
}
.tab-btn.active {
color: var(--color-primary);
border-bottom-color: var(--color-primary);
}
/* ── Share / Emergency lists ────────────────────────────────────── */
.share-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.share-item {
display: flex;
align-items: center;
gap: 12px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 12px 14px;
}
.share-icon {
font-size: 22px;
flex-shrink: 0;
}
.share-info {
flex: 1;
min-width: 0;
}
.share-name {
display: block;
font-weight: 500;
}
.share-meta {
display: block;
font-size: 12px;
color: var(--color-text-muted);
margin-top: 2px;
}
.share-actions {
display: flex;
gap: 6px;
align-items: center;
flex-shrink: 0;
}
/* ── Badges ──────────────────────────────────────────────────────── */
.badge {
display: inline-block;
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.badge-warn {
background: #fff8e1;
color: #e65100;
border: 1px solid #ffb74d;
}
.badge-info {
background: #e3f2fd;
color: #1565c0;
border: 1px solid #90caf9;
}
/* ── Settings modal ──────────────────────────────────────────────── */
.modal-settings {
max-width: 520px;
}
.settings-section {
padding: 16px 0;
border-bottom: 1px solid var(--color-border);
}
.settings-section:last-child {
border-bottom: none;
}
.settings-section-title {
font-size: 15px;
font-weight: 600;
margin-bottom: 8px;
}
.settings-desc {
font-size: 13px;
color: var(--color-text-muted);
margin-bottom: 10px;
line-height: 1.5;
}
.mfa-qr {
display: block;
margin: 12px auto;
max-width: 180px;
border: 1px solid var(--color-border);
border-radius: 4px;
}
.mfa-secret-text {
font-family: monospace;
font-size: 12px;
}
.mfa-secret-text code {
background: var(--color-bg);
padding: 2px 6px;
border-radius: 4px;
user-select: all;
}
/* ── Sort control ────────────────────────────────────────────────── */
.sort-wrapper select {
padding: 6px 10px;
border: 1px solid var(--color-border);
border-radius: 20px;
background: var(--color-bg);
color: var(--color-text);
font-size: 13px;
cursor: pointer;
outline: none;
}
.sort-wrapper select:focus {
border-color: var(--color-primary);
}
/* ── Modal item (wider for address/card forms) ───────────────────── */
.modal-item {
max-width: 540px;
}
/* ── Multi-column form rows ──────────────────────────────────────── */
.form-row {
display: flex;
gap: 12px;
}
.form-row .form-group {
flex: 1;
}
/* ── Btn small ───────────────────────────────────────────────────── */
.btn-sm {
padding: 5px 12px;
font-size: 12px;
border-radius: 6px;
}
/* ── Security dashboard ──────────────────────────────────────────── */
.security-dashboard {
flex: 1;
overflow-y: auto;
padding: 24px;
display: flex;
flex-direction: column;
gap: 24px;
}
.sec-notice {
text-align: center;
color: var(--color-text-muted);
padding: 40px 0;
font-size: 15px;
}
.security-summary {
display: flex;
gap: 20px;
align-items: center;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 24px;
flex-wrap: wrap;
}
.sec-score-card {
text-align: center;
flex-shrink: 0;
}
.sec-score {
font-size: 56px;
font-weight: 700;
line-height: 1;
}
.sec-score.score-good {
color: #2e7d32;
}
.sec-score.score-fair {
color: #e65100;
}
.sec-score.score-poor {
color: #c62828;
}
.sec-score-label {
font-size: 16px;
font-weight: 600;
margin-top: 4px;
}
.sec-score-desc {
font-size: 12px;
color: var(--color-text-muted);
margin-top: 2px;
}
.sec-stats {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.sec-stat {
text-align: center;
background: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 12px 20px;
min-width: 80px;
}
.sec-stat-warn {
border-color: #ffb74d;
background: #fff8e1;
}
.sec-stat-info {
border-color: #90caf9;
background: #e3f2fd;
}
.sec-stat-ok {
border-color: #a5d6a7;
background: #e8f5e9;
}
.sec-stat-num {
display: block;
font-size: 28px;
font-weight: 700;
}
.sec-stat-label {
display: block;
font-size: 12px;
color: var(--color-text-muted);
margin-top: 2px;
}
.sec-section {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
overflow: hidden;
}
.sec-section-header {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
background: var(--color-bg);
}
.sec-section-icon {
font-size: 20px;
flex-shrink: 0;
}
.sec-section-title {
font-weight: 600;
font-size: 15px;
}
.sec-section-desc {
font-size: 12px;
color: var(--color-text-muted);
margin-top: 2px;
}
.sec-item-list {
padding: 0;
}
.sec-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 20px;
border-bottom: 1px solid var(--color-border);
}
.sec-item:last-child {
border-bottom: none;
}
.sec-item-name {
font-weight: 500;
flex: 1;
}
.sec-item-sub {
font-size: 12px;
color: var(--color-text-muted);
flex: 1;
}
/* ── Item Detail Modal ───────────────────────────────────────────── */
.modal-detail {
max-height: 80vh;
display: flex;
flex-direction: column;
}
.detail-body {
flex: 1;
overflow-y: auto;
padding: 4px 0;
}
.detail-field {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 10px 0;
border-bottom: 1px solid var(--color-border);
}
.detail-field:last-child {
border-bottom: none;
}
.detail-label {
font-size: 12px;
color: var(--color-text-muted);
width: 140px;
flex-shrink: 0;
padding-top: 4px;
}
.detail-val-row {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
flex-wrap: wrap;
}
.detail-val {
font-size: 14px;
word-break: break-all;
}
.detail-sensitive {
display: inline-flex;
align-items: center;
font-family: monospace;
font-size: 14px;
}
.detail-masked {
letter-spacing: 2px;
}
.detail-actual {
word-break: break-all;
}
.btn-reveal,
.btn-copy-field {
background: none;
border: none;
cursor: pointer;
padding: 2px 4px;
font-size: 14px;
color: var(--color-text-muted);
flex-shrink: 0;
}
.btn-reveal:hover,
.btn-copy-field:hover {
color: var(--color-primary);
}
/* ── Emergency Vault Panel ───────────────────────────────────────── */
.em-vault-panel {
padding: 8px 0;
}
.em-vault-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 0 16px;
border-bottom: 2px solid var(--color-border);
margin-bottom: 8px;
}
.em-vault-header h4 {
margin: 0;
font-size: 15px;
font-weight: 600;
}
.em-vault-list {
list-style: none;
padding: 0;
margin: 0;
}
.em-vault-item {
border-bottom: 1px solid var(--color-border);
}
.em-vault-item:last-child {
border-bottom: none;
}
.em-vault-item-header {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
background: none;
border: none;
padding: 12px 4px;
cursor: pointer;
text-align: left;
}
.em-vault-item-header:hover {
background: var(--color-sidebar-hover);
border-radius: var(--radius);
}
.em-vault-icon {
font-size: 18px;
flex-shrink: 0;
}
.em-vault-name {
font-weight: 500;
flex: 1;
}
.em-vault-type {
font-size: 12px;
color: var(--color-text-muted);
}
.em-vault-chevron {
font-size: 12px;
color: var(--color-text-muted);
flex-shrink: 0;
}
.em-vault-item-body {
padding: 0 8px 12px 36px;
}
.em-detail-body .detail-field {
padding: 8px 0;
}
/* ── Responsive ──────────────────────────────────────────────────── */
/* Mobile top bar — hidden on tablet+ */
.mobile-topbar {
display: none;
align-items: center;
gap: 12px;
padding: 0 16px;
height: 54px;
background: var(--color-sidebar-bg);
color: #fff;
flex-shrink: 0;
position: sticky;
top: 0;
z-index: 50;
}
.btn-mobile-menu {
font-size: 22px;
color: rgba(255, 255, 255, 0.8);
background: none;
border: none;
padding: 4px 6px;
cursor: pointer;
flex-shrink: 0;
}
.btn-mobile-menu:hover {
color: #fff;
}
.mobile-logo {
flex: 1;
font-size: 16px;
font-weight: 700;
color: #fff;
}
.btn-fab-mobile {
width: 36px;
height: 36px;
font-size: 20px;
flex-shrink: 0;
}
/* Sidebar backdrop — only active on mobile */
.sidebar-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 89;
}
.sidebar-backdrop.open {
display: block;
}
/* ── Phone (≤ 640px) ─────────────────────────────────────────────── */
@media (max-width: 640px) {
/* Layout: stack topbar above main, no sidebar space in flow */
.app-layout {
flex-direction: column;
height: 100vh;
overflow: hidden;
}
/* Topbar always visible */
.mobile-topbar {
display: flex;
}
/* Sidebar slides in from the left as an overlay */
.sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 260px !important; /* always full-width on mobile regardless of collapsed state */
z-index: 90;
transform: translateX(-100%);
transition: transform 0.25s ease;
overflow-y: auto;
}
.sidebar.mobile-open {
transform: translateX(0);
}
/* Show all labels inside the mobile overlay sidebar */
.sidebar .sidebar-label {
opacity: 1 !important;
max-width: none !important;
}
.sidebar .sidebar-section-header {
opacity: 1 !important;
height: auto !important;
padding: 12px 16px 4px !important;
}
.sidebar .sidebar-item {
justify-content: flex-start !important;
padding: 9px 16px !important;
overflow: hidden !important;
}
.sidebar .sidebar-item::after {
display: none !important;
}
/* Hide desktop collapse toggle on mobile */
.btn-sidebar-toggle {
display: none;
}
/* Main area fills everything below topbar */
.vault-main {
flex: 1;
overflow: hidden;
}
/* Tighter padding */
.vault-header {
padding: 12px 16px;
gap: 8px;
}
.vault-title {
font-size: 16px;
}
.vault-list {
padding: 8px 12px 80px;
} /* bottom pad for FAB */
.panel-body {
padding: 16px;
}
.security-dashboard {
padding: 12px;
gap: 16px;
}
/* Search takes full width, hide sort */
.vault-toolbar {
gap: 8px;
}
.search-wrapper {
max-width: none;
}
.sort-wrapper {
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 */
.security-summary {
padding: 16px;
gap: 12px;
}
.sec-score {
font-size: 40px;
}
.sec-stats {
gap: 8px;
}
.sec-stat {
padding: 8px 12px;
min-width: 68px;
}
.sec-stat-num {
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;
}
.detail-label {
width: auto;
}
}
/* ── Tablet (641px 1024px) ─────────────────────────────────────── */
@media (min-width: 641px) and (max-width: 1024px) {
/* Sidebar always shows as icon rail on tablet — user can expand with toggle */
.sidebar:not(.collapsed) {
width: 200px;
}
/* Slightly tighter padding */
.vault-header {
padding: 14px 18px;
}
.vault-list {
padding: 10px 18px 18px;
}
.panel-body {
padding: 16px 18px;
}
.security-dashboard {
padding: 16px;
gap: 16px;
}
/* Search a bit narrower */
.search-wrapper {
max-width: 280px;
}
/* Security stats wrap gracefully */
.security-summary {
flex-wrap: wrap;
gap: 12px;
}
.sec-stats {
flex-wrap: wrap;
gap: 10px;
}
/* Form rows stay side-by-side */
.form-row {
flex-direction: row;
}
/* Modal fits tablet width */
.modal {
max-width: 460px;
}
}
/* ── Laptop (1025px 1440px) ───────────────────────────────────── */
@media (min-width: 1025px) and (max-width: 1440px) {
/* Full sidebar, comfortable padding */
.vault-header {
padding: 16px 24px;
}
.vault-list {
padding: 12px 24px 24px;
}
.security-dashboard {
padding: 20px 24px;
}
}
/* ── Large PC (> 1440px) ────────────────────────────────────────── */
@media (min-width: 1441px) {
/* Wider sidebar, more generous spacing */
.sidebar:not(.collapsed) {
width: 260px;
}
.vault-header {
padding: 18px 32px;
}
.vault-list {
padding: 16px 32px 32px;
}
.panel-body {
padding: 24px 32px;
}
.security-dashboard {
padding: 24px 32px;
gap: 28px;
}
.search-wrapper {
max-width: 440px;
}
.modal {
max-width: 520px;
}
.modal-settings {
max-width: 580px;
}
}
/* ── Settings — new sections (Phase 6) ──────────────────────────── */
.settings-section-danger {
border-top: 2px solid var(--color-danger, #e53e3e);
margin-top: 8px;
padding-top: 16px;
}
.settings-section-danger .settings-section-title {
color: var(--color-danger, #e53e3e);
}
.btn-danger {
background: var(--color-danger, #e53e3e);
color: #fff;
border: none;
border-radius: var(--radius);
padding: 8px 18px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: opacity 0.15s;
}
.btn-danger:hover {
opacity: 0.85;
}
.btn-danger:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.recovery-code-box {
display: flex;
align-items: center;
gap: 8px;
background: var(--color-bg-secondary, #f7f7f7);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 12px 14px;
margin: 8px 0;
}
.recovery-code-box code {
font-family: monospace;
font-size: 15px;
letter-spacing: 0.08em;
word-break: break-all;
flex: 1;
}
.warning-text {
color: var(--color-danger, #e53e3e);
font-size: 13px;
font-weight: 500;
}