Merge pull request #505 from AtalayaLabs/claude/ui-ux-design-review-n4bs46

This commit is contained in:
Dionisio Pozo
2026-06-20 01:05:28 +02:00
committed by GitHub
6 changed files with 103 additions and 62 deletions
+18 -9
View File
@@ -23,22 +23,30 @@
href: string; href: string;
label: string; label: string;
icon: string; icon: string;
/** Stable key driving the per-section icon colour (see sidebar.css). */
section: string;
admin?: boolean; admin?: boolean;
} }
const LINKS: NavLink[] = [ const LINKS: NavLink[] = [
{ href: '/files', label: t('nav.files', 'Files'), icon: 'folder' }, { href: '/files', label: t('nav.files', 'Files'), icon: 'folder', section: 'files' },
{ href: '/shared', label: t('nav.shared', 'Shared'), icon: 'oxiexport' }, { href: '/shared', label: t('nav.shared', 'Shared'), icon: 'oxiexport', section: 'shared' },
{ {
href: '/shared-with-me', href: '/shared-with-me',
label: t('nav.shared_with_me', '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: '/recent', label: t('nav.recent', 'Recent'), icon: 'clock', section: 'recent' },
{ href: '/favorites', label: t('nav.favorites', 'Favorites'), icon: 'star' }, {
{ href: '/photos', label: t('nav.photos', 'Photos'), icon: 'images' }, href: '/favorites',
{ href: '/music', label: t('nav.music', 'Music'), icon: 'music' }, label: t('nav.favorites', 'Favorites'),
{ href: '/trash', label: t('nav.trash', 'Trash'), icon: 'trash' } 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'); const isAdmin = $derived(session.user?.role === 'admin');
@@ -256,6 +264,7 @@
class="nav-item" class="nav-item"
class:active={active(link.href)} class:active={active(link.href)}
href={link.href} href={link.href}
data-section={link.section}
onclick={() => (sidebarOpen = false)} onclick={() => (sidebarOpen = false)}
> >
<Icon name={link.icon} /> <Icon name={link.icon} />
@@ -1019,7 +1028,7 @@
.about-overlay { .about-overlay {
position: fixed; position: fixed;
inset: 0; inset: 0;
z-index: 1200; z-index: var(--z-modal);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
+10 -7
View File
@@ -221,11 +221,14 @@
--color-text: light-dark(#2d3748, #e2e8f0); /* primary body */ --color-text: light-dark(#2d3748, #e2e8f0); /* primary body */
--color-text-heading: light-dark(#1e293b, #f1f5f9); /* headings */ --color-text-heading: light-dark(#1e293b, #f1f5f9); /* headings */
--color-text-secondary: light-dark(#475569, #cbd5e1); /* strong secondary */ --color-text-secondary: light-dark(#475569, #cbd5e1); /* strong secondary */
/* muted/subtle/faint converge: AA 4.5:1 on the grayish page/muted bgs AND /* Three perceptibly distinct tiers, each verified AA ≥4.5:1 on every
* on the lighter dark hover bg leaves only a narrow passing window. */ * page/surface/hover/muted background in BOTH modes. muted carries the most
--color-text-muted: light-dark(#5e6a78, #9fadbe); /* muted */ * weight (general secondary text — by far the most-used), faint the least
--color-text-subtle: light-dark(#5e6a78, #9fadbe); /* subtle */ * (timestamps, placeholders) and sits right on the AA floor. Emphasis maps
--color-text-faint: light-dark(#5e6a78, #9fadbe); /* faintest still-AA */ * 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 */ /* legacy aliases → one of the tiers above */
--color-text-dark: var(--color-text-secondary); --color-text-dark: var(--color-text-secondary);
--color-text-dim: var(--color-text-secondary); --color-text-dim: var(--color-text-secondary);
@@ -368,8 +371,8 @@
--color-item-active: light-dark(#f8d2ae, #5a5047); --color-item-active: light-dark(#f8d2ae, #5a5047);
--color-item-selected: light-dark(#fff8f6, #39281a); --color-item-selected: light-dark(#fff8f6, #39281a);
--color-item-hover-accent: light-dark(#fff0ec, #3d342c); --color-item-hover-accent: light-dark(#fff0ec, #3d342c);
--color-item-hover-blue: #f0f8ff; --color-item-hover-blue: light-dark(#f0f8ff, #18293f);
--color-item-hover-sky: #e0f2fe; --color-item-hover-sky: light-dark(#e0f2fe, #103048);
/* Sidebar — already dark-leaning in both modes; dark mode goes deeper. */ /* Sidebar — already dark-leaning in both modes; dark mode goes deeper. */
--color-sidebar-bg-from: light-dark(#2a3042, #0f172a); --color-sidebar-bg-from: light-dark(#2a3042, #0f172a);
+19 -15
View File
@@ -9,27 +9,32 @@
font-size: var(--text-base); font-size: var(--text-base);
font-weight: var(--weight-medium); font-weight: var(--weight-medium);
gap: var(--space-2); gap: var(--space-2);
transition: all 0.2s ease; transition: all var(--motion-base) var(--ease-standard);
} }
.btn i { .btn i {
font-size: 15px; 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 { .btn-primary {
background: var(--color-accent-gradient); background: var(--color-accent-gradient);
color: var(--color-danger-text); color: var(--color-on-accent);
box-shadow: 0 4px 15px var(--color-accent-shadow); box-shadow: var(--shadow-sm);
} }
.btn-primary:hover { .btn-primary:hover {
transform: translateY(-2px); box-shadow: 0 4px 14px var(--color-accent-shadow);
box-shadow: 0 6px 20px var(--color-accent-shadow-lg); filter: brightness(1.05);
} }
.btn-primary:active { .btn-primary:active {
transform: translateY(0); transform: scale(0.98);
box-shadow: 0 2px 10px var(--color-accent-shadow); box-shadow: var(--shadow-xs);
filter: brightness(0.97);
} }
.btn-secondary { .btn-secondary {
@@ -41,29 +46,28 @@
.btn-secondary:hover { .btn-secondary:hover {
background-color: var(--color-bg-input-alt); background-color: var(--color-bg-input-alt);
border-color: var(--color-border-medium); border-color: var(--color-border-medium);
transform: translateY(-2px);
box-shadow: 0 4px 12px var(--color-shadow-sm);
} }
.btn-secondary:active { .btn-secondary:active {
transform: translateY(0); transform: scale(0.98);
background-color: var(--color-border); background-color: var(--color-border);
} }
.btn-danger { .btn-danger {
background: var(--color-danger-gradient); background: var(--color-danger-gradient);
color: var(--color-danger-text); color: var(--color-danger-text);
box-shadow: 0 4px 15px var(--color-danger-ring); box-shadow: var(--shadow-sm);
} }
.btn-danger:hover { .btn-danger:hover {
transform: translateY(-2px); box-shadow: 0 4px 14px var(--color-danger-ring);
box-shadow: 0 6px 20px var(--color-danger-ring-lg); filter: brightness(1.05);
} }
.btn-danger:active { .btn-danger:active {
transform: translateY(0); transform: scale(0.98);
box-shadow: 0 2px 10px var(--color-danger-ring); box-shadow: var(--shadow-xs);
filter: brightness(0.97);
} }
/* ── State matrix: focus / disabled / loading ───────────────── */ /* ── State matrix: focus / disabled / loading ───────────────── */
+19 -8
View File
@@ -1,18 +1,27 @@
/* ── Scrollbar ── */ /* ── Scrollbar ── */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 10px;
height: 10px;
} }
::-webkit-scrollbar-track { ::-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 { ::-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); background: var(--color-accent);
border-radius: 3px; background-clip: padding-box;
} }
* { * {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: var(--color-accent) var(--color-bg-surface); scrollbar-color: var(--color-border-medium) transparent;
} }
/* Content area */ /* Content area */
@@ -50,11 +59,13 @@
.page-sticky-header { .page-sticky-header {
position: sticky; position: sticky;
margin: 0px; margin: 0;
padding: var(--space-2-5) 0px; padding: var(--space-2-5) 0;
top: -20px; /* due to padding top of content-area */ /* 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); 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 { .actions-bar {
+36 -22
View File
@@ -175,30 +175,44 @@
} }
} }
/* Colored icons per section */ /* Colored icons per section.
.nav-item:nth-child(1) i, Keyed off the stable `data-section` attribute (set in AppShell's LINKS), NOT
.nav-item:nth-child(1) .oxi-icon { DOM order — adding/reordering nav items can no longer desync the colours from
color: var(--color-cal-1); their labels. Each section maps to one curated calendar-dot hue (the same
} /* Files - orange */ --color-cal-* family used elsewhere), spread around the wheel so they read as
.nav-item:nth-child(2) i, a set: the two share directions are sibling blues, music is purple to match
.nav-item:nth-child(2) .oxi-icon { 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); color: var(--color-cal-2);
} /* Shared - blue */ } /* Files - amber */
.nav-item:nth-child(3) i, .nav-item[data-section="shared"] i,
.nav-item:nth-child(3) .oxi-icon { .nav-item[data-section="shared"] .oxi-icon {
color: var(--color-cal-3); color: var(--color-cal-7);
} /* Recent - teal */ } /* Shared (outbound) - sky */
.nav-item:nth-child(4) i, .nav-item[data-section="shared-with-me"] i,
.nav-item:nth-child(4) .oxi-icon { .nav-item[data-section="shared-with-me"] .oxi-icon {
color: var(--color-cal-4); color: var(--color-cal-8);
} /* Favorites - gold */ } /* Shared with me (inbound) - blue */
.nav-item:nth-child(5) i, .nav-item[data-section="recent"] i,
.nav-item:nth-child(5) .oxi-icon { .nav-item[data-section="recent"] .oxi-icon {
color: var(--color-cal-5);
} /* Photos - pink */
.nav-item:nth-child(6) i,
.nav-item:nth-child(6) .oxi-icon {
color: var(--color-cal-6); 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 */ } /* Trash - red */
/* Colourful icons at rest, but the ACTIVE item is always accent — one /* Colourful icons at rest, but the ACTIVE item is always accent — one
+1 -1
View File
@@ -165,7 +165,7 @@
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
background: var(--color-accent-gradient); background: var(--color-accent-gradient);
color: var(--color-danger-text); color: var(--color-on-accent);
border: none; border: none;
border-radius: var(--radius-xl); border-radius: var(--radius-xl);
width: 36px; width: 36px;