iptv-stream-web/static/css/components.css
VinnyNC 313ee80726 Complete Phase 5.1.1: Comprehensive CSS performance optimization
- Removed unused CSS rules: eliminated redundant height utilities and duplicate responsive rules in utilities.css
- Optimized CSS selectors: confirmed efficient BEM architecture and class-based selectors throughout codebase
- Implemented hardware acceleration: added backface-visibility, perspective, transform:translateZ(0), and will-change properties to animated components (messages, buttons) for GPU acceleration
- Maintained performance: preserved only essential utilities while ensuring browser compatibility

Related to task 5.1.1 in UI_UPDATE.MD: CSS Optimization for UI rendering performance.
2025-09-29 23:38:07 -04:00

2455 lines
62 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Component styles - Reusable UI components */
/* =================================================================
BUTTON COMPONENT SYSTEM
================================================================= */
/* Base button styles */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-2);
padding: var(--spacing-3) var(--spacing-5);
border: 2px solid transparent;
border-radius: var(--border-radius-lg);
font-family: var(--font-family-base);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
text-align: center;
text-decoration: none;
cursor: pointer;
transition: all var(--transition-fast);
user-select: none;
position: relative;
overflow: hidden;
min-height: var(--min-tap-target-size, 44px);
box-sizing: border-box;
}
/* Button sizes */
.btn-sm {
padding: var(--spacing-2) var(--spacing-4);
font-size: var(--font-size-xs);
min-height: var(--min-tap-target-size-sm, 36px);
}
.btn-lg {
padding: var(--spacing-4) var(--spacing-6);
font-size: var(--font-size-base);
min-height: var(--min-tap-target-size-lg, 52px);
}
/* Button variants */
.btn-primary {
background: linear-gradient(135deg, var(--color-primary), var(--color-primary-darker));
color: var(--color-on-primary);
box-shadow: var(--elevation-3);
border-color: var(--color-primary);
}
.btn-secondary {
background: var(--color-secondary);
color: var(--color-on-secondary);
border-color: var(--color-secondary);
}
.btn-accent {
background: linear-gradient(135deg, var(--color-accent), var(--color-accent-darker));
color: var(--color-on-accent);
box-shadow: var(--elevation-3);
border-color: var(--color-accent);
}
.btn-outline {
background: transparent;
border-color: var(--color-outline);
color: var(--color-on-surface);
}
.btn-outline-primary {
background: transparent;
border-color: var(--color-primary);
color: var(--color-primary);
}
.btn-text {
background: transparent;
border-color: transparent;
color: var(--color-primary);
padding: var(--spacing-2) var(--spacing-3);
box-shadow: none;
}
/* Button states */
.btn:active {
transform: translateY(0);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none !important;
}
.btn-primary:hover {
background: linear-gradient(135deg, var(--color-primary-light), var(--color-primary));
transform: translateY(-1px);
box-shadow: var(--elevation-4);
}
.btn-secondary:hover {
transform: translateY(-1px);
box-shadow: var(--elevation-2);
}
.btn-accent:hover {
background: linear-gradient(135deg, var(--color-accent-light), var(--color-accent));
transform: translateY(-1px);
box-shadow: var(--elevation-4);
}
.btn-outline:hover {
background: var(--color-surface-variant);
}
.btn-outline-primary:hover {
background: var(--color-primary);
color: var(--color-on-primary);
}
.btn-text:hover {
background: rgba(var(--color-primary-rgb), 0.1);
}
/* Focus states for accessibility - WCAG AA compliant */
.btn:focus-visible {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
box-shadow: 0 0 0 1px var(--color-surface), 0 0 0 4px var(--dodgers-blue-100);
}
/* Loading state */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
position: absolute;
content: '';
width: 1em;
height: 1em;
border: 2px solid rgba(255,255,255,0.3);
border-top: 2px solid white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Full width button */
.btn-full {
width: 100%;
}
/* Icon buttons */
.btn-icon {
padding: var(--spacing-2);
width: auto;
aspect-ratio: 1;
}
.btn-icon-only {
width: var(--min-tap-target-size, 44px);
height: var(--min-tap-target-size, 44px);
padding: 0;
}
/* =================================================================
CARD COMPONENT SYSTEM
================================================================= */
/* Base card styles */
.card {
background: var(--color-surface);
border-radius: var(--border-radius-lg);
box-shadow: var(--elevation-1);
border: 1px solid var(--color-outline-variant);
transition: all var(--transition-fast);
overflow: hidden;
position: relative;
}
.card-elevated {
box-shadow: var(--elevation-2);
}
.card-outlined {
border-width: 2px;
background: var(--color-surface);
}
.card-header {
padding: var(--spacing-4);
border-bottom: 1px solid var(--color-outline-variant);
background: var(--color-surface-variant);
}
.card-body {
padding: var(--spacing-4);
}
.card-footer {
padding: var(--spacing-4);
border-top: 1px solid var(--color-outline-variant);
background: var(--color-surface-variant);
}
/* Card interaction states */
.card:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-3);
}
.card-interactive {
cursor: pointer;
}
.card-interactive:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-3);
}
.card-interactive:active {
transform: translateY(0);
box-shadow: var(--elevation-1);
}
.card:focus-visible {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--dodgers-blue-100);
}
/* Form focus states - WCAG AA compliant */
.form-control:focus,
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--dodgers-blue-100);
border-color: var(--color-focus);
}
.chat__input input:focus {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
box-shadow: 0 0 0 2px var(--dodgers-blue-100);
}
/* Link focus states */
a:focus-visible {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
text-decoration: underline;
}
/* Dashboard and control focus states */
.dashboard__toggle-btn:focus-visible {
outline: 3px solid var(--dodgers-white);
outline-offset: 2px;
background: rgba(255,255,255,0.3);
}
.video-player__quality-selector:focus-visible,
.video-player__toggle-chat-btn:focus-visible,
.stream-stats__refresh-btn:focus-visible {
outline: 3px solid var(--dodgers-white);
outline-offset: 2px;
background: rgba(255,255,255,0.3);
}
/* Chat admin controls focus */
.chat__admin-btn:focus-visible {
outline: 3px solid var(--dodgers-gold);
outline-offset: 1px;
}
/* Mobile navigation focus */
.mobile-nav-btn:focus-visible {
outline: 3px solid var(--dodgers-white);
outline-offset: 2px;
background: rgba(255,255,255,0.15);
}
/* FAB focus */
.fab:focus-visible {
outline: 3px solid var(--dodgers-white);
outline-offset: 2px;
box-shadow: 0 0 0 1px var(--dodgers-blue-400), var(--elevation-5);
}
/* Card variants */
.card-compact .card-body {
padding: var(--spacing-3);
}
.card-compact .card-header,
.card-compact .card-footer {
padding: var(--spacing-3);
}
/* =================================================================
FORM ELEMENT SYSTEM
================================================================= */
/* Base input styles */
.form-control {
width: 100%;
padding: var(--spacing-3) var(--spacing-4);
border: 2px solid var(--color-outline);
border-radius: var(--border-radius-md);
background: var(--color-surface);
color: var(--color-on-surface);
font-family: inherit;
font-size: var(--font-size-sm);
transition: all var(--transition-fast);
box-sizing: border-box;
}
.form-control:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px var(--focus-ring);
}
.form-label {
display: block;
margin-bottom: var(--spacing-2);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--color-on-surface);
}
.form-input,
.form-textarea,
.form-select {
/* Inherit from form-control */
width: 100%;
padding: var(--spacing-3) var(--spacing-4);
border: 2px solid var(--color-outline);
border-radius: var(--border-radius-md);
background: var(--color-surface);
color: var(--color-on-surface);
font-family: inherit;
font-size: var(--font-size-sm);
transition: all var(--transition-fast);
box-sizing: border-box;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Form row for horizontal layouts */
.form-row {
display: flex;
gap: var(--spacing-4);
align-items: flex-start;
}
.form-row .form-control {
flex: 1;
}
/* Validation states */
.form-group {
margin-bottom: var(--spacing-4);
position: relative;
}
.form-group--error .form-control {
border-color: var(--color-error);
}
.form-group--error .form-control:focus {
box-shadow: 0 0 0 3px rgba(var(--color-error-rgb), 0.2);
}
.form-group--success .form-control {
border-color: var(--color-success);
}
.form-group--success .form-control:focus {
box-shadow: 0 0 0 3px rgba(var(--color-success-rgb), 0.2);
}
.form-error,
.form-success {
font-size: var(--font-size-xs);
margin-top: var(--spacing-1);
display: block;
}
.form-error {
color: var(--color-error);
}
.form-success {
color: var(--color-success);
}
/* =================================================================
COMPONENT ANIMATIONS AND STATE TRANSITIONS
================================================================= */
/* ===== INTERSECTION OBSERVER ANIMATIONS ===== */
/* Base classes for scroll-triggered animations */
.animate-on-scroll {
opacity: 0;
transform: translateY(20px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll.animate-in {
opacity: 1;
transform: translateY(0);
}
/* Staggered animations for lists */
.animate-stagger {
opacity: 0;
transform: translateY(15px) scale(0.95);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
}
.animate-stagger.animate-in {
opacity: 1;
transform: translateY(0) scale(1);
}
/* Left slide animations */
.animate-on-scroll-left {
opacity: 0;
transform: translateX(-30px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-left.animate-in {
opacity: 1;
transform: translateX(0);
}
/* Right slide animations */
.animate-on-scroll-right {
opacity: 0;
transform: translateX(30px);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-right.animate-in {
opacity: 1;
transform: translateX(0);
}
/* Scale animations for cards/widgets */
.animate-on-scroll-scale {
opacity: 0;
transform: scale(0.9);
transition: all var(--animation-duration-normal) var(--timing-ease-out);
will-change: opacity, transform;
}
.animate-on-scroll-scale.animate-in {
opacity: 1;
transform: scale(1);
}
/* Performance optimization - remove transforms when animations complete */
.animate-on-scroll.animate-in,
.animate-on-scroll-left.animate-in,
.animate-on-scroll-right.animate-in,
.animate-on-scroll-scale.animate-in,
.animate-stagger.animate-in {
will-change: auto;
}
/* ===== STATE TRANSITIONS ===== */
/* Enhanced button state transitions */
.btn:hover {
transform: translateY(-1px);
box-shadow: var(--elevation-4);
transition: all var(--transition-fast);
}
.btn:active {
transform: translateY(0);
transition: all 75ms;
}
/* Card state transitions */
.card:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-3);
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.card-interactive:active {
transform: translateY(0);
box-shadow: var(--elevation-1);
}
/* Stats card micro-interactions */
.stats-card {
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.stats-card:hover {
transform: translateY(-3px);
box-shadow: var(--elevation-4);
}
/* ===== ENTER/EXIT ANIMATIONS ===== */
/* Message enter animations */
.message {
animation: messageSlideIn var(--animation-duration-normal) ease-out;
transform: translateX(0);
opacity: 1;
}
@keyframes messageSlideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.message.own-message {
animation: ownMessageSlideIn var(--animation-duration-normal) ease-out;
}
@keyframes ownMessageSlideIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* System message animations */
.system-message {
animation: systemMessageFadeIn var(--animation-duration-fast) ease-out;
transform: translateY(0);
opacity: 1;
}
@keyframes systemMessageFadeIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ===== MICRO-INTERACTIONS ===== */
/* Button micro-feedback */
.btn-primary:active {
transform: scale(0.98);
transition: transform 75ms ease-out;
}
.btn-accent:active {
transform: scale(0.98);
}
/* Input focus micro-interactions */
.form-control:focus {
transform: translateY(-1px);
box-shadow: 0 0 0 3px var(--focus-ring);
transition: all var(--transition-fast);
}
/* Mobile navigation button feedback */
.mobile-nav-btn:active {
transform: scale(0.92);
transition: transform 75ms ease-out;
}
/* Chat input button feedback */
.chat__input button:active {
transform: scale(0.95);
box-shadow: var(--elevation-1);
}
/* ===== LOADING STATES ANIMATIONS ===== */
/* Skeleton loading animations */
@keyframes skeleton-pulse {
0% { opacity: 1; }
50% { opacity: 0.6; }
100% { opacity: 1; }
}
@keyframes skeleton-shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Base skeleton styles */
.skeleton {
background: linear-gradient(90deg, var(--color-surface-variant) 25%, var(--color-surface) 50%, var(--color-surface-variant) 75%);
background-size: 200% 100%;
animation: skeleton-pulse 1.5s ease-in-out infinite, skeleton-shimmer 1.5s ease-in-out infinite;
border-radius: var(--border-radius-sm);
}
@keyframes skeleton-shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Specific skeleton types */
.skeleton-text {
height: var(--font-size-base);
width: 100%;
margin-bottom: var(--spacing-2);
}
.skeleton-text:last-child {
margin-bottom: 0;
}
.skeleton-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
}
.skeleton-button {
height: var(--min-tap-target-size, 44px);
width: 120px;
border-radius: var(--border-radius-lg);
}
.skeleton-card {
padding: var(--spacing-4);
margin-bottom: var(--spacing-4);
}
.skeleton-card .skeleton-header {
height: var(--font-size-lg);
width: 60%;
margin-bottom: var(--spacing-3);
}
.skeleton-card .skeleton-content {
height: var(--font-size-sm);
width: 100%;
margin-bottom: var(--spacing-1);
}
.skeleton-card .skeleton-content:nth-child(2) {
width: 80%;
}
.skeleton-card .skeleton-content:nth-child(3) {
width: 90%;
}
/* Loading overlay */
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(var(--color-surface-rgb), 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
opacity: 0;
transition: opacity var(--transition-fast);
pointer-events: none;
}
.loading-overlay.active {
opacity: 1;
pointer-events: auto;
}
/* Loading spinner */
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid var(--color-surface-variant);
border-top: 3px solid var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Loading bar */
.loading-bar {
width: 100%;
height: 3px;
background: var(--color-surface-variant);
border-radius: 2px;
overflow: hidden;
position: relative;
}
.loading-bar::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--color-primary), transparent);
animation: loading-bar-anim 1.5s ease-in-out infinite;
}
@keyframes loading-bar-anim {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
/* =================================================================
STATEFUL COMPONENTS - Interactive States
================================================================= */
/* State utilities for dynamic components */
.state-loading {
position: relative;
overflow: hidden;
}
.state-loading::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.1) 50%, transparent 100%);
animation: state-loading-shimmer 2s infinite;
z-index: 1;
}
@keyframes state-loading-shimmer {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
.state-disabled {
opacity: 0.6;
pointer-events: none;
}
.state-expanded {
transform: rotate(180deg);
}
.state-collapsed {
transform: rotate(0deg);
}
.state-active {
background: var(--color-primary);
color: var(--color-on-primary);
}
.state-inactive {
background: var(--color-surface-variant);
color: var(--color-on-surface);
}
/* =================================================================
CONTAINER QUERY SETUP - Modern responsive design
================================================================= */
/* Container query containers for components that need size awareness */
.card, .card-elevated, .card-outlined {
container-type: inline-size;
container-name: card;
}
/* Chat components container queries */
.chat__messages {
container-type: inline-size;
container-name: chat-messages;
}
.message {
container-type: inline-size;
container-name: message;
}
/* Button containers for sizing */
.btn, .btn-primary, .btn-secondary, .btn-accent, .btn-outline, .btn-text {
container-type: inline-size;
container-name: button;
}
/* =================================================================
COMPONENT BREAKPOINT OVERRIDES - Responsive behavior per breakpoint
================================================================= */
/* Button responsive behavior */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.btn:not(.btn-responsive-preserve) {
padding: var(--spacing-2) var(--spacing-3);
font-size: var(--font-size-xs);
min-height: var(--min-tap-target-size, 44px);
}
.btn-lg:not(.btn-responsive-preserve) {
padding: var(--spacing-3) var(--spacing-5);
font-size: var(--font-size-sm);
}
}
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.btn:not(.btn-responsive-preserve) {
padding: var(--spacing-3) var(--spacing-4);
font-size: var(--font-size-base);
}
}
@media (min-width: var(--breakpoint-lg)) {
.btn:not(.btn-responsive-preserve) {
padding: var(--spacing-4) var(--spacing-6);
font-size: var(--font-size-lg);
}
}
/* Card responsive behavior */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.card:not(.card-responsive-preserve) .card-body {
padding: var(--spacing-3);
}
.card:not(.card-responsive-preserve) .card-header,
.card:not(.card-responsive-preserve) .card-footer {
padding: var(--spacing-2) var(--spacing-3);
}
}
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.card:not(.card-responsive-preserve) .card-body {
padding: var(--spacing-4);
}
}
@media (min-width: var(--breakpoint-lg)) {
.card:not(.card-responsive-preserve) .card-body {
padding: var(--spacing-5);
}
}
/* Form control responsive behavior */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.form-control:not(.form-responsive-preserve) {
padding: var(--spacing-2) var(--spacing-3);
font-size: var(--font-size-sm);
}
}
@media (min-width: calc(var(--breakpoint-lg))) {
.form-control:not(.form-responsive-preserve) {
padding: var(--spacing-4) var(--spacing-5);
font-size: var(--font-size-base);
}
}
/* Message responsive behavior for chat */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.message:not(.message-responsive-preserve) .message-text {
max-width: 85%;
font-size: var(--font-size-sm);
padding: var(--spacing-2);
}
.message:not(.message-responsive-preserve) .message-header {
gap: var(--spacing-1);
margin-bottom: var(--spacing-1);
}
}
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.message:not(.message-responsive-preserve) .message-text {
max-width: 90%;
font-size: var(--font-size-base);
}
}
@media (min-width: var(--breakpoint-lg)) {
.message:not(.message-responsive-preserve) .message-text {
max-width: 95%;
font-size: var(--font-size-base);
}
}
/* Video player responsive behavior */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.video-player__header:not(.video-responsive-preserve) {
padding: var(--spacing-2) var(--spacing-3);
}
.video-player__header-left:not(.video-responsive-preserve) {
gap: var(--spacing-3);
}
}
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.video-player__header:not(.video-responsive-preserve) {
padding: var(--spacing-3) var(--spacing-4);
}
}
@media (min-width: var(--breakpoint-lg)) {
.video-player__header:not(.video-responsive-preserve) {
padding: var(--spacing-4) var(--spacing-6);
}
}
/* =================================================================
CONTAINER QUERY IMPLEMENTATIONS - Size-based responsive design
================================================================= */
/* Card container query behavior */
@container card (max-width: 400px) {
.card .card-body {
padding: var(--spacing-3);
}
.card .card-header,
.card .card-footer {
padding: var(--spacing-2) var(--spacing-3);
}
.card .card-header-title {
font-size: var(--font-size-sm);
}
}
@container card (min-width: 401px) and (max-width: 640px) {
.card .card-body {
padding: var(--spacing-4);
}
.card .card-header,
.card .card-footer {
padding: var(--spacing-3) var(--spacing-4);
}
}
@container card (min-width: 641px) {
.card .card-body {
padding: var(--spacing-5);
}
.card .card-header,
.card .card-footer {
padding: var(--spacing-4) var(--spacing-5);
}
}
/* Chat messages container query */
@container chat-messages (max-width: 500px) {
.message .message-text {
max-width: 85%;
padding: var(--spacing-2);
font-size: var(--font-size-sm);
}
.message .message-nickname {
font-size: var(--font-size-sm);
}
}
@container chat-messages (min-width: 501px) {
.message .message-text {
max-width: 92%;
padding: var(--spacing-2) var(--spacing-3);
}
}
/* Individual message container query */
@container message (max-width: 300px) {
.message .message-text {
font-size: var(--font-size-sm);
padding: var(--spacing-2);
}
.message .message-id {
display: none;
}
}
@container message (min-width: 301px) {
.message .message-text {
padding: var(--spacing-2) var(--spacing-3);
}
.message .message-id {
display: inline;
}
}
/* Button container query behavior */
@container button (max-width: 120px) {
.btn:not(.btn-container-preserve) {
padding: var(--spacing-1) var(--spacing-2);
font-size: var(--font-size-xs);
min-height: var(--min-tap-target-size-sm, 36px);
}
.btn-icon-only:not(.btn-container-preserve) {
width: var(--min-tap-target-size-sm, 36px);
height: var(--min-tap-target-size-sm, 36px);
}
}
@container button (min-width: 121px) and (max-width: 200px) {
.btn:not(.btn-container-preserve) {
padding: var(--spacing-2) var(--spacing-3);
font-size: var(--font-size-sm);
}
}
@container button (min-width: 201px) {
.btn:not(.btn-container-preserve) {
padding: var(--spacing-3) var(--spacing-4);
}
}
/* =================================================================
COMPONENT-SPECIFIC RESPONSIVE UTILITY CLASSES
================================================================= */
/* Button responsive utilities */
.btn-responsive-xs { padding: var(--spacing-2) var(--spacing-3) !important; }
.btn-responsive-sm { padding: var(--spacing-3) var(--spacing-4) !important; }
.btn-responsive-md { padding: var(--spacing-4) var(--spacing-5) !important; }
.btn-responsive-lg { padding: var(--spacing-4) var(--spacing-6) !important; }
/* Card responsive utilities */
.card-responsive-xs .card-body { padding: var(--spacing-3) !important; }
.card-responsive-sm .card-body { padding: var(--spacing-4) !important; }
.card-responsive-md .card-body { padding: var(--spacing-5) !important; }
/* Message responsive utilities */
.message-responsive-mobile .message-text { max-width: 85% !important; font-size: var(--font-size-sm) !important; }
.message-responsive-tablet .message-text { max-width: 90% !important; }
.message-responsive-desktop .message-text { max-width: 95% !important; }
/* Video player responsive utilities */
.video-responsive-mobile .video-player__header { padding: var(--spacing-2) var(--spacing-3) !important; }
.video-responsive-tablet .video-player__header { padding: var(--spacing-3) var(--spacing-4) !important; }
.video-responsive-desktop .video-player__header { padding: var(--spacing-4) var(--spacing-6) !important; }
/* =================================================================
DASHBOARD COMPONENTS
================================================================= */
/* Dashboard header */
.dashboard__header {
background: linear-gradient(135deg, var(--dodgers-blue-600) 0%, var(--dodgers-blue-400) 100%);
padding: var(--spacing-4) var(--spacing-5);
color: white;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: var(--elevation-2);
z-index: 5;
border-bottom: 1px solid var(--dodgers-blue-300);
}
.dashboard__title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.dashboard__title::before {
content: '';
display: inline-block;
width: 1em;
height: 1em;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z'%3E%3C/svg%3E") no-repeat center center;
background-size: contain;
margin-right: var(--spacing-2);
}
.dashboard__controls {
display: flex;
gap: var(--spacing-2);
}
.dashboard__toggle-btn {
background: rgba(255,255,255,0.2);
border: 1px solid rgba(255,255,255,0.3);
color: white;
padding: var(--spacing-2) var(--spacing-3);
border-radius: var(--border-radius-lg);
cursor: pointer;
font-size: var(--font-size-sm);
transition: all var(--transition-fast);
backdrop-filter: blur(10px);
}
.dashboard__toggle-btn:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-1px);
}
/* Stats grid */
.dashboard__stats-grid {
display: grid;
gap: var(--spacing-3);
padding: var(--spacing-4) var(--spacing-5) var(--spacing-3);
grid-template-columns: 1fr;
}
.stats-card {
background: var(--color-surface);
border-radius: var(--border-radius-lg);
padding: var(--spacing-4);
border: 1px solid var(--color-outline-variant);
display: flex;
align-items: center;
gap: var(--spacing-3);
transition: all var(--transition-fast);
box-shadow: var(--elevation-1);
}
.stats-card:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-3);
}
.stats-card__icon {
width: 48px;
height: 48px;
background: linear-gradient(135deg, var(--dodgers-blue-500), var(--dodgers-blue-300));
border-radius: var(--border-radius-lg);
display: flex;
align-items: center;
justify-content: center;
color: white;
flex-shrink: 0;
}
.stats-card__content {
flex: 1;
min-width: 0;
}
.stats-card__value {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-bold);
color: var(--text-primary);
margin-bottom: var(--spacing-1);
}
.stats-card__label {
font-size: var(--font-size-sm);
color: var(--text-muted);
font-weight: var(--font-weight-medium);
}
/* Dashboard widgets */
.dashboard__widgets {
flex: 1;
overflow-y: auto;
padding: var(--spacing-4) var(--spacing-5);
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
.widget {
background: var(--color-surface);
border-radius: var(--border-radius-lg);
border: 1px solid var(--color-outline-variant);
box-shadow: var(--elevation-1);
overflow: hidden;
}
.widget__header {
padding: var(--spacing-4);
border-bottom: 1px solid var(--color-outline-variant);
background: var(--color-surface-variant);
}
.widget__title {
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
margin: 0;
}
.widget__content {
padding: var(--spacing-4);
}
/* Activity items */
.activity-item,
.user-item {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-2) 0;
border-bottom: 1px solid var(--color-outline-variant);
}
.activity-item:last-child,
.user-item:last-child {
border-bottom: none;
}
.activity-item__avatar {
width: 32px;
height: 32px;
background: var(--dodgers-blue-500);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-sm);
flex-shrink: 0;
}
.activity-item__content {
flex: 1;
min-width: 0;
}
.activity-item__text {
font-size: var(--font-size-sm);
color: var(--text-primary);
margin-bottom: var(--spacing-1);
}
.activity-item__time {
font-size: var(--font-size-xs);
color: var(--text-muted);
}
/* User items */
.user-item__status {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.user-item__status.online {
background: var(--color-success);
box-shadow: 0 0 6px rgba(var(--color-success-rgb), 0.5);
}
.user-item__status.offline {
background: var(--color-outline);
}
.user-item__nickname {
font-size: var(--font-size-sm);
color: var(--text-primary);
font-weight: var(--font-weight-medium);
}
/* Responsive dashboard */
@media (min-width: var(--breakpoint-lg)) and (max-width: calc(var(--breakpoint-2xl) - 1px)) {
.dashboard__stats-grid {
grid-template-columns: 1fr 1fr;
}
}
@media (min-width: var(--breakpoint-2xl)) {
.dashboard__stats-grid {
grid-template-columns: 1fr;
}
.stats-card {
padding: var(--spacing-3);
}
.stats-card__icon {
width: 40px;
height: 40px;
}
.stats-card__value {
font-size: var(--font-size-xl);
}
}
/* =================================================================
VIDEO HEADER - Top section of video area
================================================================= */
.video-player__header {
background: linear-gradient(135deg, var(--dodgers-blue-700) 0%, var(--dodgers-blue-500) 100%);
padding: var(--spacing-3) var(--spacing-5);
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: var(--elevation-4);
z-index: 10;
}
.video-player__header-left {
display: flex;
align-items: center;
gap: var(--spacing-5);
}
/* Tablet-specific video header adjustments */
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.video-player__header:not(.video-responsive-preserve) {
padding: var(--spacing-4) var(--spacing-6);
}
.video-player__header-left:not(.video-responsive-preserve) {
gap: var(--spacing-6);
}
.stream-logo {
font-size: var(--font-size-2xl);
}
}
.stream-logo {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-bold);
color: white;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.stream-logo::before {
content: '';
display: inline-block;
width: 1.25em;
height: 1.25em;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z'%3E%3C/svg%3E") no-repeat center center;
background-size: contain;
margin-right: var(--spacing-2);
}
/* =================================================================
STREAM STATS - Viewer count and badges
================================================================= */
.stream-stats {
display: flex;
align-items: center;
gap: var(--spacing-4);
}
.stream-stats__status {
background: var(--dodgers-red);
color: white;
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--border-radius-2xl);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-bold);
text-transform: uppercase;
animation: pulse 2s infinite;
}
.stream-stats__viewer-count {
background: rgba(255,255,255,0.2);
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--border-radius-2xl);
color: white;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
display: flex;
align-items: center;
gap: var(--spacing-2);
backdrop-filter: blur(10px);
}
.stream-stats__viewer-count::before {
content: '';
display: inline-block;
width: 1em;
height: 1em;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zM6.5 9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z'%3E%3C/svg%3E") no-repeat center center;
background-size: contain;
margin-right: var(--spacing-2);
}
/* =================================================================
HEADER CONTROLS - Buttons and selectors
================================================================= */
.video-player__header-controls {
display: flex;
gap: var(--spacing-3);
align-items: center;
}
/* Ensure all header control buttons have identical dimensions */
.video-player__header-controls > * {
height: 35px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
vertical-align: top;
line-height: 1;
}
.video-player__quality-selector {
background: rgba(255,255,255,0.2);
border: none;
color: white;
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--border-radius-2xl);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
backdrop-filter: blur(10px);
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
min-height: auto;
}
.video-player__toggle-chat-btn {
background: rgba(255,255,255,0.2);
border: none;
color: white;
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--border-radius-2xl);
cursor: pointer;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
transition: all var(--transition-base);
backdrop-filter: blur(10px);
position: relative;
}
.video-player__toggle-chat-btn:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-1px);
}
.stream-stats__refresh-btn {
background: rgba(255,255,255,0.2);
border: none;
color: white;
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--border-radius-2xl);
cursor: pointer;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
transition: all var(--transition-base);
backdrop-filter: blur(10px);
position: relative;
}
.stream-stats__refresh-btn:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-1px);
}
/* =================================================================
CHAT HEADER
================================================================= */
.chat__header {
background: linear-gradient(135deg, var(--dodgers-blue-500) 0%, var(--dodgers-blue-300) 100%);
padding: var(--spacing-4) var(--spacing-5);
color: white;
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
box-shadow: var(--elevation-1);
display: flex;
align-items: center;
justify-content: space-between;
}
/* Tablet-specific chat header adjustments */
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.chat__header:not(.chat-responsive-preserve) {
padding: var(--spacing-5) var(--spacing-6);
font-size: var(--font-size-lg);
}
.chat__header-title {
gap: var(--spacing-3);
}
.chat__header-title::before {
width: 1.5em;
height: 1.5em;
}
}
.chat__header-title {
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.chat__header-title::before {
content: '';
display: inline-block;
width: 1em;
height: 1em;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z'%3E%3C/svg%3E") no-repeat center center;
background-size: contain;
margin-right: var(--spacing-2);
}
.chat__admin-controls {
display: flex;
gap: var(--spacing-2);
}
.chat__admin-btn {
background: rgba(255,215,0,0.3);
border: 1px solid var(--dodgers-gold);
color: white;
padding: var(--spacing-1) var(--spacing-3);
border-radius: var(--border-radius-xl);
font-size: var(--font-size-xs);
cursor: pointer;
transition: all var(--transition-fast);
}
.chat__admin-btn:hover {
background: rgba(255,215,0,0.5);
}
/* =================================================================
USER INFO SECTION
================================================================= */
.chat__user-info {
padding: var(--spacing-3) var(--spacing-4);
background: var(--card-bg);
border-bottom: 1px solid var(--border-color);
}
.chat__user-id-display {
font-size: var(--font-size-xs);
color: var(--text-muted);
margin-bottom: var(--spacing-2);
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.chat__user-id-badge {
background: var(--dodgers-blue-500);
color: white;
padding: var(--spacing-1) var(--spacing-2);
border-radius: var(--border-radius-xl);
font-weight: var(--font-weight-semibold);
font-family: var(--font-family-mono);
}
.chat__user-id-badge.admin {
background: linear-gradient(135deg, var(--dodgers-gold), #FFB700);
color: #333;
}
.chat__nickname-input {
position: relative;
}
.chat__nickname-input input {
width: 100%;
padding: var(--spacing-3) var(--spacing-3);
border: 2px solid var(--border-color);
border-radius: var(--border-radius-md);
font-size: var(--font-size-sm);
transition: all var(--transition-base);
background: var(--input-bg);
color: var(--text-primary);
}
.chat__nickname-input input::placeholder {
color: var(--text-muted);
}
.chat__nickname-input input:focus {
outline: none;
border-color: var(--dodgers-blue-500);
box-shadow: 0 0 0 3px var(--focus-ring);
}
/* =================================================================
CHAT MESSAGES CONTAINER
================================================================= */
.chat__messages {
flex: 1;
overflow-y: auto;
padding: var(--spacing-4);
background: var(--bg-dark);
}
/* =================================================================
MESSAGE COMPONENTS
================================================================= */
.message {
margin-bottom: var(--spacing-4);
animation: slideIn var(--transition-slow);
position: relative;
}
.message:hover .message-actions {
opacity: 1;
}
/* Hardware acceleration for animations */
.message {
backface-visibility: hidden;
perspective: 1000px;
transform: translateZ(0);
will-change: opacity, transform;
}
.message.selected {
backface-visibility: hidden;
perspective: 1000px;
transform: translateZ(0);
}
.message-actions {
backface-visibility: hidden;
perspective: 1000px;
transform: translateZ(0);
}
.message-actions {
position: absolute;
right: 0;
top: 0;
opacity: 0;
transition: opacity var(--transition-fast);
display: flex;
gap: var(--spacing-1);
}
.delete-btn, .ban-btn {
background: rgba(239,62,66,0.9);
color: white;
border: none;
padding: var(--spacing-1) var(--spacing-2);
border-radius: var(--border-radius-sm);
font-size: var(--font-size-xs);
cursor: pointer;
}
.ban-btn {
background: rgba(255,152,0,0.9);
}
.message-header {
display: flex;
align-items: baseline;
gap: var(--spacing-2);
margin-bottom: var(--spacing-1);
flex-wrap: wrap;
}
.message-nickname {
font-weight: var(--font-weight-semibold);
color: var(--dodgers-blue-500);
font-size: var(--font-size-sm);
}
.message-nickname.admin {
color: var(--dodgers-gold);
text-shadow: 0 0 2px rgba(255,215,0,0.5);
}
.message-id {
font-size: var(--font-size-xs);
color: var(--text-muted);
font-family: var(--font-family-mono);
background: var(--border-color);
padding: 1px var(--spacing-1);
border-radius: var(--border-radius-xl);
}
.message-time {
font-size: var(--font-size-xs);
color: var(--text-muted);
margin-left: auto;
}
.message-text {
padding: var(--spacing-2) var(--spacing-3);
background: var(--card-bg);
border-radius: var(--border-radius-lg);
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
box-shadow: var(--elevation-1);
border-left: 3px solid transparent;
color: var(--text-primary);
word-wrap: break-word;
word-break: break-word;
overflow-wrap: break-word;
white-space: pre-wrap;
max-width: 100%;
}
.own-message .message-nickname {
color: var(--dodgers-red-500);
}
.own-message .message-text {
background: rgba(0,90,156,0.2);
border-left-color: var(--dodgers-blue-500);
}
.admin-message .message-text {
background: var(--admin-bg);
border-left-color: var(--dodgers-gold);
}
.system-message {
text-align: center;
color: var(--text-muted);
font-size: var(--font-size-xs);
font-style: italic;
margin: var(--spacing-3) 0;
padding: var(--spacing-2);
background: rgba(0,90,156,0.1);
border-radius: var(--border-radius-md);
}
.chat__typing-indicator {
padding: 0 var(--spacing-4) var(--spacing-2);
font-size: var(--font-size-xs);
color: var(--text-muted);
font-style: italic;
display: none;
}
.chat__typing-indicator.active {
display: block;
}
.chat__typing-indicator span {
animation: blink 1.4s infinite;
}
.chat__typing-indicator span:nth-child(2) {
animation-delay: 0.2s;
}
.chat__typing-indicator span:nth-child(3) {
animation-delay: 0.4s;
}
/* =================================================================
CHAT INPUT AREA
================================================================= */
.chat__input {
padding: var(--spacing-3) var(--spacing-4);
background: var(--card-bg);
border-top: 1px solid var(--border-color);
}
.chat__input-group {
display: flex;
gap: var(--spacing-2);
}
.chat__input input {
flex: 1;
padding: var(--spacing-3) var(--spacing-4);
border: 2px solid var(--border-color);
border-radius: var(--border-radius-2xl);
font-size: var(--font-size-sm);
transition: all var(--transition-base);
background: var(--input-bg);
color: var(--text-primary);
}
.chat__input input::placeholder {
color: var(--text-muted);
}
.chat__input input:focus {
outline: none;
border-color: var(--dodgers-blue-500);
box-shadow: 0 0 0 3px var(--focus-ring);
}
.chat__input button {
padding: var(--spacing-3) var(--spacing-5);
background: linear-gradient(135deg, var(--dodgers-blue-500), var(--dodgers-blue-300));
color: white;
border: none;
border-radius: var(--border-radius-2xl);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
transition: all var(--transition-base);
box-shadow: var(--elevation-3);
}
.chat__input button:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-4);
}
.chat__input button:active {
transform: translateY(0);
box-shadow: var(--elevation-1);
}
/* Active states for links and form elements */
a:active {
transform: scale(0.98);
}
/* Form elements pressed states */
.form-control:active {
transform: translateY(0);
}
.form-input:active,
.form-textarea:active,
.form-select:active {
transform: translateY(0);
box-shadow: 0 0 0 2px var(--dodgers-blue-200);
}
/* Dashboard controls active states */
.dashboard__toggle-btn:active {
transform: translateY(0);
background: rgba(255,255,255,0.4);
}
.stats-card:active {
transform: translateY(-1px);
box-shadow: var(--elevation-2);
}
/* Video controls pressed states */
.video-player__quality-selector:active,
.video-player__toggle-chat-btn:active,
.stream-stats__refresh-btn:active {
transform: translateY(0);
background: rgba(255,255,255,0.3);
}
/* Chat admin controls active states */
.chat__admin-btn:active {
transform: translateY(0);
background: rgba(255,215,0,0.6);
}
/* Message actions pressed states */
.delete-btn:active, .ban-btn:active {
transform: scale(0.95);
}
/* Mobile navigation active states */
.mobile-nav-btn:active {
transform: scale(0.95) translateY(0);
background: rgba(255,255,255,0.15);
}
/* FAB active states */
.fab:active, .fab.secondary:active {
transform: scale(1.05);
box-shadow: var(--elevation-3);
}
/* Toast notifications active states */
.toast:active {
transform: translateX(-50%) scale(0.95);
}
/* Activity and user item active states */
.activity-item:active,
.user-item:active {
transform: scale(0.98);
background: var(--color-surface-variant);
}
.chat__empty-state {
text-align: center;
color: var(--text-muted);
padding: var(--spacing-12) var(--spacing-5);
font-size: var(--font-size-sm);
}
/* =================================================================
CONNECTION STATUS
================================================================= */
.chat__connection-status {
padding: var(--spacing-2);
background: var(--bg-darker);
text-align: center;
font-size: var(--font-size-xs);
color: var(--text-muted);
display: flex;
align-items: center;
justify-content: center;
gap: var(--spacing-2);
border-top: 1px solid var(--border-color);
}
.chat__connection-indicator {
width: var(--spacing-2);
height: var(--spacing-2);
border-radius: 50%;
background: #4caf50;
animation: blink 2s infinite;
}
.chat__connection-indicator.offline {
background: #f44336;
animation: none;
}
/* =================================================================
NOTIFICATION SYSTEM - Enhanced with Variants & Queue
================================================================= */
/* Notification container for stacking multiple notifications */
.notifications-container {
position: fixed;
top: var(--spacing-5);
right: var(--spacing-5);
z-index: var(--z-toast);
pointer-events: none;
display: flex;
flex-direction: column;
gap: var(--spacing-3);
align-items: flex-end;
max-width: min(400px, calc(100vw - var(--spacing-5) * 2));
}
.notifications-container--bottom {
top: auto;
bottom: var(--spacing-5);
}
.notifications-container--center {
right: auto;
left: 50%;
transform: translateX(-50%);
align-items: center;
}
/* Base notification styles */
.notification {
position: relative;
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-4);
border-radius: var(--border-radius-lg);
font-family: var(--font-family-base);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
line-height: var(--line-height-normal);
box-shadow: var(--elevation-4);
border: 1px solid transparent;
min-width: 300px;
max-width: 100%;
pointer-events: auto;
transition: all var(--transition-fast);
animation: notification-slide-in var(--transition-normal) ease-out;
word-wrap: break-word;
overflow-wrap: break-word;
}
.notification.exiting {
animation: notification-slide-out 0.3s ease-in;
}
/* Notification variants */
.notification--success {
background: var(--color-success-container);
color: var(--color-on-success-container);
border-color: var(--color-success-outline);
}
.notification--success::before {
content: '✓';
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background: var(--color-success);
color: var(--color-on-success);
border-radius: 50%;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
}
.notification--error {
background: var(--color-error-container);
color: var(--color-on-error-container);
border-color: var(--color-error-outline);
}
.notification--error::before {
content: '✕';
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background: var(--color-error);
color: var(--color-on-error);
border-radius: 50%;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
}
.notification--warning {
background: var(--color-warning-container);
color: var(--color-on-warning-container);
border-color: var(--color-warning-outline);
}
.notification--warning::before {
content: '⚠';
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background: var(--color-warning);
color: var(--color-on-warning);
border-radius: 50%;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
}
.notification--info {
background: var(--color-primary-container);
color: var(--color-on-primary-container);
border-color: var(--color-primary-outline);
}
.notification--info::before {
content: '';
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background: var(--color-primary);
color: var(--color-on-primary);
border-radius: 50%;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
}
.notification--default {
background: var(--color-surface);
color: var(--color-on-surface);
border-color: var(--color-outline-variant);
}
/* Notification content area */
.notification__content {
flex: 1;
min-width: 0;
}
.notification__title {
font-weight: var(--font-weight-semibold);
margin-bottom: var(--spacing-1);
font-size: var(--font-size-sm);
}
.notification__message {
margin: 0;
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
}
/* Notification actions */
.notification__actions {
display: flex;
gap: var(--spacing-2);
margin-left: auto;
}
.notification__action {
background: transparent;
border: none;
color: inherit;
cursor: pointer;
padding: var(--spacing-1);
border-radius: var(--border-radius-sm);
font-size: 16px;
line-height: 1;
transition: all var(--transition-fast);
opacity: 0.7;
flex-shrink: 0;
}
.notification__action:hover {
opacity: 1;
background: rgba(var(--color-on-surface-rgb), 0.1);
}
.notification__action:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
opacity: 1;
}
/* Progress indicator for auto-dismissing notifications */
.notification__progress {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 3px;
background: rgba(var(--color-on-surface-rgb), 0.2);
border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
overflow: hidden;
}
.notification__progress-bar {
height: 100%;
background: currentColor;
animation: notification-progress linear forwards;
}
/* Notification animations */
@keyframes notification-slide-in {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes notification-slide-out {
from {
opacity: 1;
transform: translateX(0) scale(1);
max-height: 200px;
margin-bottom: var(--spacing-3);
}
to {
opacity: 0;
transform: translateX(100%) scale(0.9);
max-height: 0;
margin-bottom: 0;
}
}
@keyframes notification-progress {
from { width: 100%; }
to { width: 0%; }
}
/* Notification enter animations for different positions */
.notifications-container--bottom .notification {
animation: notification-slide-up var(--transition-normal) ease-out;
}
.notifications-container--center .notification {
animation: notification-fade-in var(--transition-normal) ease-out;
}
@keyframes notification-slide-up {
from {
opacity: 0;
transform: translateY(100%);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes notification-fade-in {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Mobile responsive adjustments */
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.notifications-container {
top: var(--spacing-4);
right: var(--spacing-4);
left: var(--spacing-4);
align-items: stretch;
}
.notifications-container--center {
right: var(--spacing-4);
left: var(--spacing-4);
transform: none;
}
.notification {
min-width: auto;
max-width: none;
}
.notification__content {
flex: 1;
}
}
/* Legacy toast support - deprecated, use notifications instead */
.toast {
position: fixed;
bottom: var(--spacing-5);
left: 50%;
transform: translateX(-50%);
background: rgba(0,0,0,0.9);
color: white;
padding: var(--spacing-3) var(--spacing-5);
border-radius: var(--border-radius-2xl);
font-size: var(--font-size-sm);
z-index: var(--z-toast);
opacity: 0;
transition: opacity var(--transition-fast);
}
.toast.show {
opacity: 1;
}
.toast:active {
transform: translateX(-50%) scale(0.95);
}
/* Video player notification badge - unchanged */
.video-player__notification-badge {
position: absolute;
top: calc(var(--spacing-2) * -1);
right: calc(var(--spacing-2) * -1);
background: var(--dodgers-red);
color: white;
border-radius: var(--border-radius-xl);
padding: var(--spacing-1) var(--spacing-2);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-bold);
display: none;
animation: bounce 0.5s;
}
.video-player__notification-badge.show {
display: block;
}
/* =================================================================
FLOATING ACTION BUTTONS
================================================================= */
.fab-container {
position: fixed;
bottom: var(--spacing-5);
right: var(--spacing-5);
display: flex;
flex-direction: column;
gap: var(--spacing-3);
z-index: var(--z-fixed);
}
.fab {
width: 56px;
height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, var(--dodgers-blue-500), var(--dodgers-blue-300));
color: white;
border: none;
cursor: pointer;
box-shadow: var(--elevation-4);
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
transition: all var(--transition-base);
}
.fab:hover {
transform: scale(1.1);
box-shadow: var(--elevation-5);
}
.fab.secondary {
width: 48px;
height: 48px;
font-size: 20px;
background: rgba(0,90,156,0.9);
}
/* =================================================================
MOBILE BOTTOM NAVIGATION
================================================================= */
.mobile-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(135deg, var(--dodgers-blue-700), var(--dodgers-blue-600));
border-top: 1px solid rgba(255,255,255,0.2);
box-shadow: var(--elevation-8);
backdrop-filter: blur(10px);
padding: var(--spacing-3) var(--spacing-4);
display: none; /* Hidden by default, shown only on mobile */
z-index: var(--z-fixed);
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.mobile-nav.active {
display: flex;
}
.mobile-nav-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--spacing-1);
padding: var(--spacing-2) var(--spacing-1);
min-height: var(--min-tap-target-size, 44px);
min-width: var(--min-tap-target-size, 44px);
border: none;
background: transparent;
color: rgba(255,255,255,0.9);
border-radius: var(--border-radius-lg);
cursor: pointer;
transition: all var(--transition-fast);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
text-align: center;
}
.mobile-nav-btn:active {
transform: scale(0.95);
background: rgba(255,255,255,0.1);
}
.mobile-nav-btn:hover {
color: white;
background: rgba(255,255,255,0.15);
}
.mobile-nav-btn.active {
background: rgba(255,255,255,0.2);
color: white;
}
.mobile-nav-btn .icon {
font-size: 20px;
width: 24px;
height: 24px;
}
.mobile-nav-btn span {
font-size: 10px;
line-height: 1;
opacity: 0.9;
}
/* Mobile navigation responsive behavior */
@media (max-width: calc(var(--breakpoint-md) - 1px)) {
.mobile-nav {
display: flex;
}
}
@media (max-width: calc(var(--breakpoint-sm) - 1px)) {
.mobile-nav {
padding: var(--spacing-2) var(--spacing-3);
gap: var(--spacing-3);
}
.mobile-nav-btn {
padding: var(--spacing-1);
gap: 2px;
min-width: 48px;
}
.mobile-nav-btn .icon {
width: 20px;
height: 20px;
font-size: 18px;
}
.mobile-nav-btn span {
font-size: 9px;
}
}
/* Safe area support for devices with notches */
@supports (padding-bottom: max(0px)) {
.mobile-nav {
padding-bottom: max(var(--spacing-3), env(safe-area-inset-bottom));
}
body.mobile-nav-active {
padding-bottom: 80px; /* Space for bottom nav */
}
@media (max-width: calc(var(--breakpoint-md) - 1px)) {
body.mobile-nav-active {
padding-bottom: max(70px, calc(70px + env(safe-area-inset-bottom)));
}
}
}