Merge pull request #505 from AtalayaLabs/claude/ui-ux-design-review-n4bs46
This commit is contained in:
@@ -23,22 +23,30 @@
|
||||
href: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
/** Stable key driving the per-section icon colour (see sidebar.css). */
|
||||
section: string;
|
||||
admin?: boolean;
|
||||
}
|
||||
|
||||
const LINKS: NavLink[] = [
|
||||
{ href: '/files', label: t('nav.files', 'Files'), icon: 'folder' },
|
||||
{ href: '/shared', label: t('nav.shared', 'Shared'), icon: 'oxiexport' },
|
||||
{ href: '/files', label: t('nav.files', 'Files'), icon: 'folder', section: 'files' },
|
||||
{ href: '/shared', label: t('nav.shared', 'Shared'), icon: 'oxiexport', section: 'shared' },
|
||||
{
|
||||
href: '/shared-with-me',
|
||||
label: t('nav.shared_with_me', 'Shared with me'),
|
||||
icon: 'oxiimport'
|
||||
icon: 'oxiimport',
|
||||
section: 'shared-with-me'
|
||||
},
|
||||
{ href: '/recent', label: t('nav.recent', 'Recent'), icon: 'clock' },
|
||||
{ href: '/favorites', label: t('nav.favorites', 'Favorites'), icon: 'star' },
|
||||
{ href: '/photos', label: t('nav.photos', 'Photos'), icon: 'images' },
|
||||
{ href: '/music', label: t('nav.music', 'Music'), icon: 'music' },
|
||||
{ href: '/trash', label: t('nav.trash', 'Trash'), icon: 'trash' }
|
||||
{ href: '/recent', label: t('nav.recent', 'Recent'), icon: 'clock', section: 'recent' },
|
||||
{
|
||||
href: '/favorites',
|
||||
label: t('nav.favorites', 'Favorites'),
|
||||
icon: 'star',
|
||||
section: 'favorites'
|
||||
},
|
||||
{ href: '/photos', label: t('nav.photos', 'Photos'), icon: 'images', section: 'photos' },
|
||||
{ href: '/music', label: t('nav.music', 'Music'), icon: 'music', section: 'music' },
|
||||
{ href: '/trash', label: t('nav.trash', 'Trash'), icon: 'trash', section: 'trash' }
|
||||
];
|
||||
|
||||
const isAdmin = $derived(session.user?.role === 'admin');
|
||||
@@ -256,6 +264,7 @@
|
||||
class="nav-item"
|
||||
class:active={active(link.href)}
|
||||
href={link.href}
|
||||
data-section={link.section}
|
||||
onclick={() => (sidebarOpen = false)}
|
||||
>
|
||||
<Icon name={link.icon} />
|
||||
@@ -1019,7 +1028,7 @@
|
||||
.about-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1200;
|
||||
z-index: var(--z-modal);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -221,11 +221,14 @@
|
||||
--color-text: light-dark(#2d3748, #e2e8f0); /* primary body */
|
||||
--color-text-heading: light-dark(#1e293b, #f1f5f9); /* headings */
|
||||
--color-text-secondary: light-dark(#475569, #cbd5e1); /* strong secondary */
|
||||
/* muted/subtle/faint converge: AA 4.5:1 on the grayish page/muted bgs AND
|
||||
* on the lighter dark hover bg leaves only a narrow passing window. */
|
||||
--color-text-muted: light-dark(#5e6a78, #9fadbe); /* muted */
|
||||
--color-text-subtle: light-dark(#5e6a78, #9fadbe); /* subtle */
|
||||
--color-text-faint: light-dark(#5e6a78, #9fadbe); /* faintest still-AA */
|
||||
/* Three perceptibly distinct tiers, each verified AA ≥4.5:1 on every
|
||||
* page/surface/hover/muted background in BOTH modes. muted carries the most
|
||||
* weight (general secondary text — by far the most-used), faint the least
|
||||
* (timestamps, placeholders) and sits right on the AA floor. Emphasis maps
|
||||
* to contrast: stronger = darker in light / lighter in dark. */
|
||||
--color-text-muted: light-dark(#586472, #b2c0d0); /* muted — strongest (5.4 / 5.6) */
|
||||
--color-text-subtle: light-dark(#5e6a78, #a6b4c6); /* subtle — middle (5.0 / 4.9) */
|
||||
--color-text-faint: light-dark(#647082, #9fadbe); /* faint — AA floor (4.5 / 4.5) */
|
||||
/* legacy aliases → one of the tiers above */
|
||||
--color-text-dark: var(--color-text-secondary);
|
||||
--color-text-dim: var(--color-text-secondary);
|
||||
@@ -368,8 +371,8 @@
|
||||
--color-item-active: light-dark(#f8d2ae, #5a5047);
|
||||
--color-item-selected: light-dark(#fff8f6, #39281a);
|
||||
--color-item-hover-accent: light-dark(#fff0ec, #3d342c);
|
||||
--color-item-hover-blue: #f0f8ff;
|
||||
--color-item-hover-sky: #e0f2fe;
|
||||
--color-item-hover-blue: light-dark(#f0f8ff, #18293f);
|
||||
--color-item-hover-sky: light-dark(#e0f2fe, #103048);
|
||||
|
||||
/* Sidebar — already dark-leaning in both modes; dark mode goes deeper. */
|
||||
--color-sidebar-bg-from: light-dark(#2a3042, #0f172a);
|
||||
|
||||
@@ -9,27 +9,32 @@
|
||||
font-size: var(--text-base);
|
||||
font-weight: var(--weight-medium);
|
||||
gap: var(--space-2);
|
||||
transition: all 0.2s ease;
|
||||
transition: all var(--motion-base) var(--ease-standard);
|
||||
}
|
||||
|
||||
.btn i {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Filled buttons rest on a soft, neutral elevation; their warm brand glow
|
||||
blooms in on hover (rather than glowing at rest), and a gentle scale-down
|
||||
gives a tactile press. The old "translateY lift on every button" is gone —
|
||||
vertical lift is reserved for cards now, so buttons feel calm, not jittery. */
|
||||
.btn-primary {
|
||||
background: var(--color-accent-gradient);
|
||||
color: var(--color-danger-text);
|
||||
box-shadow: 0 4px 15px var(--color-accent-shadow);
|
||||
color: var(--color-on-accent);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px var(--color-accent-shadow-lg);
|
||||
box-shadow: 0 4px 14px var(--color-accent-shadow);
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 10px var(--color-accent-shadow);
|
||||
transform: scale(0.98);
|
||||
box-shadow: var(--shadow-xs);
|
||||
filter: brightness(0.97);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@@ -41,29 +46,28 @@
|
||||
.btn-secondary:hover {
|
||||
background-color: var(--color-bg-input-alt);
|
||||
border-color: var(--color-border-medium);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px var(--color-shadow-sm);
|
||||
}
|
||||
|
||||
.btn-secondary:active {
|
||||
transform: translateY(0);
|
||||
transform: scale(0.98);
|
||||
background-color: var(--color-border);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: var(--color-danger-gradient);
|
||||
color: var(--color-danger-text);
|
||||
box-shadow: 0 4px 15px var(--color-danger-ring);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px var(--color-danger-ring-lg);
|
||||
box-shadow: 0 4px 14px var(--color-danger-ring);
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.btn-danger:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 10px var(--color-danger-ring);
|
||||
transform: scale(0.98);
|
||||
box-shadow: var(--shadow-xs);
|
||||
filter: brightness(0.97);
|
||||
}
|
||||
|
||||
/* ── State matrix: focus / disabled / loading ───────────────── */
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
/* ── Scrollbar ── */
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--color-bg-surface);
|
||||
background: transparent;
|
||||
}
|
||||
/* Neutral, padded pill that blends in at rest and warms to the brand accent
|
||||
only on hover — the bar no longer competes with content for attention. */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--color-border-medium);
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--radius-full);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-accent);
|
||||
border-radius: 3px;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--color-accent) var(--color-bg-surface);
|
||||
scrollbar-color: var(--color-border-medium) transparent;
|
||||
}
|
||||
|
||||
/* Content area */
|
||||
@@ -50,11 +59,13 @@
|
||||
|
||||
.page-sticky-header {
|
||||
position: sticky;
|
||||
margin: 0px;
|
||||
padding: var(--space-2-5) 0px;
|
||||
top: -20px; /* due to padding top of content-area */
|
||||
margin: 0;
|
||||
padding: var(--space-2-5) 0;
|
||||
/* Cancel .content-area's --space-5 top padding so the header sticks flush;
|
||||
stays correct if the gutter token ever changes. */
|
||||
top: calc(-1 * var(--space-5));
|
||||
background-color: var(--color-bg-page);
|
||||
z-index: 100; /* ensure header is above image preview */
|
||||
z-index: var(--z-sticky); /* ensure header is above image preview */
|
||||
}
|
||||
|
||||
.actions-bar {
|
||||
|
||||
@@ -175,30 +175,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Colored icons per section */
|
||||
.nav-item:nth-child(1) i,
|
||||
.nav-item:nth-child(1) .oxi-icon {
|
||||
color: var(--color-cal-1);
|
||||
} /* Files - orange */
|
||||
.nav-item:nth-child(2) i,
|
||||
.nav-item:nth-child(2) .oxi-icon {
|
||||
/* Colored icons per section.
|
||||
Keyed off the stable `data-section` attribute (set in AppShell's LINKS), NOT
|
||||
DOM order — adding/reordering nav items can no longer desync the colours from
|
||||
their labels. Each section maps to one curated calendar-dot hue (the same
|
||||
--color-cal-* family used elsewhere), spread around the wheel so they read as
|
||||
a set: the two share directions are sibling blues, music is purple to match
|
||||
its gradient, and trash is red as a soft "destructive" affordance. */
|
||||
.nav-item[data-section="files"] i,
|
||||
.nav-item[data-section="files"] .oxi-icon {
|
||||
color: var(--color-cal-2);
|
||||
} /* Shared - blue */
|
||||
.nav-item:nth-child(3) i,
|
||||
.nav-item:nth-child(3) .oxi-icon {
|
||||
color: var(--color-cal-3);
|
||||
} /* Recent - teal */
|
||||
.nav-item:nth-child(4) i,
|
||||
.nav-item:nth-child(4) .oxi-icon {
|
||||
color: var(--color-cal-4);
|
||||
} /* Favorites - gold */
|
||||
.nav-item:nth-child(5) i,
|
||||
.nav-item:nth-child(5) .oxi-icon {
|
||||
color: var(--color-cal-5);
|
||||
} /* Photos - pink */
|
||||
.nav-item:nth-child(6) i,
|
||||
.nav-item:nth-child(6) .oxi-icon {
|
||||
} /* Files - amber */
|
||||
.nav-item[data-section="shared"] i,
|
||||
.nav-item[data-section="shared"] .oxi-icon {
|
||||
color: var(--color-cal-7);
|
||||
} /* Shared (outbound) - sky */
|
||||
.nav-item[data-section="shared-with-me"] i,
|
||||
.nav-item[data-section="shared-with-me"] .oxi-icon {
|
||||
color: var(--color-cal-8);
|
||||
} /* Shared with me (inbound) - blue */
|
||||
.nav-item[data-section="recent"] i,
|
||||
.nav-item[data-section="recent"] .oxi-icon {
|
||||
color: var(--color-cal-6);
|
||||
} /* Recent - teal */
|
||||
.nav-item[data-section="favorites"] i,
|
||||
.nav-item[data-section="favorites"] .oxi-icon {
|
||||
color: var(--color-cal-3);
|
||||
} /* Favorites - gold */
|
||||
.nav-item[data-section="photos"] i,
|
||||
.nav-item[data-section="photos"] .oxi-icon {
|
||||
color: var(--color-cal-10);
|
||||
} /* Photos - magenta */
|
||||
.nav-item[data-section="music"] i,
|
||||
.nav-item[data-section="music"] .oxi-icon {
|
||||
color: var(--color-cal-9);
|
||||
} /* Music - purple */
|
||||
.nav-item[data-section="trash"] i,
|
||||
.nav-item[data-section="trash"] .oxi-icon {
|
||||
color: var(--color-cal-1);
|
||||
} /* Trash - red */
|
||||
|
||||
/* Colourful icons at rest, but the ACTIVE item is always accent — one
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: var(--color-accent-gradient);
|
||||
color: var(--color-danger-text);
|
||||
color: var(--color-on-accent);
|
||||
border: none;
|
||||
border-radius: var(--radius-xl);
|
||||
width: 36px;
|
||||
|
||||
Reference in New Issue
Block a user