diff --git a/app/static/css/style.css b/app/static/css/style.css index 010a605..bbf93cf 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -1,132 +1,587 @@ -/* Custom styles for LEGO Instructions Manager */ +/* Enhanced styles for LEGO Instructions Manager */ +/* ===== CSS Variables ===== */ :root { + /* LEGO Brand Colors */ --lego-red: #d11013; + --lego-red-dark: #a00d10; --lego-yellow: #ffd700; + --lego-yellow-bright: #ffed4e; --lego-blue: #0055bf; + --lego-blue-light: #2b7fdb; + + /* Modern Palette */ + --primary-gradient: linear-gradient(135deg, #d11013 0%, #ff4757 100%); + --secondary-gradient: linear-gradient(135deg, #0055bf 0%, #0abde3 100%); + --success-gradient: linear-gradient(135deg, #10ac84 0%, #1dd1a1 100%); + --warning-gradient: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%); + + /* Neutrals */ + --gray-50: #f8f9fa; + --gray-100: #e9ecef; + --gray-200: #dee2e6; + --gray-300: #ced4da; + --gray-600: #6c757d; + --gray-800: #343a40; + --gray-900: #212529; + + /* Shadows */ + --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.08); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12); + --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15); + --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.18); + + /* Border Radius */ + --radius-sm: 0.375rem; + --radius-md: 0.5rem; + --radius-lg: 0.75rem; + --radius-xl: 1rem; + + /* Transitions */ + --transition-fast: 0.2s ease; + --transition-base: 0.3s ease; + --transition-slow: 0.5s ease; } +/* ===== Base Styles ===== */ body { min-height: 100vh; display: flex; flex-direction: column; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background: linear-gradient(to bottom, #ffffff 0%, var(--gray-50) 100%); + color: var(--gray-900); } main { flex: 1; + padding-top: 2rem; + padding-bottom: 4rem; +} + +/* ===== Enhanced Navbar ===== */ +.navbar { + background: var(--primary-gradient) !important; + box-shadow: var(--shadow-md); + padding: 1rem 0; + border-bottom: 3px solid var(--lego-red-dark); } -/* Navbar customization */ .navbar-brand { - font-weight: bold; + font-weight: 800; font-size: 1.5rem; + letter-spacing: -0.5px; + transition: transform var(--transition-fast); + display: flex; + align-items: center; + gap: 0.5rem; } -/* Card hover effects */ +.navbar-brand:hover { + transform: translateY(-2px); +} + +.navbar-brand i { + font-size: 1.8rem; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +.nav-link { + font-weight: 500; + transition: all var(--transition-fast); + padding: 0.5rem 1rem !important; + border-radius: var(--radius-md); +} + +.nav-link:hover { + background-color: rgba(255, 255, 255, 0.15); + transform: translateY(-1px); +} + +.navbar .dropdown-menu { + border: none; + box-shadow: var(--shadow-lg); + border-radius: var(--radius-md); + padding: 0.5rem; +} + +.navbar .dropdown-item { + border-radius: var(--radius-sm); + padding: 0.6rem 1rem; + transition: all var(--transition-fast); +} + +.navbar .dropdown-item:hover { + background: var(--gray-100); + transform: translateX(4px); +} + +/* ===== Hero Section ===== */ +.display-3 { + font-weight: 800; + letter-spacing: -2px; + background: var(--primary-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.lead { + font-size: 1.25rem; + line-height: 1.8; + color: var(--gray-600); + max-width: 800px; + margin: 0 auto; +} + +/* ===== Enhanced Buttons ===== */ +.btn { + font-weight: 600; + border-radius: var(--radius-md); + padding: 0.6rem 1.5rem; + transition: all var(--transition-base); + border: none; + position: relative; + overflow: hidden; +} + +.btn::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: rgba(255, 255, 255, 0.3); + transform: translate(-50%, -50%); + transition: width 0.6s, height 0.6s; +} + +.btn:hover::before { + width: 300px; + height: 300px; +} + +.btn-danger { + background: var(--primary-gradient); + box-shadow: var(--shadow-md); +} + +.btn-danger:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-lg); +} + +.btn-outline-secondary, +.btn-outline-warning { + border-width: 2px; + font-weight: 600; +} + +.btn-outline-secondary:hover { + background: var(--gray-800); + border-color: var(--gray-800); + transform: translateY(-2px); +} + +.btn-lg { + padding: 0.8rem 2rem; + font-size: 1.1rem; +} + +/* ===== Card Enhancements ===== */ .card { - transition: transform 0.2s, box-shadow 0.2s; + border: none; + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); + transition: all var(--transition-base); + overflow: hidden; + background: white; } .card:hover { - transform: translateY(-5px); - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; + transform: translateY(-8px); + box-shadow: var(--shadow-xl); } -/* Set card image */ +.card-header { + background: linear-gradient(135deg, var(--gray-50) 0%, white 100%); + border-bottom: 2px solid var(--gray-200); + font-weight: 700; + padding: 1.25rem 1.5rem; +} + +.card-header h5 { + margin: 0; + font-size: 1.1rem; + color: var(--gray-800); +} + +.card-body { + padding: 1.5rem; +} + +.card-footer { + background: transparent; + border-top: 1px solid var(--gray-200); + padding: 1rem 1.5rem; +} + +/* ===== Statistics Cards ===== */ +.stat-card { + border-left: 4px solid transparent; + background: white; + position: relative; + overflow: hidden; +} + +.stat-card::before { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 100px; + height: 100px; + background: var(--gray-50); + border-radius: 50%; + transform: translate(30%, -30%); + transition: all var(--transition-base); +} + +.stat-card:hover::before { + transform: translate(30%, -30%) scale(1.5); +} + +.stat-card:nth-child(1) { + border-left-color: var(--lego-blue); +} + +.stat-card:nth-child(2) { + border-left-color: #10ac84; +} + +.stat-card:nth-child(3) { + border-left-color: var(--lego-red); +} + +.stat-card:nth-child(4) { + border-left-color: var(--lego-yellow); +} + +.stat-card h2 { + font-size: 2.5rem; + font-weight: 800; + margin: 0; + background: var(--primary-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.stat-card h6 { + font-weight: 600; + text-transform: uppercase; + font-size: 0.75rem; + letter-spacing: 1px; + color: var(--gray-600); +} + +.stat-card i.display-4 { + font-size: 3rem; + opacity: 0.15; + position: relative; + z-index: 1; +} + +/* ===== Set Card Images ===== */ .set-image { height: 200px; object-fit: contain; - background-color: #f8f9fa; + background: linear-gradient(135deg, var(--gray-50) 0%, white 100%); + padding: 1rem; + transition: all var(--transition-base); } -/* Dashboard clickable thumbnails */ .dashboard a .set-image, .dashboard a .card-img-top { - transition: opacity 0.3s, transform 0.3s; + transition: all var(--transition-base); } .dashboard a:hover .set-image, .dashboard a:hover .card-img-top { - opacity: 0.85; - transform: scale(1.02); + transform: scale(1.05); + filter: brightness(1.1); } -.dashboard a:hover img { - filter: brightness(1.05); +/* ===== Badges ===== */ +.badge { + font-weight: 600; + padding: 0.4em 0.8em; + border-radius: var(--radius-sm); + font-size: 0.85rem; } -/* Instruction thumbnails */ +.badge-theme { + background: var(--secondary-gradient); + color: white; +} + +.badge-year { + background: var(--warning-gradient); + color: var(--gray-900); + box-shadow: var(--shadow-sm); +} + +.bg-warning { + background: var(--warning-gradient) !important; +} + +/* ===== List Groups ===== */ +.list-group-item { + border: none; + border-bottom: 1px solid var(--gray-200); + padding: 1rem 1.25rem; + transition: all var(--transition-fast); +} + +.list-group-item:hover { + background: var(--gray-50); + padding-left: 1.5rem; +} + +.list-group-item:last-child { + border-bottom: none; +} + +.list-group-flush .list-group-item:first-child { + border-top: none; +} + +.badge.rounded-pill { + padding: 0.5em 1em; + font-weight: 700; +} + +/* ===== Feature Cards (Home Page) ===== */ +.shadow-sm { + box-shadow: var(--shadow-md) !important; + border-radius: var(--radius-lg); + transition: all var(--transition-base); +} + +.shadow-sm:hover { + transform: translateY(-8px); + box-shadow: var(--shadow-xl) !important; +} + +.shadow-sm i.display-1 { + font-size: 4rem; + margin-bottom: 1rem; +} + +.shadow-sm h3 { + font-weight: 700; + color: var(--gray-800); +} + +/* ===== Instruction Thumbnails ===== */ .instruction-thumbnail { width: 150px; height: 150px; object-fit: cover; cursor: pointer; - transition: transform 0.2s; + border-radius: var(--radius-md); + transition: all var(--transition-base); + box-shadow: var(--shadow-sm); } .instruction-thumbnail:hover { - transform: scale(1.05); + transform: scale(1.1) rotate(2deg); + box-shadow: var(--shadow-lg); + z-index: 10; } -/* File upload area */ +/* ===== File Upload Area ===== */ .upload-area { - border: 2px dashed #dee2e6; - border-radius: 0.5rem; + border: 3px dashed var(--gray-300); + border-radius: var(--radius-lg); padding: 3rem; text-align: center; - transition: all 0.3s; + transition: all var(--transition-base); + background: white; } .upload-area:hover { border-color: var(--lego-red); - background-color: #f8f9fa; + background: linear-gradient(135deg, var(--gray-50) 0%, white 100%); + transform: scale(1.02); } .upload-area.dragover { border-color: var(--lego-red); - background-color: #fff3cd; + background: linear-gradient(135deg, #fff3cd 0%, white 100%); + box-shadow: var(--shadow-lg); + transform: scale(1.05); } -/* Badge styling */ -.badge-theme { - background-color: var(--lego-blue); +/* ===== Pagination ===== */ +.pagination { + gap: 0.5rem; } -.badge-year { - background-color: var(--lego-yellow); - color: #000; -} - -/* Stats cards */ -.stat-card { - border-left: 4px solid var(--lego-red); -} - -/* Search bar */ -.search-container { - max-width: 600px; - margin: 0 auto 2rem; -} - -/* Pagination */ .pagination .page-link { color: var(--lego-red); + border: 2px solid var(--gray-300); + border-radius: var(--radius-sm); + font-weight: 600; + transition: all var(--transition-fast); +} + +.pagination .page-link:hover { + background: var(--primary-gradient); + color: white; + border-color: var(--lego-red); + transform: translateY(-2px); } .pagination .page-item.active .page-link { - background-color: var(--lego-red); + background: var(--primary-gradient); border-color: var(--lego-red); + box-shadow: var(--shadow-md); } -/* Loading spinner */ +/* ===== Footer ===== */ +footer { + background: linear-gradient(135deg, var(--gray-800) 0%, var(--gray-900) 100%); + color: var(--gray-300); + padding: 2rem 0; + margin-top: auto; + border-top: 4px solid var(--lego-red); +} + +footer p { + margin: 0; + font-size: 0.9rem; +} + +footer .badge { + font-size: 0.8rem; + padding: 0.4em 0.8em; +} + +/* ===== Flash Messages ===== */ +.alert { + border: none; + border-radius: var(--radius-lg); + padding: 1rem 1.5rem; + box-shadow: var(--shadow-md); + border-left: 4px solid; + animation: slideIn 0.3s ease; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.alert-success { + background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); + border-left-color: #28a745; +} + +.alert-danger { + background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%); + border-left-color: #dc3545; +} + +.alert-warning { + background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); + border-left-color: var(--lego-yellow); +} + +.alert-info { + background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%); + border-left-color: #17a2b8; +} + +/* ===== Search Container ===== */ +.search-container { + max-width: 700px; + margin: 0 auto 2.5rem; +} + +.search-container .form-control { + border-radius: var(--radius-lg); + padding: 0.8rem 1.5rem; + border: 2px solid var(--gray-300); + transition: all var(--transition-fast); + font-size: 1rem; +} + +.search-container .form-control:focus { + border-color: var(--lego-red); + box-shadow: 0 0 0 0.2rem rgba(209, 16, 19, 0.15); +} + +/* ===== Loading Spinner ===== */ .spinner-wrapper { display: flex; justify-content: center; align-items: center; - min-height: 200px; + min-height: 300px; } -/* Responsive adjustments */ +.spinner-border { + width: 3rem; + height: 3rem; + border-width: 0.3rem; +} + +/* ===== Empty States ===== */ +.text-center.py-5 { + padding: 4rem 2rem !important; +} + +.text-center i.display-1 { + font-size: 5rem; + opacity: 0.3; + margin-bottom: 1rem; +} + +/* ===== MOC Badge ===== */ +.bg-warning.text-dark { + background: var(--warning-gradient) !important; + box-shadow: var(--shadow-sm); +} + +/* ===== Form Controls ===== */ +.form-control, +.form-select { + border-radius: var(--radius-md); + border: 2px solid var(--gray-300); + padding: 0.6rem 1rem; + transition: all var(--transition-fast); +} + +.form-control:focus, +.form-select:focus { + border-color: var(--lego-red); + box-shadow: 0 0 0 0.2rem rgba(209, 16, 19, 0.15); +} + +/* ===== Responsive Adjustments ===== */ @media (max-width: 768px) { .set-image { height: 150px; @@ -136,11 +591,82 @@ main { width: 100px; height: 100px; } -} - -/* Print styles for instructions */ -@media print { - .navbar, .btn, footer { - display: none; + + .stat-card h2 { + font-size: 2rem; + } + + .display-3 { + font-size: 2.5rem; + } + + .navbar-brand { + font-size: 1.25rem; } } + +@media (max-width: 576px) { + .btn-lg { + padding: 0.6rem 1.5rem; + font-size: 1rem; + } + + .card-body { + padding: 1rem; + } + + .stat-card h2 { + font-size: 1.75rem; + } +} + +/* ===== Print Styles ===== */ +@media print { + .navbar, .btn, footer, .alert { + display: none; + } + + .card { + box-shadow: none; + border: 1px solid var(--gray-300); + } +} + +/* ===== Accessibility ===== */ +.btn:focus, +.form-control:focus, +.form-select:focus { + outline: 3px solid var(--lego-yellow); + outline-offset: 2px; +} + +/* ===== LEGO Brick Pattern (Optional Background) ===== */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + radial-gradient(circle at 25% 25%, rgba(209, 16, 19, 0.03) 0%, transparent 50%), + radial-gradient(circle at 75% 75%, rgba(0, 85, 191, 0.03) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +/* ===== Smooth Scrolling ===== */ +html { + scroll-behavior: smooth; +} + +/* ===== Selection Color ===== */ +::selection { + background: var(--lego-red); + color: white; +} + +::-moz-selection { + background: var(--lego-red); + color: white; +} \ No newline at end of file