/** * Main stylesheet for QR Code Management System * static/css/style.css */ /* CSS Variables for consistent theming */ :root { /* Primary Colors */ --primary-color: #2563eb; --primary-hover: #1d4ed8; --primary-light: #dbeafe; /* Secondary Colors */ --secondary-color: #64748b; --secondary-hover: #475569; /* Status Colors */ --success-color: #059669; --success-light: #dcfce7; --warning-color: #d97706; --warning-light: #fef3c7; --danger-color: #dc2626; --danger-light: #fee2e2; --info-color: #0284c7; --info-light: #e0f2fe; /* Neutral Colors */ --white: #ffffff; --gray-50: #f9fafb; --gray-100: #f3f4f6; --gray-200: #e5e7eb; --gray-300: #d1d5db; --gray-400: #9ca3af; --gray-500: #6b7280; --gray-600: #4b5563; --gray-700: #374151; --gray-800: #1f2937; --gray-900: #111827; /* Spacing Scale */ --spacing-1: 0.25rem; --spacing-2: 0.5rem; --spacing-3: 0.75rem; --spacing-4: 1rem; --spacing-5: 1.25rem; --spacing-6: 1.5rem; --spacing-8: 2rem; --spacing-10: 2.5rem; --spacing-12: 3rem; --spacing-16: 4rem; --spacing-20: 5rem; /* Border Radius */ --radius: 0.375rem; --radius-md: 0.5rem; --radius-lg: 0.75rem; --radius-xl: 1rem; --radius-2xl: 1.5rem; --radius-full: 9999px; /* Shadows */ --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); /* Typography */ --font-size-xs: 0.75rem; --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; --font-size-2xl: 1.5rem; --font-size-3xl: 1.875rem; --font-size-4xl: 2.25rem; /* Transitions */ --transition: all 0.15s ease-in-out; --transition-slow: all 0.3s ease-in-out; /* Z-Index Scale */ --z-dropdown: 1000; --z-modal: 1050; --z-toast: 1100; } /* Dark theme variables */ [data-theme="dark"] { --white: #1f2937; --gray-50: #374151; --gray-100: #4b5563; --gray-200: #6b7280; --gray-800: #f9fafb; --gray-900: #ffffff; } /* Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } html { scroll-behavior: smooth; } body { font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; color: var(--gray-700); background-color: var(--gray-50); min-height: 100vh; display: flex; flex-direction: column; } /* Typography */ h1, h2, h3, h4, h5, h6 { color: var(--gray-900); font-weight: 600; line-height: 1.25; margin-bottom: var(--spacing-4); } h1 { font-size: var(--font-size-4xl); } h2 { font-size: var(--font-size-3xl); } h3 { font-size: var(--font-size-2xl); } h4 { font-size: var(--font-size-xl); } h5 { font-size: var(--font-size-lg); } h6 { font-size: var(--font-size-base); } p { margin-bottom: var(--spacing-4); } a { color: var(--primary-color); text-decoration: none; transition: var(--transition); } a:hover { color: var(--primary-hover); text-decoration: underline; } /* Layout */ .container { max-width: 1200px; margin: 0 auto; padding: 0 var(--spacing-4); } .main-content { flex: 1; padding: var(--spacing-8) 0; } /* Navigation */ .navbar { background: linear-gradient( 135deg, var(--primary-color), var(--primary-hover) ); color: var(--white); padding: var(--spacing-4) 0; box-shadow: var(--shadow-md); position: sticky; top: 0; z-index: var(--z-dropdown); } .nav-container { max-width: 1200px; margin: 0 auto; padding: 0 var(--spacing-4); display: flex; justify-content: space-between; align-items: center; } .nav-brand { display: flex; align-items: center; gap: var(--spacing-3); font-size: var(--font-size-xl); font-weight: 700; color: var(--white); } .nav-menu { display: flex; gap: var(--spacing-6); align-items: center; } .nav-link { color: var(--white); padding: var(--spacing-2) var(--spacing-4); border-radius: var(--radius); transition: var(--transition); display: flex; align-items: center; gap: var(--spacing-2); } .nav-link:hover { background-color: rgba(255, 255, 255, 0.1); text-decoration: none; } .nav-link.logout:hover { background-color: var(--danger-color); } .nav-toggle { display: none; flex-direction: column; cursor: pointer; padding: var(--spacing-2); } .nav-toggle .bar { width: 24px; height: 3px; background-color: var(--white); margin: 3px 0; transition: var(--transition); border-radius: var(--radius-full); } /* Buttons */ .btn { display: inline-flex; align-items: center; gap: var(--spacing-2); padding: var(--spacing-3) var(--spacing-6); font-size: var(--font-size-sm); font-weight: 500; text-align: center; text-decoration: none; border: 1px solid transparent; border-radius: var(--radius-lg); cursor: pointer; transition: var(--transition); white-space: nowrap; } .btn:focus { outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .btn:disabled { opacity: 0.6; cursor: not-allowed; } /* Button Variants */ .btn-primary { background-color: var(--primary-color); color: var(--white); border-color: var(--primary-color); } .btn-primary:hover:not(:disabled) { background-color: var(--primary-hover); border-color: var(--primary-hover); color: var(--white); text-decoration: none; } .btn-secondary { background-color: var(--gray-100); color: var(--gray-700); border-color: var(--gray-200); } .btn-secondary:hover:not(:disabled) { background-color: var(--gray-200); color: var(--gray-800); text-decoration: none; } .btn-success { background-color: var(--success-color); color: var(--white); border-color: var(--success-color); } .btn-success:hover:not(:disabled) { background-color: #047857; color: var(--white); text-decoration: none; } .btn-warning { background-color: var(--warning-color); color: var(--white); border-color: var(--warning-color); } .btn-warning:hover:not(:disabled) { background-color: #b45309; color: var(--white); text-decoration: none; } .btn-danger { background-color: var(--danger-color); color: var(--white); border-color: var(--danger-color); } .btn-danger:hover:not(:disabled) { background-color: #b91c1c; color: var(--white); text-decoration: none; } .btn-outline { background-color: transparent; color: var(--primary-color); border-color: var(--primary-color); } .btn-outline:hover:not(:disabled) { background-color: var(--primary-color); color: var(--white); text-decoration: none; } /* Button Sizes */ .btn-sm { padding: var(--spacing-2) var(--spacing-4); font-size: var(--font-size-xs); } .btn-lg { padding: var(--spacing-4) var(--spacing-8); font-size: var(--font-size-lg); } /* Forms */ .form-group { margin-bottom: var(--spacing-6); } .form-label { display: block; font-size: var(--font-size-sm); font-weight: 500; color: var(--gray-700); margin-bottom: var(--spacing-2); } .form-label.required::after { content: " *"; color: var(--danger-color); } .form-input, .form-select, .form-textarea { width: 100%; padding: var(--spacing-3); font-size: var(--font-size-sm); border: 2px solid var(--gray-200); border-radius: var(--radius-lg); transition: var(--transition); background-color: var(--white); } .form-input:focus, .form-select:focus, .form-textarea:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .form-input.error, .form-select.error, .form-textarea.error { border-color: var(--danger-color); box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1); } .form-textarea { resize: vertical; min-height: 100px; } .field-error { color: var(--danger-color); font-size: var(--font-size-xs); margin-top: var(--spacing-1); } /* Cards */ .card { background: var(--white); border-radius: var(--radius-xl); box-shadow: var(--shadow); overflow: hidden; transition: var(--transition); } .card:hover { box-shadow: var(--shadow-lg); } .card-header { padding: var(--spacing-6); border-bottom: 1px solid var(--gray-200); background-color: var(--gray-50); } .card-body { padding: var(--spacing-6); } .card-footer { padding: var(--spacing-6); border-top: 1px solid var(--gray-200); background-color: var(--gray-50); } /* Tables */ .table-container { overflow-x: auto; border-radius: var(--radius-xl); box-shadow: var(--shadow); } .table { width: 100%; border-collapse: collapse; background: var(--white); } .table th, .table td { padding: var(--spacing-4); text-align: left; border-bottom: 1px solid var(--gray-200); } .table th { background-color: var(--gray-50); font-weight: 600; color: var(--gray-700); font-size: var(--font-size-sm); } .table tbody tr:hover { background-color: var(--gray-50); } .table tbody tr:last-child td { border-bottom: none; } /* Modals */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: none; justify-content: center; align-items: center; z-index: var(--z-modal); opacity: 0; transition: opacity 0.3s ease-in-out; } .modal.show { opacity: 1; } .modal-content { background: var(--white); border-radius: var(--radius-xl); box-shadow: var(--shadow-xl); max-width: 500px; width: 90%; max-height: 90vh; overflow-y: auto; transform: scale(0.95); transition: transform 0.3s ease-in-out; } .modal.show .modal-content { transform: scale(1); } .modal-header { padding: var(--spacing-6); border-bottom: 1px solid var(--gray-200); display: flex; justify-content: space-between; align-items: center; } .modal-header h3 { margin: 0; display: flex; align-items: center; gap: var(--spacing-3); } .modal-close { background: none; border: none; color: var(--gray-400); cursor: pointer; padding: var(--spacing-2); border-radius: var(--radius); transition: var(--transition); } .modal-close:hover { color: var(--gray-600); background-color: var(--gray-100); } .modal-body { padding: var(--spacing-6); } .modal-footer { padding: var(--spacing-6); border-top: 1px solid var(--gray-200); display: flex; gap: var(--spacing-3); justify-content: flex-end; } /* Alerts */ .flash-messages { position: fixed; top: var(--spacing-4); right: var(--spacing-4); z-index: var(--z-toast); max-width: 400px; width: 100%; } .alert { display: flex; align-items: center; gap: var(--spacing-3); padding: var(--spacing-4); margin-bottom: var(--spacing-3); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); animation: slideInRight 0.3s ease-out; } .alert-success { background-color: var(--success-light); color: var(--success-color); border-left: 4px solid var(--success-color); } .alert-error { background-color: var(--danger-light); color: var(--danger-color); border-left: 4px solid var(--danger-color); } .alert-warning { background-color: var(--warning-light); color: var(--warning-color); border-left: 4px solid var(--warning-color); } .alert-info { background-color: var(--info-light); color: var(--info-color); border-left: 4px solid var(--info-color); } .alert-close { background: none; border: none; color: currentColor; cursor: pointer; margin-left: auto; padding: var(--spacing-1); border-radius: var(--radius); transition: var(--transition); opacity: 0.7; } .alert-close:hover { opacity: 1; background-color: rgba(0, 0, 0, 0.1); } /* Toasts */ .toast { position: fixed; top: var(--spacing-4); right: var(--spacing-4); z-index: var(--z-toast); max-width: 400px; width: auto; background: var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); animation: slideInRight 0.3s ease-out; } .toast-content { display: flex; align-items: center; gap: var(--spacing-3); padding: var(--spacing-4); } .toast-success { border-left: 4px solid var(--success-color); } .toast-error { border-left: 4px solid var(--danger-color); } .toast-warning { border-left: 4px solid var(--warning-color); } .toast-info { border-left: 4px solid var(--info-color); } .toast-close { background: none; border: none; color: var(--gray-400); cursor: pointer; margin-left: auto; padding: var(--spacing-1); border-radius: var(--radius); transition: var(--transition); } .toast-close:hover { color: var(--gray-600); background-color: var(--gray-100); } /* Dropdowns */ .dropdown { position: relative; display: inline-block; } .dropdown-trigger { background: none; border: none; cursor: pointer; padding: var(--spacing-2); border-radius: var(--radius); transition: var(--transition); } .dropdown-trigger:hover { background-color: var(--gray-100); } .dropdown-menu { position: absolute; top: 100%; right: 0; min-width: 200px; background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); z-index: var(--z-dropdown); opacity: 0; visibility: hidden; transform: translateY(-10px); transition: all 0.2s ease-in-out; } .dropdown-menu.show { opacity: 1; visibility: visible; transform: translateY(0); } .dropdown-item { display: block; width: 100%; padding: var(--spacing-3) var(--spacing-4); color: var(--gray-700); text-decoration: none; border: none; background: none; text-align: left; cursor: pointer; transition: var(--transition); } .dropdown-item:hover { background-color: var(--gray-50); color: var(--gray-900); text-decoration: none; } .dropdown-item:first-child { border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg); } .dropdown-item:last-child { border-bottom-left-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg); } .dropdown-divider { height: 1px; background-color: var(--gray-200); margin: var(--spacing-2) 0; } /* Utilities */ .text-left { text-align: left; } .text-center { text-align: center; } .text-right { text-align: right; } .text-primary { color: var(--primary-color); } .text-secondary { color: var(--secondary-color); } .text-success { color: var(--success-color); } .text-warning { color: var(--warning-color); } .text-danger { color: var(--danger-color); } .text-info { color: var(--info-color); } .text-muted { color: var(--gray-500); } .bg-primary { background-color: var(--primary-color); } .bg-secondary { background-color: var(--secondary-color); } .bg-success { background-color: var(--success-color); } .bg-warning { background-color: var(--warning-color); } .bg-danger { background-color: var(--danger-color); } .bg-info { background-color: var(--info-color); } .d-none { display: none; } .d-block { display: block; } .d-flex { display: flex; } .d-grid { display: grid; } .flex-column { flex-direction: column; } .flex-wrap { flex-wrap: wrap; } .justify-content-center { justify-content: center; } .justify-content-between { justify-content: space-between; } .align-items-center { align-items: center; } .mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: var(--spacing-1); } .mb-2 { margin-bottom: var(--spacing-2); } .mb-3 { margin-bottom: var(--spacing-3); } .mb-4 { margin-bottom: var(--spacing-4); } .mb-5 { margin-bottom: var(--spacing-5); } .mb-6 { margin-bottom: var(--spacing-6); } .mt-0 { margin-top: 0; } .mt-1 { margin-top: var(--spacing-1); } .mt-2 { margin-top: var(--spacing-2); } .mt-3 { margin-top: var(--spacing-3); } .mt-4 { margin-top: var(--spacing-4); } .mt-5 { margin-top: var(--spacing-5); } .mt-6 { margin-top: var(--spacing-6); } /* Animations */ @keyframes slideInRight { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fadeIn 0.3s ease-out; } .fade-out { animation: fadeOut 0.3s ease-out; } .slide-up { animation: slideUp 0.3s ease-out; } /* Footer */ .footer { background-color: var(--gray-800); color: var(--gray-300); text-align: center; padding: var(--spacing-6) 0; margin-top: auto; } /* Responsive Design */ @media (max-width: 768px) { .container { padding: 0 var(--spacing-3); } .nav-menu { position: fixed; top: 0; right: -100%; width: 300px; height: 100vh; background: linear-gradient( 135deg, var(--primary-color), var(--primary-hover) ); flex-direction: column; padding: var(--spacing-8) var(--spacing-4); transition: var(--transition-slow); z-index: 1001; } .nav-menu.active { right: 0; } .nav-toggle { display: flex; z-index: 1002; } .nav-toggle.active .bar:nth-child(1) { transform: rotate(-45deg) translate(-5px, 6px); } .nav-toggle.active .bar:nth-child(2) { opacity: 0; } .nav-toggle.active .bar:nth-child(3) { transform: rotate(45deg) translate(-5px, -6px); } .modal-content { width: 95%; margin: var(--spacing-4); } .btn { width: 100%; justify-content: center; } .flash-messages, .toast { left: var(--spacing-3); right: var(--spacing-3); max-width: none; } h1 { font-size: var(--font-size-3xl); } h2 { font-size: var(--font-size-2xl); } h3 { font-size: var(--font-size-xl); } } @media (max-width: 480px) { .container { padding: 0 var(--spacing-2); } .main-content { padding: var(--spacing-4) 0; } .card-body, .card-header, .card-footer { padding: var(--spacing-4); } .modal-body, .modal-header, .modal-footer { padding: var(--spacing-4); } } /* Print Styles */ @media print { .navbar, .footer, .btn, .dropdown, .flash-messages, .toast { display: none !important; } .main-content { padding: 0; } .card { box-shadow: none; border: 1px solid var(--gray-300); } }