Complete 2.4.4-2.5.4: Phase 2 Visual Design Modernization components - accessibility icons, modern button/card/form systems, skeleton loading patterns

This commit is contained in:
VinnyNC 2025-09-29 19:16:37 -04:00
parent 443797bfac
commit b8bf274731
3 changed files with 602 additions and 15 deletions

View file

@ -246,31 +246,31 @@ Always come back and update UI_UPDATE.MD once complete with task and task item.
- [x] Add hover state animations for interactive icons
#### 2.4.4: Accessibility Implementation
- [ ] Add screen reader labels for decorative icons
- [ ] Implement focus indicators for icon buttons
- [ ] Test keyboard navigation for icon controls
- [x] Add screen reader labels for decorative icons
- [x] Implement focus indicators for icon buttons
- [x] Test keyboard navigation for icon controls
### Sub-task 2.5: Component Visual Polish
#### 2.5.1: Button Style Redesign
- [ ] Create button component with multiple variants
- [ ] Implement consistent button sizing and padding
- [ ] Add button state variations (hover, active, disabled)
- [x] Create button component with multiple variants
- [x] Implement consistent button sizing and padding
- [x] Add button state variations (hover, active, disabled)
#### 2.5.2: Card Design Updates
- [ ] Redesign card components with modern styling
- [ ] Implement consistent card shadows and borders
- [ ] Add card interaction states
- [x] Redesign card components with modern styling
- [x] Implement consistent card shadows and borders
- [x] Add card interaction states
#### 2.5.3: Form Element Updates
- [ ] Enhance input field styling
- [ ] Create consistent form element design
- [ ] Implement form validation states
- [x] Enhance input field styling
- [x] Create consistent form element design
- [x] Implement form validation states
#### 2.5.4: Loading States
- [ ] Implement skeleton loading patterns
- [ ] Create smooth loading transitions
- [ ] Add stateful component styling
- [x] Implement skeleton loading patterns
- [x] Create smooth loading transitions
- [x] Add stateful component styling
---

View file

@ -1,5 +1,529 @@
/* 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:hover {
/* Transform handled by state variants */
}
.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 */
.btn:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
/* 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: 2px solid var(--color-focus);
outline-offset: 2px;
}
/* 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);
}
/* =================================================================
LOADING STATES - SKELETONS AND TRANSITIONS
================================================================= */
/* Skeleton loading animations */
@keyframes skeleton-pulse {
0% { opacity: 1; }
50% { opacity: 0.6; }
100% { opacity: 1; }
}
/* 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);
}
/* =================================================================
VIDEO HEADER - Top section of video area
================================================================= */

View file

@ -207,6 +207,69 @@
height: var(--current-icon-size);
}
/* =================================================================
ACCESSIBILITY - Screen Reader Support
================================================================= */
/* Screen reader only text - hide visually but available to assistive tech */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Screen reader only - but show when focused for keyboard users */
.sr-only:focus {
position: static;
width: auto;
height: auto;
padding: 0.5rem;
margin: 0;
overflow: visible;
clip: auto;
white-space: normal;
background: var(--color-surface);
color: var(--color-on-surface);
border-radius: var(--border-radius-md);
box-shadow: var(--elevation-3);
z-index: var(--z-tooltip);
}
/* =================================================================
FOCUS INDICATORS FOR ICON CONTROLS
================================================================= */
/* Base focus styles for interactive icons */
.icon-interactive:focus {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
border-radius: var(--border-radius-sm);
}
/* Enhanced focus ring that matches design system */
.icon-focus-ring {
position: relative;
}
.icon-focus-ring:focus::after {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
border: 2px solid var(--color-focus);
border-radius: var(--border-radius-md);
z-index: 1;
pointer-events: none;
}
/* =================================================================
ANIMATED ICONS
================================================================= */