mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
Simplify remaining comments in global.d.ts and SCSS theme files
- Remove file headers and verbose documentation from 2 global.d.ts files - Simplify 12 SCSS theme files by removing multi-line documentation blocks - Remove verbose inline comments that just repeat what the code does - Keep helpful inline comments for non-obvious code Files modified: - src/Prime/Resources/assets/global.d.ts - src/Toastr/Prime/Resources/assets/global.d.ts - src/Prime/Resources/assets/themes/aurora/aurora.scss - src/Prime/Resources/assets/themes/facebook/facebook.scss - src/Prime/Resources/assets/themes/google/google.scss - src/Prime/Resources/assets/themes/ios/ios.scss - src/Prime/Resources/assets/themes/jade/jade.scss - src/Prime/Resources/assets/themes/material/material.scss - src/Prime/Resources/assets/themes/minimal/minimal.scss - src/Prime/Resources/assets/themes/neon/neon.scss - src/Prime/Resources/assets/themes/onyx/onyx.scss - src/Prime/Resources/assets/themes/ruby/ruby.scss - src/Prime/Resources/assets/themes/sapphire/sapphire.scss - src/Prime/Resources/assets/themes/slack/slack.scss
This commit is contained in:
-16
@@ -1,23 +1,7 @@
|
||||
/**
|
||||
* @file TypeScript Global Declarations
|
||||
* @description Type definitions for global objects
|
||||
* @author Younes ENNAJI
|
||||
*/
|
||||
import type Flasher from './flasher'
|
||||
|
||||
/**
|
||||
* Extend the Window interface to include the global flasher instance.
|
||||
*
|
||||
* This allows TypeScript to recognize window.flasher as a valid property
|
||||
* with proper type information.
|
||||
*/
|
||||
declare global {
|
||||
interface Window {
|
||||
/**
|
||||
* Global PHPFlasher instance.
|
||||
*
|
||||
* Available as window.flasher in browser environments.
|
||||
*/
|
||||
flasher: Flasher
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +1,72 @@
|
||||
.fl-aurora {
|
||||
/* Theme variables - Defines the visual appearance of Aurora notifications */
|
||||
/* Base colors and appearance */
|
||||
--aurora-bg-light: rgba(255, 255, 255); /* Semi-transparent light background */
|
||||
--aurora-bg-dark: rgba(20, 20, 28); /* Semi-transparent dark background */
|
||||
--aurora-text-light: #1e293b; /* Light mode text color */
|
||||
--aurora-text-dark: #f8fafc; /* Dark mode text color */
|
||||
--aurora-shadow: 0 8px 25px rgba(0, 0, 0, 0.08); /* Light mode shadow */
|
||||
--aurora-shadow-dark: 0 10px 30px rgba(0, 0, 0, 0.16); /* Dark mode shadow */
|
||||
--aurora-border-radius: 4px; /* Rounded corners radius */
|
||||
--aurora-blur: 15px; /* Amount of backdrop blur */
|
||||
/* Gradient overlays for each notification type - Light mode */
|
||||
--aurora-bg-light: rgba(255, 255, 255);
|
||||
--aurora-bg-dark: rgba(20, 20, 28);
|
||||
--aurora-text-light: #1e293b;
|
||||
--aurora-text-dark: #f8fafc;
|
||||
--aurora-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
|
||||
--aurora-shadow-dark: 0 10px 30px rgba(0, 0, 0, 0.16);
|
||||
--aurora-border-radius: 4px;
|
||||
--aurora-blur: 15px;
|
||||
--aurora-success-gradient: linear-gradient(135deg, rgba(16, 185, 129, 0.08) 0%, rgba(16, 185, 129, 0.2) 100%);
|
||||
--aurora-info-gradient: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0.2) 100%);
|
||||
--aurora-warning-gradient: linear-gradient(135deg, rgba(245, 158, 11, 0.08) 0%, rgba(245, 158, 11, 0.2) 100%);
|
||||
--aurora-error-gradient: linear-gradient(135deg, rgba(239, 68, 68, 0.08) 0%, rgba(239, 68, 68, 0.2) 100%);
|
||||
/* Type-specific accent colors for progress bars */
|
||||
--aurora-success: #10b981; /* Success color (green) */
|
||||
--aurora-info: #3b82f6; /* Info color (blue) */
|
||||
--aurora-warning: #f59e0b; /* Warning color (orange) */
|
||||
--aurora-error: #ef4444; /* Error color (red) */
|
||||
--aurora-success: #10b981;
|
||||
--aurora-info: #3b82f6;
|
||||
--aurora-warning: #f59e0b;
|
||||
--aurora-error: #ef4444;
|
||||
}
|
||||
@keyframes auroraFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-12px) scale(0.98); /* Start slightly smaller */
|
||||
transform: translateY(-12px) scale(0.98);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1); /* End at full size */
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
.fl-aurora {
|
||||
/* Core appearance */
|
||||
background-color: var(--aurora-bg-light);
|
||||
color: var(--aurora-text-light);
|
||||
border-radius: var(--aurora-border-radius) var(--aurora-border-radius) 0 0; /* Rounded top corners */
|
||||
border-radius: var(--aurora-border-radius) var(--aurora-border-radius) 0 0;
|
||||
box-shadow: var(--aurora-shadow);
|
||||
padding: 16px 18px;
|
||||
margin: 10px 0;
|
||||
position: relative;
|
||||
animation: auroraFadeIn 0.35s cubic-bezier(0.21, 1.02, 0.73, 1); /* Custom easing */
|
||||
animation: auroraFadeIn 0.35s cubic-bezier(0.21, 1.02, 0.73, 1);
|
||||
font-family: var(--fl-font), sans-serif;
|
||||
overflow: hidden; /* Prevents gradient from leaking */
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
/* Glass morphism effect with backdrop blur */
|
||||
backdrop-filter: blur(var(--aurora-blur)); /* Creates frosted glass look */
|
||||
-webkit-backdrop-filter: blur(var(--aurora-blur)); /* Safari support */
|
||||
/**
|
||||
* Gradient overlay
|
||||
* Creates a colored gradient based on notification type
|
||||
*/
|
||||
overflow: hidden;
|
||||
will-change: transform, opacity;
|
||||
backdrop-filter: blur(var(--aurora-blur));
|
||||
-webkit-backdrop-filter: blur(var(--aurora-blur));
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0; /* Cover the entire notification */
|
||||
z-index: 0; /* Place behind content */
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
opacity: 0.8;
|
||||
border-radius: inherit; /* Match parent's border radius */
|
||||
border-radius: inherit;
|
||||
}
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and close button
|
||||
*/
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1; /* Place above gradient overlay */
|
||||
z-index: 1;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* The main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
flex: 1; /* Take available space */
|
||||
font-size: 0.9375rem; /* 15px at default font size */
|
||||
flex: 1;
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.5;
|
||||
font-weight: 500; /* Medium weight for better readability */
|
||||
font-weight: 500;
|
||||
margin-right: 10px;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
flex-shrink: 0; /* Prevent shrinking */
|
||||
flex-shrink: 0;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
background: rgba(0, 0, 0, 0.05); /* Subtle background */
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
@@ -100,13 +78,9 @@
|
||||
color: inherit;
|
||||
&:hover, &:focus {
|
||||
opacity: 1;
|
||||
background: rgba(0, 0, 0, 0.1); /* Darker on hover/focus */
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
@@ -114,22 +88,14 @@
|
||||
bottom: 2px;
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
border-radius: 6px; /* Rounded ends */
|
||||
opacity: 0.7; /* Slightly transparent */
|
||||
z-index: 1; /* Above gradient, below content */
|
||||
border-radius: 6px;
|
||||
opacity: 0.7;
|
||||
z-index: 1;
|
||||
}
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type gets its own gradient and progress bar color
|
||||
*/
|
||||
&.fl-success {
|
||||
&::before { background: var(--aurora-success-gradient); }
|
||||
.fl-progress { background-color: var(--aurora-success); }
|
||||
@@ -146,26 +112,18 @@
|
||||
&::before { background: var(--aurora-error-gradient); }
|
||||
.fl-progress { background-color: var(--aurora-error); }
|
||||
}
|
||||
/**
|
||||
* RTL support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-message {
|
||||
margin-right: 0;
|
||||
margin-left: 10px; /* Swap margins */
|
||||
margin-left: 10px;
|
||||
}
|
||||
.fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-aurora,
|
||||
@@ -174,14 +132,12 @@ html.fl-dark .fl-aurora,
|
||||
background-color: var(--aurora-bg-dark);
|
||||
color: var(--aurora-text-dark);
|
||||
box-shadow: var(--aurora-shadow-dark);
|
||||
/* Adjusted close button for dark mode */
|
||||
.fl-close {
|
||||
background: rgba(255, 255, 255, 0.1); /* Lighter background in dark mode */
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
&:hover, &:focus {
|
||||
background: rgba(255, 255, 255, 0.15); /* Lighter hover in dark mode */
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
}
|
||||
/* Stronger gradients for better visibility in dark mode */
|
||||
&.fl-success::before { background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(16, 185, 129, 0.25) 100%); }
|
||||
&.fl-info::before { background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(59, 130, 246, 0.25) 100%); }
|
||||
&.fl-warning::before { background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(245, 158, 11, 0.25) 100%); }
|
||||
|
||||
@@ -1,96 +1,74 @@
|
||||
.fl-facebook {
|
||||
/* Theme variables - Define the visual appearance of Facebook notifications */
|
||||
/* Base colors for light and dark modes */
|
||||
--fb-bg-light: #ffffff; /* White background in light mode */
|
||||
--fb-bg-dark: #242526; /* Dark gray in dark mode */
|
||||
--fb-text-light: #050505; /* Near-black text in light mode */
|
||||
--fb-text-secondary-light: #65676b; /* Gray secondary text in light mode */
|
||||
--fb-text-dark: #e4e6eb; /* Off-white text in dark mode */
|
||||
--fb-text-secondary-dark: #b0b3b8; /* Light gray secondary text in dark mode */
|
||||
--fb-hover-light: #f0f2f5; /* Light gray hover state in light mode */
|
||||
--fb-hover-dark: #3a3b3c; /* Dark gray hover state in dark mode */
|
||||
--fb-border-light: #e4e6eb; /* Light gray borders in light mode */
|
||||
--fb-border-dark: #3e4042; /* Dark gray borders in dark mode */
|
||||
--fb-blue: #1876f2; /* Facebook's signature blue */
|
||||
--fb-name-color: #050505; /* Username color in light mode */
|
||||
--fb-name-color-dark: #e4e6eb; /* Username color in dark mode */
|
||||
/* Type-specific colors for icons */
|
||||
--fb-success: #31a24c; /* Green for success notifications */
|
||||
--fb-info: #1876f2; /* Blue for info notifications */
|
||||
--fb-warning: #f7b928; /* Yellow for warning notifications */
|
||||
--fb-error: #e41e3f; /* Red for error notifications */
|
||||
/* Icon background colors - Light mode */
|
||||
--fb-success-bg: #e7f3ff; /* Light blue background for success icons */
|
||||
--fb-info-bg: #e7f3ff; /* Light blue background for info icons */
|
||||
--fb-warning-bg: #fff5cc; /* Light yellow background for warning icons */
|
||||
--fb-error-bg: #ffebe9; /* Light red background for error icons */
|
||||
/* Icon background colors - Dark mode */
|
||||
--fb-success-bg-dark: #263c4b; /* Dark blue background for success icons */
|
||||
--fb-info-bg-dark: #263c4b; /* Dark blue background for info icons */
|
||||
--fb-warning-bg-dark: #3e3c26; /* Dark yellow background for warning icons */
|
||||
--fb-error-bg-dark: #472835; /* Dark red background for error icons */
|
||||
/* Animation timing */
|
||||
--fb-animation-duration: 0.2s; /* Duration for entrance animation */
|
||||
--fb-bg-light: #ffffff;
|
||||
--fb-bg-dark: #242526;
|
||||
--fb-text-light: #050505;
|
||||
--fb-text-secondary-light: #65676b;
|
||||
--fb-text-dark: #e4e6eb;
|
||||
--fb-text-secondary-dark: #b0b3b8;
|
||||
--fb-hover-light: #f0f2f5;
|
||||
--fb-hover-dark: #3a3b3c;
|
||||
--fb-border-light: #e4e6eb;
|
||||
--fb-border-dark: #3e4042;
|
||||
--fb-blue: #1876f2;
|
||||
--fb-name-color: #050505;
|
||||
--fb-name-color-dark: #e4e6eb;
|
||||
--fb-success: #31a24c;
|
||||
--fb-info: #1876f2;
|
||||
--fb-warning: #f7b928;
|
||||
--fb-error: #e41e3f;
|
||||
--fb-success-bg: #e7f3ff;
|
||||
--fb-info-bg: #e7f3ff;
|
||||
--fb-warning-bg: #fff5cc;
|
||||
--fb-error-bg: #ffebe9;
|
||||
--fb-success-bg-dark: #263c4b;
|
||||
--fb-info-bg-dark: #263c4b;
|
||||
--fb-warning-bg-dark: #3e3c26;
|
||||
--fb-error-bg-dark: #472835;
|
||||
--fb-animation-duration: 0.2s;
|
||||
}
|
||||
@keyframes fbFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px); /* Start slightly above final position */
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at natural position */
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.fl-facebook {
|
||||
position: relative;
|
||||
margin: 8px 0; /* Spacing between notifications */
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; /* Facebook's font stack */
|
||||
margin: 8px 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
animation: fbFadeIn var(--fb-animation-duration) ease-out;
|
||||
/**
|
||||
* Main notification card
|
||||
* Contains icon, message, and actions
|
||||
*/
|
||||
.fl-fb-notification {
|
||||
background-color: var(--fb-bg-light);
|
||||
color: var(--fb-text-light);
|
||||
border-radius: 8px; /* Rounded corners */
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
align-items: flex-start; /* Align items to top for proper icon alignment */
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); /* Subtle shadow */
|
||||
transition: background-color 0.1s ease; /* Smooth hover transition */
|
||||
align-items: flex-start;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
transition: background-color 0.1s ease;
|
||||
&:hover {
|
||||
background-color: var(--fb-hover-light); /* Background change on hover */
|
||||
background-color: var(--fb-hover-light);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Icon container
|
||||
* Holds the notification type icon
|
||||
*/
|
||||
.fl-icon-container {
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0; /* Prevent icon from shrinking */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/**
|
||||
* Icon styling
|
||||
* Circular background with centered icon
|
||||
*/
|
||||
.fl-fb-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center; /* Center the SVG icon */
|
||||
justify-content: center;
|
||||
svg {
|
||||
color: white; /* Icon color is white in light mode */
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific icon styling
|
||||
* Each notification type has its own icon color
|
||||
*/
|
||||
.fl-fb-icon-success {
|
||||
background-color: var(--fb-success);
|
||||
}
|
||||
@@ -103,65 +81,37 @@
|
||||
.fl-fb-icon-error {
|
||||
background-color: var(--fb-error);
|
||||
}
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and timestamp
|
||||
*/
|
||||
.fl-content {
|
||||
flex: 1; /* Take available space */
|
||||
min-width: 0; /* Enable text truncation */
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 15px; /* Facebook's standard text size */
|
||||
line-height: 1.33; /* Improved readability */
|
||||
font-size: 15px;
|
||||
line-height: 1.33;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
/**
|
||||
* Username styling
|
||||
* For displaying user names in bold
|
||||
*/
|
||||
.fl-user-name {
|
||||
font-weight: 600; /* Bold weight for usernames */
|
||||
font-weight: 600;
|
||||
color: var(--fb-name-color);
|
||||
margin-right: 4px;
|
||||
}
|
||||
/**
|
||||
* Metadata container
|
||||
* Holds timestamp and additional info
|
||||
*/
|
||||
.fl-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/**
|
||||
* Timestamp styling
|
||||
* Shows when the notification was created
|
||||
*/
|
||||
.fl-time {
|
||||
font-size: 13px; /* Smaller text for timestamp */
|
||||
color: var(--fb-text-secondary-light); /* Gray secondary text color */
|
||||
font-size: 13px;
|
||||
color: var(--fb-text-secondary-light);
|
||||
}
|
||||
/**
|
||||
* Action buttons container
|
||||
* Holds interactive buttons like close
|
||||
*/
|
||||
.fl-actions {
|
||||
display: flex;
|
||||
margin-left: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
/**
|
||||
* Button styling
|
||||
* Circular buttons with hover effect
|
||||
*/
|
||||
.fl-button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%; /* Circular button */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -170,49 +120,37 @@
|
||||
cursor: pointer;
|
||||
color: var(--fb-text-secondary-light);
|
||||
margin-left: 8px;
|
||||
transition: background-color 0.1s; /* Quick hover transition */
|
||||
transition: background-color 0.1s;
|
||||
&:hover {
|
||||
background-color: var(--fb-border-light); /* Darker background on hover */
|
||||
background-color: var(--fb-border-light);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Button icon container
|
||||
* Centers SVG icons within buttons
|
||||
*/
|
||||
.fl-button-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-icon-container {
|
||||
margin-right: 0;
|
||||
margin-left: 12px; /* Swap margins for RTL */
|
||||
margin-left: 12px;
|
||||
}
|
||||
.fl-user-name {
|
||||
margin-right: 0;
|
||||
margin-left: 4px; /* Swap margins for RTL */
|
||||
margin-left: 4px;
|
||||
}
|
||||
.fl-actions {
|
||||
margin-left: 0;
|
||||
margin-right: 12px; /* Swap margins for RTL */
|
||||
margin-right: 12px;
|
||||
}
|
||||
.fl-button {
|
||||
margin-left: 0;
|
||||
margin-right: 8px; /* Swap margins for RTL */
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-facebook,
|
||||
@@ -221,7 +159,7 @@ html.fl-dark .fl-facebook,
|
||||
.fl-fb-notification {
|
||||
background-color: var(--fb-bg-dark);
|
||||
color: var(--fb-text-dark);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); /* Stronger shadow in dark mode */
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
&:hover {
|
||||
background-color: var(--fb-hover-dark);
|
||||
}
|
||||
@@ -239,13 +177,9 @@ html.fl-dark .fl-facebook,
|
||||
background-color: var(--fb-border-dark);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific icon styling for dark mode
|
||||
* Uses darker backgrounds with colored icons for better visibility
|
||||
*/
|
||||
.fl-fb-icon-success {
|
||||
background-color: var(--fb-success-bg-dark);
|
||||
svg { color: var(--fb-success); } /* Icon color matches type in dark mode */
|
||||
svg { color: var(--fb-success); }
|
||||
}
|
||||
.fl-fb-icon-info {
|
||||
background-color: var(--fb-info-bg-dark);
|
||||
|
||||
@@ -1,252 +1,191 @@
|
||||
.fl-google {
|
||||
/* Theme variables - Define the visual appearance of Material Design notifications */
|
||||
/* Base colors and appearance for light and dark modes */
|
||||
--md-bg-light: #ffffff; /* Card background in light mode */
|
||||
--md-bg-dark: #2d2d2d; /* Card background in dark mode */
|
||||
--md-text-light: rgba(0, 0, 0, 0.87); /* Primary text in light mode (87% black) */
|
||||
--md-text-secondary-light: rgba(0, 0, 0, 0.6); /* Secondary text in light mode (60% black) */
|
||||
--md-text-dark: rgba(255, 255, 255, 0.87); /* Primary text in dark mode (87% white) */
|
||||
--md-text-secondary-dark: rgba(255, 255, 255, 0.6); /* Secondary text in dark mode (60% white) */
|
||||
/* Material Design elevation - multi-layered shadows */
|
||||
--md-elevation: 0 3px 5px -1px rgba(0,0,0,0.2), /* Ambient shadow */
|
||||
0 6px 10px 0 rgba(0,0,0,0.14), /* Penumbra shadow */
|
||||
0 1px 18px 0 rgba(0,0,0,0.12); /* Umbra shadow */
|
||||
--md-elevation-dark: 0 3px 5px -1px rgba(0,0,0,0.4), /* Darker ambient shadow */
|
||||
0 6px 10px 0 rgba(0,0,0,0.28), /* Darker penumbra shadow */
|
||||
0 1px 18px 0 rgba(0,0,0,0.24); /* Darker umbra shadow */
|
||||
--md-border-radius: 4px; /* Material Design default corner radius */
|
||||
/* Material Design color palette for notification types */
|
||||
--md-success: #43a047; /* Green 600 from Material palette */
|
||||
--md-info: #1e88e5; /* Blue 600 from Material palette */
|
||||
--md-warning: #fb8c00; /* Orange 600 from Material palette */
|
||||
--md-error: #e53935; /* Red 600 from Material palette */
|
||||
/* Animation timing variables */
|
||||
--md-animation-duration: 0.3s; /* Standard Material motion duration */
|
||||
--md-ripple-duration: 0.6s; /* Ripple effect duration */
|
||||
--md-bg-light: #ffffff;
|
||||
--md-bg-dark: #2d2d2d;
|
||||
--md-text-light: rgba(0, 0, 0, 0.87);
|
||||
--md-text-secondary-light: rgba(0, 0, 0, 0.6);
|
||||
--md-text-dark: rgba(255, 255, 255, 0.87);
|
||||
--md-text-secondary-dark: rgba(255, 255, 255, 0.6);
|
||||
--md-elevation: 0 3px 5px -1px rgba(0,0,0,0.2),
|
||||
0 6px 10px 0 rgba(0,0,0,0.14),
|
||||
0 1px 18px 0 rgba(0,0,0,0.12);
|
||||
--md-elevation-dark: 0 3px 5px -1px rgba(0,0,0,0.4),
|
||||
0 6px 10px 0 rgba(0,0,0,0.28),
|
||||
0 1px 18px 0 rgba(0,0,0,0.24);
|
||||
--md-border-radius: 4px;
|
||||
--md-success: #43a047;
|
||||
--md-info: #1e88e5;
|
||||
--md-warning: #fb8c00;
|
||||
--md-error: #e53935;
|
||||
--md-animation-duration: 0.3s;
|
||||
--md-ripple-duration: 0.6s;
|
||||
}
|
||||
@keyframes mdSlideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px); /* Start below final position */
|
||||
transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at final position */
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@keyframes mdRipple {
|
||||
to {
|
||||
transform: scale(4); /* Expand to 4x original size */
|
||||
opacity: 0; /* Fade out completely */
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.fl-google {
|
||||
position: relative;
|
||||
margin: 8px 0; /* Spacing between notifications */
|
||||
font-family: Roboto, "Segoe UI", Helvetica, Arial, sans-serif; /* Material uses Roboto */
|
||||
animation: mdSlideUp var(--md-animation-duration) cubic-bezier(0.4, 0, 0.2, 1); /* Material standard easing */
|
||||
/**
|
||||
* Main card container
|
||||
* Follows Material Design card component styling
|
||||
*/
|
||||
margin: 8px 0;
|
||||
font-family: Roboto, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
animation: mdSlideUp var(--md-animation-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
.fl-md-card {
|
||||
background-color: var(--md-bg-light);
|
||||
color: var(--md-text-light);
|
||||
border-radius: var(--md-border-radius);
|
||||
box-shadow: var(--md-elevation); /* Multi-layered shadow for depth */
|
||||
overflow: hidden; /* Contains progress bar */
|
||||
box-shadow: var(--md-elevation);
|
||||
overflow: hidden;
|
||||
}
|
||||
/**
|
||||
* Content section
|
||||
* Contains icon and text content
|
||||
*/
|
||||
.fl-content {
|
||||
padding: 16px; /* Standard Material padding */
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: flex-start; /* Align items to top */
|
||||
align-items: flex-start;
|
||||
}
|
||||
/**
|
||||
* Icon container
|
||||
* Holds the Material Design SVG icon
|
||||
*/
|
||||
.fl-icon-wrapper {
|
||||
margin-right: 16px; /* Space between icon and text */
|
||||
color: var(--md-text-secondary-light); /* Default icon color */
|
||||
flex-shrink: 0; /* Prevent icon from shrinking */
|
||||
margin-right: 16px;
|
||||
color: var(--md-text-secondary-light);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/**
|
||||
* Text content container
|
||||
* Holds title and message
|
||||
*/
|
||||
.fl-text-content {
|
||||
flex: 1; /* Take available space */
|
||||
flex: 1;
|
||||
}
|
||||
/**
|
||||
* Title styling
|
||||
* Following Material Design typography
|
||||
*/
|
||||
.fl-title {
|
||||
font-size: 1rem; /* 16px - Material body 1 */
|
||||
font-weight: 500; /* Medium weight per Material guidelines */
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Following Material Design typography
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.875rem; /* 14px - Material body 2 */
|
||||
line-height: 1.43; /* Material line height for body 2 */
|
||||
color: var(--md-text-secondary-light); /* Secondary text color (60% opacity) */
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.43;
|
||||
color: var(--md-text-secondary-light);
|
||||
}
|
||||
/**
|
||||
* Action buttons section
|
||||
* Contains dismiss button
|
||||
*/
|
||||
.fl-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end; /* Align buttons to right */
|
||||
padding: 8px; /* Standard Material padding */
|
||||
justify-content: flex-end;
|
||||
padding: 8px;
|
||||
}
|
||||
/**
|
||||
* Action button styling
|
||||
* Following Material Design "text button" guidelines
|
||||
*/
|
||||
.fl-action-button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: currentColor; /* Inherit color from parent */
|
||||
color: currentColor;
|
||||
font-family: inherit;
|
||||
font-weight: 500; /* Medium weight per Material specs */
|
||||
font-size: 0.8125rem; /* 13px - Material button text size */
|
||||
text-transform: uppercase; /* Material buttons use uppercase */
|
||||
letter-spacing: 0.0892857143em; /* Material's letter spacing for buttons */
|
||||
padding: 8px 12px; /* Material button padding */
|
||||
border-radius: 4px; /* Rounded corners per Material */
|
||||
font-weight: 500;
|
||||
font-size: 0.8125rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.0892857143em;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s; /* Smooth hover effect */
|
||||
position: relative; /* For ripple positioning */
|
||||
overflow: hidden; /* Contain ripple effect */
|
||||
transition: background-color 0.2s;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(0, 0, 0, 0.04); /* Material hover state - 4% opacity */
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
/**
|
||||
* Ripple effect
|
||||
* Material Design's signature ink ripple on interaction
|
||||
*/
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 5px; /* Initial small circle */
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: currentColor; /* Use button text color */
|
||||
background: currentColor;
|
||||
opacity: 0;
|
||||
border-radius: 50%; /* Perfect circle */
|
||||
border-radius: 50%;
|
||||
transform: scale(1);
|
||||
pointer-events: none; /* Don't interfere with clicks */
|
||||
pointer-events: none;
|
||||
}
|
||||
&:active::after {
|
||||
opacity: 0.3; /* Material ripple opacity */
|
||||
animation: mdRipple var(--md-ripple-duration) linear; /* Expand and fade */
|
||||
opacity: 0.3;
|
||||
animation: mdRipple var(--md-ripple-duration) linear;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type has its own color based on Material palette
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-success); /* Green icon */
|
||||
color: var(--md-success);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-success); /* Green button */
|
||||
color: var(--md-success);
|
||||
}
|
||||
}
|
||||
&.fl-info {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-info); /* Blue icon */
|
||||
color: var(--md-info);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-info); /* Blue button */
|
||||
color: var(--md-info);
|
||||
}
|
||||
}
|
||||
&.fl-warning {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-warning); /* Orange icon */
|
||||
color: var(--md-warning);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-warning); /* Orange button */
|
||||
color: var(--md-warning);
|
||||
}
|
||||
}
|
||||
&.fl-error {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-error); /* Red icon */
|
||||
color: var(--md-error);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-error); /* Red button */
|
||||
color: var(--md-error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar
|
||||
* Material Design linear progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px; /* Material's standard progress height */
|
||||
height: 4px;
|
||||
overflow: hidden;
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
transform-origin: left center; /* Animation starts from left */
|
||||
transform-origin: left center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific progress colors
|
||||
* Each notification type has its own progress bar color
|
||||
*/
|
||||
&.fl-success .fl-progress {
|
||||
background-color: var(--md-success); /* Green progress */
|
||||
background-color: var(--md-success);
|
||||
}
|
||||
&.fl-info .fl-progress {
|
||||
background-color: var(--md-info); /* Blue progress */
|
||||
background-color: var(--md-info);
|
||||
}
|
||||
&.fl-warning .fl-progress {
|
||||
background-color: var(--md-warning); /* Orange progress */
|
||||
background-color: var(--md-warning);
|
||||
}
|
||||
&.fl-error .fl-progress {
|
||||
background-color: var(--md-error); /* Red progress */
|
||||
background-color: var(--md-error);
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-content {
|
||||
flex-direction: row-reverse; /* Reverse flex direction */
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.fl-icon-wrapper {
|
||||
margin-right: 0;
|
||||
margin-left: 16px; /* Swap margins for RTL */
|
||||
margin-left: 16px;
|
||||
}
|
||||
.fl-actions {
|
||||
justify-content: flex-start; /* Align buttons to left in RTL */
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable slide animation */
|
||||
animation: none;
|
||||
.fl-action-button:active::after {
|
||||
animation: none; /* Disable ripple animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,16 +193,16 @@ body.fl-dark .fl-google,
|
||||
html.fl-dark .fl-google,
|
||||
.fl-google.fl-auto-dark {
|
||||
.fl-md-card {
|
||||
background-color: var(--md-bg-dark); /* Darker background */
|
||||
color: var(--md-text-dark); /* Lighter text */
|
||||
box-shadow: var(--md-elevation-dark); /* Stronger shadows */
|
||||
background-color: var(--md-bg-dark);
|
||||
color: var(--md-text-dark);
|
||||
box-shadow: var(--md-elevation-dark);
|
||||
}
|
||||
.fl-message {
|
||||
color: var(--md-text-secondary-dark); /* Lighter secondary text */
|
||||
color: var(--md-text-secondary-dark);
|
||||
}
|
||||
.fl-action-button {
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(255, 255, 255, 0.08); /* Material dark hover - 8% opacity */
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +1,47 @@
|
||||
.fl-ios {
|
||||
/* Theme variables - Define the visual appearance of iOS notifications */
|
||||
/* Base colors and appearance */
|
||||
--ios-bg-light: rgba(255, 255, 255); /* Semi-transparent white in light mode */
|
||||
--ios-bg-dark: rgba(30, 30, 30); /* Semi-transparent dark in dark mode */
|
||||
--ios-text-light: #000000; /* Black text in light mode */
|
||||
--ios-text-secondary-light: #6e6e6e; /* Gray secondary text in light mode */
|
||||
--ios-text-dark: #ffffff; /* White text in dark mode */
|
||||
--ios-text-secondary-dark: #a8a8a8; /* Light gray secondary text in dark mode */
|
||||
--ios-border-radius: 13px; /* iOS notification corner radius */
|
||||
--ios-shadow: 0 2px 12px rgba(0, 0, 0, 0.15); /* Light shadow in light mode */
|
||||
--ios-shadow-dark: 0 2px 12px rgba(0, 0, 0, 0.35); /* Darker shadow in dark mode */
|
||||
--ios-icon-size: 18px; /* Size for icons */
|
||||
--ios-blur: 30px; /* Amount of backdrop blur for glass effect */
|
||||
/* Type-specific colors following iOS palette */
|
||||
--ios-success: #34c759; /* iOS green */
|
||||
--ios-info: #007aff; /* iOS blue */
|
||||
--ios-warning: #ff9500; /* iOS orange */
|
||||
--ios-error: #ff3b30; /* iOS red */
|
||||
/* Animation timing */
|
||||
--ios-animation-duration: 0.4s; /* Duration for entrance animation */
|
||||
--ios-bg-light: rgba(255, 255, 255);
|
||||
--ios-bg-dark: rgba(30, 30, 30);
|
||||
--ios-text-light: #000000;
|
||||
--ios-text-secondary-light: #6e6e6e;
|
||||
--ios-text-dark: #ffffff;
|
||||
--ios-text-secondary-dark: #a8a8a8;
|
||||
--ios-border-radius: 13px;
|
||||
--ios-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||
--ios-shadow-dark: 0 2px 12px rgba(0, 0, 0, 0.35);
|
||||
--ios-icon-size: 18px;
|
||||
--ios-blur: 30px;
|
||||
--ios-success: #34c759;
|
||||
--ios-info: #007aff;
|
||||
--ios-warning: #ff9500;
|
||||
--ios-error: #ff3b30;
|
||||
--ios-animation-duration: 0.4s;
|
||||
}
|
||||
@keyframes iosSlideIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-15px) scale(0.96); /* Start smaller and above */
|
||||
transform: translateY(-15px) scale(0.96);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1); /* End at normal size and position */
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes iosExpand {
|
||||
0% {
|
||||
max-height: 0; /* Start collapsed */
|
||||
opacity: 0; /* Start hidden */
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
max-height: 100px; /* Expand to fit content */
|
||||
opacity: 1; /* Fade in */
|
||||
max-height: 100px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.fl-ios {
|
||||
position: relative;
|
||||
margin: 10px 0; /* Space between notifications */
|
||||
font-family: -apple-system, BlinkMacSystemFont, "San Francisco", "Helvetica Neue", Helvetica, Arial, sans-serif; /* Apple system fonts */
|
||||
animation: iosSlideIn var(--ios-animation-duration) cubic-bezier(0.23, 1, 0.32, 1); /* iOS-like easing */
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
/**
|
||||
* Main notification container
|
||||
* Replicates iOS notification card with frosted glass effect
|
||||
*/
|
||||
margin: 10px 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "San Francisco", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
animation: iosSlideIn var(--ios-animation-duration) cubic-bezier(0.23, 1, 0.32, 1);
|
||||
will-change: transform, opacity;
|
||||
.fl-ios-notification {
|
||||
background-color: var(--ios-bg-light);
|
||||
color: var(--ios-text-light);
|
||||
@@ -57,202 +49,149 @@
|
||||
box-shadow: var(--ios-shadow);
|
||||
padding: 12px 15px;
|
||||
position: relative;
|
||||
/* iOS-typical frosted glass effect */
|
||||
backdrop-filter: blur(var(--ios-blur));
|
||||
-webkit-backdrop-filter: blur(var(--ios-blur));
|
||||
}
|
||||
/**
|
||||
* Header section
|
||||
* Contains app icon, app name, and timestamp
|
||||
*/
|
||||
.fl-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
padding-right: 20px; /* Space for close button */
|
||||
padding-right: 20px;
|
||||
}
|
||||
/**
|
||||
* App icon container
|
||||
* Square with rounded corners like iOS app icons
|
||||
*/
|
||||
.fl-app-icon {
|
||||
width: 22px; /* Standard iOS notification icon size */
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 5px; /* iOS app icon corner radius */
|
||||
background-color: currentColor; /* Color based on notification type */
|
||||
border-radius: 5px;
|
||||
background-color: currentColor;
|
||||
margin-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0; /* Prevent icon from shrinking */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/**
|
||||
* SVG icon styling
|
||||
* White icon on colored background
|
||||
*/
|
||||
.fl-icon-svg {
|
||||
color: white; /* Icon is always white */
|
||||
color: white;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
/**
|
||||
* App info container
|
||||
* Holds app name and timestamp
|
||||
*/
|
||||
.fl-app-info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
}
|
||||
/**
|
||||
* App name styling
|
||||
* Bold text like in iOS notifications
|
||||
*/
|
||||
.fl-app-name {
|
||||
font-weight: 600; /* Semi-bold like iOS */
|
||||
font-size: 0.85rem; /* iOS app name size */
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
/**
|
||||
* Time display
|
||||
* Shows current time in iOS style
|
||||
*/
|
||||
.fl-time {
|
||||
font-size: 0.75rem; /* Smaller text for time */
|
||||
color: var(--ios-text-secondary-light); /* Gray secondary text */
|
||||
font-size: 0.75rem;
|
||||
color: var(--ios-text-secondary-light);
|
||||
margin-left: 5px;
|
||||
flex-shrink: 0; /* Prevent time from wrapping */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/**
|
||||
* Content/message area
|
||||
* Contains the notification message
|
||||
*/
|
||||
.fl-content {
|
||||
animation: iosExpand 0.3s forwards; /* Expand content after header appears */
|
||||
animation-delay: 0.1s; /* Slight delay for sequenced animation */
|
||||
overflow: hidden; /* Contain expansion animation */
|
||||
animation: iosExpand 0.3s forwards;
|
||||
animation-delay: 0.1s;
|
||||
overflow: hidden;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.95rem; /* iOS notification text size */
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
padding-right: 15px; /* Space for close button */
|
||||
padding-right: 15px;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular close button like in iOS
|
||||
*/
|
||||
.fl-close {
|
||||
position: absolute; /* Positioned in top right */
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 12px;
|
||||
width: 18px; /* Small circular button */
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background-color: rgba(0, 0, 0, 0.1); /* Subtle background */
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
color: var(--ios-text-light);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
opacity: 0.7; /* Semi-transparent by default */
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
padding: 0;
|
||||
&:hover, &:focus {
|
||||
opacity: 1; /* Full opacity on hover/focus */
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type gets its own app icon color
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-app-icon {
|
||||
color: var(--ios-success); /* Green for success */
|
||||
color: var(--ios-success);
|
||||
}
|
||||
}
|
||||
&.fl-info {
|
||||
.fl-app-icon {
|
||||
color: var(--ios-info); /* Blue for info */
|
||||
color: var(--ios-info);
|
||||
}
|
||||
}
|
||||
&.fl-warning {
|
||||
.fl-app-icon {
|
||||
color: var(--ios-warning); /* Orange for warning */
|
||||
color: var(--ios-warning);
|
||||
}
|
||||
}
|
||||
&.fl-error {
|
||||
.fl-app-icon {
|
||||
color: var(--ios-error); /* Red for error */
|
||||
color: var(--ios-error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-header {
|
||||
padding-right: 0;
|
||||
padding-left: 20px; /* Swap padding for RTL */
|
||||
padding-left: 20px;
|
||||
}
|
||||
.fl-app-icon {
|
||||
margin-right: 0;
|
||||
margin-left: 8px; /* Swap margins for RTL */
|
||||
margin-left: 8px;
|
||||
}
|
||||
.fl-time {
|
||||
margin-left: 0;
|
||||
margin-right: 5px; /* Swap margins for RTL */
|
||||
margin-right: 5px;
|
||||
}
|
||||
.fl-message {
|
||||
padding-right: 0;
|
||||
padding-left: 15px; /* Swap padding for RTL */
|
||||
padding-left: 15px;
|
||||
}
|
||||
.fl-close {
|
||||
right: auto;
|
||||
left: 12px; /* Move close button to left for RTL */
|
||||
left: 12px;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable entrance animation */
|
||||
animation: none;
|
||||
.fl-content {
|
||||
animation: none; /* Disable content expansion */
|
||||
max-height: none; /* Show full content */
|
||||
opacity: 1; /* Ensure content is visible */
|
||||
animation: none;
|
||||
max-height: none;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Mobile optimization
|
||||
* Full width on small screens
|
||||
*/
|
||||
@media screen and (max-width: 480px) {
|
||||
width: 100%; /* Full width on mobile */
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-ios,
|
||||
html.fl-dark .fl-ios,
|
||||
.fl-ios.fl-auto-dark {
|
||||
.fl-ios-notification {
|
||||
background-color: var(--ios-bg-dark); /* Dark, semi-transparent background */
|
||||
color: var(--ios-text-dark); /* Light text */
|
||||
box-shadow: var(--ios-shadow-dark); /* Stronger shadow */
|
||||
background-color: var(--ios-bg-dark);
|
||||
color: var(--ios-text-dark);
|
||||
box-shadow: var(--ios-shadow-dark);
|
||||
}
|
||||
.fl-time {
|
||||
color: var(--ios-text-secondary-dark); /* Lighter secondary text */
|
||||
color: var(--ios-text-secondary-dark);
|
||||
}
|
||||
.fl-close {
|
||||
background-color: rgba(255, 255, 255, 0.2); /* Lighter background for close button */
|
||||
color: var(--ios-text-dark); /* Light text color */
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
color: var(--ios-text-dark);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +1,75 @@
|
||||
.fl-jade {
|
||||
/* Theme variables - Define the visual appearance of Jade notifications */
|
||||
/* Base colors and appearance */
|
||||
--jade-text-light: #5f6c7b; /* Soft slate gray for text */
|
||||
--jade-text-dark: #e2e8f0; /* Light gray for dark mode text */
|
||||
--jade-shadow: 0 8px 24px rgba(149, 157, 165, 0.1); /* Subtle shadow */
|
||||
--jade-shadow-dark: 0 8px 24px rgba(0, 0, 0, 0.2); /* Stronger shadow for dark mode */
|
||||
--jade-border-radius: 4px; /* Large rounded corners */
|
||||
--jade-transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1); /* Material-inspired transition */
|
||||
/* Type-specific colors and backgrounds - Light mode */
|
||||
--jade-success-bg: #f0fdf4; /* Very light green background */
|
||||
--jade-success-color: #16a34a; /* Green text */
|
||||
--jade-info-bg: #eff6ff; /* Very light blue background */
|
||||
--jade-info-color: #3b82f6; /* Blue text */
|
||||
--jade-warning-bg: #fffbeb; /* Very light yellow background */
|
||||
--jade-warning-color: #f59e0b; /* Orange text */
|
||||
--jade-error-bg: #fef2f2; /* Very light red background */
|
||||
--jade-error-color: #dc2626; /* Red text */
|
||||
/* Dark mode backgrounds - Semi-transparent colored overlays */
|
||||
--jade-success-bg-dark: rgba(22, 163, 74, 0.15); /* Semi-transparent green */
|
||||
--jade-info-bg-dark: rgba(59, 130, 246, 0.15); /* Semi-transparent blue */
|
||||
--jade-warning-bg-dark: rgba(245, 158, 11, 0.15); /* Semi-transparent orange */
|
||||
--jade-error-bg-dark: rgba(220, 38, 38, 0.15); /* Semi-transparent red */
|
||||
--jade-text-light: #5f6c7b;
|
||||
--jade-text-dark: #e2e8f0;
|
||||
--jade-shadow: 0 8px 24px rgba(149, 157, 165, 0.1);
|
||||
--jade-shadow-dark: 0 8px 24px rgba(0, 0, 0, 0.2);
|
||||
--jade-border-radius: 4px;
|
||||
--jade-transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--jade-success-bg: #f0fdf4;
|
||||
--jade-success-color: #16a34a;
|
||||
--jade-info-bg: #eff6ff;
|
||||
--jade-info-color: #3b82f6;
|
||||
--jade-warning-bg: #fffbeb;
|
||||
--jade-warning-color: #f59e0b;
|
||||
--jade-error-bg: #fef2f2;
|
||||
--jade-error-color: #dc2626;
|
||||
--jade-success-bg-dark: rgba(22, 163, 74, 0.15);
|
||||
--jade-info-bg-dark: rgba(59, 130, 246, 0.15);
|
||||
--jade-warning-bg-dark: rgba(245, 158, 11, 0.15);
|
||||
--jade-error-bg-dark: rgba(220, 38, 38, 0.15);
|
||||
}
|
||||
@keyframes jadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px) scale(0.95); /* Start smaller and above */
|
||||
transform: translateY(-10px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1); /* End at normal size and position */
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
.fl-jade {
|
||||
padding: 1rem 1.25rem; /* Comfortable padding */
|
||||
margin: 0.5rem 0; /* Vertical spacing */
|
||||
padding: 1rem 1.25rem;
|
||||
margin: 0.5rem 0;
|
||||
position: relative;
|
||||
box-shadow: var(--jade-shadow); /* Subtle shadow for depth */
|
||||
border-radius: var(--jade-border-radius) var(--jade-border-radius) 0 0; /* Large rounded corners */
|
||||
animation: jadeIn 0.4s var(--jade-transition); /* Smooth entrance animation */
|
||||
box-shadow: var(--jade-shadow);
|
||||
border-radius: var(--jade-border-radius) var(--jade-border-radius) 0 0;
|
||||
animation: jadeIn 0.4s var(--jade-transition);
|
||||
font-family: var(--fl-font), serif;
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
border: 1px solid transparent; /* Border for type-specific colors */
|
||||
overflow: hidden; /* Contain progress bar */
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and close button
|
||||
*/
|
||||
will-change: transform, opacity;
|
||||
border: 1px solid transparent;
|
||||
overflow: hidden;
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center; /* Vertically center content */
|
||||
align-items: center;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
flex: 1; /* Take available space */
|
||||
font-size: 0.875rem; /* 14px at default size */
|
||||
line-height: 1.5; /* Comfortable line height */
|
||||
font-weight: 500; /* Medium weight for better readability */
|
||||
padding-right: 0.75rem; /* Space between text and close button */
|
||||
flex: 1;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
font-weight: 500;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.125rem; /* 18px close icon */
|
||||
font-size: 1.125rem;
|
||||
padding: 0.375rem;
|
||||
cursor: pointer;
|
||||
opacity: 0.6; /* Subtle appearance by default */
|
||||
transition: all var(--jade-transition); /* Smooth hover transition */
|
||||
border-radius: 50%; /* Circular button */
|
||||
width: 1.875rem; /* 30px diameter */
|
||||
opacity: 0.6;
|
||||
transition: all var(--jade-transition);
|
||||
border-radius: 50%;
|
||||
width: 1.875rem;
|
||||
height: 1.875rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0; /* Prevent button from shrinking */
|
||||
flex-shrink: 0;
|
||||
&:hover, &:focus {
|
||||
opacity: 1; /* Full opacity on hover/focus */
|
||||
background-color: rgba(0, 0, 0, 0.05); /* Subtle background on hover */
|
||||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -97,141 +77,104 @@
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 var(--jade-border-radius) var(--jade-border-radius); /* Match parent corners */
|
||||
opacity: 0.7; /* Slightly transparent */
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
border-radius: 0 0 var(--jade-border-radius) var(--jade-border-radius);
|
||||
opacity: 0.7;
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
/* Type-specific styling for each notification type */
|
||||
/**
|
||||
* Success notification styling
|
||||
* Green theme with appropriate hover states
|
||||
*/
|
||||
&.fl-success {
|
||||
background-color: var(--jade-success-bg);
|
||||
color: var(--jade-success-color);
|
||||
border-color: rgba(22, 163, 74, 0.1); /* Very subtle border */
|
||||
border-color: rgba(22, 163, 74, 0.1);
|
||||
.fl-close {
|
||||
color: var(--jade-success-color); /* Green close button */
|
||||
color: var(--jade-success-color);
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(22, 163, 74, 0.1); /* Green hover state */
|
||||
background-color: rgba(22, 163, 74, 0.1);
|
||||
}
|
||||
}
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--jade-success-color); /* Green progress bar */
|
||||
background-color: var(--jade-success-color);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Info notification styling
|
||||
* Blue theme with appropriate hover states
|
||||
*/
|
||||
&.fl-info {
|
||||
background-color: var(--jade-info-bg);
|
||||
color: var(--jade-info-color);
|
||||
border-color: rgba(59, 130, 246, 0.1); /* Very subtle border */
|
||||
border-color: rgba(59, 130, 246, 0.1);
|
||||
.fl-close {
|
||||
color: var(--jade-info-color); /* Blue close button */
|
||||
color: var(--jade-info-color);
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(59, 130, 246, 0.1); /* Blue hover state */
|
||||
background-color: rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
}
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--jade-info-color); /* Blue progress bar */
|
||||
background-color: var(--jade-info-color);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warning notification styling
|
||||
* Orange theme with appropriate hover states
|
||||
*/
|
||||
&.fl-warning {
|
||||
background-color: var(--jade-warning-bg);
|
||||
color: var(--jade-warning-color);
|
||||
border-color: rgba(245, 158, 11, 0.1); /* Very subtle border */
|
||||
border-color: rgba(245, 158, 11, 0.1);
|
||||
.fl-close {
|
||||
color: var(--jade-warning-color); /* Orange close button */
|
||||
color: var(--jade-warning-color);
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(245, 158, 11, 0.1); /* Orange hover state */
|
||||
background-color: rgba(245, 158, 11, 0.1);
|
||||
}
|
||||
}
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--jade-warning-color); /* Orange progress bar */
|
||||
background-color: var(--jade-warning-color);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Error notification styling
|
||||
* Red theme with appropriate hover states
|
||||
*/
|
||||
&.fl-error {
|
||||
background-color: var(--jade-error-bg);
|
||||
color: var(--jade-error-color);
|
||||
border-color: rgba(220, 38, 38, 0.1); /* Very subtle border */
|
||||
border-color: rgba(220, 38, 38, 0.1);
|
||||
.fl-close {
|
||||
color: var(--jade-error-color); /* Red close button */
|
||||
color: var(--jade-error-color);
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(220, 38, 38, 0.1); /* Red hover state */
|
||||
background-color: rgba(220, 38, 38, 0.1);
|
||||
}
|
||||
}
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--jade-error-color); /* Red progress bar */
|
||||
background-color: var(--jade-error-color);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-message {
|
||||
padding-right: 0;
|
||||
padding-left: 0.75rem; /* Swap padding for RTL */
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
.fl-progress .fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-jade,
|
||||
html.fl-dark .fl-jade,
|
||||
.fl-jade.fl-auto-dark {
|
||||
box-shadow: var(--jade-shadow-dark); /* Stronger shadow in dark mode */
|
||||
color: var(--jade-text-dark); /* Lighter text */
|
||||
/**
|
||||
* Type-specific backgrounds for dark mode
|
||||
* Uses semi-transparent colored overlays
|
||||
*/
|
||||
box-shadow: var(--jade-shadow-dark);
|
||||
color: var(--jade-text-dark);
|
||||
&.fl-success {
|
||||
background-color: var(--jade-success-bg-dark);
|
||||
border-color: rgba(22, 163, 74, 0.2); /* Slightly stronger border */
|
||||
border-color: rgba(22, 163, 74, 0.2);
|
||||
}
|
||||
&.fl-info {
|
||||
background-color: var(--jade-info-bg-dark);
|
||||
border-color: rgba(59, 130, 246, 0.2); /* Slightly stronger border */
|
||||
border-color: rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
&.fl-warning {
|
||||
background-color: var(--jade-warning-bg-dark);
|
||||
border-color: rgba(245, 158, 11, 0.2); /* Slightly stronger border */
|
||||
border-color: rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
&.fl-error {
|
||||
background-color: var(--jade-error-bg-dark);
|
||||
border-color: rgba(220, 38, 38, 0.2); /* Slightly stronger border */
|
||||
border-color: rgba(220, 38, 38, 0.2);
|
||||
}
|
||||
/**
|
||||
* Dark mode hover states
|
||||
* Lighter background for better visibility
|
||||
*/
|
||||
.fl-close:hover, .fl-close:focus {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@@ -1,234 +1,181 @@
|
||||
.fl-material {
|
||||
/* Theme variables - Define the visual appearance of Material Design notifications */
|
||||
/* Base colors and appearance for light and dark modes */
|
||||
--md-bg-light: #ffffff; /* Card background in light mode */
|
||||
--md-bg-dark: #2d2d2d; /* Card background in dark mode */
|
||||
--md-text-light: rgba(0, 0, 0, 0.87); /* Primary text in light mode (87% black) */
|
||||
--md-text-secondary-light: rgba(0, 0, 0, 0.6); /* Secondary text in light mode (60% black) */
|
||||
--md-text-dark: rgba(255, 255, 255, 0.87); /* Primary text in dark mode (87% white) */
|
||||
--md-text-secondary-dark: rgba(255, 255, 255, 0.6); /* Secondary text in dark mode (60% white) */
|
||||
/* Material Design elevation - multi-layered shadows */
|
||||
--md-elevation: 0 3px 5px -1px rgba(0,0,0,0.2), /* Ambient shadow */
|
||||
0 6px 10px 0 rgba(0,0,0,0.14), /* Penumbra shadow */
|
||||
0 1px 18px 0 rgba(0,0,0,0.12); /* Umbra shadow */
|
||||
--md-elevation-dark: 0 3px 5px -1px rgba(0,0,0,0.4), /* Darker ambient shadow */
|
||||
0 6px 10px 0 rgba(0,0,0,0.28), /* Darker penumbra shadow */
|
||||
0 1px 18px 0 rgba(0,0,0,0.24); /* Darker umbra shadow */
|
||||
--md-border-radius: 4px; /* Material Design default corner radius */
|
||||
/* Material Design color palette for notification types */
|
||||
--md-success: #43a047; /* Green 600 from Material palette */
|
||||
--md-info: #1e88e5; /* Blue 600 from Material palette */
|
||||
--md-warning: #fb8c00; /* Orange 600 from Material palette */
|
||||
--md-error: #e53935; /* Red 600 from Material palette */
|
||||
/* Animation timing variables */
|
||||
--md-animation-duration: 0.3s; /* Standard Material motion duration */
|
||||
--md-ripple-duration: 0.6s; /* Ripple effect duration */
|
||||
--md-bg-light: #ffffff;
|
||||
--md-bg-dark: #2d2d2d;
|
||||
--md-text-light: rgba(0, 0, 0, 0.87);
|
||||
--md-text-secondary-light: rgba(0, 0, 0, 0.6);
|
||||
--md-text-dark: rgba(255, 255, 255, 0.87);
|
||||
--md-text-secondary-dark: rgba(255, 255, 255, 0.6);
|
||||
--md-elevation: 0 3px 5px -1px rgba(0,0,0,0.2),
|
||||
0 6px 10px 0 rgba(0,0,0,0.14),
|
||||
0 1px 18px 0 rgba(0,0,0,0.12);
|
||||
--md-elevation-dark: 0 3px 5px -1px rgba(0,0,0,0.4),
|
||||
0 6px 10px 0 rgba(0,0,0,0.28),
|
||||
0 1px 18px 0 rgba(0,0,0,0.24);
|
||||
--md-border-radius: 4px;
|
||||
--md-success: #43a047;
|
||||
--md-info: #1e88e5;
|
||||
--md-warning: #fb8c00;
|
||||
--md-error: #e53935;
|
||||
--md-animation-duration: 0.3s;
|
||||
--md-ripple-duration: 0.6s;
|
||||
}
|
||||
@keyframes mdSlideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px); /* Start below final position */
|
||||
transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at final position */
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@keyframes mdRipple {
|
||||
to {
|
||||
transform: scale(4); /* Expand to 4x original size */
|
||||
opacity: 0; /* Fade out completely */
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.fl-material {
|
||||
position: relative;
|
||||
margin: 8px 0; /* Spacing between notifications */
|
||||
font-family: Roboto, "Segoe UI", Helvetica, Arial, sans-serif; /* Material uses Roboto */
|
||||
animation: mdSlideUp var(--md-animation-duration) cubic-bezier(0.4, 0, 0.2, 1); /* Material standard easing */
|
||||
/**
|
||||
* Main card container
|
||||
* Follows Material Design card component styling
|
||||
*/
|
||||
margin: 8px 0;
|
||||
font-family: Roboto, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
animation: mdSlideUp var(--md-animation-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
.fl-md-card {
|
||||
background-color: var(--md-bg-light);
|
||||
color: var(--md-text-light);
|
||||
border-radius: var(--md-border-radius);
|
||||
box-shadow: var(--md-elevation); /* Multi-layered shadow for depth */
|
||||
overflow: hidden; /* Contains progress bar */
|
||||
box-shadow: var(--md-elevation);
|
||||
overflow: hidden;
|
||||
}
|
||||
/**
|
||||
* Content section
|
||||
* Contains message text
|
||||
*/
|
||||
.fl-content {
|
||||
padding: 16px; /* Standard Material padding */
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: flex-start; /* Align items to top */
|
||||
align-items: flex-start;
|
||||
}
|
||||
/**
|
||||
* Text content container
|
||||
* Holds message
|
||||
*/
|
||||
.fl-text-content {
|
||||
flex: 1; /* Take available space */
|
||||
flex: 1;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Following Material Design typography
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.875rem; /* 14px - Material body 2 */
|
||||
line-height: 1.43; /* Material line height for body 2 */
|
||||
color: var(--md-text-secondary-light); /* Secondary text color (60% opacity) */
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.43;
|
||||
color: var(--md-text-secondary-light);
|
||||
}
|
||||
/**
|
||||
* Action buttons section
|
||||
* Contains dismiss button
|
||||
*/
|
||||
.fl-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end; /* Align buttons to right */
|
||||
padding: 8px; /* Standard Material padding */
|
||||
justify-content: flex-end;
|
||||
padding: 8px;
|
||||
}
|
||||
/**
|
||||
* Action button styling
|
||||
* Following Material Design "text button" guidelines
|
||||
*/
|
||||
.fl-action-button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: currentColor; /* Inherit color from parent */
|
||||
color: currentColor;
|
||||
font-family: inherit;
|
||||
font-weight: 500; /* Medium weight per Material specs */
|
||||
font-size: 0.8125rem; /* 13px - Material button text size */
|
||||
text-transform: uppercase; /* Material buttons use uppercase */
|
||||
letter-spacing: 0.0892857143em; /* Material's letter spacing for buttons */
|
||||
padding: 8px 12px; /* Material button padding */
|
||||
border-radius: 4px; /* Rounded corners per Material */
|
||||
font-weight: 500;
|
||||
font-size: 0.8125rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.0892857143em;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s; /* Smooth hover effect */
|
||||
position: relative; /* For ripple positioning */
|
||||
overflow: hidden; /* Contain ripple effect */
|
||||
transition: background-color 0.2s;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(0, 0, 0, 0.04); /* Material hover state - 4% opacity */
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
/**
|
||||
* Ripple effect
|
||||
* Material Design's signature ink ripple on interaction
|
||||
*/
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 5px; /* Initial small circle */
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: currentColor; /* Use button text color */
|
||||
background: currentColor;
|
||||
opacity: 0;
|
||||
border-radius: 50%; /* Perfect circle */
|
||||
border-radius: 50%;
|
||||
transform: scale(1);
|
||||
pointer-events: none; /* Don't interfere with clicks */
|
||||
pointer-events: none;
|
||||
}
|
||||
&:active::after {
|
||||
opacity: 0.3; /* Material ripple opacity */
|
||||
animation: mdRipple var(--md-ripple-duration) linear; /* Expand and fade */
|
||||
opacity: 0.3;
|
||||
animation: mdRipple var(--md-ripple-duration) linear;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type has its own color based on Material palette
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-success); /* Green icon */
|
||||
color: var(--md-success);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-success); /* Green button */
|
||||
color: var(--md-success);
|
||||
}
|
||||
}
|
||||
&.fl-info {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-info); /* Blue icon */
|
||||
color: var(--md-info);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-info); /* Blue button */
|
||||
color: var(--md-info);
|
||||
}
|
||||
}
|
||||
&.fl-warning {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-warning); /* Orange icon */
|
||||
color: var(--md-warning);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-warning); /* Orange button */
|
||||
color: var(--md-warning);
|
||||
}
|
||||
}
|
||||
&.fl-error {
|
||||
.fl-icon-wrapper {
|
||||
color: var(--md-error); /* Red icon */
|
||||
color: var(--md-error);
|
||||
}
|
||||
.fl-action-button {
|
||||
color: var(--md-error); /* Red button */
|
||||
color: var(--md-error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar
|
||||
* Material Design linear progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px; /* Material's standard progress height */
|
||||
height: 4px;
|
||||
overflow: hidden;
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
transform-origin: left center; /* Animation starts from left */
|
||||
transform-origin: left center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific progress colors
|
||||
* Each notification type has its own progress bar color
|
||||
*/
|
||||
&.fl-success .fl-progress {
|
||||
background-color: var(--md-success); /* Green progress */
|
||||
background-color: var(--md-success);
|
||||
}
|
||||
&.fl-info .fl-progress {
|
||||
background-color: var(--md-info); /* Blue progress */
|
||||
background-color: var(--md-info);
|
||||
}
|
||||
&.fl-warning .fl-progress {
|
||||
background-color: var(--md-warning); /* Orange progress */
|
||||
background-color: var(--md-warning);
|
||||
}
|
||||
&.fl-error .fl-progress {
|
||||
background-color: var(--md-error); /* Red progress */
|
||||
background-color: var(--md-error);
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-content {
|
||||
flex-direction: row-reverse; /* Reverse flex direction */
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.fl-icon-wrapper {
|
||||
margin-right: 0;
|
||||
margin-left: 16px; /* Swap margins for RTL */
|
||||
margin-left: 16px;
|
||||
}
|
||||
.fl-actions {
|
||||
justify-content: flex-start; /* Align buttons to left in RTL */
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable slide animation */
|
||||
animation: none;
|
||||
.fl-action-button:active::after {
|
||||
animation: none; /* Disable ripple animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,16 +183,16 @@ body.fl-dark .fl-material,
|
||||
html.fl-dark .fl-material,
|
||||
.fl-material.fl-auto-dark {
|
||||
.fl-md-card {
|
||||
background-color: var(--md-bg-dark); /* Darker background */
|
||||
color: var(--md-text-dark); /* Lighter text */
|
||||
box-shadow: var(--md-elevation-dark); /* Stronger shadows */
|
||||
background-color: var(--md-bg-dark);
|
||||
color: var(--md-text-dark);
|
||||
box-shadow: var(--md-elevation-dark);
|
||||
}
|
||||
.fl-message {
|
||||
color: var(--md-text-secondary-dark); /* Lighter secondary text */
|
||||
color: var(--md-text-secondary-dark);
|
||||
}
|
||||
.fl-action-button {
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(255, 255, 255, 0.08); /* Material dark hover - 8% opacity */
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +1,93 @@
|
||||
.fl-minimal {
|
||||
/* Theme variables - Define the visual appearance of Minimal notifications */
|
||||
/* Base colors and appearance */
|
||||
--minimal-bg-light: rgba(255, 255, 255); /* Semi-transparent white in light mode */
|
||||
--minimal-bg-dark: rgba(25, 25, 25); /* Semi-transparent dark in dark mode */
|
||||
--minimal-text-light: #333333; /* Dark gray text in light mode */
|
||||
--minimal-text-dark: #f5f5f5; /* Off-white text in dark mode */
|
||||
--minimal-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); /* Very subtle shadow */
|
||||
--minimal-shadow-dark: 0 2px 8px rgba(0, 0, 0, 0.15); /* Slightly stronger shadow for dark mode */
|
||||
--minimal-border-radius: 4px; /* Modest border radius */
|
||||
--minimal-border-color: rgba(0, 0, 0, 0.05); /* Nearly invisible border in light mode */
|
||||
--minimal-border-color-dark: rgba(255, 255, 255, 0.1); /* Subtle border in dark mode */
|
||||
/* Type-specific colors - semi-transparent for subtlety */
|
||||
--minimal-success: rgba(34, 197, 94, 0.9); /* Green with slight transparency */
|
||||
--minimal-info: rgba(14, 165, 233, 0.9); /* Blue with slight transparency */
|
||||
--minimal-warning: rgba(245, 158, 11, 0.9); /* Orange with slight transparency */
|
||||
--minimal-error: rgba(239, 68, 68, 0.9); /* Red with slight transparency */
|
||||
--minimal-bg-light: rgba(255, 255, 255);
|
||||
--minimal-bg-dark: rgba(25, 25, 25);
|
||||
--minimal-text-light: #333333;
|
||||
--minimal-text-dark: #f5f5f5;
|
||||
--minimal-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
--minimal-shadow-dark: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
--minimal-border-radius: 4px;
|
||||
--minimal-border-color: rgba(0, 0, 0, 0.05);
|
||||
--minimal-border-color-dark: rgba(255, 255, 255, 0.1);
|
||||
--minimal-success: rgba(34, 197, 94, 0.9);
|
||||
--minimal-info: rgba(14, 165, 233, 0.9);
|
||||
--minimal-warning: rgba(245, 158, 11, 0.9);
|
||||
--minimal-error: rgba(239, 68, 68, 0.9);
|
||||
}
|
||||
@keyframes minimalIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px); /* Start slightly above final position */
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at natural position */
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.fl-minimal {
|
||||
background-color: var(--minimal-bg-light);
|
||||
color: var(--minimal-text-light);
|
||||
padding: 0.75rem 1rem; /* Compact padding */
|
||||
margin: 0.5rem 0; /* Modest vertical spacing */
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 0.5rem 0;
|
||||
position: relative;
|
||||
box-shadow: var(--minimal-shadow); /* Very subtle shadow */
|
||||
box-shadow: var(--minimal-shadow);
|
||||
border-radius: var(--minimal-border-radius);
|
||||
animation: minimalIn 0.2s ease-out; /* Quick, subtle animation */
|
||||
font-family: -apple-system, BlinkMacSystemFont, var(--fl-font), sans-serif; /* System font stack */
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
backdrop-filter: blur(8px); /* Frosted glass effect */
|
||||
-webkit-backdrop-filter: blur(8px); /* Safari support */
|
||||
border: 1px solid var(--minimal-border-color); /* Nearly invisible border */
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and close button
|
||||
*/
|
||||
animation: minimalIn 0.2s ease-out;
|
||||
font-family: -apple-system, BlinkMacSystemFont, var(--fl-font), sans-serif;
|
||||
will-change: transform, opacity;
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
border: 1px solid var(--minimal-border-color);
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center; /* Vertically center content */
|
||||
gap: 0.75rem; /* Space between elements */
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
/**
|
||||
* Small colored dot indicator
|
||||
* Used instead of large icons for minimal appearance
|
||||
*/
|
||||
.fl-dot {
|
||||
width: 8px; /* Small dot size */
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
flex-shrink: 0; /* Prevent dot from shrinking */
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.875rem; /* 14px at default font size */
|
||||
line-height: 1.4; /* Comfortable line height */
|
||||
font-weight: 450; /* Slightly heavier than normal */
|
||||
flex: 1; /* Take available space */
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.4;
|
||||
font-weight: 450;
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Simple, minimal close button
|
||||
*/
|
||||
.fl-close {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0.25rem;
|
||||
cursor: pointer;
|
||||
opacity: 0.5; /* Subtle appearance by default */
|
||||
transition: opacity 0.15s; /* Quick hover transition */
|
||||
color: currentColor; /* Inherit color from parent */
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.15s;
|
||||
color: currentColor;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.5rem; /* 24px clickable area */
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
font-size: 1rem; /* 16px × symbol */
|
||||
flex-shrink: 0; /* Prevent button from shrinking */
|
||||
font-size: 1rem;
|
||||
flex-shrink: 0;
|
||||
&:hover, &:focus {
|
||||
opacity: 0.8; /* More visible on hover/focus, but still subtle */
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 2px; /* Very thin progress bar */
|
||||
height: 2px;
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 var(--minimal-border-radius) var(--minimal-border-radius); /* Match parent corners */
|
||||
opacity: 0.7; /* Slightly transparent */
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
border-radius: 0 0 var(--minimal-border-radius) var(--minimal-border-radius);
|
||||
opacity: 0.7;
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type gets its own color for the dot and progress bar
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-dot { background-color: var(--minimal-success); }
|
||||
.fl-progress-bar .fl-progress { background-color: var(--minimal-success); }
|
||||
@@ -135,29 +104,21 @@
|
||||
.fl-dot { background-color: var(--minimal-error); }
|
||||
.fl-progress-bar .fl-progress { background-color: var(--minimal-error); }
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-progress .fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-minimal,
|
||||
html.fl-dark .fl-minimal,
|
||||
.fl-minimal.fl-auto-dark {
|
||||
background-color: var(--minimal-bg-dark); /* Dark, semi-transparent background */
|
||||
color: var(--minimal-text-dark); /* Light text */
|
||||
box-shadow: var(--minimal-shadow-dark); /* Slightly stronger shadow */
|
||||
border-color: var(--minimal-border-color-dark); /* More visible border in dark mode */
|
||||
background-color: var(--minimal-bg-dark);
|
||||
color: var(--minimal-text-dark);
|
||||
box-shadow: var(--minimal-shadow-dark);
|
||||
border-color: var(--minimal-border-color-dark);
|
||||
}
|
||||
|
||||
@@ -1,113 +1,90 @@
|
||||
.fl-neon {
|
||||
/* Theme variables - Define the visual appearance of Neon notifications */
|
||||
/* Base colors and appearance */
|
||||
--neon-bg-light: rgba(255, 255, 255); /* Translucent white in light mode */
|
||||
--neon-bg-dark: rgba(15, 23, 42); /* Translucent slate in dark mode */
|
||||
--neon-text-light: #334155; /* Slate gray text in light mode */
|
||||
--neon-text-dark: #f1f5f9; /* Light gray text in dark mode */
|
||||
--neon-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); /* Soft, spread shadow */
|
||||
--neon-shadow-dark: 0 8px 30px rgba(0, 0, 0, 0.25); /* Deeper shadow for dark mode */
|
||||
--neon-border-radius: 4px; /* Rounded corners */
|
||||
/* Glow colors for different notification types */
|
||||
--neon-success: #10b981; /* Emerald green for success */
|
||||
--neon-info: #3b82f6; /* Blue for info */
|
||||
--neon-warning: #f59e0b; /* Amber for warning */
|
||||
--neon-error: #ef4444; /* Red for error */
|
||||
/* Glow and animation properties */
|
||||
--neon-glow-strength: 10px; /* How far the glow extends */
|
||||
--neon-animation-duration: 0.35s; /* Duration for entrance animation */
|
||||
--neon-bg-light: rgba(255, 255, 255);
|
||||
--neon-bg-dark: rgba(15, 23, 42);
|
||||
--neon-text-light: #334155;
|
||||
--neon-text-dark: #f1f5f9;
|
||||
--neon-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||
--neon-shadow-dark: 0 8px 30px rgba(0, 0, 0, 0.25);
|
||||
--neon-border-radius: 4px;
|
||||
--neon-success: #10b981;
|
||||
--neon-info: #3b82f6;
|
||||
--neon-warning: #f59e0b;
|
||||
--neon-error: #ef4444;
|
||||
--neon-glow-strength: 10px;
|
||||
--neon-animation-duration: 0.35s;
|
||||
}
|
||||
@keyframes neonEntrance {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-15px); /* Start above final position */
|
||||
filter: blur(3px); /* Start blurred */
|
||||
transform: translateY(-15px);
|
||||
filter: blur(3px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at natural position */
|
||||
filter: blur(0); /* End with clear focus */
|
||||
transform: translateY(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
@keyframes neonGlow {
|
||||
0%, 100% {
|
||||
filter: drop-shadow(0 0 var(--neon-glow-strength) currentColor); /* Full glow */
|
||||
filter: drop-shadow(0 0 var(--neon-glow-strength) currentColor);
|
||||
}
|
||||
50% {
|
||||
filter: drop-shadow(0 0 calc(var(--neon-glow-strength) * 0.7) currentColor); /* Reduced glow */
|
||||
filter: drop-shadow(0 0 calc(var(--neon-glow-strength) * 0.7) currentColor);
|
||||
}
|
||||
}
|
||||
.fl-neon {
|
||||
background-color: var(--neon-bg-light);
|
||||
color: var(--neon-text-light);
|
||||
border-radius: var(--neon-border-radius) var(--neon-border-radius) 0 0; /* Rounded top corners */
|
||||
border-radius: var(--neon-border-radius) var(--neon-border-radius) 0 0;
|
||||
box-shadow: var(--neon-shadow);
|
||||
padding: 14px 18px; /* Comfortable padding */
|
||||
margin: 12px 0; /* Vertical spacing */
|
||||
padding: 14px 18px;
|
||||
margin: 12px 0;
|
||||
position: relative;
|
||||
animation: neonEntrance var(--neon-animation-duration) ease-out;
|
||||
font-family: 'Inter', var(--fl-font), sans-serif; /* Prefer Inter font for elegant typography */
|
||||
will-change: transform, opacity, filter; /* Optimize for animation performance */
|
||||
overflow: hidden; /* Contain progress bar */
|
||||
/* Frosted glass effect */
|
||||
font-family: 'Inter', var(--fl-font), sans-serif;
|
||||
will-change: transform, opacity, filter;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
/**
|
||||
* Floating illuminated indicator
|
||||
* Creates a glowing circle that appears to float above the notification
|
||||
*/
|
||||
.fl-icon-box {
|
||||
position: absolute;
|
||||
top: -12px; /* Position above the notification */
|
||||
top: -12px;
|
||||
left: 16px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: neonGlow 3s ease-in-out infinite; /* Continuous gentle pulsing */
|
||||
/* Semi-transparent circular background */
|
||||
animation: neonGlow 3s ease-in-out infinite;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
opacity: 0.4; /* Subtle background */
|
||||
opacity: 0.4;
|
||||
}
|
||||
/* Solid colored center dot */
|
||||
&::after {
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
z-index: 1; /* Ensure dot appears above the glow */
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and close button
|
||||
*/
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center; /* Vertically center content */
|
||||
align-items: center;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
flex: 1; /* Take available space */
|
||||
font-size: 0.9375rem; /* 15px at default font size */
|
||||
line-height: 1.5; /* Comfortable line height */
|
||||
font-weight: 500; /* Medium weight for better readability */
|
||||
flex: 1;
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.5;
|
||||
font-weight: 500;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
background: none;
|
||||
border: none;
|
||||
@@ -115,25 +92,21 @@
|
||||
margin-left: 16px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%; /* Circular button */
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: inherit; /* Inherit text color */
|
||||
opacity: 0.6; /* Subtle appearance by default */
|
||||
transition: all 0.2s ease; /* Smooth hover transition */
|
||||
color: inherit;
|
||||
opacity: 0.6;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 1.2rem;
|
||||
flex-shrink: 0; /* Prevent button from shrinking */
|
||||
flex-shrink: 0;
|
||||
&:hover, &:focus {
|
||||
opacity: 1; /* Full opacity on hover/focus */
|
||||
background-color: rgba(0, 0, 0, 0.06); /* Subtle background on hover */
|
||||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -141,91 +114,71 @@
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 var(--neon-border-radius) var(--neon-border-radius); /* Match parent corners */
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
border-radius: 0 0 var(--neon-border-radius) var(--neon-border-radius);
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling for each notification type
|
||||
* Each type gets its own color for the indicator and progress bar
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-icon-box {
|
||||
color: var(--neon-success); /* Green glow */
|
||||
&::before { background-color: var(--neon-success); } /* Transparent green circle */
|
||||
&::after { background-color: var(--neon-success); } /* Solid green dot */
|
||||
color: var(--neon-success);
|
||||
&::before { background-color: var(--neon-success); }
|
||||
&::after { background-color: var(--neon-success); }
|
||||
}
|
||||
.fl-progress { background-color: var(--neon-success); } /* Green progress bar */
|
||||
.fl-progress { background-color: var(--neon-success); }
|
||||
}
|
||||
&.fl-info {
|
||||
.fl-icon-box {
|
||||
color: var(--neon-info); /* Blue glow */
|
||||
&::before { background-color: var(--neon-info); } /* Transparent blue circle */
|
||||
&::after { background-color: var(--neon-info); } /* Solid blue dot */
|
||||
color: var(--neon-info);
|
||||
&::before { background-color: var(--neon-info); }
|
||||
&::after { background-color: var(--neon-info); }
|
||||
}
|
||||
.fl-progress { background-color: var(--neon-info); } /* Blue progress bar */
|
||||
.fl-progress { background-color: var(--neon-info); }
|
||||
}
|
||||
&.fl-warning {
|
||||
.fl-icon-box {
|
||||
color: var(--neon-warning); /* Amber glow */
|
||||
&::before { background-color: var(--neon-warning); } /* Transparent amber circle */
|
||||
&::after { background-color: var(--neon-warning); } /* Solid amber dot */
|
||||
color: var(--neon-warning);
|
||||
&::before { background-color: var(--neon-warning); }
|
||||
&::after { background-color: var(--neon-warning); }
|
||||
}
|
||||
.fl-progress { background-color: var(--neon-warning); } /* Amber progress bar */
|
||||
.fl-progress { background-color: var(--neon-warning); }
|
||||
}
|
||||
&.fl-error {
|
||||
.fl-icon-box {
|
||||
color: var(--neon-error); /* Red glow */
|
||||
&::before { background-color: var(--neon-error); } /* Transparent red circle */
|
||||
&::after { background-color: var(--neon-error); } /* Solid red dot */
|
||||
color: var(--neon-error);
|
||||
&::before { background-color: var(--neon-error); }
|
||||
&::after { background-color: var(--neon-error); }
|
||||
}
|
||||
.fl-progress { background-color: var(--neon-error); } /* Red progress bar */
|
||||
.fl-progress { background-color: var(--neon-error); }
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-icon-box {
|
||||
left: auto;
|
||||
right: 16px; /* Move icon to right side */
|
||||
right: 16px;
|
||||
}
|
||||
.fl-close {
|
||||
margin-left: 0;
|
||||
margin-right: 16px; /* Swap margins */
|
||||
margin-right: 16px;
|
||||
}
|
||||
.fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable entrance animation */
|
||||
animation: none;
|
||||
.fl-icon-box {
|
||||
animation: none; /* Disable glow animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-neon,
|
||||
html.fl-dark .fl-neon,
|
||||
.fl-neon.fl-auto-dark {
|
||||
background-color: var(--neon-bg-dark); /* Darker, semi-transparent background */
|
||||
color: var(--neon-text-dark); /* Light text */
|
||||
box-shadow: var(--neon-shadow-dark); /* Stronger shadow */
|
||||
/**
|
||||
* Adjust hover effect for dark mode
|
||||
* Use white instead of black with appropriate opacity
|
||||
*/
|
||||
background-color: var(--neon-bg-dark);
|
||||
color: var(--neon-text-dark);
|
||||
box-shadow: var(--neon-shadow-dark);
|
||||
.fl-close:hover, .fl-close:focus {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@@ -1,182 +1,140 @@
|
||||
.fl-onyx {
|
||||
/* Theme variables - Define the visual appearance of Onyx notifications */
|
||||
/* Base colors and appearance */
|
||||
--onyx-bg-light: #ffffff; /* Pure white background in light mode */
|
||||
--onyx-bg-dark: #1e1e1e; /* Dark background in dark mode */
|
||||
--onyx-text-light: #333333; /* Dark gray text in light mode */
|
||||
--onyx-text-dark: #f5f5f5; /* Light gray text in dark mode */
|
||||
--onyx-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); /* Soft, spread shadow */
|
||||
--onyx-shadow-dark: 0 8px 30px rgba(0, 0, 0, 0.25); /* Deeper shadow for dark mode */
|
||||
--onyx-border-radius: 4px; /* Generous rounded corners */
|
||||
/* Type-specific colors for accent dots and progress bar */
|
||||
--onyx-success: #10b981; /* Green for success */
|
||||
--onyx-info: #3b82f6; /* Blue for info */
|
||||
--onyx-warning: #f59e0b; /* Amber for warning */
|
||||
--onyx-error: #ef4444; /* Red for error */
|
||||
--onyx-bg-light: #ffffff;
|
||||
--onyx-bg-dark: #1e1e1e;
|
||||
--onyx-text-light: #333333;
|
||||
--onyx-text-dark: #f5f5f5;
|
||||
--onyx-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||
--onyx-shadow-dark: 0 8px 30px rgba(0, 0, 0, 0.25);
|
||||
--onyx-border-radius: 4px;
|
||||
--onyx-success: #10b981;
|
||||
--onyx-info: #3b82f6;
|
||||
--onyx-warning: #f59e0b;
|
||||
--onyx-error: #ef4444;
|
||||
}
|
||||
@keyframes onyxIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(15px); /* Start below final position */
|
||||
filter: blur(3px); /* Start blurred */
|
||||
transform: translateY(15px);
|
||||
filter: blur(3px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0); /* End at natural position */
|
||||
filter: blur(0); /* End with clear focus */
|
||||
transform: translateY(0);
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
.fl-onyx {
|
||||
background-color: var(--onyx-bg-light);
|
||||
color: var(--onyx-text-light);
|
||||
padding: 1rem 1.25rem; /* Comfortable padding */
|
||||
margin: 0.75rem 0; /* Vertical spacing */
|
||||
padding: 1rem 1.25rem;
|
||||
margin: 0.75rem 0;
|
||||
position: relative;
|
||||
box-shadow: var(--onyx-shadow); /* Elegant floating shadow */
|
||||
animation: onyxIn 0.4s cubic-bezier(0.16, 1, 0.3, 1); /* Refined animation with custom easing */
|
||||
box-shadow: var(--onyx-shadow);
|
||||
animation: onyxIn 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
font-family: var(--fl-font), serif;
|
||||
will-change: transform, opacity, filter; /* Optimize for animation performance */
|
||||
border-radius: var(--onyx-border-radius) var(--onyx-border-radius) 0 0; /* Rounded corners */
|
||||
overflow: hidden; /* Contain progress bar */
|
||||
/**
|
||||
* Accent dots at the corners
|
||||
* Small circular indicators of notification type
|
||||
*/
|
||||
will-change: transform, opacity, filter;
|
||||
border-radius: var(--onyx-border-radius) var(--onyx-border-radius) 0 0;
|
||||
overflow: hidden;
|
||||
&::before, &::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 6px; /* Small dot size */
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
z-index: 1; /* Ensure dots appear above content */
|
||||
border-radius: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
/* Top-left dot */
|
||||
&::before {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
/* Bottom-right dot */
|
||||
&::after {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
/**
|
||||
* Content container
|
||||
* Holds message and close button
|
||||
*/
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center; /* Vertically center content */
|
||||
padding-left: 0.4rem; /* Space after the dot */
|
||||
align-items: center;
|
||||
padding-left: 0.4rem;
|
||||
}
|
||||
/**
|
||||
* Text container
|
||||
* Wraps the message
|
||||
*/
|
||||
.fl-text {
|
||||
flex: 1; /* Take available space */
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.925rem; /* Slightly smaller than 15px */
|
||||
line-height: 1.5; /* Comfortable line height */
|
||||
font-weight: 400; /* Regular weight for clean appearance */
|
||||
letter-spacing: 0.01rem; /* Slight letter spacing for readability */
|
||||
font-size: 0.925rem;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.01rem;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.25rem; /* 20px × symbol */
|
||||
font-size: 1.25rem;
|
||||
padding: 0.25rem;
|
||||
cursor: pointer;
|
||||
opacity: 0.6; /* Subtle appearance by default */
|
||||
transition: all 0.2s ease; /* Smooth hover transition */
|
||||
color: currentColor; /* Inherit text color */
|
||||
margin-left: 1rem; /* Space between message and button */
|
||||
flex-shrink: 0; /* Prevent button from shrinking */
|
||||
border-radius: 50%; /* Circular button */
|
||||
opacity: 0.6;
|
||||
transition: all 0.2s ease;
|
||||
color: currentColor;
|
||||
margin-left: 1rem;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem; /* 28px diameter */
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
&:hover, &:focus {
|
||||
opacity: 1; /* Full opacity on hover/focus */
|
||||
background-color: rgba(0, 0, 0, 0.05); /* Subtle background on hover */
|
||||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 3px; /* Thin progress bar */
|
||||
height: 3px;
|
||||
overflow: hidden;
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
transform-origin: left center; /* Animation starts from left */
|
||||
transform-origin: left center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling for each notification type
|
||||
* Each type gets its own color for the dots and progress bar
|
||||
*/
|
||||
&.fl-success {
|
||||
&::before, &::after { background-color: var(--onyx-success); } /* Green dots */
|
||||
&::before, &::after { background-color: var(--onyx-success); }
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--onyx-success); /* Green progress bar */
|
||||
background-color: var(--onyx-success);
|
||||
}
|
||||
}
|
||||
&.fl-info {
|
||||
&::before, &::after { background-color: var(--onyx-info); } /* Blue dots */
|
||||
&::before, &::after { background-color: var(--onyx-info); }
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--onyx-info); /* Blue progress bar */
|
||||
background-color: var(--onyx-info);
|
||||
}
|
||||
}
|
||||
&.fl-warning {
|
||||
&::before, &::after { background-color: var(--onyx-warning); } /* Amber dots */
|
||||
&::before, &::after { background-color: var(--onyx-warning); }
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--onyx-warning); /* Amber progress bar */
|
||||
background-color: var(--onyx-warning);
|
||||
}
|
||||
}
|
||||
&.fl-error {
|
||||
&::before, &::after { background-color: var(--onyx-error); } /* Red dots */
|
||||
&::before, &::after { background-color: var(--onyx-error); }
|
||||
.fl-progress-bar .fl-progress {
|
||||
background-color: var(--onyx-error); /* Red progress bar */
|
||||
background-color: var(--onyx-error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-content {
|
||||
padding-left: 0;
|
||||
padding-right: 0.4rem; /* Swap padding for RTL */
|
||||
padding-right: 0.4rem;
|
||||
}
|
||||
.fl-close {
|
||||
margin-left: 0;
|
||||
margin-right: 1rem; /* Swap margins for RTL */
|
||||
margin-right: 1rem;
|
||||
}
|
||||
/* Swap dot positions for RTL */
|
||||
&::before {
|
||||
left: auto;
|
||||
right: 10px;
|
||||
@@ -186,27 +144,19 @@
|
||||
left: 10px;
|
||||
}
|
||||
.fl-progress .fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-onyx,
|
||||
html.fl-dark .fl-onyx,
|
||||
.fl-onyx.fl-auto-dark {
|
||||
background-color: var(--onyx-bg-dark); /* Dark background */
|
||||
color: var(--onyx-text-dark); /* Light text */
|
||||
box-shadow: var(--onyx-shadow-dark); /* Stronger shadow */
|
||||
/**
|
||||
* Adjust hover effect for dark mode
|
||||
* Use white instead of black with appropriate opacity
|
||||
*/
|
||||
background-color: var(--onyx-bg-dark);
|
||||
color: var(--onyx-text-dark);
|
||||
box-shadow: var(--onyx-shadow-dark);
|
||||
.fl-close:hover, .fl-close:focus {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@@ -1,219 +1,168 @@
|
||||
.fl-ruby {
|
||||
/* Theme variables - Define the visual appearance of Ruby notifications */
|
||||
/* Base colors and appearance */
|
||||
--ruby-text: #ffffff; /* White text for good contrast on gradients */
|
||||
--ruby-text-dark: #f8fafc; /* Slightly off-white text for dark mode */
|
||||
--ruby-border-radius: 4px; /* Rounded corners (18px) */
|
||||
--ruby-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.2); /* Soft shadow for depth */
|
||||
/* Type-specific gradients - rich, vibrant color combinations */
|
||||
--ruby-success-gradient: linear-gradient(135deg, #059669 0%, #10b981 100%); /* Green gradient */
|
||||
--ruby-info-gradient: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%); /* Blue gradient */
|
||||
--ruby-warning-gradient: linear-gradient(135deg, #d97706 0%, #f59e0b 100%); /* Amber gradient */
|
||||
--ruby-error-gradient: linear-gradient(135deg, #b91c1c 0%, #ef4444 100%); /* Red gradient */
|
||||
--ruby-text: #ffffff;
|
||||
--ruby-text-dark: #f8fafc;
|
||||
--ruby-border-radius: 4px;
|
||||
--ruby-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.2);
|
||||
--ruby-success-gradient: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
--ruby-info-gradient: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%);
|
||||
--ruby-warning-gradient: linear-gradient(135deg, #d97706 0%, #f59e0b 100%);
|
||||
--ruby-error-gradient: linear-gradient(135deg, #b91c1c 0%, #ef4444 100%);
|
||||
}
|
||||
@keyframes rubyShine {
|
||||
0% {
|
||||
left: -100%; /* Start off-screen left */
|
||||
opacity: 0.6; /* Semi-transparent */
|
||||
left: -100%;
|
||||
opacity: 0.6;
|
||||
}
|
||||
60% {
|
||||
left: 100%; /* Move to right edge */
|
||||
opacity: 0.6; /* Maintain opacity during animation */
|
||||
left: 100%;
|
||||
opacity: 0.6;
|
||||
}
|
||||
100% {
|
||||
left: 100%; /* Stay at right edge */
|
||||
opacity: 0; /* Fade out at the end */
|
||||
left: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes rubyIn {
|
||||
0% {
|
||||
opacity: 0; /* Start invisible */
|
||||
transform: scale(0.96); /* Start slightly smaller */
|
||||
opacity: 0;
|
||||
transform: scale(0.96);
|
||||
}
|
||||
100% {
|
||||
opacity: 1; /* End fully visible */
|
||||
transform: scale(1); /* End at normal size */
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.fl-ruby {
|
||||
color: var(--ruby-text); /* White text for readability on gradients */
|
||||
padding: 0; /* No padding at the container level */
|
||||
margin: 0.75rem 0; /* Vertical spacing between notifications */
|
||||
color: var(--ruby-text);
|
||||
padding: 0;
|
||||
margin: 0.75rem 0;
|
||||
position: relative;
|
||||
box-shadow: var(--ruby-shadow); /* Soft shadow for depth */
|
||||
border-radius: var(--ruby-border-radius) var(--ruby-border-radius) 0 0; /* Rounded corners */
|
||||
animation: rubyIn 0.35s cubic-bezier(0.21, 1.02, 0.73, 1); /* Custom easing for natural feel */
|
||||
box-shadow: var(--ruby-shadow);
|
||||
border-radius: var(--ruby-border-radius) var(--ruby-border-radius) 0 0;
|
||||
animation: rubyIn 0.35s cubic-bezier(0.21, 1.02, 0.73, 1);
|
||||
font-family: var(--fl-font), serif;
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
overflow: hidden; /* Contain the shine effect and progress bar */
|
||||
/**
|
||||
* Shine effect overlay
|
||||
* Creates the gemstone-like reflecting light animation
|
||||
*/
|
||||
will-change: transform, opacity;
|
||||
overflow: hidden;
|
||||
.fl-shine {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%; /* Start off-screen */
|
||||
width: 50%; /* Cover half the width */
|
||||
left: -100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255,255,255,0) 0%, /* Transparent at edges */
|
||||
rgba(255,255,255,0.3) 50%, /* Semi-transparent white in middle */
|
||||
rgba(255,255,255,0) 0%,
|
||||
rgba(255,255,255,0.3) 50%,
|
||||
rgba(255,255,255,0) 100%
|
||||
);
|
||||
transform: skewX(-20deg); /* Angle the shine effect */
|
||||
animation: rubyShine 6s infinite; /* Repeating shine animation */
|
||||
animation-delay: 1s; /* Delay before first shine */
|
||||
z-index: 1; /* Above the background, below content */
|
||||
transform: skewX(-20deg);
|
||||
animation: rubyShine 6s infinite;
|
||||
animation-delay: 1s;
|
||||
z-index: 1;
|
||||
}
|
||||
/**
|
||||
* Content container
|
||||
* Holds icon, message and close button
|
||||
*/
|
||||
.fl-content {
|
||||
display: flex;
|
||||
align-items: center; /* Vertically center content */
|
||||
padding: 0.9rem 1.1rem; /* Content padding */
|
||||
align-items: center;
|
||||
padding: 0.9rem 1.1rem;
|
||||
position: relative;
|
||||
z-index: 2; /* Ensure content is above shine effect */
|
||||
z-index: 2;
|
||||
}
|
||||
/**
|
||||
* Circular icon container
|
||||
* Translucent white circle holding the icon
|
||||
*/
|
||||
.fl-icon-circle {
|
||||
flex-shrink: 0; /* Prevent circle from shrinking */
|
||||
width: 2.25rem; /* 36px diameter */
|
||||
flex-shrink: 0;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
margin-right: 1rem; /* Space between icon and text */
|
||||
background-color: rgba(255, 255, 255, 0.25); /* Translucent white */
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
margin-right: 1rem;
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
/**
|
||||
* Icon styling
|
||||
* Icon within the circular container
|
||||
*/
|
||||
.fl-icon {
|
||||
margin: 0;
|
||||
font-size: 1rem; /* 16px icon size */
|
||||
color: var(--ruby-text); /* White icon */
|
||||
font-size: 1rem;
|
||||
color: var(--ruby-text);
|
||||
background-color: transparent;
|
||||
}
|
||||
/**
|
||||
* Text container
|
||||
* Holds the message
|
||||
*/
|
||||
.fl-text {
|
||||
flex: 1; /* Take available space */
|
||||
flex: 1;
|
||||
}
|
||||
/**
|
||||
* Message styling
|
||||
* Main notification text
|
||||
*/
|
||||
.fl-message {
|
||||
font-size: 0.925rem; /* ~15px at default font size */
|
||||
line-height: 1.5; /* Comfortable line height */
|
||||
font-weight: 500; /* Medium weight for better readability on colored backgrounds */
|
||||
font-size: 0.925rem;
|
||||
line-height: 1.5;
|
||||
font-weight: 500;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Circular button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
background: rgba(255, 255, 255, 0.2); /* Translucent white background */
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: none;
|
||||
font-size: 1.1rem; /* ~17.6px × symbol */
|
||||
font-size: 1.1rem;
|
||||
padding: 0.1rem;
|
||||
width: 1.6rem; /* ~25.6px diameter */
|
||||
width: 1.6rem;
|
||||
height: 1.6rem;
|
||||
border-radius: 50%; /* Perfectly circular */
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
opacity: 0.8; /* Slightly transparent by default */
|
||||
transition: all 0.2s; /* Smooth hover transition */
|
||||
color: var(--ruby-text); /* White text */
|
||||
margin-left: 0.75rem; /* Space between message and button */
|
||||
flex-shrink: 0; /* Prevent button from shrinking */
|
||||
opacity: 0.8;
|
||||
transition: all 0.2s;
|
||||
color: var(--ruby-text);
|
||||
margin-left: 0.75rem;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&:hover, &:focus {
|
||||
opacity: 1; /* Full opacity on hover/focus */
|
||||
background: rgba(255, 255, 255, 0.3); /* Lighter background on hover */
|
||||
transform: scale(1.05); /* Subtle grow effect on hover */
|
||||
opacity: 1;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Progress bar container
|
||||
* Holds the animated progress indicator
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 5px; /* Taller than typical progress bars */
|
||||
background-color: rgba(0, 0, 0, 0.1); /* Slightly dark background */
|
||||
height: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
z-index: 3; /* Above other elements */
|
||||
/**
|
||||
* Progress indicator
|
||||
* Animated by JavaScript to show remaining time
|
||||
*/
|
||||
z-index: 3;
|
||||
.fl-progress {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.4); /* Translucent white progress */
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type gets its own gradient background
|
||||
*/
|
||||
&.fl-success {
|
||||
background: var(--ruby-success-gradient); /* Green gradient */
|
||||
background: var(--ruby-success-gradient);
|
||||
}
|
||||
&.fl-info {
|
||||
background: var(--ruby-info-gradient); /* Blue gradient */
|
||||
background: var(--ruby-info-gradient);
|
||||
}
|
||||
&.fl-warning {
|
||||
background: var(--ruby-warning-gradient); /* Amber gradient */
|
||||
background: var(--ruby-warning-gradient);
|
||||
}
|
||||
&.fl-error {
|
||||
background: var(--ruby-error-gradient); /* Red gradient */
|
||||
background: var(--ruby-error-gradient);
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl;
|
||||
.fl-icon-circle {
|
||||
margin-right: 0;
|
||||
margin-left: 1rem; /* Swap margins for RTL */
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.fl-close {
|
||||
margin-left: 0;
|
||||
margin-right: 0.75rem; /* Swap margins for RTL */
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
.fl-shine {
|
||||
transform: skewX(20deg); /* Reverse shine angle for RTL */
|
||||
transform: skewX(20deg);
|
||||
}
|
||||
.fl-progress .fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable entrance animation */
|
||||
animation: none;
|
||||
.fl-shine {
|
||||
display: none; /* Remove shine effect for reduced motion */
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,117 +1,83 @@
|
||||
/* Theme-specific variables - override these to customize the sapphire theme */
|
||||
.fl-sapphire {
|
||||
/* Base appearance */
|
||||
--sapphire-bg-base: rgba(30, 30, 30, 0.9); /* Dark semi-transparent background */
|
||||
--sapphire-text: #f0f0f0; /* Light text for contrast */
|
||||
--sapphire-shadow: rgba(0, 0, 0, 0.15); /* Subtle shadow */
|
||||
/* Progress bar colors */
|
||||
--sapphire-progress-bg: rgba(255, 255, 255, 0.2); /* Light translucent background */
|
||||
--sapphire-progress-fill: rgba(255, 255, 255, 0.9); /* Nearly white progress indicator */
|
||||
/* Notification type colors - all with high transparency */
|
||||
--sapphire-success: rgba(16, 185, 129, 0.95); /* Transparent green */
|
||||
--sapphire-error: rgba(239, 68, 68, 0.95); /* Transparent red */
|
||||
--sapphire-warning: rgba(245, 158, 11, 0.95); /* Transparent amber */
|
||||
--sapphire-info: rgba(59, 130, 246, 0.95); /* Transparent blue */
|
||||
/* Animation timing */
|
||||
--sapphire-animation: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); /* Smooth bounce easing */
|
||||
--sapphire-bg-base: rgba(30, 30, 30, 0.9);
|
||||
--sapphire-text: #f0f0f0;
|
||||
--sapphire-shadow: rgba(0, 0, 0, 0.15);
|
||||
--sapphire-progress-bg: rgba(255, 255, 255, 0.2);
|
||||
--sapphire-progress-fill: rgba(255, 255, 255, 0.9);
|
||||
--sapphire-success: rgba(16, 185, 129, 0.95);
|
||||
--sapphire-error: rgba(239, 68, 68, 0.95);
|
||||
--sapphire-warning: rgba(245, 158, 11, 0.95);
|
||||
--sapphire-info: rgba(59, 130, 246, 0.95);
|
||||
--sapphire-animation: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
@keyframes sapphireIn {
|
||||
0% {
|
||||
opacity: 0; /* Start invisible */
|
||||
transform: translateY(10px); /* Start below final position */
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-3px); /* Slight overshoot (bounce) */
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1; /* End fully visible */
|
||||
transform: translateY(0); /* End at natural position */
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.fl-sapphire {
|
||||
/* Base appearance */
|
||||
background-color: var(--sapphire-bg-base); /* Semi-transparent background */
|
||||
color: var(--sapphire-text); /* Light text color */
|
||||
padding: 1em 1.5em; /* Comfortable padding */
|
||||
margin: 0 0 0.75em 0; /* Bottom spacing between notifications */
|
||||
background-color: var(--sapphire-bg-base);
|
||||
color: var(--sapphire-text);
|
||||
padding: 1em 1.5em;
|
||||
margin: 0 0 0.75em 0;
|
||||
position: relative;
|
||||
box-shadow: 0 6px 16px var(--sapphire-shadow); /* Soft shadow for depth */
|
||||
transition: all 0.3s ease; /* Smooth transitions */
|
||||
animation: sapphireIn var(--sapphire-animation); /* Entrance animation with bounce */
|
||||
font-family: Roboto, var(--fl-font), serif; /* Prefer Roboto font */
|
||||
border-radius: 4px 4px 0 0; /* Rounded corners */
|
||||
will-change: transform, opacity; /* Optimize for animation performance */
|
||||
/**
|
||||
* Glassmorphism effect
|
||||
* Creates the frosted glass appearance
|
||||
*/
|
||||
backdrop-filter: blur(12px); /* Strong blur effect */
|
||||
-webkit-backdrop-filter: blur(12px); /* Safari support */
|
||||
/**
|
||||
* Message styling
|
||||
* Clean, readable text
|
||||
*/
|
||||
box-shadow: 0 6px 16px var(--sapphire-shadow);
|
||||
transition: all 0.3s ease;
|
||||
animation: sapphireIn var(--sapphire-animation);
|
||||
font-family: Roboto, var(--fl-font), serif;
|
||||
border-radius: 4px 4px 0 0;
|
||||
will-change: transform, opacity;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
.fl-message {
|
||||
font-size: 0.925em; /* ~15px at default font size */
|
||||
line-height: 1.4; /* Comfortable line height */
|
||||
color: var(--sapphire-text); /* Consistent text color */
|
||||
font-size: 0.925em;
|
||||
line-height: 1.4;
|
||||
color: var(--sapphire-text);
|
||||
}
|
||||
/**
|
||||
* Progress bar styling
|
||||
* Indicates time remaining before dismissal
|
||||
*/
|
||||
.fl-progress-bar {
|
||||
position: absolute;
|
||||
bottom: 0; /* Positioned at the bottom */
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px; /* Thin progress bar */
|
||||
background-color: var(--sapphire-progress-bg); /* Semi-transparent background */
|
||||
height: 4px;
|
||||
background-color: var(--sapphire-progress-bg);
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 0.375em 0.375em; /* Rounded bottom corners */
|
||||
/**
|
||||
* Progress indicator
|
||||
* The actual moving part of the progress bar
|
||||
*/
|
||||
border-radius: 0 0 0.375em 0.375em;
|
||||
.fl-progress {
|
||||
background-color: var(--sapphire-progress-fill); /* Lighter fill color */
|
||||
background-color: var(--sapphire-progress-fill);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
transform-origin: left center; /* Animation starts from left */
|
||||
will-change: transform; /* Optimize animation performance */
|
||||
transform-origin: left center;
|
||||
will-change: transform;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific colors
|
||||
* Each notification type gets its own semi-transparent background
|
||||
*/
|
||||
&.fl-success {
|
||||
background-color: var(--sapphire-success); /* Green background */
|
||||
background-color: var(--sapphire-success);
|
||||
}
|
||||
&.fl-error {
|
||||
background-color: var(--sapphire-error); /* Red background */
|
||||
background-color: var(--sapphire-error);
|
||||
}
|
||||
&.fl-warning {
|
||||
background-color: var(--sapphire-warning); /* Amber background */
|
||||
background-color: var(--sapphire-warning);
|
||||
}
|
||||
&.fl-info {
|
||||
background-color: var(--sapphire-info); /* Blue background */
|
||||
background-color: var(--sapphire-info);
|
||||
}
|
||||
/**
|
||||
* RTL language support
|
||||
* Right-to-left text direction
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl; /* Right-to-left text */
|
||||
direction: rtl;
|
||||
.fl-progress .fl-progress {
|
||||
transform-origin: right center; /* Animation starts from right */
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,209 +1,161 @@
|
||||
.fl-slack {
|
||||
/* Theme variables - Define the visual appearance of Slack notifications */
|
||||
/* Base colors and appearance */
|
||||
--slack-bg-light: #ffffff; /* White background in light mode */
|
||||
--slack-bg-dark: #1a1d21; /* Dark background in dark mode (Slack dark) */
|
||||
--slack-hover-light: #f8f8f8; /* Light hover state */
|
||||
--slack-hover-dark: #222529; /* Dark hover state */
|
||||
--slack-text-light: #1d1c1d; /* Dark text in light mode */
|
||||
--slack-text-secondary-light: #616061; /* Gray secondary text in light mode */
|
||||
--slack-text-dark: #e0e0e0; /* Light text in dark mode */
|
||||
--slack-text-secondary-dark: #ababad; /* Gray secondary text in dark mode */
|
||||
--slack-border-light: #e0e0e0; /* Light border color */
|
||||
--slack-border-dark: #393a3e; /* Dark border color */
|
||||
--slack-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); /* Subtle shadow in light mode */
|
||||
--slack-shadow-dark: 0 1px 0 rgba(0, 0, 0, 0.2); /* Stronger shadow in dark mode */
|
||||
--slack-avatar-size: 36px; /* Size of avatar/icon container */
|
||||
/* Type-specific colors matching Slack's color scheme */
|
||||
--slack-success: #2bac76; /* Green */
|
||||
--slack-info: #1264a3; /* Blue */
|
||||
--slack-warning: #e8912d; /* Orange */
|
||||
--slack-error: #e01e5a; /* Red/Pink */
|
||||
/* Animation timing */
|
||||
--slack-animation-duration: 150ms; /* Quick animation for responsive feel */
|
||||
--slack-bg-light: #ffffff;
|
||||
--slack-bg-dark: #1a1d21;
|
||||
--slack-hover-light: #f8f8f8;
|
||||
--slack-hover-dark: #222529;
|
||||
--slack-text-light: #1d1c1d;
|
||||
--slack-text-secondary-light: #616061;
|
||||
--slack-text-dark: #e0e0e0;
|
||||
--slack-text-secondary-dark: #ababad;
|
||||
--slack-border-light: #e0e0e0;
|
||||
--slack-border-dark: #393a3e;
|
||||
--slack-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||
--slack-shadow-dark: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
--slack-avatar-size: 36px;
|
||||
--slack-success: #2bac76;
|
||||
--slack-info: #1264a3;
|
||||
--slack-warning: #e8912d;
|
||||
--slack-error: #e01e5a;
|
||||
--slack-animation-duration: 150ms;
|
||||
}
|
||||
@keyframes slackFadeIn {
|
||||
from {
|
||||
opacity: 0; /* Start invisible */
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1; /* End fully visible */
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.fl-slack {
|
||||
position: relative;
|
||||
margin: 4px 0; /* Minimal spacing between messages */
|
||||
font-family: "Lato", "Slack-Lato", "Helvetica Neue", "Helvetica", sans-serif; /* Slack's font stack */
|
||||
animation: slackFadeIn var(--slack-animation-duration) ease-out; /* Quick fade in */
|
||||
/**
|
||||
* Message bubble
|
||||
* The main container that resembles a Slack message
|
||||
*/
|
||||
margin: 4px 0;
|
||||
font-family: "Lato", "Slack-Lato", "Helvetica Neue", "Helvetica", sans-serif;
|
||||
animation: slackFadeIn var(--slack-animation-duration) ease-out;
|
||||
.fl-slack-message {
|
||||
background-color: var(--slack-bg-light);
|
||||
color: var(--slack-text-light);
|
||||
padding: 8px 20px 8px 8px; /* More padding on right for close button */
|
||||
border-radius: 4px; /* Slightly rounded corners */
|
||||
padding: 8px 20px 8px 8px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: flex-start; /* Align content to top */
|
||||
transition: background-color 0.1s ease; /* Smooth hover transition */
|
||||
border: 1px solid var(--slack-border-light); /* Subtle border */
|
||||
box-shadow: var(--slack-shadow); /* Slight shadow for depth */
|
||||
align-items: flex-start;
|
||||
transition: background-color 0.1s ease;
|
||||
border: 1px solid var(--slack-border-light);
|
||||
box-shadow: var(--slack-shadow);
|
||||
&:hover {
|
||||
background-color: var(--slack-hover-light); /* Background change on hover */
|
||||
background-color: var(--slack-hover-light);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Avatar container
|
||||
* Colored square that holds the type icon
|
||||
*/
|
||||
.fl-avatar {
|
||||
width: var(--slack-avatar-size); /* Fixed size avatar */
|
||||
width: var(--slack-avatar-size);
|
||||
height: var(--slack-avatar-size);
|
||||
border-radius: 4px; /* Slightly rounded corners */
|
||||
margin-right: 8px; /* Space between avatar and text */
|
||||
flex-shrink: 0; /* Prevent avatar from shrinking */
|
||||
border-radius: 4px;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: currentColor; /* Uses the type color */
|
||||
background-color: currentColor;
|
||||
}
|
||||
/**
|
||||
* Type icon
|
||||
* Symbol within the colored avatar
|
||||
*/
|
||||
.fl-type-icon {
|
||||
color: white; /* White icon on colored background */
|
||||
font-weight: bold; /* Bold symbol */
|
||||
font-size: 16px; /* Icon size */
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
/**
|
||||
* Message content container
|
||||
* Holds the message text
|
||||
*/
|
||||
.fl-message-content {
|
||||
flex: 1; /* Take available space */
|
||||
min-width: 0; /* Allows text to wrap */
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
/**
|
||||
* Message text styling
|
||||
* Follows Slack's text appearance
|
||||
*/
|
||||
.fl-message-text {
|
||||
font-size: 15px; /* Slack's standard message size */
|
||||
line-height: 1.46668; /* Slack's line height */
|
||||
word-break: break-word; /* Allows breaking long words */
|
||||
font-size: 15px;
|
||||
line-height: 1.46668;
|
||||
word-break: break-word;
|
||||
}
|
||||
/**
|
||||
* Actions container
|
||||
* Holds the close button that appears on hover
|
||||
*/
|
||||
.fl-actions {
|
||||
visibility: hidden; /* Hidden by default */
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
right: 6px; /* Positioned in top-right */
|
||||
right: 6px;
|
||||
top: 8px;
|
||||
opacity: 0; /* Transparent by default */
|
||||
transition: opacity 0.1s ease; /* Smooth fade in/out */
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s ease;
|
||||
}
|
||||
/**
|
||||
* Show actions on hover
|
||||
* Makes the close button appear when hovering the message
|
||||
*/
|
||||
.fl-slack-message:hover .fl-actions {
|
||||
visibility: visible; /* Show on hover */
|
||||
opacity: 1; /* Fade in */
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
/**
|
||||
* Close button styling
|
||||
* Simple button with hover effect
|
||||
*/
|
||||
.fl-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--slack-text-secondary-light); /* Gray icon by default */
|
||||
color: var(--slack-text-secondary-light);
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
border-radius: 4px; /* Slightly rounded corners */
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&:hover {
|
||||
color: var(--slack-text-light); /* Darker on hover */
|
||||
background-color: var(--slack-hover-light); /* Light background on hover */
|
||||
color: var(--slack-text-light);
|
||||
background-color: var(--slack-hover-light);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Type-specific styling
|
||||
* Each notification type gets its own colored avatar
|
||||
*/
|
||||
&.fl-success {
|
||||
.fl-avatar {
|
||||
color: var(--slack-success); /* Green avatar */
|
||||
color: var(--slack-success);
|
||||
}
|
||||
}
|
||||
&.fl-info {
|
||||
.fl-avatar {
|
||||
color: var(--slack-info); /* Blue avatar */
|
||||
color: var(--slack-info);
|
||||
}
|
||||
}
|
||||
&.fl-warning {
|
||||
.fl-avatar {
|
||||
color: var(--slack-warning); /* Orange avatar */
|
||||
color: var(--slack-warning);
|
||||
}
|
||||
}
|
||||
&.fl-error {
|
||||
.fl-avatar {
|
||||
color: var(--slack-error); /* Red avatar */
|
||||
color: var(--slack-error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* RTL Support
|
||||
* Right-to-left language direction support
|
||||
*/
|
||||
&.fl-rtl {
|
||||
direction: rtl; /* Right-to-left text */
|
||||
direction: rtl;
|
||||
.fl-avatar {
|
||||
margin-right: 0;
|
||||
margin-left: 8px; /* Swap margins */
|
||||
margin-left: 8px;
|
||||
}
|
||||
.fl-username {
|
||||
margin-right: 0;
|
||||
margin-left: 4px; /* Swap margins */
|
||||
margin-left: 4px;
|
||||
}
|
||||
.fl-actions {
|
||||
right: auto;
|
||||
left: 6px; /* Move to top-left */
|
||||
left: 6px;
|
||||
}
|
||||
.fl-slack-message {
|
||||
padding: 8px 8px 8px 20px; /* Swap padding */
|
||||
padding: 8px 8px 8px 20px;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Accessibility
|
||||
* Respects reduced motion preferences
|
||||
*/
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none; /* Disable animation */
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
body.fl-dark .fl-slack,
|
||||
html.fl-dark .fl-slack,
|
||||
.fl-slack.fl-auto-dark {
|
||||
.fl-slack-message {
|
||||
background-color: var(--slack-bg-dark); /* Dark background */
|
||||
color: var(--slack-text-dark); /* Light text */
|
||||
border-color: var(--slack-border-dark); /* Darker border */
|
||||
box-shadow: var(--slack-shadow-dark); /* Stronger shadow */
|
||||
background-color: var(--slack-bg-dark);
|
||||
color: var(--slack-text-dark);
|
||||
border-color: var(--slack-border-dark);
|
||||
box-shadow: var(--slack-shadow-dark);
|
||||
&:hover {
|
||||
background-color: var(--slack-hover-dark); /* Dark hover state */
|
||||
background-color: var(--slack-hover-dark);
|
||||
}
|
||||
}
|
||||
.fl-close {
|
||||
color: var(--slack-text-secondary-dark); /* Lighter gray icon */
|
||||
color: var(--slack-text-secondary-dark);
|
||||
&:hover {
|
||||
color: var(--slack-text-dark); /* White on hover */
|
||||
background-color: var(--slack-hover-dark); /* Dark background on hover */
|
||||
color: var(--slack-text-dark);
|
||||
background-color: var(--slack-hover-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file TypeScript Global Declarations for Toastr
|
||||
* @description Type definitions for jQuery and Toastr globals
|
||||
* @author Younes ENNAJI
|
||||
*/
|
||||
|
||||
// Declare jQuery on the global window object
|
||||
interface Window {
|
||||
jQuery?: any
|
||||
$?: any
|
||||
|
||||
Reference in New Issue
Block a user