feat(ui): Aurora design system — glassmorphic dark mode, warm light mode, snappy animations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+102
-23
@@ -90,9 +90,9 @@
|
|||||||
/* ─── Light Theme Surface Variables ─────────────────────────────────────── */
|
/* ─── Light Theme Surface Variables ─────────────────────────────────────── */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--surface-page: 246 247 251;
|
--surface-page: 253 251 255;
|
||||||
--surface-card: 255 255 255;
|
--surface-card: 255 255 255;
|
||||||
--surface-elevated: 249 250 252;
|
--surface-elevated: 248 246 255;
|
||||||
--surface-input: 255 255 255;
|
--surface-input: 255 255 255;
|
||||||
--border-subtle: 219 224 232;
|
--border-subtle: 219 224 232;
|
||||||
--border-input: 197 205 218;
|
--border-input: 197 205 218;
|
||||||
@@ -108,18 +108,18 @@
|
|||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
--surface-page: 12 17 29;
|
--surface-page: 8 8 22;
|
||||||
--surface-card: 16 23 38;
|
--surface-card: 13 14 34;
|
||||||
--surface-elevated: 24 33 52;
|
--surface-elevated: 19 20 46;
|
||||||
--surface-input: 18 28 45;
|
--surface-input: 11 12 30;
|
||||||
--border-subtle: 41 55 78;
|
--border-subtle: 38 42 68;
|
||||||
--border-input: 61 79 110;
|
--border-input: 58 64 98;
|
||||||
--text-primary: 237 242 247;
|
--text-primary: 237 242 247;
|
||||||
--text-secondary: 196 207 223;
|
--text-secondary: 196 207 223;
|
||||||
--text-muted: 147 161 185;
|
--text-muted: 147 161 185;
|
||||||
--text-very-muted: 118 133 161;
|
--text-very-muted: 118 133 161;
|
||||||
--shadow-soft: 2 6 23 / 0.38;
|
--shadow-soft: 0 0 0 / 0.45;
|
||||||
--shadow-strong: 2 6 23 / 0.65;
|
--shadow-strong: 0 0 0 / 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Base Layer: Apply variables to body ────────────────────────────────── */
|
/* ─── Base Layer: Apply variables to body ────────────────────────────────── */
|
||||||
@@ -132,6 +132,7 @@
|
|||||||
background-color 0.15s ease,
|
background-color 0.15s ease,
|
||||||
color 0.15s ease;
|
color 0.15s ease;
|
||||||
background-image:
|
background-image:
|
||||||
|
radial-gradient(ellipse 80% 40% at 50% -5%, rgba(var(--accent-300), 0.05) 0%, transparent 55%),
|
||||||
radial-gradient(ellipse at 0% 0%, rgb(var(--accent-50) / 0.15), transparent 50%),
|
radial-gradient(ellipse at 0% 0%, rgb(var(--accent-50) / 0.15), transparent 50%),
|
||||||
radial-gradient(ellipse at 100% 100%, rgb(var(--accent-100) / 0.08), transparent 50%),
|
radial-gradient(ellipse at 100% 100%, rgb(var(--accent-100) / 0.08), transparent 50%),
|
||||||
radial-gradient(circle at top left, rgb(var(--accent-100) / 0.32), transparent 24rem),
|
radial-gradient(circle at top left, rgb(var(--accent-100) / 0.32), transparent 24rem),
|
||||||
@@ -141,6 +142,7 @@
|
|||||||
|
|
||||||
.dark body {
|
.dark body {
|
||||||
background-image:
|
background-image:
|
||||||
|
radial-gradient(ellipse 80% 50% at 50% -10%, rgba(var(--accent-400), 0.07) 0%, transparent 60%),
|
||||||
radial-gradient(circle at top left, rgb(var(--accent-600) / 0.16), transparent 26rem),
|
radial-gradient(circle at top left, rgb(var(--accent-600) / 0.16), transparent 26rem),
|
||||||
linear-gradient(180deg, rgb(15 23 42 / 0.35), transparent 28rem);
|
linear-gradient(180deg, rgb(15 23 42 / 0.35), transparent 28rem);
|
||||||
}
|
}
|
||||||
@@ -352,33 +354,67 @@
|
|||||||
@layer components {
|
@layer components {
|
||||||
.app-surface {
|
.app-surface {
|
||||||
@apply rounded-2xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/90;
|
@apply rounded-2xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/90;
|
||||||
--tw-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.03);
|
background: linear-gradient(145deg, #ffffff 0%, #fdfbff 100%);
|
||||||
|
--tw-shadow: 0 1px 3px rgba(100, 80, 160, 0.06), 0 4px 16px rgba(100, 80, 160, 0.04);
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(.dark) .app-surface {
|
:is(.dark) .app-surface {
|
||||||
--tw-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.15);
|
background: linear-gradient(135deg, rgba(255,255,255,0.055) 0%, rgba(255,255,255,0.018) 100%);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
-webkit-backdrop-filter: blur(16px);
|
||||||
|
border-color: rgba(255,255,255,0.09);
|
||||||
|
--tw-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.05), inset 0 1px 0 rgba(255,255,255,0.07);
|
||||||
|
box-shadow: var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-surface-strong {
|
.app-surface-strong {
|
||||||
@apply rounded-3xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900;
|
@apply rounded-3xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900;
|
||||||
--tw-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.04);
|
background: linear-gradient(145deg, #ffffff 0%, #fdfbff 100%);
|
||||||
|
--tw-shadow: 0 2px 8px rgba(100, 80, 160, 0.06), 0 8px 24px rgba(100, 80, 160, 0.04);
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(.dark) .app-surface-strong {
|
:is(.dark) .app-surface-strong {
|
||||||
--tw-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.2);
|
background: linear-gradient(135deg, rgba(255,255,255,0.065) 0%, rgba(255,255,255,0.022) 100%);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
|
border-color: rgba(255,255,255,0.10);
|
||||||
|
--tw-shadow: 0 4px 16px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.06), inset 0 1px 0 rgba(255,255,255,0.08);
|
||||||
|
box-shadow: var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-toolbar {
|
.app-toolbar {
|
||||||
@apply sticky top-0 z-10 rounded-2xl border border-gray-200 bg-white/80 p-4 shadow-sm backdrop-blur-sm;
|
@apply sticky top-0 z-10 rounded-2xl border p-4;
|
||||||
@apply dark:border-gray-700 dark:bg-gray-900/80 dark:shadow-black/20;
|
background: rgba(253,251,255,0.85);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
|
border-color: rgba(100,80,160,0.12);
|
||||||
|
box-shadow: 0 1px 3px rgba(100,80,160,0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.dark) .app-toolbar {
|
||||||
|
background: rgba(13,14,34,0.82);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
|
border-color: rgba(255,255,255,0.08);
|
||||||
|
box-shadow: 0 1px 0 rgba(255,255,255,0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-input {
|
.app-input {
|
||||||
@apply w-full rounded-xl border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none transition;
|
@apply w-full rounded-xl border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none transition;
|
||||||
@apply focus:border-brand-500 focus:ring-4 focus:ring-brand-100/80;
|
@apply dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100;
|
||||||
@apply dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:focus:ring-brand-900/50;
|
}
|
||||||
|
|
||||||
|
.app-input:focus {
|
||||||
|
border-color: rgb(var(--accent-500));
|
||||||
|
box-shadow: 0 0 0 3px rgba(var(--accent-400), 0.25), 0 1px 2px rgba(0,0,0,0.05);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.dark) .app-input:focus {
|
||||||
|
border-color: rgb(var(--accent-400));
|
||||||
|
box-shadow: 0 0 0 3px rgba(var(--accent-400), 0.20), inset 0 0 8px rgba(var(--accent-400), 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-select {
|
.app-select {
|
||||||
@@ -403,6 +439,13 @@
|
|||||||
@apply font-display text-3xl font-semibold text-gray-900 dark:text-gray-100;
|
@apply font-display text-3xl font-semibold text-gray-900 dark:text-gray-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:is(.dark) .app-page-title {
|
||||||
|
background: linear-gradient(135deg, rgb(var(--accent-200)) 0%, #e8e4ff 50%, rgb(237 242 247) 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
.app-page-subtitle {
|
.app-page-subtitle {
|
||||||
@apply text-sm text-gray-500 dark:text-gray-400;
|
@apply text-sm text-gray-500 dark:text-gray-400;
|
||||||
}
|
}
|
||||||
@@ -419,6 +462,10 @@
|
|||||||
@apply bg-gray-50/90 dark:bg-gray-800/80;
|
@apply bg-gray-50/90 dark:bg-gray-800/80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:is(.dark) .app-data-table thead tr {
|
||||||
|
background: rgba(255,255,255,0.04);
|
||||||
|
}
|
||||||
|
|
||||||
.app-data-table th {
|
.app-data-table th {
|
||||||
@apply text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400;
|
@apply text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400;
|
||||||
}
|
}
|
||||||
@@ -447,6 +494,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── Aurora: new keyframes ──────────────────────────────────────────────── */
|
||||||
|
@keyframes fadeSlideUp {
|
||||||
|
from { opacity: 0; transform: translateY(6px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleIn {
|
||||||
|
from { opacity: 0; transform: scale(0.96); }
|
||||||
|
to { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glowPulse {
|
||||||
|
0%, 100% { box-shadow: 0 0 12px rgba(var(--accent-400), 0.3); }
|
||||||
|
50% { box-shadow: 0 0 24px rgba(var(--accent-400), 0.55); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-slide-up {
|
||||||
|
animation: fadeSlideUp 0.12s ease-out both;
|
||||||
|
}
|
||||||
|
.animate-scale-in {
|
||||||
|
animation: scaleIn 0.12s ease-out both;
|
||||||
|
}
|
||||||
|
.animate-glow-pulse {
|
||||||
|
animation: glowPulse 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Overbooking blink animation ──────────────────────────────────────────── */
|
/* ─── Overbooking blink animation ──────────────────────────────────────────── */
|
||||||
@keyframes overbooking-blink {
|
@keyframes overbooking-blink {
|
||||||
0%, 100% { background-color: rgba(239, 68, 68, 0); }
|
0%, 100% { background-color: rgba(239, 68, 68, 0); }
|
||||||
@@ -480,6 +553,12 @@
|
|||||||
animation: shimmer 1.8s ease-in-out infinite;
|
animation: shimmer 1.8s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:is(.dark) .shimmer-skeleton {
|
||||||
|
background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.09) 50%, rgba(255,255,255,0.04) 100%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: shimmer 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Table row stagger entrance ─────────────────────────────────────────── */
|
/* ─── Table row stagger entrance ─────────────────────────────────────────── */
|
||||||
@keyframes fadeSlideIn {
|
@keyframes fadeSlideIn {
|
||||||
from {
|
from {
|
||||||
@@ -493,20 +572,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.animate-row-enter {
|
.animate-row-enter {
|
||||||
animation: fadeSlideIn 0.25s ease-out both;
|
animation: fadeSlideIn 0.12s ease-out both;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Subtle hover lift for cards and table rows ─────────────────────────── */
|
/* ─── Subtle hover lift for cards and table rows ─────────────────────────── */
|
||||||
.hover-lift {
|
.hover-lift {
|
||||||
transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
|
transition: transform 0.1s ease-out, box-shadow 0.1s ease-out;
|
||||||
}
|
}
|
||||||
.hover-lift:hover {
|
.hover-lift:hover {
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 6px 20px rgba(var(--accent-400), 0.18), 0 2px 8px rgba(0,0,0,0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(.dark) .hover-lift:hover {
|
:is(.dark) .hover-lift:hover {
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
box-shadow: 0 6px 24px rgba(var(--accent-400), 0.22), 0 2px 8px rgba(0,0,0,0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── Smooth scroll + reduced-motion accessibility ────────────────────────── */
|
/* ─── Smooth scroll + reduced-motion accessibility ────────────────────────── */
|
||||||
@@ -530,7 +609,7 @@ html {
|
|||||||
/* ─── Table row hover accent border ──────────────────────────────────────── */
|
/* ─── Table row hover accent border ──────────────────────────────────────── */
|
||||||
.table-row-hover {
|
.table-row-hover {
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
transition: border-color 0.15s ease-out, background-color 0.15s ease-out, transform 0.15s ease-out, box-shadow 0.15s ease-out;
|
transition: border-color 100ms ease-out, background-color 100ms ease-out, transform 100ms ease-out, box-shadow 100ms ease-out;
|
||||||
}
|
}
|
||||||
.table-row-hover:hover {
|
.table-row-hover:hover {
|
||||||
border-left-color: rgb(var(--accent-400));
|
border-left-color: rgb(var(--accent-400));
|
||||||
|
|||||||
@@ -334,17 +334,17 @@ const NavItemLink = memo(function NavItemLink({
|
|||||||
href={href as Route}
|
href={href as Route}
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"group relative flex items-center rounded-2xl text-sm font-medium transition-colors",
|
"group relative flex items-center rounded-2xl text-sm transition-colors",
|
||||||
collapsed ? "justify-center px-2 py-2" : "gap-3 px-3 py-2",
|
collapsed ? "justify-center px-2 py-2" : "gap-3 px-3 py-2",
|
||||||
isActive
|
isActive
|
||||||
? "text-brand-800 dark:text-brand-200"
|
? "font-medium text-brand-700 dark:border-l-2 dark:border-brand-400/70 dark:text-brand-300"
|
||||||
: "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-slate-900 dark:hover:text-white",
|
: "font-medium text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-white/[0.05] dark:hover:text-white",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isActive && (
|
{isActive && (
|
||||||
<motion.div
|
<motion.div
|
||||||
layoutId="nav-indicator"
|
layoutId="nav-indicator"
|
||||||
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-100 to-brand-50/80 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-900/30 dark:to-brand-800/20 dark:ring-brand-900/40"
|
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-50 to-brand-100/60 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-500/15 dark:to-brand-400/[0.08] dark:ring-brand-900/40"
|
||||||
transition={{ type: "spring", stiffness: 350, damping: 30 }}
|
transition={{ type: "spring", stiffness: 350, damping: 30 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -426,7 +426,7 @@ function SidebarContent({
|
|||||||
sidebarCollapsed ? "px-3 py-4" : "px-6 py-6",
|
sidebarCollapsed ? "px-3 py-4" : "px-6 py-6",
|
||||||
)}>
|
)}>
|
||||||
<div className={clsx(
|
<div className={clsx(
|
||||||
"inline-flex items-center rounded-2xl border border-brand-200/70 bg-gradient-to-br from-white to-brand-50 shadow-sm dark:border-brand-900/50 dark:from-slate-950 dark:to-slate-900",
|
"inline-flex items-center rounded-2xl border border-brand-200/70 bg-gradient-to-br from-white to-brand-50 shadow-sm dark:border-brand-900/40 dark:from-[#0d0e22] dark:to-[#13162a]",
|
||||||
sidebarCollapsed ? "p-2" : "gap-3 px-4 py-3",
|
sidebarCollapsed ? "p-2" : "gap-3 px-4 py-3",
|
||||||
)}>
|
)}>
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-brand-600 text-white shadow-lg shadow-brand-600/25">
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-brand-600 text-white shadow-lg shadow-brand-600/25">
|
||||||
@@ -551,7 +551,7 @@ function SidebarContent({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => toggleSection(entry.label)}
|
onClick={() => toggleSection(entry.label)}
|
||||||
className="flex w-full items-center gap-3 rounded-2xl px-3 py-2 text-sm font-medium text-gray-500 transition-all hover:bg-gray-100/90 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-slate-900 dark:hover:text-gray-200"
|
className="flex w-full items-center gap-3 rounded-2xl px-3 py-2 text-sm font-medium text-gray-500 transition-all hover:bg-gray-100/90 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/[0.05] dark:hover:text-gray-200"
|
||||||
>
|
>
|
||||||
<IconFrame><AdminIcon /></IconFrame>
|
<IconFrame><AdminIcon /></IconFrame>
|
||||||
<span className="flex-1 text-left">{entry.label}</span>
|
<span className="flex-1 text-left">{entry.label}</span>
|
||||||
@@ -587,14 +587,14 @@ function SidebarContent({
|
|||||||
className={clsx(
|
className={clsx(
|
||||||
"group relative flex items-center gap-3 rounded-2xl px-3 py-1.5 text-sm font-medium transition-colors",
|
"group relative flex items-center gap-3 rounded-2xl px-3 py-1.5 text-sm font-medium transition-colors",
|
||||||
isActive
|
isActive
|
||||||
? "text-brand-800 dark:text-brand-200"
|
? "text-brand-700 dark:border-l-2 dark:border-brand-400/70 dark:text-brand-300"
|
||||||
: "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-slate-900 dark:hover:text-white",
|
: "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-white/[0.05] dark:hover:text-white",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isActive && (
|
{isActive && (
|
||||||
<motion.div
|
<motion.div
|
||||||
layoutId="nav-indicator"
|
layoutId="nav-indicator"
|
||||||
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-100 to-brand-50/80 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-900/30 dark:to-brand-800/20 dark:ring-brand-900/40"
|
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-50 to-brand-100/60 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-500/15 dark:to-brand-400/[0.08] dark:ring-brand-900/40"
|
||||||
transition={{ type: "spring", stiffness: 350, damping: 30 }}
|
transition={{ type: "spring", stiffness: 350, damping: 30 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -649,7 +649,7 @@ function SidebarContent({
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={onChatOpen}
|
onClick={onChatOpen}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900",
|
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
|
||||||
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -667,7 +667,7 @@ function SidebarContent({
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={onPrefsOpen}
|
onClick={onPrefsOpen}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900",
|
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
|
||||||
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -686,7 +686,7 @@ function SidebarContent({
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={() => void signOut({ callbackUrl: "/auth/signin" })}
|
onClick={() => void signOut({ callbackUrl: "/auth/signin" })}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900",
|
"flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
|
||||||
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -705,7 +705,7 @@ function SidebarContent({
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={onToggleCollapse}
|
onClick={onToggleCollapse}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"flex w-full items-center rounded-2xl text-sm text-gray-400 transition-colors hover:bg-gray-100/90 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-slate-900 dark:hover:text-gray-300",
|
"flex w-full items-center rounded-2xl text-sm text-gray-400 transition-colors hover:bg-gray-100/90 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-white/[0.05] dark:hover:text-gray-300",
|
||||||
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -741,7 +741,7 @@ function DesktopSidebar({
|
|||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"hidden shrink-0 border-r border-gray-200/60 bg-white/60 shadow-[1px_0_12px_rgba(0,0,0,0.03)] backdrop-blur-2xl backdrop-saturate-150 dark:border-slate-800 dark:bg-slate-950/75 dark:shadow-none lg:flex lg:flex-col",
|
"hidden shrink-0 border-r border-gray-200/60 bg-white/95 shadow-[1px_0_12px_rgba(0,0,0,0.03)] backdrop-blur-xl backdrop-saturate-150 dark:border-white/[0.06] dark:bg-[#0d0e22]/90 dark:shadow-none lg:flex lg:flex-col",
|
||||||
"transition-[width] duration-200 ease-out overflow-hidden",
|
"transition-[width] duration-200 ease-out overflow-hidden",
|
||||||
sidebarCollapsed ? "w-[72px]" : "w-72",
|
sidebarCollapsed ? "w-[72px]" : "w-72",
|
||||||
)}
|
)}
|
||||||
@@ -793,7 +793,7 @@ function MobileSidebar({
|
|||||||
animate={{ x: 0 }}
|
animate={{ x: 0 }}
|
||||||
exit={{ x: -288 }}
|
exit={{ x: -288 }}
|
||||||
transition={{ type: "spring", stiffness: 400, damping: 35 }}
|
transition={{ type: "spring", stiffness: 400, damping: 35 }}
|
||||||
className="fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-gray-200/60 bg-white/95 shadow-2xl backdrop-blur-2xl backdrop-saturate-150 dark:border-slate-800 dark:bg-slate-950/95 lg:hidden"
|
className="fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-gray-200/60 bg-white/95 shadow-2xl backdrop-blur-2xl backdrop-saturate-150 dark:border-white/[0.06] dark:bg-[#0d0e22]/95 lg:hidden"
|
||||||
>
|
>
|
||||||
{/* Close button */}
|
{/* Close button */}
|
||||||
<button
|
<button
|
||||||
@@ -897,7 +897,7 @@ export function AppShell({ children, userRole = "USER" }: { children: React.Reac
|
|||||||
{/* Main content area */}
|
{/* Main content area */}
|
||||||
<main ref={contentRef} className="flex-1 overflow-auto bg-transparent">
|
<main ref={contentRef} className="flex-1 overflow-auto bg-transparent">
|
||||||
{/* Mobile hamburger */}
|
{/* Mobile hamburger */}
|
||||||
<div className="sticky top-0 z-20 flex items-center border-b border-gray-200/60 bg-white/80 px-4 py-2 backdrop-blur-lg dark:border-slate-800 dark:bg-slate-950/80 lg:hidden">
|
<div className="sticky top-0 z-20 flex items-center border-b border-gray-200/60 bg-white/85 px-4 py-2 backdrop-blur-xl dark:border-white/[0.06] dark:bg-[#0d0e22]/82 lg:hidden">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setMobileOpen(true)}
|
onClick={() => setMobileOpen(true)}
|
||||||
|
|||||||
Reference in New Issue
Block a user