diff --git a/src/components/AppHeader.tsx b/src/components/AppHeader.tsx index fc63d5c..be05d94 100644 --- a/src/components/AppHeader.tsx +++ b/src/components/AppHeader.tsx @@ -1,66 +1,7 @@ import React from 'react'; -import { Link, useLocation, useParams } from 'react-router-dom'; +import { Link } from 'react-router-dom'; export const AppHeader: React.FC = () => { - const location = useLocation(); - const params = useParams(); - - const getPageTitle = () => { - const { pathname } = location; - - // Route patterns with titles (cleaner than manual parsing) - const routes = [ - { pattern: /^\/$/, title: 'Welcome to Slideshare' }, - { pattern: /^\/presentations$/, title: 'My Presentations' }, - { pattern: /^\/presentations\/new$/, title: 'Create New Presentation' }, - { pattern: /^\/presentations\/[^/]+\/edit\/slides\/(\d+)$/, title: () => `Editing Slide ${params.slideNumber}` }, - { pattern: /^\/presentations\/[^/]+\/view\/slides\/(\d+)$/, title: () => `Viewing Slide ${params.slideNumber}` }, - { pattern: /^\/presentations\/[^/]+\/present\/(\d+)$/, title: () => `Presenting Slide ${params.slideNumber}` }, - { pattern: /^\/presentations\/[^/]+\/slide\/new\/edit$/, title: 'Add New Slide' }, - { pattern: /^\/presentations\/[^/]+\/slide\/[^/]+\/edit$/, title: 'Edit Slide' }, - { pattern: /^\/themes$/, title: 'Theme Browser' }, - { pattern: /^\/themes\/([^/]+)$/, title: () => `Theme: ${params.themeId}` }, - { pattern: /^\/themes\/[^/]+\/layouts\/([^/]+)$/, title: () => `Layout: ${params.layoutId}` }, - { pattern: /^\/themes\/[^/]+\/layouts\/[^/]+\/preview$/, title: () => `Preview Layout` }, - ]; - - for (const route of routes) { - if (route.pattern.test(pathname)) { - return typeof route.title === 'function' ? route.title() : route.title; - } - } - - return 'Slideshare'; - }; - - const getPageDescription = () => { - const { pathname } = location; - - // Route patterns with descriptions - const routes = [ - { pattern: /^\/$/, description: 'Create beautiful presentations with customizable themes' }, - { pattern: /^\/presentations$/, description: 'View and manage all your presentations' }, - { pattern: /^\/presentations\/new$/, description: 'Enter details for your new presentation' }, - { pattern: /^\/presentations\/[^/]+\/edit\/slides\/(\d+)$/, description: 'Edit slide content, add notes, and manage your presentation' }, - { pattern: /^\/presentations\/[^/]+\/view\/slides\/(\d+)$/, description: 'View your presentation slides in read-only mode' }, - { pattern: /^\/presentations\/[^/]+\/present\/(\d+)$/, description: 'Present your slides in full screen mode' }, - { pattern: /^\/presentations\/[^/]+\/slide\/new\/edit$/, description: 'Choose a layout and add content for your new slide' }, - { pattern: /^\/presentations\/[^/]+\/slide\/[^/]+\/edit$/, description: 'Edit slide content and layout' }, - { pattern: /^\/themes$/, description: 'Browse and select themes for your presentations' }, - { pattern: /^\/themes\/([^/]+)$/, description: 'View theme details, layouts, and color palette' }, - { pattern: /^\/themes\/[^/]+\/layouts\/([^/]+)$/, description: 'View layout template, slots, and configuration' }, - { pattern: /^\/themes\/[^/]+\/layouts\/[^/]+\/preview$/, description: 'Preview layout with sample content' }, - ]; - - for (const route of routes) { - if (route.pattern.test(pathname)) { - return route.description; - } - } - - return 'Slide authoring and presentation tool'; - }; - return (
-
-

{getPageTitle()}

-

{getPageDescription()}

-
); }; \ No newline at end of file diff --git a/src/components/presentations/NewPresentationPage.css b/src/components/presentations/NewPresentationPage.css index b659458..2692e33 100644 --- a/src/components/presentations/NewPresentationPage.css +++ b/src/components/presentations/NewPresentationPage.css @@ -1,154 +1,21 @@ -.new-presentation-page { - min-height: 100vh; - background: #f8fafc; -} - -.page-header { - background: white; - border-bottom: 1px solid #e2e8f0; - padding: 1.5rem 2rem; - display: flex; - align-items: center; - gap: 1.5rem; -} - -.back-button { - background: none; - border: none; - color: #64748b; - font-size: 0.875rem; - font-weight: 500; - cursor: pointer; - padding: 0.5rem 0.75rem; - border-radius: 0.375rem; - transition: all 0.2s ease; -} - -.back-button:hover { - background: #f1f5f9; - color: #334155; -} +/* Component uses utility classes: .page-container, .page-header, .page-content */ +/* Component-specific styles only */ .header-content h1 { - margin: 0; font-size: 1.875rem; font-weight: 700; - color: #1e293b; } -.header-content p { - margin: 0.25rem 0 0 0; - color: #64748b; - font-size: 0.875rem; -} - -.page-content { - padding: 2rem; - max-width: 1200px; - margin: 0 auto; -} +/* Uses utility classes: .flex .flex-col .gap-8 for creation-form */ +/* Uses .card class for presentation-details, theme-selection, creation-actions */ +/* Uses .form-group, .form-label, .form-input classes from application.css */ .creation-form { - display: flex; - flex-direction: column; - gap: 3rem; -} - -/* Presentation Details Section */ -.presentation-details { - background: white; - border-radius: 0.75rem; - padding: 2rem; - border: 1px solid #e2e8f0; -} - -.presentation-details h2 { - margin: 0 0 1.5rem 0; - font-size: 1.25rem; - font-weight: 600; - color: #1e293b; -} - -.form-group { - margin-bottom: 1.5rem; -} - -.form-group:last-child { - margin-bottom: 0; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 500; - color: #374151; - font-size: 0.875rem; -} - -.form-input, -.form-textarea { - width: 100%; - padding: 0.75rem; - border: 1px solid #d1d5db; - border-radius: 0.5rem; - font-size: 0.875rem; - transition: border-color 0.2s ease, box-shadow 0.2s ease; - background: white; - color: #374151; - box-sizing: border-box; -} - -.form-input:focus, -.form-textarea:focus { - outline: none; - border-color: #3b82f6; - box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); -} - -.form-textarea { - resize: vertical; - min-height: 80px; - font-family: inherit; -} - -/* Theme Selection Section */ -.theme-selection { - background: white; - border-radius: 0.75rem; - padding: 2rem; - border: 1px solid #e2e8f0; -} - -.theme-selection h2 { - margin: 0 0 0.5rem 0; - font-size: 1.25rem; - font-weight: 600; - color: #1e293b; + gap: 3rem; /* Override default gap */ } .section-description { margin: 0 0 2rem 0; - color: #64748b; - font-size: 0.875rem; -} - -.no-themes { - text-align: center; - padding: 3rem; - color: #64748b; -} - -/* Creation Actions Section */ -.creation-actions { - background: white; - border-radius: 0.75rem; - padding: 2rem; - border: 1px solid #e2e8f0; - display: flex; - justify-content: space-between; - align-items: center; - gap: 2rem; - flex-wrap: wrap; } .selected-theme-info { @@ -160,223 +27,54 @@ margin: 0 0 0.5rem 0; font-size: 1.125rem; font-weight: 600; - color: #1e293b; + color: var(--text-primary); } .theme-preview-info p { margin: 0 0 0.75rem 0; - color: #64748b; + color: var(--text-secondary); font-size: 0.875rem; } -.theme-stats { - display: flex; - gap: 1rem; - font-size: 0.75rem; - color: #6b7280; -} +/* Uses .flex .gap-4 .text-xs utility classes for theme-stats */ +/* Uses .badge-secondary class for theme-stats span */ +/* Uses .alert-error class for creation-error */ -.theme-stats span { - background: #f1f5f9; - padding: 0.25rem 0.5rem; - border-radius: 0.25rem; -} - -.creation-error { - margin-top: 1rem; - padding: 0.75rem; - background: #fef2f2; - border: 1px solid #fecaca; - border-radius: 0.375rem; - color: #dc2626; -} - -.creation-error p { - margin: 0; - font-size: 0.875rem; - font-weight: 500; -} - -/* Aspect Ratio Selection */ +/* Aspect Ratio Selection - uses .grid-auto-fill-250 .gap-4 */ .aspect-ratio-selection { margin-bottom: 2rem; } -.aspect-ratio-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1rem; -} - +/* Aspect ratio cards extend .card base class */ .aspect-ratio-card { - border: 2px solid #e2e8f0; - border-radius: 0.75rem; - padding: 1.5rem; + border: 2px solid var(--border-primary); cursor: pointer; - transition: all 0.2s ease; - background: white; -} - -.aspect-ratio-card:hover { - border-color: #cbd5e1; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); } .aspect-ratio-card.selected { - border-color: #3b82f6; - box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.2); - background: #eff6ff; + border-color: var(--border-accent); + box-shadow: 0 4px 6px -1px var(--bg-accent); + background: var(--bg-accent); } +/* Preview content - component specific */ .aspect-ratio-preview { - display: flex; - align-items: center; - justify-content: center; height: 80px; - margin-bottom: 1rem; - background: #f8fafc; - border-radius: 0.5rem; - border: 1px dashed #cbd5e1; + background: var(--bg-primary); + border: 1px dashed var(--border-secondary); } .preview-box { - background: #3b82f6; - border-radius: 0.25rem; + background: var(--text-accent); } -.preview-box.aspect-16-9 { - width: 64px; - height: 36px; -} +.preview-box.aspect-16-9 { width: 64px; height: 36px; } +.preview-box.aspect-4-3 { width: 60px; height: 45px; } +.preview-box.aspect-16-10 { width: 64px; height: 40px; } -.preview-box.aspect-4-3 { - width: 60px; - height: 45px; -} +/* Uses .badge-secondary for ratio-dimensions */ +/* Uses .flex .gap-4 .flex-shrink-0 for action-buttons */ -.preview-box.aspect-16-10 { - width: 64px; - height: 40px; -} - -.aspect-ratio-info h3 { - margin: 0 0 0.5rem 0; - font-size: 1rem; - font-weight: 600; - color: #1e293b; -} - -.ratio-description { - margin: 0 0 0.75rem 0; - font-size: 0.875rem; - color: #64748b; - line-height: 1.4; -} - -.ratio-dimensions { - font-size: 0.75rem; - color: #6b7280; - background: #f1f5f9; - padding: 0.25rem 0.5rem; - border-radius: 0.25rem; - display: inline-block; -} - -.action-buttons { - display: flex; - gap: 1rem; - flex-shrink: 0; -} - -.button { - padding: 0.75rem 1.5rem; - border-radius: 0.5rem; - font-weight: 500; - font-size: 0.875rem; - cursor: pointer; - transition: all 0.2s ease; - border: none; - text-decoration: none; - display: inline-flex; - align-items: center; - justify-content: center; -} - -.button.primary { - background: #3b82f6; - color: white; -} - -.button.primary:hover:not(:disabled) { - background: #2563eb; -} - -.button.primary:disabled { - background: #9ca3af; - cursor: not-allowed; -} - -.button.secondary { - background: #f8fafc; - color: #64748b; - border: 1px solid #e2e8f0; -} - -.button.secondary:hover { - background: #f1f5f9; - color: #475569; -} - -/* Loading and Error States */ -.loading-content, -.error-content { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 50vh; - text-align: center; - gap: 1rem; -} - -.loading-spinner { - color: #64748b; - font-size: 1.125rem; -} - -.error-content h2 { - color: #dc2626; - margin: 0; -} - -.error-content p { - color: #64748b; - margin: 0.5rem 0 1.5rem 0; -} - -/* Responsive Design */ -@media (max-width: 768px) { - .page-header { - padding: 1rem; - flex-direction: column; - align-items: flex-start; - gap: 1rem; - } - - .page-content { - padding: 1rem; - } - - .creation-actions { - flex-direction: column; - align-items: stretch; - } - - .action-buttons { - justify-content: stretch; - } - - .button { - flex: 1; - } -} \ No newline at end of file +/* Uses .btn, .btn-primary, .btn-secondary classes from application.css */ +/* Uses .loading-content, .error-content, .loading-spinner classes from application.css */ +/* Responsive design handled by utility classes in application.css */ \ No newline at end of file diff --git a/src/components/slide-editor/SlideEditor.css b/src/components/slide-editor/SlideEditor.css index 4b6ede5..ee6b968 100644 --- a/src/components/slide-editor/SlideEditor.css +++ b/src/components/slide-editor/SlideEditor.css @@ -638,7 +638,7 @@ } .preview-info span { - background: rgba(0, 0, 0, 0.5); + background: var(--bg-overlay); padding: var(--space-sm) var(--space-lg); border-radius: var(--radius-sm); backdrop-filter: blur(8px); diff --git a/src/components/ui/Modal.css b/src/components/ui/Modal.css index d29bd40..de041ec 100644 --- a/src/components/ui/Modal.css +++ b/src/components/ui/Modal.css @@ -5,7 +5,7 @@ left: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.5); + background-color: var(--bg-overlay); display: flex; align-items: center; justify-content: center; @@ -16,7 +16,7 @@ /* Modal Content */ .modal-content { - background: white; + background: var(--bg-primary); border-radius: 0.75rem; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); max-width: 100%; @@ -25,6 +25,7 @@ display: flex; flex-direction: column; animation: modalSlideIn 0.2s ease-out; + border: 1px solid var(--border-primary); } @keyframes modalSlideIn { diff --git a/src/index.css b/src/index.css index b9baad7..be1a9ff 100644 --- a/src/index.css +++ b/src/index.css @@ -1,5 +1,7 @@ /* Import global color system */ @import './styles/colors.css'; +/* Import consolidated application styles */ +@import './styles/application.css'; :root { font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; diff --git a/src/styles/application.css b/src/styles/application.css new file mode 100644 index 0000000..4a656e2 --- /dev/null +++ b/src/styles/application.css @@ -0,0 +1,631 @@ +/* Application CSS - Consolidated Styles */ +/* Import color system first */ +@import './colors.css'; + +/* ================================================================= + UTILITY CLASSES - Layout + ================================================================= */ + +/* Display */ +.flex { display: flex; } +.grid { display: grid; } +.block { display: block; } +.inline-block { display: inline-block; } +.hidden { display: none; } + +/* Flex Direction */ +.flex-col { flex-direction: column; } +.flex-row { flex-direction: row; } + +/* Flex Alignment */ +.items-start { align-items: flex-start; } +.items-center { align-items: center; } +.items-end { align-items: flex-end; } +.items-stretch { align-items: stretch; } + +.justify-start { justify-content: flex-start; } +.justify-center { justify-content: center; } +.justify-end { justify-content: flex-end; } +.justify-between { justify-content: space-between; } + +/* Flex Properties */ +.flex-1 { flex: 1; } +.flex-shrink-0 { flex-shrink: 0; } +.flex-wrap { flex-wrap: wrap; } + +/* Grid Templates */ +.grid-auto-fill-200 { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } +.grid-auto-fill-250 { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); } +.grid-auto-fill-300 { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); } +.grid-cols-2 { grid-template-columns: repeat(2, 1fr); } +.grid-cols-3 { grid-template-columns: repeat(3, 1fr); } + +/* Gap */ +.gap-1 { gap: 0.25rem; } +.gap-2 { gap: 0.5rem; } +.gap-3 { gap: 0.75rem; } +.gap-4 { gap: 1rem; } +.gap-6 { gap: 1.5rem; } +.gap-8 { gap: 2rem; } + +/* Position */ +.relative { position: relative; } +.absolute { position: absolute; } +.fixed { position: fixed; } +.sticky { position: sticky; } + +/* ================================================================= + UTILITY CLASSES - Spacing + ================================================================= */ + +/* Margin */ +.m-0 { margin: 0; } +.m-auto { margin: auto; } +.mx-auto { margin-left: auto; margin-right: auto; } + +.mt-1 { margin-top: 0.25rem; } +.mt-2 { margin-top: 0.5rem; } +.mt-4 { margin-top: 1rem; } +.mt-6 { margin-top: 1.5rem; } +.mt-8 { margin-top: 2rem; } + +.mb-1 { margin-bottom: 0.25rem; } +.mb-2 { margin-bottom: 0.5rem; } +.mb-4 { margin-bottom: 1rem; } +.mb-6 { margin-bottom: 1.5rem; } +.mb-8 { margin-bottom: 2rem; } + +.ml-2 { margin-left: 0.5rem; } +.ml-4 { margin-left: 1rem; } +.mr-2 { margin-right: 0.5rem; } +.mr-4 { margin-right: 1rem; } + +/* Padding */ +.p-1 { padding: 0.25rem; } +.p-2 { padding: 0.5rem; } +.p-3 { padding: 0.75rem; } +.p-4 { padding: 1rem; } +.p-6 { padding: 1.5rem; } +.p-8 { padding: 2rem; } + +.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; } +.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } +.px-4 { padding-left: 1rem; padding-right: 1rem; } +.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; } +.px-8 { padding-left: 2rem; padding-right: 2rem; } + +.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; } +.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; } +.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; } +.py-4 { padding-top: 1rem; padding-bottom: 1rem; } +.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; } +.py-8 { padding-top: 2rem; padding-bottom: 2rem; } + +/* ================================================================= + UTILITY CLASSES - Sizing + ================================================================= */ + +/* Width */ +.w-full { width: 100%; } +.w-auto { width: auto; } +.w-8 { width: 2rem; } +.w-12 { width: 3rem; } +.w-16 { width: 4rem; } +.w-32 { width: 8rem; } + +/* Height */ +.h-full { height: 100%; } +.h-auto { height: auto; } +.h-8 { height: 2rem; } +.h-12 { height: 3rem; } +.h-16 { height: 4rem; } +.h-20 { height: 5rem; } +.h-32 { height: 8rem; } + +/* Min/Max Width */ +.max-w-sm { max-width: 24rem; } +.max-w-md { max-width: 28rem; } +.max-w-lg { max-width: 32rem; } +.max-w-xl { max-width: 36rem; } +.max-w-2xl { max-width: 42rem; } +.max-w-4xl { max-width: 56rem; } +.max-w-6xl { max-width: 72rem; } +.max-w-7xl { max-width: 80rem; } +.max-w-full { max-width: 100%; } + +/* Min Height */ +.min-h-0 { min-height: 0; } +.min-h-screen { min-height: 100vh; } +.min-h-20 { min-height: 5rem; } +.min-h-32 { min-height: 8rem; } + +/* ================================================================= + UTILITY CLASSES - Typography + ================================================================= */ + +/* Font Size */ +.text-xs { font-size: 0.75rem; line-height: 1rem; } +.text-sm { font-size: 0.875rem; line-height: 1.25rem; } +.text-base { font-size: 1rem; line-height: 1.5rem; } +.text-lg { font-size: 1.125rem; line-height: 1.75rem; } +.text-xl { font-size: 1.25rem; line-height: 1.75rem; } +.text-2xl { font-size: 1.5rem; line-height: 2rem; } +.text-3xl { font-size: 1.875rem; line-height: 2.25rem; } + +/* Font Weight */ +.font-normal { font-weight: 400; } +.font-medium { font-weight: 500; } +.font-semibold { font-weight: 600; } +.font-bold { font-weight: 700; } + +/* Text Alignment */ +.text-left { text-align: left; } +.text-center { text-align: center; } +.text-right { text-align: right; } + +/* Line Height */ +.leading-none { line-height: 1; } +.leading-tight { line-height: 1.25; } +.leading-normal { line-height: 1.5; } +.leading-relaxed { line-height: 1.625; } + +/* ================================================================= + UTILITY CLASSES - Borders & Appearance + ================================================================= */ + +/* Border Radius */ +.rounded { border-radius: 0.25rem; } +.rounded-md { border-radius: 0.375rem; } +.rounded-lg { border-radius: 0.5rem; } +.rounded-xl { border-radius: 0.75rem; } +.rounded-2xl { border-radius: 1rem; } +.rounded-full { border-radius: 50%; } + +/* Borders */ +.border { border: 1px solid var(--border-primary); } +.border-2 { border: 2px solid var(--border-primary); } +.border-t { border-top: 1px solid var(--border-primary); } +.border-b { border-bottom: 1px solid var(--border-primary); } +.border-l { border-left: 1px solid var(--border-primary); } +.border-r { border-right: 1px solid var(--border-primary); } + +.border-dashed { border-style: dashed; } + +/* Box Shadow */ +.shadow-none { box-shadow: none; } +.shadow-sm { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } +.shadow { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); } +.shadow-md { box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } +.shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } + +/* ================================================================= + UTILITY CLASSES - Aspect Ratios + ================================================================= */ + +.aspect-16-9 { aspect-ratio: 16 / 9; } +.aspect-4-3 { aspect-ratio: 4 / 3; } +.aspect-16-10 { aspect-ratio: 16 / 10; } +.aspect-square { aspect-ratio: 1 / 1; } + +/* ================================================================= + UTILITY CLASSES - Transitions & Animations + ================================================================= */ + +.transition { transition: all 0.2s ease; } +.transition-colors { + transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; +} +.transition-opacity { transition: opacity 0.2s ease; } +.transition-transform { transition: transform 0.2s ease; } + +/* Common Animation States */ +.hover\:shadow-md:hover { box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); } +.hover\:bg-hover:hover { background-color: var(--bg-hover); } + +/* ================================================================= + UTILITY CLASSES - Interactions + ================================================================= */ + +.cursor-pointer { cursor: pointer; } +.cursor-not-allowed { cursor: not-allowed; } +.select-none { user-select: none; } + +/* Opacity */ +.opacity-50 { opacity: 0.5; } +.opacity-75 { opacity: 0.75; } + +/* Z-Index */ +.z-10 { z-index: 10; } +.z-20 { z-index: 20; } +.z-50 { z-index: 50; } +.z-1000 { z-index: 1000; } + +/* ================================================================= + COMPONENT BASE CLASSES + ================================================================= */ + +/* Page Layout */ +.page-container { + min-height: 100vh; + background: var(--bg-primary); +} + +.page-header { + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-primary); + padding: 1.5rem 2rem; + display: flex; + align-items: center; + gap: 1.5rem; +} + +.page-content { + padding: 2rem; + max-width: 1200px; + margin: 0 auto; +} + +/* Cards */ +.card { + background: var(--bg-secondary); + border: 1px solid var(--border-primary); + border-radius: 0.75rem; + padding: 1.5rem; + transition: all 0.2s ease; +} + +.card:hover { + border-color: var(--border-hover); + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + +.card-compact { + padding: 1rem; +} + +.card-header { + margin-bottom: 1.5rem; +} + +.card-header h1, +.card-header h2, +.card-header h3 { + margin: 0 0 0.5rem 0; + color: var(--text-primary); +} + +.card-header p { + margin: 0; + color: var(--text-secondary); + font-size: 0.875rem; +} + +/* Grid Cards */ +.card-grid { + display: grid; + gap: 1.5rem; +} + +.card-grid-auto-300 { + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); +} + +.card-grid-auto-250 { + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); +} + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.75rem 1.5rem; + border-radius: 0.5rem; + font-weight: 500; + font-size: 0.875rem; + cursor: pointer; + transition: all 0.2s ease; + text-decoration: none; + border: none; + box-sizing: border-box; +} + +.btn:disabled { + cursor: not-allowed; + opacity: 0.5; +} + +.btn-primary { + background: var(--text-accent); + color: white; +} + +.btn-primary:hover:not(:disabled) { + background: var(--text-link-hover); +} + +.btn-secondary { + background: var(--bg-primary); + color: var(--text-secondary); + border: 1px solid var(--border-primary); +} + +.btn-secondary:hover:not(:disabled) { + background: var(--bg-hover); + color: var(--text-primary); +} + +.btn-danger { + background: var(--text-error); + color: white; +} + +.btn-danger:hover:not(:disabled) { + background: var(--text-error); + opacity: 0.9; +} + +/* Button Sizes */ +.btn-sm { + padding: 0.5rem 1rem; + font-size: 0.75rem; +} + +.btn-lg { + padding: 1rem 2rem; + font-size: 1rem; +} + +/* Icon Buttons */ +.btn-icon { + padding: 0.5rem; + width: 2.5rem; + height: 2.5rem; + border-radius: 0.375rem; +} + +.btn-icon-sm { + padding: 0.25rem; + width: 2rem; + height: 2rem; + border-radius: 0.25rem; +} + +/* Form Elements */ +.form-group { + margin-bottom: 1.5rem; +} + +.form-group:last-child { + margin-bottom: 0; +} + +.form-label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; + color: var(--text-primary); + font-size: 0.875rem; +} + +.form-input { + width: 100%; + padding: 0.75rem; + border: 1px solid var(--border-secondary); + border-radius: 0.5rem; + font-size: 0.875rem; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + background: var(--bg-secondary); + color: var(--text-primary); + box-sizing: border-box; +} + +.form-input:focus { + outline: none; + border-color: var(--border-accent); + box-shadow: 0 0 0 3px var(--bg-accent); +} + +.form-textarea { + resize: vertical; + min-height: 80px; + font-family: inherit; +} + +/* Error States */ +.form-input.error { + border-color: var(--border-error); +} + +.form-error { + margin-top: 0.25rem; + color: var(--text-error); + font-size: 0.75rem; +} + +/* Loading States */ +.loading-content, +.error-content, +.empty-content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 50vh; + text-align: center; + gap: 1rem; +} + +.loading-spinner { + color: var(--text-secondary); + font-size: 1.125rem; +} + +.error-content h2 { + color: var(--text-error); + margin: 0; +} + +.error-content p { + color: var(--text-secondary); + margin: 0.5rem 0 1.5rem 0; +} + +/* Alert/Notification Styles */ +.alert { + padding: 0.75rem; + border-radius: 0.375rem; + margin-bottom: 1rem; + border: 1px solid; +} + +.alert-error { + background: var(--bg-error); + border-color: var(--border-error); + color: var(--text-error); +} + +.alert-success { + background: var(--bg-success); + border-color: var(--border-success); + color: var(--text-success); +} + +.alert-warning { + background: var(--bg-warning); + border-color: var(--border-warning); + color: var(--text-warning); +} + +/* Modal Base */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: var(--bg-overlay); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 1rem; + box-sizing: border-box; +} + +.modal-content { + background: var(--bg-primary); + border-radius: 0.75rem; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + max-width: 100%; + max-height: 90vh; + overflow: hidden; + display: flex; + flex-direction: column; + border: 1px solid var(--border-primary); +} + +/* Navigation */ +.nav-link { + color: var(--text-secondary); + text-decoration: none; + font-weight: 500; + font-size: 0.875rem; + padding: 0.5rem 0.75rem; + border-radius: 0.375rem; + transition: all 0.2s ease; +} + +.nav-link:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +/* Stats/Badge Components */ +.badge { + padding: 0.25rem 0.75rem; + border-radius: 0.375rem; + font-size: 0.75rem; + font-weight: 500; +} + +.badge-primary { + background: var(--bg-accent); + color: var(--text-accent); +} + +.badge-secondary { + background: var(--bg-muted); + color: var(--text-tertiary); +} + +/* ================================================================= + RESPONSIVE UTILITIES + ================================================================= */ + +@media (max-width: 768px) { + .page-header { + padding: 1rem; + flex-direction: column; + align-items: flex-start; + gap: 1rem; + } + + .page-content { + padding: 1rem; + } + + .card-grid-auto-300 { + grid-template-columns: 1fr; + } + + .card-grid-auto-250 { + grid-template-columns: 1fr; + } + + .flex-col-mobile { + flex-direction: column; + } + + .text-center-mobile { + text-align: center; + } +} + +/* ================================================================= + ANIMATION KEYFRAMES + ================================================================= */ + +@keyframes slideIn { + from { + opacity: 0; + transform: scale(0.95) translateY(-10px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +/* Animation utilities */ +.animate-slide-in { + animation: slideIn 0.2s ease-out; +} + +.animate-fade-in { + animation: fadeIn 0.2s ease-out; +} + +.animate-spin { + animation: spin 1s linear infinite; +} \ No newline at end of file diff --git a/src/styles/colors.css b/src/styles/colors.css index f7903a4..ee8e4c0 100644 --- a/src/styles/colors.css +++ b/src/styles/colors.css @@ -154,6 +154,7 @@ --bg-muted: var(--color-gray-50); --bg-hover: var(--color-slate-100); --bg-active: var(--color-slate-200); + --bg-overlay: rgba(0, 0, 0, 0.5); /* Borders */ --border-primary: var(--color-slate-200); @@ -238,6 +239,7 @@ --bg-muted: var(--color-gray-800); --bg-hover: var(--color-gray-700); --bg-active: var(--color-gray-600); + --bg-overlay: rgba(0, 0, 0, 0.7); --border-primary: var(--color-gray-600); --border-secondary: var(--color-gray-500);