Add comprehensive semantic design token system
Implement complete semantic layer for all design tokens including typography, spacing, motion, colors, borders, shadows, z-index, opacity, and glass effects. Each semantic token maps base design tokens to contextual usage patterns for improved maintainability and developer experience. Features: - Complete semantic typography system with font weights, sizes, line heights, and letter spacing - Comprehensive spacing tokens for components, layouts, and interactions - Full motion system with durations, easing, transitions, and hover transforms - Semantic color system with individual access to all Material Design 3 colors - Border tokens with widths, radius, and styles for all use cases - Shadow system including standard and AI-themed shadows - Z-index layering system for proper stacking context - Opacity tokens for transparency and visibility states - Glass morphism tokens with blur, opacity, and theming support All semantic tokens provide direct access to base token values while offering meaningful contextual aliases for common UI patterns. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,452 @@
|
||||
// ==========================================================================
|
||||
// INTERACTION PATTERNS
|
||||
// ==========================================================================
|
||||
// Common interaction and state patterns
|
||||
// Theme-agnostic behavioral styles
|
||||
// ==========================================================================
|
||||
|
||||
// HOVER EFFECTS
|
||||
.hover-lift {
|
||||
transition: transform var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
transform: var(--hover-lift-transform, translateY(-4px));
|
||||
}
|
||||
}
|
||||
|
||||
.hover-scale {
|
||||
transition: transform var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
transform: var(--hover-scale-transform, scale(1.05));
|
||||
}
|
||||
}
|
||||
|
||||
.hover-glow {
|
||||
transition: box-shadow var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
box-shadow: var(--hover-glow-shadow, 0 0 20px rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
}
|
||||
|
||||
.hover-fade {
|
||||
transition: opacity var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
opacity: var(--hover-fade-opacity, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.hover-brighten {
|
||||
transition: filter var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
filter: brightness(var(--hover-brighten-value, 1.1));
|
||||
}
|
||||
}
|
||||
|
||||
.hover-darken {
|
||||
transition: filter var(--hover-transition-duration, 0.2s) var(--hover-transition-easing, ease);
|
||||
|
||||
&:hover {
|
||||
filter: brightness(var(--hover-darken-value, 0.9));
|
||||
}
|
||||
}
|
||||
|
||||
// FOCUS STATES
|
||||
.focus-ring {
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, #007bff);
|
||||
outline-offset: var(--focus-ring-offset, 2px);
|
||||
}
|
||||
}
|
||||
|
||||
.focus-ring-inset {
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, #007bff);
|
||||
outline-offset: var(--focus-ring-inset-offset, -2px);
|
||||
}
|
||||
}
|
||||
|
||||
.focus-glow {
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
box-shadow: var(--focus-glow-shadow, 0 0 0 3px rgba(0, 123, 255, 0.25));
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
// ACTIVE STATES
|
||||
.active-press {
|
||||
transition: transform var(--active-transition-duration, 0.1s) var(--active-transition-easing, ease);
|
||||
|
||||
&:active {
|
||||
transform: var(--active-press-transform, scale(0.98));
|
||||
}
|
||||
}
|
||||
|
||||
.active-sink {
|
||||
transition: transform var(--active-transition-duration, 0.1s) var(--active-transition-easing, ease);
|
||||
|
||||
&:active {
|
||||
transform: var(--active-sink-transform, translateY(2px));
|
||||
}
|
||||
}
|
||||
|
||||
// LOADING STATES
|
||||
.loading {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: var(--loading-spinner-size, 20px);
|
||||
height: var(--loading-spinner-size, 20px);
|
||||
margin-top: calc(var(--loading-spinner-size, 20px) / -2);
|
||||
margin-left: calc(var(--loading-spinner-size, 20px) / -2);
|
||||
border: 2px solid var(--loading-spinner-color, rgba(0, 0, 0, 0.3));
|
||||
border-top-color: var(--loading-spinner-active-color, #007bff);
|
||||
border-radius: 50%;
|
||||
animation: loading-spin var(--loading-spin-duration, 1s) linear infinite;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&.loading-overlay::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: var(--loading-overlay-bg, rgba(255, 255, 255, 0.8));
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-pulse {
|
||||
animation: loading-pulse var(--loading-pulse-duration, 2s) infinite;
|
||||
}
|
||||
|
||||
@keyframes loading-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: var(--loading-pulse-opacity, 0.5); }
|
||||
}
|
||||
|
||||
.loading-skeleton {
|
||||
background: var(--skeleton-bg, #f0f0f0);
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
var(--skeleton-bg, #f0f0f0),
|
||||
var(--skeleton-highlight, #e0e0e0),
|
||||
var(--skeleton-bg, #f0f0f0)
|
||||
);
|
||||
background-size: 200px 100%;
|
||||
background-repeat: no-repeat;
|
||||
animation: loading-shimmer var(--skeleton-duration, 1.5s) infinite;
|
||||
border-radius: var(--skeleton-border-radius, 4px);
|
||||
}
|
||||
|
||||
@keyframes loading-shimmer {
|
||||
0% { background-position: -200px 0; }
|
||||
100% { background-position: calc(200px + 100%) 0; }
|
||||
}
|
||||
|
||||
// DISABLED STATES
|
||||
.disabled,
|
||||
[disabled] {
|
||||
opacity: var(--disabled-opacity, 0.6);
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.disabled-loading {
|
||||
opacity: var(--disabled-loading-opacity, 0.8);
|
||||
pointer-events: none;
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
// SUCCESS STATES
|
||||
.success-flash {
|
||||
animation: success-flash var(--success-flash-duration, 0.5s) ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes success-flash {
|
||||
0%, 100% { background-color: transparent; }
|
||||
50% { background-color: var(--success-flash-color, rgba(40, 167, 69, 0.2)); }
|
||||
}
|
||||
|
||||
.success-checkmark {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: var(--success-color, #28a745);
|
||||
font-size: var(--success-checkmark-size, 1.5rem);
|
||||
font-weight: bold;
|
||||
animation: success-checkmark-appear var(--success-checkmark-duration, 0.3s) ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes success-checkmark-appear {
|
||||
0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
|
||||
100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
}
|
||||
|
||||
// ERROR STATES
|
||||
.error-shake {
|
||||
animation: error-shake var(--error-shake-duration, 0.5s) ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes error-shake {
|
||||
0%, 20%, 40%, 60%, 80%, 100% { transform: translateX(0); }
|
||||
10%, 50%, 90% { transform: translateX(-5px); }
|
||||
30%, 70% { transform: translateX(5px); }
|
||||
}
|
||||
|
||||
.error-flash {
|
||||
animation: error-flash var(--error-flash-duration, 0.5s) ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes error-flash {
|
||||
0%, 100% { background-color: transparent; }
|
||||
50% { background-color: var(--error-flash-color, rgba(220, 53, 69, 0.2)); }
|
||||
}
|
||||
|
||||
// WARNING STATES
|
||||
.warning-pulse {
|
||||
animation: warning-pulse var(--warning-pulse-duration, 2s) infinite;
|
||||
}
|
||||
|
||||
@keyframes warning-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: var(--warning-pulse-opacity, 0.7); }
|
||||
}
|
||||
|
||||
// DRAG AND DROP STATES
|
||||
.draggable {
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
transition: transform var(--draggable-transition-duration, 0.2s) var(--draggable-transition-easing, ease);
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
&.dragging {
|
||||
cursor: grabbing;
|
||||
opacity: var(--dragging-opacity, 0.8);
|
||||
transform: var(--dragging-transform, rotate(5deg));
|
||||
z-index: var(--z-dragging, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
.drop-zone {
|
||||
transition: all var(--drop-zone-transition-duration, 0.2s) var(--drop-zone-transition-easing, ease);
|
||||
border: 2px dashed transparent;
|
||||
border-radius: var(--drop-zone-border-radius, 8px);
|
||||
padding: var(--drop-zone-padding, 20px);
|
||||
|
||||
&.drop-zone-active {
|
||||
border-color: var(--drop-zone-active-border, #007bff);
|
||||
background-color: var(--drop-zone-active-bg, rgba(0, 123, 255, 0.05));
|
||||
}
|
||||
|
||||
&.drop-zone-invalid {
|
||||
border-color: var(--drop-zone-invalid-border, #dc3545);
|
||||
background-color: var(--drop-zone-invalid-bg, rgba(220, 53, 69, 0.05));
|
||||
}
|
||||
}
|
||||
|
||||
// SELECTION STATES
|
||||
.selectable {
|
||||
cursor: pointer;
|
||||
transition: all var(--selectable-transition-duration, 0.2s) var(--selectable-transition-easing, ease);
|
||||
border: var(--selectable-border-width, 2px) solid transparent;
|
||||
border-radius: var(--selectable-border-radius, 4px);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--selectable-hover-border, rgba(0, 123, 255, 0.5));
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-color: var(--selectable-selected-border, #007bff);
|
||||
background-color: var(--selectable-selected-bg, rgba(0, 123, 255, 0.05));
|
||||
}
|
||||
|
||||
&.selecting {
|
||||
opacity: var(--selecting-opacity, 0.7);
|
||||
transform: var(--selecting-transform, scale(0.98));
|
||||
}
|
||||
}
|
||||
|
||||
// EXPANDABLE CONTENT
|
||||
.expandable {
|
||||
overflow: hidden;
|
||||
transition: height var(--expandable-transition-duration, 0.3s) var(--expandable-transition-easing, ease);
|
||||
|
||||
&.expanding {
|
||||
transition: height var(--expanding-transition-duration, 0.3s) var(--expanding-transition-easing, ease-out);
|
||||
}
|
||||
|
||||
&.collapsing {
|
||||
transition: height var(--collapsing-transition-duration, 0.3s) var(--collapsing-transition-easing, ease-in);
|
||||
}
|
||||
}
|
||||
|
||||
.expandable-trigger {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--expandable-trigger-gap, 8px);
|
||||
|
||||
.expand-icon {
|
||||
transition: transform var(--expand-icon-transition-duration, 0.2s) var(--expand-icon-transition-easing, ease);
|
||||
}
|
||||
|
||||
&.expanded .expand-icon {
|
||||
transform: var(--expand-icon-expanded-transform, rotate(180deg));
|
||||
}
|
||||
}
|
||||
|
||||
// SORTABLE LISTS
|
||||
.sortable {
|
||||
.sortable-item {
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
transition: all var(--sortable-transition-duration, 0.2s) var(--sortable-transition-easing, ease);
|
||||
|
||||
&.sortable-ghost {
|
||||
opacity: var(--sortable-ghost-opacity, 0.5);
|
||||
background: var(--sortable-ghost-bg, rgba(0, 123, 255, 0.1));
|
||||
}
|
||||
|
||||
&.sortable-chosen {
|
||||
opacity: var(--sortable-chosen-opacity, 0.8);
|
||||
transform: var(--sortable-chosen-transform, scale(1.02));
|
||||
}
|
||||
}
|
||||
|
||||
.sortable-handle {
|
||||
cursor: grab;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--sortable-handle-padding, 8px);
|
||||
opacity: var(--sortable-handle-opacity, 0.6);
|
||||
transition: opacity var(--sortable-handle-transition-duration, 0.2s);
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RIPPLE EFFECT
|
||||
.ripple-effect {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 50%;
|
||||
background: var(--ripple-color, rgba(255, 255, 255, 0.3));
|
||||
transform: translate(-50%, -50%);
|
||||
transition: width var(--ripple-duration, 0.6s), height var(--ripple-duration, 0.6s);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.ripple-active::before {
|
||||
width: var(--ripple-size, 200px);
|
||||
height: var(--ripple-size, 200px);
|
||||
}
|
||||
}
|
||||
|
||||
// FLOATING ELEMENTS
|
||||
.floating {
|
||||
animation: floating var(--floating-duration, 3s) ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes floating {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(var(--floating-distance, -10px)); }
|
||||
}
|
||||
|
||||
.bob {
|
||||
animation: bob var(--bob-duration, 2s) ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes bob {
|
||||
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
|
||||
40% { transform: translateY(var(--bob-distance, -10px)); }
|
||||
60% { transform: translateY(var(--bob-distance-small, -5px)); }
|
||||
}
|
||||
|
||||
// ACCESSIBILITY ENHANCEMENTS
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hover-lift,
|
||||
.hover-scale,
|
||||
.hover-glow,
|
||||
.hover-fade,
|
||||
.hover-brighten,
|
||||
.hover-darken,
|
||||
.active-press,
|
||||
.active-sink,
|
||||
.expandable,
|
||||
.expandable-trigger .expand-icon,
|
||||
.sortable .sortable-item,
|
||||
.ripple-effect,
|
||||
.floating,
|
||||
.bob {
|
||||
transition: none;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.loading-pulse,
|
||||
.loading-skeleton,
|
||||
.warning-pulse {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-contrast: high) {
|
||||
.focus-ring:focus,
|
||||
.focus-ring:focus-visible {
|
||||
outline-width: 3px;
|
||||
}
|
||||
|
||||
.selectable {
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.drop-zone {
|
||||
border-width: 3px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user