feat: implement glassmorphic depth design system for UI components
- Introduced a comprehensive glassmorphic design system to enhance visual hierarchy in UI elements such as modals, toasts, and floating panels. - Added detailed design principles, color usage guidelines, and component structure examples to AGENTS.md. - Updated AISmartSidebar component to utilize layered glass effects and smooth animations. - Enhanced CSS styles for glassmorphic elements, ensuring performance optimizations and accessibility considerations. These changes aim to elevate the user experience through refined aesthetics and improved interaction dynamics. Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
parent
b26ebc0b53
commit
b53db73211
|
|
@ -107,6 +107,114 @@ import { Button, Modal } from "@follow/components"
|
|||
import { FeedList } from "~/modules/name/components"
|
||||
```
|
||||
|
||||
## Glassmorphic Depth Design System
|
||||
|
||||
Follow uses a sophisticated glassmorphic depth design system for elevated UI components (modals, toasts, floating panels, etc.). This design provides visual hierarchy through layered transparency and subtle color accents.
|
||||
|
||||
### Design Principles
|
||||
|
||||
- **Multi-layer Depth**: Create visual depth through stacked transparent layers
|
||||
- **Subtle Color Accents**: Use brand colors at very low opacity (5-20%) for borders, glows, and backgrounds
|
||||
- **Refined Blur**: Heavy backdrop blur (backdrop-blur-2xl) for frosted glass effect
|
||||
- **Minimal Shadows**: Combine multiple soft shadows with accent colors for depth perception
|
||||
- **Smooth Animations**: Use Spring presets for all transitions
|
||||
|
||||
### Color Usage
|
||||
|
||||
- **Primary Accent**: `#FF5C00` (orange) at 5-20% opacity for borders, glows, and highlights
|
||||
- **Border**: `rgba(255, 92, 0, 0.2)` for main borders
|
||||
- **Inner Glow**: `rgba(255, 92, 0, 0.05)` for subtle radial/linear gradients inside containers
|
||||
- **Shadows**: Layered shadows with accent tint:
|
||||
- `0 8px 32px rgba(255, 92, 0, 0.08)` - large soft glow
|
||||
- `0 4px 16px rgba(255, 92, 0, 0.06)` - medium shadow
|
||||
- `0 2px 8px rgba(0, 0, 0, 0.1)` - close depth
|
||||
|
||||
### Component Structure
|
||||
|
||||
```tsx
|
||||
<div
|
||||
className="rounded-2xl backdrop-blur-2xl"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"linear-gradient(to bottom right, rgba(var(--color-background) / 0.98), rgba(var(--color-background) / 0.95))",
|
||||
borderWidth: "1px",
|
||||
borderStyle: "solid",
|
||||
borderColor: "rgba(255, 92, 0, 0.2)",
|
||||
boxShadow:
|
||||
"0 8px 32px rgba(255, 92, 0, 0.08), 0 4px 16px rgba(255, 92, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.1)",
|
||||
}}
|
||||
>
|
||||
{/* Inner glow layer */}
|
||||
<div
|
||||
className="absolute inset-0 rounded-2xl"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to bottom right, rgba(255, 92, 0, 0.05), transparent, rgba(255, 92, 0, 0.05))",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Content */}
|
||||
<div className="relative">{/* Your content here */}</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Interactive Elements
|
||||
|
||||
For hover states on buttons or interactive areas within glass containers:
|
||||
|
||||
```tsx
|
||||
<button
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background =
|
||||
"linear-gradient(to right, rgba(255, 92, 0, 0.08), rgba(255, 140, 0, 0.05))"
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = "transparent"
|
||||
}}
|
||||
>
|
||||
{/* Subtle shine effect */}
|
||||
<div className="via-gray/5 absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent to-transparent transition-transform duration-700 group-hover:translate-x-full dark:via-white/5" />
|
||||
</button>
|
||||
```
|
||||
|
||||
### Dividers
|
||||
|
||||
Use gradient dividers within glass containers:
|
||||
|
||||
```tsx
|
||||
<div
|
||||
className="mx-4 h-px"
|
||||
style={{
|
||||
background: "linear-gradient(to right, transparent, rgba(255, 92, 0, 0.2), transparent)",
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
### Animation Guidelines
|
||||
|
||||
- Entry animations: `initial={{ y: 8, opacity: 0 }}` → `animate={{ y: 0, opacity: 1 }}`
|
||||
- Use `Spring.presets.snappy` for quick interactions
|
||||
- Use `Spring.presets.smooth` for larger movements
|
||||
- Keep scale animations subtle (1.0 ↔ 1.02)
|
||||
|
||||
### When to Use
|
||||
|
||||
Apply this design system to:
|
||||
|
||||
- Toast notifications
|
||||
- Modal dialogs
|
||||
- Floating panels and popovers
|
||||
- Ambient UI prompts
|
||||
- Contextual menus
|
||||
- Elevated cards with actions
|
||||
|
||||
### Accessibility
|
||||
|
||||
- Ensure sufficient contrast for text over glass backgrounds
|
||||
- Maintain border visibility in both light and dark modes
|
||||
- Preserve keyboard focus indicators
|
||||
- Keep animations respectful of `prefers-reduced-motion`
|
||||
|
||||
## Build Outputs
|
||||
|
||||
- Desktop: `apps/desktop/out/` for packaged applications
|
||||
|
|
|
|||
|
|
@ -1,60 +1,54 @@
|
|||
/* CSS animations for AISmartSidebar (replacing motion/react) */
|
||||
/* Glassmorphic Depth Design - Apple-inspired elegant AI sidebar */
|
||||
|
||||
.ai-ambient-bar {
|
||||
/* Multi-layer glass edge bars with depth perception */
|
||||
.ai-glass-layer-1,
|
||||
.ai-glass-layer-2,
|
||||
.ai-glass-layer-3 {
|
||||
transform-origin: right center;
|
||||
transition:
|
||||
width 0.3s ease-out,
|
||||
opacity 0.3s ease-out,
|
||||
transform 0.3s ease-out;
|
||||
width 0.5s cubic-bezier(0.23, 1, 0.32, 1),
|
||||
opacity 0.5s cubic-bezier(0.23, 1, 0.32, 1),
|
||||
transform 0.5s cubic-bezier(0.23, 1, 0.32, 1),
|
||||
box-shadow 0.5s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
will-change: width, opacity, transform, box-shadow;
|
||||
}
|
||||
|
||||
@keyframes ai-bar-pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
/* Layered glass card with depth */
|
||||
.ai-glass-card {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.ai-ambient-pulse {
|
||||
animation: ai-bar-pulse 2s ease-in-out infinite;
|
||||
/* Premium glass button */
|
||||
.ai-glass-button {
|
||||
will-change: transform, box-shadow;
|
||||
position: relative;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.ai-glow-blob {
|
||||
transition:
|
||||
opacity 0.3s cubic-bezier(0.22, 1, 0.36, 1),
|
||||
transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
will-change: transform, opacity;
|
||||
border-radius: 9999px;
|
||||
/* Subtle shimmer on hover */
|
||||
.ai-glass-button:hover {
|
||||
box-shadow:
|
||||
0 4px 16px rgba(255, 92, 0, 0.15),
|
||||
0 8px 32px rgba(255, 92, 0, 0.08),
|
||||
inset 0 1px 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.ai-prompt-container {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
transition:
|
||||
opacity 0.25s cubic-bezier(0.22, 1, 0.36, 1),
|
||||
transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
/* Depth shadow for glass layers */
|
||||
.ai-glass-card > div {
|
||||
transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
}
|
||||
|
||||
.ai-prompt-visible {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
@keyframes ai-dot-pulse-kf {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 0.7;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.2);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-dot-pulse {
|
||||
animation: ai-dot-pulse-kf 2s ease-in-out infinite;
|
||||
/* Performance optimization with hardware acceleration */
|
||||
.ai-glass-layer-1,
|
||||
.ai-glass-layer-2,
|
||||
.ai-glass-layer-3,
|
||||
.ai-glass-card,
|
||||
.ai-glass-button {
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
perspective: 1000px;
|
||||
-webkit-perspective: 1000px;
|
||||
transform: translateZ(0);
|
||||
-webkit-transform: translateZ(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Replaced motion/react animations with CSS animations
|
||||
// Glassmorphic Depth Design - Apple-inspired elegant AI sidebar
|
||||
import "./AISmartSidebar.css"
|
||||
|
||||
import { useGlobalFocusableScopeSelector } from "@follow/components/common/Focusable/hooks.js"
|
||||
|
|
@ -55,70 +55,177 @@ const AIAmbientSidebar: React.FC<{ onExpand: () => void }> = ({ onExpand }) => {
|
|||
|
||||
const toggleAIChatShortcut = useCommandShortcut(COMMAND_ID.global.toggleAIChat)
|
||||
if (!canShowPrompt) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`ai-ambient-bar pointer-events-none fixed right-0 top-0 z-40 h-full w-2 ${
|
||||
intensity > 0.3 ? "ai-ambient-pulse" : ""
|
||||
}`}
|
||||
style={{
|
||||
opacity: intensity * 0.8,
|
||||
width: intensity > 0 ? 8 + intensity * 40 : 2,
|
||||
background: `linear-gradient(to left, rgba(255, 92, 0, ${intensity * 0.4}) 0%, rgba(255, 140, 0, ${intensity * 0.3}) 50%, transparent 100%)`,
|
||||
}}
|
||||
/>
|
||||
{/* Multi-layer glass edge with depth */}
|
||||
<div className="pointer-events-none fixed right-0 top-0 z-40 h-full">
|
||||
{/* Background layer - deepest */}
|
||||
<m.div
|
||||
className="ai-glass-layer-3 absolute right-0 top-0 h-full"
|
||||
style={{
|
||||
width: intensity > 0.1 ? 1 + intensity * 3 : 0,
|
||||
opacity: intensity * 0.15,
|
||||
background: "linear-gradient(to left, rgba(255, 92, 0, 0.15), transparent)",
|
||||
transform: `translateX(${intensity * -8}px)`,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Middle layer */}
|
||||
<m.div
|
||||
className="ai-glass-layer-2 absolute right-0 top-0 h-full"
|
||||
style={{
|
||||
width: intensity > 0.2 ? 1.5 + intensity * 4 : 0,
|
||||
opacity: intensity * 0.25,
|
||||
background: "linear-gradient(to left, rgba(255, 92, 0, 0.2), transparent)",
|
||||
transform: `translateX(${intensity * -4}px)`,
|
||||
boxShadow:
|
||||
intensity > 0.3
|
||||
? `0 0 ${12 + intensity * 20}px rgba(255, 92, 0, ${intensity * 0.15})`
|
||||
: "none",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Front layer - most prominent */}
|
||||
<m.div
|
||||
className="ai-glass-layer-1 absolute right-0 top-0 h-full"
|
||||
style={{
|
||||
width: intensity > 0 ? 2 + intensity * 6 : 1,
|
||||
opacity: intensity * 0.6,
|
||||
background: `linear-gradient(to left,
|
||||
rgba(255, 92, 0, ${intensity * 0.4}),
|
||||
rgba(255, 140, 0, ${intensity * 0.2}),
|
||||
transparent)`,
|
||||
boxShadow:
|
||||
intensity > 0.5
|
||||
? `0 0 ${16 + intensity * 24}px rgba(255, 92, 0, ${intensity * 0.25})`
|
||||
: "none",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Subtle ambient glow */}
|
||||
{intensity > 0.4 && (
|
||||
<m.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="absolute right-0 top-1/2 size-32 -translate-y-1/2"
|
||||
style={{
|
||||
opacity: (intensity - 0.4) * 0.3,
|
||||
background: `radial-gradient(ellipse at center,
|
||||
rgba(255, 92, 0, ${(intensity - 0.4) * 0.12}) 0%,
|
||||
transparent 70%)`,
|
||||
filter: "blur(30px)",
|
||||
transform: `translateY(-50%) translateX(${intensity * -20}px)`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<AnimatePresence>
|
||||
{showPrompt && (
|
||||
<>
|
||||
<m.div
|
||||
initial={{ opacity: 0, x: 30, scale: 0.95 }}
|
||||
animate={{ opacity: 1, x: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, x: 30, scale: 0.95 }}
|
||||
transition={Spring.presets.smooth}
|
||||
className="fixed bottom-12 right-6 z-50 flex flex-col items-end gap-3"
|
||||
style={{
|
||||
transform: `translateX(${intensity * -3}px)`,
|
||||
}}
|
||||
>
|
||||
{/* Unified glass card with integrated button */}
|
||||
<m.div
|
||||
initial={{ opacity: 0, scale: 0.5, x: 0 }}
|
||||
animate={{
|
||||
opacity: intensity * 0.6,
|
||||
scale: 0.5 + intensity * 1.5,
|
||||
x: intensity > 0 ? -10 - intensity * 30 : 0,
|
||||
}}
|
||||
exit={{ opacity: 0, scale: 0.5, x: 0 }}
|
||||
transition={Spring.presets.smooth}
|
||||
className="ai-glow-blob pointer-events-none fixed bottom-12 right-0 z-40"
|
||||
style={{
|
||||
opacity: intensity * 0.6,
|
||||
transform: `translateX(${intensity > 0 ? -10 - intensity * 30 : 0}px) scale(${0.5 + intensity * 1.5})`,
|
||||
width: 100,
|
||||
height: 100,
|
||||
background: `radial-gradient(circle, rgba(255, 92, 0, ${intensity * 0.3}) 0%, rgba(255, 140, 0, ${intensity * 0.2}) 40%, transparent 70%)`,
|
||||
}}
|
||||
/>
|
||||
<m.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: 20 }}
|
||||
className="ai-prompt-container ai-prompt-visible fixed bottom-12 right-6 z-50 flex flex-col items-end gap-3"
|
||||
className="ai-glass-card relative"
|
||||
initial={{ y: 8, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={Spring.presets.snappy}
|
||||
>
|
||||
<div className="rounded-2xl border border-folo/30 bg-background/90 px-4 py-3 backdrop-blur-xl">
|
||||
<div className="text-right">
|
||||
{/* Main unified card */}
|
||||
<div
|
||||
className="relative overflow-hidden rounded-2xl bg-gradient-to-br to-background/95 backdrop-blur-2xl"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"linear-gradient(to bottom right, rgba(var(--color-background) / 0.98), rgba(var(--color-background) / 0.95))",
|
||||
borderWidth: "1px",
|
||||
borderStyle: "solid",
|
||||
borderColor: "rgba(255, 92, 0, 0.2)",
|
||||
boxShadow:
|
||||
"0 8px 32px rgba(255, 92, 0, 0.08), 0 4px 16px rgba(255, 92, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.1)",
|
||||
}}
|
||||
>
|
||||
{/* Inner glow */}
|
||||
<div
|
||||
className="absolute inset-0 rounded-2xl"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to bottom right, rgba(255, 92, 0, 0.05), transparent, rgba(255, 92, 0, 0.05))",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Info section */}
|
||||
<div className="relative px-5 py-3.5 text-right">
|
||||
<p className="text-sm font-medium text-text">Ask AI anything</p>
|
||||
<p className="mt-1 text-xs text-text-secondary">
|
||||
<p className="mt-0.5 text-xs text-text-secondary">
|
||||
Get insights about this article
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-full border border-folo/40 bg-gradient-to-r from-folo/20 to-red-500/20 px-6 py-2 backdrop-blur-xl transition-all duration-300 hover:from-folo/30 hover:to-red-500/30"
|
||||
onClick={onExpand}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="ai-dot-pulse size-2 rounded-full bg-gradient-to-r from-folo to-red-500" />
|
||||
<span className="text-sm font-medium text-text">Open AI Chat</span>
|
||||
<KbdCombined abbr="Open AI Chat" joint className="rounded-full px-2">
|
||||
{toggleAIChatShortcut}
|
||||
</KbdCombined>
|
||||
</div>
|
||||
</button>
|
||||
{/* Divider */}
|
||||
<div
|
||||
className="mx-4 h-px"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to right, transparent, rgba(255, 92, 0, 0.2), transparent)",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Button section */}
|
||||
<button
|
||||
type="button"
|
||||
className="group relative w-full px-5 py-3 text-left transition-all duration-300"
|
||||
onClick={onExpand}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background =
|
||||
"linear-gradient(to right, rgba(255, 92, 0, 0.08), rgba(255, 140, 0, 0.05))"
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = "transparent"
|
||||
}}
|
||||
>
|
||||
{/* Subtle shine effect on hover */}
|
||||
<div className="absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-gray/5 to-transparent transition-transform duration-700 group-hover:translate-x-full dark:via-white/5" />
|
||||
|
||||
<div className="relative flex items-center justify-between">
|
||||
<div className="flex items-center gap-2.5">
|
||||
{/* Minimal indicator dot */}
|
||||
<m.div
|
||||
className="size-2 rounded-full"
|
||||
style={{ backgroundColor: "#FF5C00" }}
|
||||
animate={{
|
||||
opacity: [0.6, 1, 0.6],
|
||||
}}
|
||||
transition={{
|
||||
duration: 2,
|
||||
repeat: Number.POSITIVE_INFINITY,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
<span className="text-sm font-medium text-text">Open AI Chat</span>
|
||||
</div>
|
||||
|
||||
<KbdCombined
|
||||
abbr="Open AI Chat"
|
||||
joint
|
||||
className="rounded-md bg-fill/40 px-2 backdrop-blur-sm"
|
||||
>
|
||||
{toggleAIChatShortcut}
|
||||
</KbdCombined>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</m.div>
|
||||
</>
|
||||
</m.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ const DateItemInner: FC<DateItemInnerProps> = ({
|
|||
<div
|
||||
className={cn(
|
||||
className,
|
||||
isSticky && "border-border bg-background",
|
||||
"border-b border-transparent",
|
||||
"border-b border-transparent bg-background",
|
||||
isSticky && "border-border",
|
||||
)}
|
||||
onClick={stopPropagation}
|
||||
onMouseEnter={removeConfirm.cancel}
|
||||
|
|
|
|||
|
|
@ -52,3 +52,64 @@
|
|||
top: calc(env(safe-area-inset-top, 0px) + 20px);
|
||||
}
|
||||
}
|
||||
|
||||
[data-sonner-toast] {
|
||||
background-image: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(var(--color-background) / 0.98),
|
||||
rgba(var(--color-background) / 0.95)
|
||||
) !important;
|
||||
}
|
||||
[data-sonner-toast]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 1rem;
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(255, 92, 0, 0.05),
|
||||
transparent,
|
||||
rgba(255, 92, 0, 0.05)
|
||||
);
|
||||
z-index: -1;
|
||||
}
|
||||
[data-sonner-toast][data-type="success"]::before {
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(40, 205, 65, 0.05),
|
||||
transparent,
|
||||
rgba(40, 205, 65, 0.05)
|
||||
);
|
||||
}
|
||||
[data-sonner-toast][data-type="error"]::before {
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(255, 69, 58, 0.05),
|
||||
transparent,
|
||||
rgba(255, 69, 58, 0.05)
|
||||
);
|
||||
}
|
||||
[data-sonner-toast][data-type="warning"]::before {
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(255, 149, 0, 0.05),
|
||||
transparent,
|
||||
rgba(255, 149, 0, 0.05)
|
||||
);
|
||||
}
|
||||
[data-sonner-toast][data-type="info"]::before {
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(0, 122, 255, 0.05),
|
||||
transparent,
|
||||
rgba(0, 122, 255, 0.05)
|
||||
);
|
||||
}
|
||||
[data-sonner-toast][data-type="loading"]::before {
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(142, 142, 147, 0.05),
|
||||
transparent,
|
||||
rgba(142, 142, 147, 0.05)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
--fo-background: theme(colors.background);
|
||||
|
||||
--background: 0 0% 100%;
|
||||
--color-background: 255 255 255;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--radius: 0.5rem;
|
||||
|
|
@ -37,7 +38,7 @@
|
|||
--fo-background: theme(colors.background);
|
||||
|
||||
--background: 0 0% 7.1%;
|
||||
|
||||
--color-background: 18 18 18;
|
||||
--border: 0 0% 22.1%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
[data-theme="light"] {
|
||||
--background: 0 0% 100%;
|
||||
--color-background: 255 255 255;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--radius: 0.5rem;
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
|
||||
[data-theme="dark"] {
|
||||
--background: 0 0% 7.1%;
|
||||
--color-background: 18 18 18;
|
||||
|
||||
--border: 0 0% 22.1%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,22 @@
|
|||
export const toastStyles = {
|
||||
toast: tw`
|
||||
group relative flex w-full items-center justify-between gap-3 rounded-2xl p-4 shadow-lg
|
||||
backdrop-blur-background border border-border/50
|
||||
bg-material-ultra-thick duration-300 ease-out
|
||||
data-[type=success]:border-green/30 data-[type=success]:bg-green/20
|
||||
data-[type=error]:border-red/30 data-[type=error]:bg-red/20
|
||||
data-[type=warning]:border-orange/30 data-[type=warning]:bg-orange/20
|
||||
data-[type=info]:border-blue/30 data-[type=info]:bg-blue/20
|
||||
data-[type=loading]:border-gray/30 data-[type=loading]:bg-gray/20
|
||||
group relative flex w-full items-center justify-between gap-3 rounded-2xl p-4
|
||||
backdrop-blur-2xl duration-300 ease-out overflow-hidden
|
||||
max-w-md min-w-[320px]
|
||||
font-theme
|
||||
[&]:border [&]:border-solid
|
||||
[&]:data-[type=default]:border-[rgba(255,92,0,0.2)]
|
||||
[&]:data-[type=success]:border-[rgba(40,205,65,0.2)]
|
||||
[&]:data-[type=error]:border-[rgba(255,69,58,0.2)]
|
||||
[&]:data-[type=warning]:border-[rgba(255,149,0,0.2)]
|
||||
[&]:data-[type=info]:border-[rgba(0,122,255,0.2)]
|
||||
[&]:data-[type=loading]:border-[rgba(142,142,147,0.2)]
|
||||
[&]:shadow-[0_8px_32px_rgba(255,92,0,0.08),0_4px_16px_rgba(255,92,0,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
[&]:data-[type=success]:shadow-[0_8px_32px_rgba(40,205,65,0.08),0_4px_16px_rgba(40,205,65,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
[&]:data-[type=error]:shadow-[0_8px_32px_rgba(255,69,58,0.08),0_4px_16px_rgba(255,69,58,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
[&]:data-[type=warning]:shadow-[0_8px_32px_rgba(255,149,0,0.08),0_4px_16px_rgba(255,149,0,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
[&]:data-[type=info]:shadow-[0_8px_32px_rgba(0,122,255,0.08),0_4px_16px_rgba(0,122,255,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
[&]:data-[type=loading]:shadow-[0_8px_32px_rgba(142,142,147,0.08),0_4px_16px_rgba(142,142,147,0.06),0_2px_8px_rgba(0,0,0,0.1)]
|
||||
`,
|
||||
title: tw`
|
||||
text-sm font-medium text-text
|
||||
|
|
@ -25,7 +32,7 @@ export const toastStyles = {
|
|||
icon: tw`
|
||||
flex-shrink-0 mt-0.5 size-5
|
||||
[li[data-type="success"]_&]:text-green
|
||||
[li[data-type="error"]_&]:text-red
|
||||
[li[data-type="error"]_&]:text-red
|
||||
[li[data-type="warning"]_&]:text-orange
|
||||
[li[data-type="info"]_&]:text-blue
|
||||
[li[data-type="loading"]_&]:text-gray
|
||||
|
|
|
|||
Loading…
Reference in New Issue