diff --git a/static/style.css b/static/style.css index 5362b04..1844ff5 100644 --- a/static/style.css +++ b/static/style.css @@ -1,19 +1,30 @@ :root { - --primary-color: #f3ae3e; - --secondary-color: #f3ae3e; - --accent-color: #f3ae3e; - --text-dark: #2d3748; - --text-light: #718096; - --bg-light: #f7fafc; - --bg-white: #ffffff; - --border-color: #e2e8f0; - --shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); - --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); - - /* Microsoft Brand Colors */ - --ms-blue: #f3ae3e; - --ms-blue-dark: #f3ae3e; - --ms-gray: #5e5e5e; + /* OLIVER brand palette (from Master PPT Template) */ + --brand-yellow: #FFCB05; + --brand-yellow-soft: #FFF5C4; + --brand-orange: #FF5C00; + --brand-dark: #1A1A1A; + --brand-grey: #626262; + --brand-grey-light: #DEE2E5; + --brand-off-white: #F6F7F7; + + /* Semantic aliases (kept so legacy var refs still resolve) */ + --primary-color: var(--brand-yellow); + --secondary-color: var(--brand-yellow); + --accent-color: var(--brand-orange); + --text-dark: var(--brand-dark); + --text-light: var(--brand-grey); + --bg-light: var(--brand-off-white); + --bg-white: #FFFFFF; + --border-color: var(--brand-grey-light); + + --shadow: 0 4px 12px rgba(26, 26, 26, 0.06); + --shadow-lg: 0 12px 32px rgba(26, 26, 26, 0.08); + + /* Legacy compat — Microsoft button now uses brand orange */ + --ms-blue: var(--brand-orange); + --ms-blue-dark: #D94E00; + --ms-gray: var(--brand-grey); } * { @@ -25,323 +36,450 @@ body { margin: 0; padding: 0; - /* Reserve space for the fixed navbar below so page content isn't hidden under it. */ + /* Reserve space below the fixed navbar. */ padding-top: 64px; color: var(--text-dark); - font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - line-height: 1.6; + font-family: 'Montserrat', 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif; + font-weight: 400; + line-height: 1.55; min-height: 100vh; - background: transparent !important; -} - -/* Orange brand backdrop. Painted on a fixed pseudo-element behind everything so - no child element (e.g. .container's white bg) can cover it. Always visible - around the centred white card regardless of viewport size or scroll. */ -body::before { - content: ""; - position: fixed; - inset: 0; - z-index: -1; - background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%); + background-color: var(--brand-off-white); } .container { max-width: 1200px; - /* Always leave at least ~1rem of body gradient visible on each side, so the - orange frame doesn't disappear when the viewport is narrower than 1200px. */ width: calc(100% - 2rem); margin: 2rem auto; padding: 2rem; background-color: var(--bg-white); - border-radius: 20px; - box-shadow: var(--shadow-lg); - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 16px; + box-shadow: var(--shadow); + border: 1px solid var(--border-color); } +/* ------------------------- Navbar ------------------------- */ .navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 1100; - background: rgba(255, 255, 255, 0.95) !important; - backdrop-filter: blur(10px); + background: #FFFFFF !important; border-bottom: 1px solid var(--border-color); - box-shadow: var(--shadow); + box-shadow: 0 1px 0 rgba(26, 26, 26, 0.04); + min-height: 64px; } .navbar-brand { - font-weight: 700; - font-size: 1.5rem; - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + font-family: 'Montserrat', sans-serif; + font-weight: 800; + font-size: 1.25rem; + letter-spacing: 0.02em; + color: var(--brand-dark) !important; + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.25rem 0; +} + +.navbar-brand .brand-mark { + display: inline-block; + width: 14px; + height: 14px; + background: var(--brand-yellow); + margin-right: 0.25rem; } .nav-link { + font-family: 'Montserrat', sans-serif; font-weight: 500; - transition: all 0.3s ease; - border-radius: 8px; + font-size: 0.9rem; + color: var(--brand-dark) !important; + transition: color 0.15s ease, border-color 0.15s ease; + border-radius: 0; margin: 0 4px; - padding: 8px 16px !important; + padding: 8px 12px !important; + border-bottom: 2px solid transparent; } .nav-link:hover { - background-color: var(--bg-light); - transform: translateY(-1px); + color: var(--brand-dark) !important; + border-bottom-color: var(--brand-yellow); + background-color: transparent; } .nav-link.active { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - color: white !important; + background: transparent !important; + color: var(--brand-dark) !important; + border-bottom: 2px solid var(--brand-yellow); } +/* ------------------------- Headings & page title ------------------------- */ +h1, h2, h3, h4, h5, h6 { + font-family: 'Montserrat', sans-serif; + color: var(--brand-dark); + font-weight: 700; + margin-bottom: 1rem; + letter-spacing: -0.005em; +} + +h1 { font-size: 2.5rem; font-weight: 800; } +h2 { font-size: 2rem; font-weight: 800; } +h3 { font-size: 1.5rem; } +h4 { font-size: 1.25rem; } + +/* Yellow-highlight page title — signature OLIVER template motif. */ +.page-title { + display: inline-block; + position: relative; + font-family: 'Montserrat', sans-serif; + font-weight: 800; + font-size: 2rem; + line-height: 1.15; + color: var(--brand-dark); + padding: 0.15rem 0.6rem; + background: linear-gradient( + to top, + var(--brand-yellow) 0, + var(--brand-yellow) 70%, + transparent 70%, + transparent 100% + ); + margin-bottom: 0.5rem; +} + +.page-subtitle { + color: var(--brand-grey); + font-size: 0.95rem; + margin-top: 0.25rem; + margin-bottom: 0; +} + +/* ------------------------- Tables ------------------------- */ .table { border-radius: 12px; overflow: hidden; box-shadow: var(--shadow); border: none; - margin-top: 2rem; + margin-top: 1.5rem; + background: #FFFFFF; } .table thead th { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - color: white; + background: var(--brand-dark); + color: #FFFFFF; + font-family: 'Montserrat', sans-serif; font-weight: 600; border: none; - padding: 1rem; - font-size: 0.9rem; + padding: 1rem 1.25rem; + font-size: 0.75rem; text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 0.08em; } .table tbody tr { - transition: all 0.3s ease; + transition: background-color 0.15s ease; border: none; } .table tbody tr:hover { - background-color: var(--bg-light); - transform: scale(1.01); + background-color: var(--brand-off-white); } .table tbody td { - padding: 1rem; + padding: 1.1rem 1.25rem; border-color: var(--border-color); vertical-align: middle; + font-size: 0.92rem; } +/* ------------------------- Buttons ------------------------- */ .btn { - border-radius: 8px; - font-weight: 500; - padding: 8px 20px; - transition: all 0.3s ease; - border: none; - text-transform: uppercase; + font-family: 'Montserrat', sans-serif; + border-radius: 6px; + font-weight: 600; + padding: 8px 18px; + transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease; + border: 1px solid transparent; + text-transform: none; font-size: 0.85rem; - letter-spacing: 0.5px; + letter-spacing: 0.01em; } .btn-primary { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - border: none; + background: var(--brand-yellow); + color: var(--brand-dark); + border-color: var(--brand-yellow); } .btn-primary:hover { - transform: translateY(-2px); - box-shadow: var(--shadow); + background: #F2BE00; + border-color: #F2BE00; + color: var(--brand-dark); + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 203, 5, 0.35); +} + +.btn-primary:focus, +.btn-primary:active { + background: #F2BE00 !important; + border-color: #F2BE00 !important; + color: var(--brand-dark) !important; + box-shadow: 0 0 0 3px rgba(255, 203, 5, 0.25) !important; +} + +.btn-outline-primary { + background: transparent; + color: var(--brand-dark); + border: 1px solid var(--brand-dark); +} + +.btn-outline-primary:hover { + background: var(--brand-yellow); + color: var(--brand-dark); + border-color: var(--brand-yellow); } .btn-warning { - background: linear-gradient(135deg, #ffecd2, #fcb69f); - border: none; - color: var(--text-dark); + background: var(--brand-yellow); + border-color: var(--brand-yellow); + color: var(--brand-dark); } .btn-warning:hover { - transform: translateY(-2px); + background: #F2BE00; + border-color: #F2BE00; + color: var(--brand-dark); + transform: translateY(-1px); box-shadow: var(--shadow); - color: var(--text-dark); } .btn-danger { - background: linear-gradient(135deg, #ff9a9e, #fecfef); - border: none; - color: var(--text-dark); + background: var(--brand-orange); + border-color: var(--brand-orange); + color: #FFFFFF; } .btn-danger:hover { - transform: translateY(-2px); - box-shadow: var(--shadow); - color: var(--text-dark); + background: #D94E00; + border-color: #D94E00; + color: #FFFFFF; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 92, 0, 0.3); +} + +.btn-outline-danger { + background: transparent; + color: var(--brand-orange); + border: 1px solid var(--brand-orange); +} + +.btn-outline-danger:hover { + background: var(--brand-orange); + color: #FFFFFF; + border-color: var(--brand-orange); +} + +.btn-success { + background: #1F9D55; + border-color: #1F9D55; + color: #FFFFFF; +} + +.btn-success:hover { + background: #198044; + border-color: #198044; + color: #FFFFFF; + transform: translateY(-1px); } .btn-sm { padding: 6px 12px; + font-size: 0.78rem; margin: 0 2px; } -.form-control { - border-radius: 8px; - border: 2px solid var(--border-color); - padding: 12px; - transition: all 0.3s ease; - font-size: 1rem; +/* ------------------------- Forms ------------------------- */ +.form-control, +.form-select { + font-family: 'Montserrat', sans-serif; + border-radius: 6px; + border: 1px solid var(--border-color); + padding: 10px 12px; + transition: border-color 0.15s ease, box-shadow 0.15s ease; + font-size: 0.95rem; + color: var(--brand-dark); + background-color: #FFFFFF; } -.form-control:focus { - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(243, 174, 62, 0.1); +.form-control:focus, +.form-select:focus { + border-color: var(--brand-dark); + box-shadow: 0 0 0 3px rgba(255, 203, 5, 0.25); + outline: none; } .form-label { + font-family: 'Montserrat', sans-serif; font-weight: 600; - color: var(--text-dark); - margin-bottom: 8px; -} - -h1, h2, h3, h4, h5, h6 { - color: var(--text-dark); - font-weight: 700; - margin-bottom: 1rem; -} - -h2 { - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - -webkit-background-clip: text; - -webkit-text-fill-color: white; - background-clip: text; - font-size: 2.5rem; - text-align: center; - margin-bottom: 2rem; -} - -.alert { - border-radius: 12px; - border: none; - padding: 1rem; - margin-bottom: 1.5rem; + font-size: 0.85rem; + color: var(--brand-dark); + margin-bottom: 0.4rem; + letter-spacing: 0.01em; } +/* ------------------------- Cards ------------------------- */ .card { - border-radius: 16px; - border: none; + border-radius: 12px; + border: 1px solid var(--border-color); box-shadow: var(--shadow); - transition: all 0.3s ease; + transition: transform 0.15s ease, box-shadow 0.15s ease; + background: #FFFFFF; } .card:hover { - transform: translateY(-4px); + transform: translateY(-2px); box-shadow: var(--shadow-lg); } -.badge { - border-radius: 20px; - padding: 6px 12px; - font-weight: 500; - font-size: 0.75rem; +/* Yellow leading icon on card section titles (h5 / h6 inside .card-header). + Excludes modal headers (which are black with white text) and admin tabs. */ +.card-header:not(.card-header-tabs):not(.modal-header) h5 > i.fas:first-child, +.card-header:not(.card-header-tabs):not(.modal-header) h6 > i.fas:first-child, +.card-header h5 > i.fas:first-child, +.card-header h6 > i.fas:first-child { + color: var(--brand-yellow); + filter: drop-shadow(0 1px 0 rgba(26, 26, 26, 0.06)); } -.text-muted { - color: var(--text-light) !important; +/* Modal headers keep white icons (dark background). */ +.modal-header h5 > i.fas:first-child, +.modal-header h6 > i.fas:first-child { + color: #FFFFFF; + filter: none; } -@media (max-width: 768px) { - .container { - margin: 1rem; - padding: 1rem; - border-radius: 16px; - } - - h2 { - font-size: 2rem; - } - - .table-responsive { - border-radius: 12px; - } +/* Short yellow accent line under card section titles — + tiny rhythm element pulled from the template's "01" chapter marker. */ +.card-header h5, +.card-header h6 { + position: relative; + padding-bottom: 0.45rem; } -/* Microsoft Authentication Branding */ -.btn-microsoft { - background-color: var(--ms-blue); - border-color: var(--ms-blue); - color: white; - font-weight: 500; - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - transition: all 0.3s ease; +.card-header h5::after, +.card-header h6::after { + content: ""; + position: absolute; + left: 0; + bottom: 0; + width: 28px; + height: 3px; + background: var(--brand-yellow); + border-radius: 2px; +} + +/* The accent line doesn't belong on modal headers, the tab-bar header, + or any header that is itself a tab-strip. */ +.modal-header h5::after, +.modal-header h6::after, +.card-header.bg-white > .nav-tabs ~ h6::after, +.card-header h5.modal-title::after, +.card-header h6.modal-title::after { + display: none; +} + +/* ------------------------- Stat tile (template-inspired) ------------------------- + White card with a thick yellow strip on the left, big near-black number, + uppercase mid-grey label. Replaces the old orange gradient stat-card. */ +.stat-tile { + position: relative; + background: #FFFFFF; + border-radius: 10px; + padding: 1.1rem 1.1rem 1.1rem 1.6rem; + border: 1px solid var(--border-color); + box-shadow: var(--shadow); display: flex; align-items: center; - justify-content: center; + gap: 0.85rem; + min-height: 96px; + overflow: hidden; } -.btn-microsoft:hover { - background-color: var(--ms-blue-dark); - border-color: var(--ms-blue-dark); - color: white; - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(243, 174, 62, 0.3); -} - -.btn-microsoft:focus { - background-color: var(--ms-blue-dark); - border-color: var(--ms-blue-dark); - color: white; - box-shadow: 0 0 0 3px rgba(243, 174, 62, 0.2); -} - -.btn-microsoft:active { - background-color: var(--ms-blue-dark); - border-color: var(--ms-blue-dark); - color: white; - transform: translateY(0); -} - -/* Microsoft Login Divider */ -.auth-divider { - position: relative; - text-align: center; - margin: 1.5rem 0; -} - -.auth-divider::before { - content: ''; +.stat-tile::before { + content: ""; position: absolute; - top: 50%; + top: 0; left: 0; - right: 0; - height: 1px; - background-color: var(--border-color); + bottom: 0; + width: 8px; + background: var(--brand-yellow); } -.auth-divider-text { - background-color: white; - padding: 0 1rem; - color: var(--text-light); - font-size: 0.9rem; - position: relative; - z-index: 1; +.stat-tile .stat-tile-icon { + font-size: 1.6rem; + color: var(--brand-yellow); + flex-shrink: 0; + filter: drop-shadow(0 1px 0 rgba(26, 26, 26, 0.06)); } -/* Admin/Local Auth Section Styling */ -.local-auth-section { - border-top: 1px solid var(--border-color); - padding-top: 1.5rem; - margin-top: 1.5rem; +.stat-tile .stat-tile-value { + font-family: 'Montserrat', sans-serif; + font-size: 1.6rem; + font-weight: 800; + color: var(--brand-dark); + line-height: 1.1; + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.local-auth-section .form-label { - color: var(--ms-gray); +.stat-tile .stat-tile-label { + font-family: 'Montserrat', sans-serif; + font-size: 0.7rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--brand-grey); + margin: 0; + line-height: 1.2; } -.local-auth-section .btn-primary { - background: linear-gradient(135deg, var(--ms-gray), #4a4a4a); - border-color: var(--ms-gray); +/* ------------------------- Badges ------------------------- */ +.badge { + font-family: 'Montserrat', sans-serif; + border-radius: 4px; + padding: 5px 10px; + font-weight: 600; + font-size: 0.7rem; + letter-spacing: 0.04em; + text-transform: uppercase; } -/* Modal Centering and Positioning Fixes */ +.bg-warning { background-color: var(--brand-yellow) !important; color: var(--brand-dark) !important; } +.bg-primary { background-color: var(--brand-dark) !important; color: #FFFFFF !important; } +.bg-danger { background-color: var(--brand-orange) !important; color: #FFFFFF !important; } + +.text-muted { + color: var(--brand-grey) !important; +} + +/* ------------------------- Alerts ------------------------- */ +.alert { + border-radius: 8px; + border: 1px solid var(--border-color); + padding: 0.9rem 1rem; + margin-bottom: 1.25rem; + font-size: 0.92rem; +} + +.alert-danger { background: #FEEFE5; border-color: #FFCAA8; color: #8A2E00; } +.alert-success { background: #E8F5EE; border-color: #B7DDC5; color: #155724; } +.alert-warning { background: var(--brand-yellow-soft); border-color: var(--brand-yellow); color: var(--brand-dark); } +.alert-info { background: #EEF6FB; border-color: #C9E1ED; color: #0C4A6E; } + +/* ------------------------- Modals ------------------------- */ .modal { padding: 0 !important; } @@ -361,28 +499,30 @@ h2 { } .modal-content { - border-radius: 16px; - border: none; + border-radius: 12px; + border: 1px solid var(--border-color); box-shadow: var(--shadow-lg); width: 100%; position: relative; } .modal-header { - border-radius: 16px 16px 0 0; - background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); - color: white; + border-radius: 12px 12px 0 0; + background: var(--brand-dark); + color: #FFFFFF; border-bottom: none; - padding: 1.25rem 1.5rem; + padding: 1.1rem 1.5rem; } .modal-title { - font-weight: 600; - font-size: 1.25rem; + font-family: 'Montserrat', sans-serif; + font-weight: 700; + font-size: 1.1rem; + color: #FFFFFF; } .modal-header .btn-close { - filter: invert(1); + filter: invert(1) grayscale(100%) brightness(200%); opacity: 0.8; } @@ -398,52 +538,133 @@ h2 { .modal-footer { border-top: 1px solid var(--border-color); - border-radius: 0 0 16px 16px; + border-radius: 0 0 12px 12px; padding: 1rem 1.5rem; } -/* Ensure modals are centered on smaller screens */ @media (max-width: 768px) { .modal-dialog { margin: 1rem; max-width: calc(100% - 2rem); min-height: calc(100vh - 2rem); } - + .modal-body { max-height: 60vh; padding: 1rem; } + + .container { + margin: 1rem auto; + padding: 1rem; + border-radius: 12px; + } + + .page-title { font-size: 1.5rem; } + + .table-responsive { border-radius: 12px; } } -/* Ensure modal backdrop doesn't interfere */ .modal-backdrop { - background-color: rgba(0, 0, 0, 0.6); + background-color: rgba(26, 26, 26, 0.5); } -/* Fix page title readability */ -.container h2 { - -webkit-text-fill-color: var(--text-dark); - color: var(--text-dark); +/* ------------------------- Microsoft / SSO button ------------------------- */ +.btn-microsoft { + background-color: var(--brand-orange); + border-color: var(--brand-orange); + color: #FFFFFF; + font-family: 'Montserrat', sans-serif; + font-weight: 600; + transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease; + display: flex; + align-items: center; + justify-content: center; } -/* Star rating styles */ +.btn-microsoft:hover { + background-color: var(--ms-blue-dark); + border-color: var(--ms-blue-dark); + color: #FFFFFF; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 92, 0, 0.3); +} + +.btn-microsoft:focus, +.btn-microsoft:active { + background-color: var(--ms-blue-dark) !important; + border-color: var(--ms-blue-dark) !important; + color: #FFFFFF !important; + box-shadow: 0 0 0 3px rgba(255, 92, 0, 0.25) !important; + transform: translateY(0); +} + +/* Auth-page divider ("or") */ +.auth-divider { + position: relative; + text-align: center; + margin: 1.5rem 0; +} + +.auth-divider::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background-color: var(--border-color); +} + +.auth-divider-text { + background-color: #FFFFFF; + padding: 0 1rem; + color: var(--brand-grey); + font-size: 0.85rem; + position: relative; + z-index: 1; +} + +.local-auth-section { + border-top: 1px solid var(--border-color); + padding-top: 1.5rem; + margin-top: 1.5rem; +} + +.local-auth-section .form-label { + color: var(--brand-grey); +} + +.local-auth-section .btn-primary { + background: var(--brand-dark); + border-color: var(--brand-dark); + color: #FFFFFF; +} + +.local-auth-section .btn-primary:hover { + background: #000000; + border-color: #000000; + color: #FFFFFF; +} + +/* ------------------------- Star rating ------------------------- */ .star-interactive, .star-clickable { cursor: pointer; font-size: 1.3rem; - transition: color 0.2s, transform 0.2s; - color: #dee2e6; + transition: color 0.15s, transform 0.15s; + color: var(--border-color); } .star-interactive:hover, .star-clickable:hover { - transform: scale(1.2); + transform: scale(1.15); } .star-rating-edit { padding: 8px 0; } -/* Discipline badge */ +/* Discipline badge — kept distinct */ .bg-purple { background-color: #6f42c1 !important; -} \ No newline at end of file + color: #FFFFFF !important; +} diff --git a/templates/admin/dashboard.html b/templates/admin/dashboard.html index 2346208..1b29b4f 100644 --- a/templates/admin/dashboard.html +++ b/templates/admin/dashboard.html @@ -9,8 +9,8 @@
Manage users and AI agents across the system
+Manage users and AI agents across the system