|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import { type CSSProperties, type FocusEvent, useEffect, useRef, useState } from 'react';
|
|
|
|
|
import { type CSSProperties, type FocusEvent, useCallback, useEffect, useRef, useState } from 'react';
|
|
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { usePathname, useRouter } from 'next/navigation';
|
|
|
|
|
import { clsx } from 'clsx';
|
|
|
|
|
@@ -76,19 +76,41 @@ const createDockTone = (
|
|
|
|
|
'--dock-item-ring': ring,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const dockGlassTone = createDockTone(
|
|
|
|
|
'rgba(255, 255, 255, 0.24)',
|
|
|
|
|
'rgba(255, 255, 255, 0.36)',
|
|
|
|
|
'rgba(255, 255, 255, 0.46)',
|
|
|
|
|
'rgba(255, 255, 255, 0.2)',
|
|
|
|
|
'rgba(255, 255, 255, 0.34)',
|
|
|
|
|
'var(--color-text-muted)',
|
|
|
|
|
'var(--color-text)',
|
|
|
|
|
'rgba(255, 255, 255, 0.34)',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const homeDockTone = createDockTone(
|
|
|
|
|
'rgba(255, 255, 255, 0.58)',
|
|
|
|
|
'rgba(255, 255, 255, 0.68)',
|
|
|
|
|
'rgba(255, 255, 255, 0.76)',
|
|
|
|
|
'rgba(255, 255, 255, 0.28)',
|
|
|
|
|
'rgba(255, 255, 255, 0.46)',
|
|
|
|
|
'var(--color-text-muted)',
|
|
|
|
|
'var(--color-text)',
|
|
|
|
|
'rgba(255, 255, 255, 0.42)',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const dockToneStyles: Record<string, DockToneStyle> = {
|
|
|
|
|
home: createDockTone('rgba(232, 248, 239, 0.58)', 'rgba(220, 244, 232, 0.74)', 'rgba(211, 239, 224, 0.82)', 'rgba(65, 151, 106, 0.16)', 'rgba(65, 151, 106, 0.24)', '#5b8f72', '#377458', 'rgba(65, 151, 106, 0.16)'),
|
|
|
|
|
archive: createDockTone('rgba(239, 235, 255, 0.56)', 'rgba(231, 226, 250, 0.72)', 'rgba(224, 217, 246, 0.8)', 'rgba(111, 92, 176, 0.15)', 'rgba(111, 92, 176, 0.23)', '#7a6d9f', '#5f5289', 'rgba(111, 92, 176, 0.15)'),
|
|
|
|
|
chess: createDockTone('rgba(255, 247, 222, 0.62)', 'rgba(255, 240, 207, 0.78)', 'rgba(252, 234, 194, 0.84)', 'rgba(164, 122, 36, 0.16)', 'rgba(164, 122, 36, 0.24)', '#8a7a4b', '#6f5d2e', 'rgba(164, 122, 36, 0.15)'),
|
|
|
|
|
admin: createDockTone('rgba(232, 244, 255, 0.6)', 'rgba(220, 238, 252, 0.76)', 'rgba(209, 232, 247, 0.84)', 'rgba(60, 129, 181, 0.16)', 'rgba(60, 129, 181, 0.25)', '#5f86a8', '#3d6f98', 'rgba(60, 129, 181, 0.15)'),
|
|
|
|
|
write: createDockTone('rgba(255, 239, 229, 0.62)', 'rgba(255, 230, 215, 0.78)', 'rgba(251, 221, 203, 0.84)', 'rgba(177, 94, 58, 0.16)', 'rgba(177, 94, 58, 0.24)', '#9a755f', '#7e5843', 'rgba(177, 94, 58, 0.15)'),
|
|
|
|
|
login: createDockTone('rgba(230, 248, 249, 0.58)', 'rgba(218, 241, 244, 0.74)', 'rgba(205, 235, 239, 0.82)', 'rgba(47, 139, 148, 0.16)', 'rgba(47, 139, 148, 0.24)', '#5f9298', '#3d7880', 'rgba(47, 139, 148, 0.15)'),
|
|
|
|
|
signup: createDockTone('rgba(249, 235, 255, 0.58)', 'rgba(243, 225, 251, 0.74)', 'rgba(236, 216, 246, 0.82)', 'rgba(139, 75, 160, 0.16)', 'rgba(139, 75, 160, 0.24)', '#94739f', '#795586', 'rgba(139, 75, 160, 0.15)'),
|
|
|
|
|
logout: createDockTone('rgba(255, 237, 240, 0.62)', 'rgba(255, 226, 231, 0.78)', 'rgba(249, 216, 223, 0.84)', 'rgba(173, 70, 86, 0.16)', 'rgba(173, 70, 86, 0.25)', '#9a6870', '#7e4b55', 'rgba(173, 70, 86, 0.15)'),
|
|
|
|
|
pin: createDockTone('rgba(255, 244, 226, 0.72)', 'rgba(255, 235, 210, 0.86)', 'rgba(250, 227, 197, 0.92)', 'rgba(181, 115, 45, 0.2)', 'rgba(181, 115, 45, 0.32)', '#957049', '#765530', 'rgba(181, 115, 45, 0.18)'),
|
|
|
|
|
menu: createDockTone('rgba(238, 247, 232, 0.58)', 'rgba(228, 241, 221, 0.74)', 'rgba(219, 235, 211, 0.82)', 'rgba(91, 140, 75, 0.16)', 'rgba(91, 140, 75, 0.24)', '#728c64', '#58734a', 'rgba(91, 140, 75, 0.15)'),
|
|
|
|
|
more: createDockTone('rgba(235, 243, 255, 0.6)', 'rgba(225, 236, 252, 0.76)', 'rgba(214, 228, 246, 0.84)', 'rgba(76, 118, 178, 0.16)', 'rgba(76, 118, 178, 0.24)', '#6e86a8', '#526d91', 'rgba(76, 118, 178, 0.15)'),
|
|
|
|
|
default: createDockTone('rgba(246, 247, 250, 0.58)', 'rgba(237, 240, 246, 0.76)', 'rgba(228, 233, 242, 0.84)', 'rgba(98, 110, 132, 0.14)', 'rgba(98, 110, 132, 0.22)', '#747d8d', '#596578', 'rgba(98, 110, 132, 0.14)'),
|
|
|
|
|
home: homeDockTone,
|
|
|
|
|
archive: createDockTone('rgba(222, 216, 255, 0.54)', 'rgba(222, 216, 255, 0.64)', 'rgba(222, 216, 255, 0.72)', 'rgba(255, 255, 255, 0.26)', 'rgba(151, 132, 214, 0.34)', '#6f668f', '#514274', 'rgba(151, 132, 214, 0.2)'),
|
|
|
|
|
chess: createDockTone('rgba(255, 229, 162, 0.54)', 'rgba(255, 229, 162, 0.64)', 'rgba(255, 229, 162, 0.72)', 'rgba(255, 255, 255, 0.28)', 'rgba(184, 134, 42, 0.34)', '#7b6d4a', '#665125', 'rgba(184, 134, 42, 0.2)'),
|
|
|
|
|
admin: createDockTone('rgba(192, 226, 255, 0.54)', 'rgba(192, 226, 255, 0.64)', 'rgba(192, 226, 255, 0.72)', 'rgba(255, 255, 255, 0.27)', 'rgba(81, 145, 195, 0.34)', '#627f96', '#3f6686', 'rgba(81, 145, 195, 0.2)'),
|
|
|
|
|
write: createDockTone('rgba(255, 209, 184, 0.54)', 'rgba(255, 209, 184, 0.64)', 'rgba(255, 209, 184, 0.72)', 'rgba(255, 255, 255, 0.28)', 'rgba(187, 106, 70, 0.34)', '#8c705f', '#724d38', 'rgba(187, 106, 70, 0.2)'),
|
|
|
|
|
login: createDockTone('rgba(190, 236, 238, 0.54)', 'rgba(190, 236, 238, 0.64)', 'rgba(190, 236, 238, 0.72)', 'rgba(255, 255, 255, 0.27)', 'rgba(68, 150, 158, 0.34)', '#63898c', '#446d72', 'rgba(68, 150, 158, 0.2)'),
|
|
|
|
|
signup: createDockTone('rgba(237, 207, 250, 0.54)', 'rgba(237, 207, 250, 0.64)', 'rgba(237, 207, 250, 0.72)', 'rgba(255, 255, 255, 0.27)', 'rgba(153, 91, 176, 0.34)', '#846c8e', '#684a78', 'rgba(153, 91, 176, 0.2)'),
|
|
|
|
|
logout: createDockTone('rgba(255, 207, 216, 0.54)', 'rgba(255, 207, 216, 0.64)', 'rgba(255, 207, 216, 0.72)', 'rgba(255, 255, 255, 0.28)', 'rgba(188, 84, 99, 0.34)', '#8f6970', '#714850', 'rgba(188, 84, 99, 0.2)'),
|
|
|
|
|
pin: createDockTone('rgba(255, 219, 170, 0.56)', 'rgba(255, 219, 170, 0.66)', 'rgba(255, 219, 170, 0.74)', 'rgba(255, 255, 255, 0.28)', 'rgba(184, 118, 44, 0.36)', '#8a704e', '#6b4f2d', 'rgba(184, 118, 44, 0.22)'),
|
|
|
|
|
menu: createDockTone('rgba(213, 234, 203, 0.54)', 'rgba(213, 234, 203, 0.64)', 'rgba(213, 234, 203, 0.72)', 'rgba(255, 255, 255, 0.27)', 'rgba(98, 143, 80, 0.34)', '#6f8366', '#526f44', 'rgba(98, 143, 80, 0.2)'),
|
|
|
|
|
more: createDockTone('rgba(210, 228, 255, 0.54)', 'rgba(210, 228, 255, 0.64)', 'rgba(210, 228, 255, 0.72)', 'rgba(255, 255, 255, 0.27)', 'rgba(86, 126, 183, 0.34)', '#6d7f98', '#4f688d', 'rgba(86, 126, 183, 0.2)'),
|
|
|
|
|
default: dockGlassTone,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getDockToneStyle = (key: string) => dockToneStyles[key] ?? dockToneStyles.default;
|
|
|
|
|
@@ -102,14 +124,16 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
const [isDockHovered, setIsDockHovered] = useState(false);
|
|
|
|
|
const [isDockFocused, setIsDockFocused] = useState(false);
|
|
|
|
|
const [isDockClosing, setIsDockClosing] = useState(false);
|
|
|
|
|
const isPinnedRef = useRef(isPinned);
|
|
|
|
|
const dockZoneRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
const dockLeaveTimerRef = useRef<number | null>(null);
|
|
|
|
|
const dockCollapseTimerRef = useRef<number | null>(null);
|
|
|
|
|
const pinToggleStartedByPointerRef = useRef(false);
|
|
|
|
|
const isAdmin = _hasHydrated && isLoggedIn && role?.includes('ADMIN');
|
|
|
|
|
const isDockOpen = isPinned || isDockHovered || isDockFocused;
|
|
|
|
|
const isDockRangeExpanded = isDockOpen || isDockClosing;
|
|
|
|
|
|
|
|
|
|
const clearDockTimers = () => {
|
|
|
|
|
const clearDockTimers = useCallback(() => {
|
|
|
|
|
if (dockLeaveTimerRef.current !== null) {
|
|
|
|
|
window.clearTimeout(dockLeaveTimerRef.current);
|
|
|
|
|
dockLeaveTimerRef.current = null;
|
|
|
|
|
@@ -119,7 +143,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
window.clearTimeout(dockCollapseTimerRef.current);
|
|
|
|
|
dockCollapseTimerRef.current = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const expandDock = () => {
|
|
|
|
|
clearDockTimers();
|
|
|
|
|
@@ -127,7 +151,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
setIsDockHovered(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const startDockCollapse = () => {
|
|
|
|
|
const startDockCollapse = useCallback(() => {
|
|
|
|
|
clearDockTimers();
|
|
|
|
|
setIsDockHovered(false);
|
|
|
|
|
setIsDockClosing(true);
|
|
|
|
|
@@ -135,7 +159,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
setIsDockClosing(false);
|
|
|
|
|
dockCollapseTimerRef.current = null;
|
|
|
|
|
}, DOCK_COLLAPSE_MS);
|
|
|
|
|
};
|
|
|
|
|
}, [clearDockTimers]);
|
|
|
|
|
|
|
|
|
|
const scheduleDockCollapse = () => {
|
|
|
|
|
if (isPinned || isDockFocused) return;
|
|
|
|
|
@@ -146,10 +170,44 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
}, DOCK_LEAVE_DELAY_MS);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const blurFocusedDockItem = useCallback(() => {
|
|
|
|
|
if (
|
|
|
|
|
document.activeElement instanceof HTMLElement &&
|
|
|
|
|
dockZoneRef.current?.contains(document.activeElement)
|
|
|
|
|
) {
|
|
|
|
|
document.activeElement.blur();
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const releaseUnpinnedDockAfterNavigation = useCallback(() => {
|
|
|
|
|
if (isPinnedRef.current) return;
|
|
|
|
|
|
|
|
|
|
const isPointerInsideDock = dockZoneRef.current?.matches(':hover') ?? false;
|
|
|
|
|
|
|
|
|
|
blurFocusedDockItem();
|
|
|
|
|
setIsDockFocused(false);
|
|
|
|
|
|
|
|
|
|
if (isPointerInsideDock) {
|
|
|
|
|
clearDockTimers();
|
|
|
|
|
setIsDockClosing(false);
|
|
|
|
|
setIsDockHovered(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startDockCollapse();
|
|
|
|
|
}, [blurFocusedDockItem, clearDockTimers, startDockCollapse]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
isPinnedRef.current = isPinned;
|
|
|
|
|
}, [isPinned]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const frameId = window.requestAnimationFrame(() => {
|
|
|
|
|
const savedValue = window.localStorage.getItem(DOCK_PINNED_STORAGE_KEY);
|
|
|
|
|
setIsPinned(savedValue === null ? true : savedValue === 'true');
|
|
|
|
|
const nextValue = savedValue === null ? true : savedValue === 'true';
|
|
|
|
|
|
|
|
|
|
isPinnedRef.current = nextValue;
|
|
|
|
|
setIsPinned(nextValue);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return () => window.cancelAnimationFrame(frameId);
|
|
|
|
|
@@ -158,24 +216,51 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const frameId = window.requestAnimationFrame(() => {
|
|
|
|
|
setIsMoreOpen(false);
|
|
|
|
|
releaseUnpinnedDockAfterNavigation();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return () => window.cancelAnimationFrame(frameId);
|
|
|
|
|
}, [pathname]);
|
|
|
|
|
}, [pathname, releaseUnpinnedDockAfterNavigation]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => clearDockTimers();
|
|
|
|
|
}, []);
|
|
|
|
|
}, [clearDockTimers]);
|
|
|
|
|
|
|
|
|
|
const handlePinnedChange = () => {
|
|
|
|
|
setIsPinned((previous) => {
|
|
|
|
|
const nextValue = !previous;
|
|
|
|
|
const nextValue = !isPinned;
|
|
|
|
|
const startedByPointer = pinToggleStartedByPointerRef.current;
|
|
|
|
|
const isPointerInsideDock = dockZoneRef.current?.matches(':hover') ?? false;
|
|
|
|
|
|
|
|
|
|
pinToggleStartedByPointerRef.current = false;
|
|
|
|
|
window.localStorage.setItem(DOCK_PINNED_STORAGE_KEY, String(nextValue));
|
|
|
|
|
clearDockTimers();
|
|
|
|
|
isPinnedRef.current = nextValue;
|
|
|
|
|
setIsPinned(nextValue);
|
|
|
|
|
|
|
|
|
|
if (nextValue) {
|
|
|
|
|
setIsDockClosing(false);
|
|
|
|
|
setIsDockHovered(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (startedByPointer) {
|
|
|
|
|
setIsDockFocused(false);
|
|
|
|
|
blurFocusedDockItem();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isPointerInsideDock) {
|
|
|
|
|
setIsDockClosing(false);
|
|
|
|
|
setIsDockHovered(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isDockFocused || startedByPointer) {
|
|
|
|
|
startDockCollapse();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsDockHovered(false);
|
|
|
|
|
setIsDockClosing(false);
|
|
|
|
|
setIsDockHovered(!nextValue);
|
|
|
|
|
return nextValue;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDockZoneFocus = () => {
|
|
|
|
|
@@ -307,7 +392,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
const active = item.isActive?.(pathname) ?? false;
|
|
|
|
|
const toneStyle = getDockToneStyle(item.key);
|
|
|
|
|
const itemClass = clsx(
|
|
|
|
|
'group/item relative flex h-12 w-12 items-center justify-center rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] transition duration-150 hover:-translate-y-1 hover:border-[var(--dock-item-border-hover)] hover:bg-[var(--dock-item-bg-hover)] hover:text-[var(--dock-item-fg-strong)] focus-visible:-translate-y-1',
|
|
|
|
|
'group/item relative flex h-12 w-12 items-center justify-center rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] backdrop-blur-[18px] transition duration-150 hover:-translate-y-1 hover:border-[var(--dock-item-border-hover)] hover:bg-[var(--dock-item-bg-hover)] hover:text-[var(--dock-item-fg-strong)] focus-visible:-translate-y-1',
|
|
|
|
|
active && 'border-[var(--dock-item-border-hover)] bg-[var(--dock-item-bg-active)] text-[var(--dock-item-fg-strong)] ring-1 ring-[var(--dock-item-ring)]',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@@ -333,6 +418,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
aria-current={active ? 'page' : undefined}
|
|
|
|
|
className={itemClass}
|
|
|
|
|
style={toneStyle}
|
|
|
|
|
onClick={releaseUnpinnedDockAfterNavigation}
|
|
|
|
|
>
|
|
|
|
|
{content}
|
|
|
|
|
</Link>
|
|
|
|
|
@@ -359,7 +445,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
const active = activeOverride ?? item.isActive?.(pathname) ?? false;
|
|
|
|
|
const toneStyle = getDockToneStyle(item.key);
|
|
|
|
|
const itemClass = clsx(
|
|
|
|
|
'flex h-12 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] px-1 text-[10px] font-semibold leading-none text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] transition-colors',
|
|
|
|
|
'flex h-12 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] px-1 text-[10px] font-semibold leading-none text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] backdrop-blur-[18px] transition-colors',
|
|
|
|
|
'hover:border-[var(--dock-item-border-hover)] hover:bg-[var(--dock-item-bg-hover)] hover:text-[var(--dock-item-fg-strong)] focus-visible:bg-[var(--dock-item-bg-active)]',
|
|
|
|
|
active && 'border-[var(--dock-item-border-hover)] bg-[var(--dock-item-bg-active)] text-[var(--dock-item-fg-strong)] ring-1 ring-[var(--dock-item-ring)]',
|
|
|
|
|
);
|
|
|
|
|
@@ -462,9 +548,12 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
title={isPinned ? 'Dock 고정 해제' : 'Dock 고정'}
|
|
|
|
|
aria-label={isPinned ? 'Dock 고정 해제' : 'Dock 고정'}
|
|
|
|
|
aria-pressed={isPinned}
|
|
|
|
|
onPointerDown={() => {
|
|
|
|
|
pinToggleStartedByPointerRef.current = true;
|
|
|
|
|
}}
|
|
|
|
|
onClick={handlePinnedChange}
|
|
|
|
|
className={clsx(
|
|
|
|
|
'group/item relative ml-1 flex h-12 w-12 items-center justify-center rounded-lg border border-[var(--dock-item-border-hover)] bg-[var(--dock-item-bg-active)] text-[var(--dock-item-fg-strong)] shadow-[var(--shadow-control)] ring-1 ring-[var(--dock-item-ring)] transition duration-150 hover:-translate-y-1 hover:bg-[var(--dock-item-bg-hover)]',
|
|
|
|
|
'group/item relative ml-1 flex h-12 w-12 items-center justify-center rounded-lg border border-[var(--dock-item-border-hover)] bg-[var(--dock-item-bg-active)] text-[var(--dock-item-fg-strong)] shadow-[var(--shadow-control)] ring-1 ring-[var(--dock-item-ring)] backdrop-blur-[18px] transition duration-150 hover:-translate-y-1 hover:bg-[var(--dock-item-bg-hover)]',
|
|
|
|
|
isPinned && 'shadow-[var(--shadow-dock)]',
|
|
|
|
|
)}
|
|
|
|
|
style={getDockToneStyle('pin')}
|
|
|
|
|
@@ -493,7 +582,7 @@ export default function DesktopDock({ isSidebarCollapsed, onOpenMobileMenu }: De
|
|
|
|
|
const active = item.isActive?.(pathname) ?? false;
|
|
|
|
|
const toneStyle = getDockToneStyle(item.key);
|
|
|
|
|
const className = clsx(
|
|
|
|
|
'inline-flex h-10 min-w-0 items-center justify-center gap-2 rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] px-3 text-sm font-semibold text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] transition-colors hover:border-[var(--dock-item-border-hover)] hover:bg-[var(--dock-item-bg-hover)] hover:text-[var(--dock-item-fg-strong)]',
|
|
|
|
|
'inline-flex h-10 min-w-0 items-center justify-center gap-2 rounded-lg border border-[var(--dock-item-border)] bg-[var(--dock-item-bg)] px-3 text-sm font-semibold text-[var(--dock-item-fg)] shadow-[var(--shadow-control)] backdrop-blur-[18px] transition-colors hover:border-[var(--dock-item-border-hover)] hover:bg-[var(--dock-item-bg-hover)] hover:text-[var(--dock-item-fg-strong)]',
|
|
|
|
|
active && 'border-[var(--dock-item-border-hover)] bg-[var(--dock-item-bg-active)] text-[var(--dock-item-fg-strong)] ring-1 ring-[var(--dock-item-ring)]',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|