feat: improve web UI UX with global search, breadcrumbs, and better feedback
This commit is contained in:
@@ -150,6 +150,86 @@ header nav a.active::after {
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* ── Header Search ────────────────────────────────────────── */
|
||||
.header-search {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.header-search input {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
padding: 0.35rem 0.75rem;
|
||||
padding-right: 2.2rem;
|
||||
border-radius: var(--radius);
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.78rem;
|
||||
width: 140px;
|
||||
transition: width 0.2s ease, border-color 0.15s, box-shadow 0.15s;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.header-search input:focus {
|
||||
width: 220px;
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 3px var(--accent-dim);
|
||||
}
|
||||
|
||||
.header-search kbd {
|
||||
position: absolute;
|
||||
right: 0.6rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text-dim);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.65rem;
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 3px;
|
||||
pointer-events: none;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.header-search input:focus + kbd {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ── Breadcrumbs ─────────────────────────────────────────── */
|
||||
.breadcrumbs {
|
||||
max-width: 1240px;
|
||||
margin: 0 auto;
|
||||
padding: 1rem 2rem 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.78rem;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
|
||||
.breadcrumbs a {
|
||||
color: var(--text-dim);
|
||||
text-decoration: none;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
|
||||
.breadcrumbs a:hover {
|
||||
color: var(--text-bright);
|
||||
}
|
||||
|
||||
.breadcrumbs .sep {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.breadcrumbs .current {
|
||||
color: var(--text-bright);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── Main ──────────────────────────────────────────────────── */
|
||||
main {
|
||||
max-width: 1240px;
|
||||
@@ -348,6 +428,36 @@ tr.clickable:hover td:first-child {
|
||||
padding-left: calc(1.25rem - 2px);
|
||||
}
|
||||
|
||||
tr.tr-error td {
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
tr.tr-error .id-cell {
|
||||
color: var(--error);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.skeleton-line {
|
||||
height: 0.8rem;
|
||||
background: var(--surface-2);
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.skeleton-line::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.05), transparent);
|
||||
animation: skeletonPulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes skeletonPulse {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
/* ── Status badges ─────────────────────────────────────────── */
|
||||
.status-badge {
|
||||
display: inline-flex;
|
||||
@@ -406,6 +516,60 @@ tr.clickable:hover td:first-child {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
padding: 0.1rem;
|
||||
border-radius: 4px;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
margin-left: 0.25rem;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
tr:hover .copy-btn,
|
||||
.meta-tile:hover .copy-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
color: var(--accent);
|
||||
background: var(--accent-dim);
|
||||
}
|
||||
|
||||
/* ── Toast notifications ───────────────────────────────────── */
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
right: 2rem;
|
||||
z-index: 1000;
|
||||
padding: 0.75rem 1.25rem;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
color: var(--text-bright);
|
||||
font-size: 0.85rem;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
|
||||
transform: translateY(1rem);
|
||||
opacity: 0;
|
||||
transition: transform 0.2s cubic-bezier(0.17, 0.67, 0.83, 0.67), opacity 0.2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toast.visible {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.toast-success { border-left: 3px solid var(--success); }
|
||||
.toast-error { border-left: 3px solid var(--error); }
|
||||
.toast-info { border-left: 3px solid var(--accent); }
|
||||
|
||||
/* ── Load more ─────────────────────────────────────────────── */
|
||||
.load-more {
|
||||
display: block;
|
||||
|
||||
Reference in New Issue
Block a user