Five defects, four of them mine from 0.11.0, found by using the feature. THE SERIOUS ONE: ShopFloorMap never checked a marker's level. It skipped null coordinates and drew everything else on whatever blueprint was displayed, so level 1 markers appeared on level 2 - the exact failure ADR-017 exists to prevent, in the one component that draws the map. The build gate did not catch it because that rule checks files EMITTING mapx, not the component consuming it. Markers are now filtered to the drawn level, and a position with no level is omitted rather than approximated. The map page had no way to choose a level at all. It read currentlevelid only to title the PDF, so a second floor was unreachable from the viewer that most people use. Adds a level selector (hidden when a site has one level), passes it to the map, and switches the drawing, the bounds, the coordinate space and the markers together - swapping the image without the bounds would place every marker against the wrong scale. Searching the map now follows results across levels: a search whose matches are all on another floor showed an empty map while the filter counted them. Floor map settings had NO height input - only width - so a level's native size could not be set even while empty, which is the one time it is editable. Both fields are there now, and size is editable on a level that has markers, because refusing it blocked the case the feature was built for: a new blueprint of new dimensions on a floor already full of markers. It confirms first and points at landmark recalibration. Search results differed between the sidebar box and the results-page box: - 14 of 16 searchers truncated with .limit() and no ORDER BY, so the database could return a DIFFERENT subset of matching rows for the same query. Every searcher now ends in a total order (display key plus primary key). - Searching a term already in the URL was a duplicate navigation the router aborts, so the route watcher never fired and the button did nothing. The sidebar never hit this, because it always navigates from another page - which is why the two boxes appeared to disagree. Also removes a scrollbar from both map pages. They subtracted 2rem and 40px from 100vh for the page chrome, which is really 90px of padding on .main-content, so each overflowed by the difference. The padding is now a CSS variable both the layout and the pages read. Measured in the browser before and after: 1058 vs a 1000px viewport, now 1000.
1766 lines
34 KiB
CSS
1766 lines
34 KiB
CSS
/* Reset and base styles */
|
|
/* Inter is bundled locally via @fontsource-variable/inter (imported in main.js) */
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* GE Aerospace Color Palette */
|
|
:root {
|
|
/* Brand Colors */
|
|
--ge-atmosphere-blue: #00003d;
|
|
--ge-sky-blue: #4181ff;
|
|
--ge-avionics-green: #0ad64f;
|
|
--ge-tungsten: #eaeaea;
|
|
|
|
/* Light Mode (default) */
|
|
--primary: #4181ff;
|
|
--primary-dark: #2d6ce0;
|
|
--secondary: #6c757d;
|
|
--success: #0ad64f;
|
|
--warning: #ff9500;
|
|
--danger: #dc3545;
|
|
--info: #4181ff;
|
|
--bg: #f5f5f5;
|
|
--bg-card: #ffffff;
|
|
--bg-card-solid: #ffffff;
|
|
--text: #1a1a2e;
|
|
--text-light: #6c757d;
|
|
--border: #dee2e6;
|
|
--link: #4181ff;
|
|
--sidebar-bg: #00003d;
|
|
--sidebar-text: #ffffff;
|
|
--sidebar-width: 250px;
|
|
/* Vertical chrome around .main-content. A full-height page subtracts these;
|
|
hardcoding a different number is what put a scrollbar on the map. */
|
|
--main-pad-top: 20px;
|
|
--main-pad-bottom: 70px;
|
|
|
|
/* Hover variants */
|
|
--secondary-dark: #82503f;
|
|
--success-dark: #019e4c;
|
|
--info-dark: #039ce0;
|
|
--warning-dark: #e67c02;
|
|
--danger-dark: #e62c51;
|
|
|
|
/* Additional semantic colors */
|
|
--purple: #9c27b0;
|
|
--bg-popover: #111111;
|
|
}
|
|
|
|
/* Dark Mode - via data-theme attribute or system preference fallback */
|
|
[data-theme="dark"],
|
|
:root:not([data-theme]) {
|
|
@media (prefers-color-scheme: dark) {
|
|
--primary: #4181ff;
|
|
--primary-dark: #2d6ce0;
|
|
--secondary: #6c757d;
|
|
--success: #0ad64f;
|
|
--warning: #ff9500;
|
|
--danger: #f5365c;
|
|
--info: #4181ff;
|
|
--bg: #0a0a1a;
|
|
--bg-card: rgba(0, 0, 61, 0.4);
|
|
--bg-card-solid: #0d0d2b;
|
|
--text: rgba(255, 255, 255, 0.9);
|
|
--text-light: rgba(255, 255, 255, 0.6);
|
|
--border: rgba(65, 129, 255, 0.2);
|
|
--link: #4181ff;
|
|
--sidebar-bg: #00003d;
|
|
--sidebar-text: #ffffff;
|
|
}
|
|
}
|
|
|
|
/* Dark Mode - explicit selection */
|
|
[data-theme="dark"] {
|
|
--primary: #4181ff;
|
|
--primary-dark: #2d6ce0;
|
|
--secondary: #6c757d;
|
|
--success: #0ad64f;
|
|
--warning: #ff9500;
|
|
--danger: #f5365c;
|
|
--info: #4181ff;
|
|
--bg: #0a0a1a;
|
|
--bg-card: rgba(0, 0, 61, 0.4);
|
|
--bg-card-solid: #0d0d2b;
|
|
--text: rgba(255, 255, 255, 0.9);
|
|
--text-light: rgba(255, 255, 255, 0.6);
|
|
--border: rgba(65, 129, 255, 0.2);
|
|
--link: #4181ff;
|
|
--sidebar-bg: #00003d;
|
|
--sidebar-text: #ffffff;
|
|
}
|
|
|
|
/* Card border only in light mode */
|
|
[data-theme="light"] .card {
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
body {
|
|
font-family: 'Inter Variable', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
line-height: 1.6;
|
|
font-size: 15px;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
/* Links */
|
|
a {
|
|
color: var(--link);
|
|
text-decoration: none;
|
|
outline: none;
|
|
}
|
|
|
|
a:hover {
|
|
color: var(--primary-dark);
|
|
text-decoration: none;
|
|
}
|
|
|
|
/* Inline text links get underline on hover (exclude buttons) */
|
|
p a:not(.btn):hover,
|
|
td a:not(.btn):hover,
|
|
.info-value a:not(.btn):hover,
|
|
.notes-text a:not(.btn):hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Headings */
|
|
h1, h2, h3, h4, h5, h6 {
|
|
color: var(--text);
|
|
}
|
|
|
|
/* Layout */
|
|
.app-layout {
|
|
display: flex;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.sidebar {
|
|
width: var(--sidebar-width);
|
|
background: var(--sidebar-bg);
|
|
color: var(--sidebar-text);
|
|
padding: 0;
|
|
position: fixed;
|
|
height: 100vh;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
z-index: 1000;
|
|
}
|
|
|
|
.sidebar-header {
|
|
padding: 1rem;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
|
text-align: center;
|
|
}
|
|
|
|
.sidebar-header h1 {
|
|
font-size: 14px;
|
|
font-weight: 400;
|
|
text-transform: uppercase;
|
|
color: var(--sidebar-text);
|
|
margin: 0.5rem 0 0 0;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
.sidebar-logo {
|
|
width: 180px;
|
|
height: auto;
|
|
display: block;
|
|
margin: 0 auto;
|
|
filter: brightness(0) invert(1);
|
|
}
|
|
|
|
.sidebar-search {
|
|
padding: 10px 15px;
|
|
}
|
|
|
|
.sidebar-search input {
|
|
width: 100%;
|
|
padding: 0.375rem 0.75rem;
|
|
border: 0;
|
|
border-radius: 0.25rem;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
color: white;
|
|
font-size: 15px;
|
|
height: 34px;
|
|
}
|
|
|
|
.sidebar-search input::placeholder {
|
|
color: #fff !important;
|
|
font-size: 13px;
|
|
opacity: 0.5 !important;
|
|
}
|
|
|
|
.sidebar-search input:focus {
|
|
outline: none;
|
|
background: rgba(0,0,0,0.2);
|
|
box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.45);
|
|
}
|
|
|
|
.sidebar-nav a {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.7rem 1.25rem;
|
|
color: rgba(255,255,255,0.85);
|
|
text-decoration: none;
|
|
transition: all 0.2s;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.sidebar-nav a svg {
|
|
margin-right: 0.5rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.sidebar-nav a:hover,
|
|
.sidebar-nav a.active {
|
|
background: rgba(255,255,255,0.1);
|
|
color: white;
|
|
}
|
|
|
|
.sidebar-nav a.active {
|
|
border-left: 3px solid var(--primary);
|
|
}
|
|
|
|
.sidebar-nav a.external-link::after {
|
|
content: '\2197';
|
|
font-size: 10px;
|
|
margin-left: auto;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.nav-section {
|
|
padding: 0.75rem 1.25rem 0.5rem;
|
|
color: rgba(255,255,255,0.5);
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.main-content {
|
|
flex: 1;
|
|
margin-left: var(--sidebar-width);
|
|
padding: var(--main-pad-top) 10px var(--main-pad-bottom) 10px;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Header */
|
|
.page-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.page-header h1 {
|
|
font-size: 20px;
|
|
font-weight: 500;
|
|
line-height: 20px;
|
|
margin: 0;
|
|
}
|
|
|
|
.page-header h2 {
|
|
font-size: 20px;
|
|
font-weight: 500;
|
|
line-height: 20px;
|
|
}
|
|
|
|
/* Cards */
|
|
.card {
|
|
background: var(--bg-card);
|
|
border-radius: 0.25rem;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
padding: 1.25rem;
|
|
margin-bottom: 25px;
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
[data-theme="dark"] .card {
|
|
border: none;
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0;
|
|
padding: 0.75rem 1.25rem;
|
|
background: transparent;
|
|
border-bottom: 1px solid var(--border);
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
color: var(--text);
|
|
}
|
|
|
|
.card-header h3 {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
}
|
|
|
|
.card-title {
|
|
margin-bottom: 0.75rem;
|
|
font-weight: 600;
|
|
font-size: 16px;
|
|
color: var(--text);
|
|
}
|
|
|
|
.card-footer {
|
|
padding: 0.75rem 1.25rem;
|
|
background-color: transparent;
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
/* Dashboard widgets */
|
|
.dashboard-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
gap: 25px;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.stat-card {
|
|
background: var(--bg-card);
|
|
border-radius: 0.25rem;
|
|
padding: 1.25rem;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.stat-card .label {
|
|
font-size: 14px;
|
|
color: var(--text-light);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.stat-card .value {
|
|
font-size: 2rem;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
|
|
.stat-card.success .value { color: var(--success); }
|
|
.stat-card.warning .value { color: var(--warning); }
|
|
.stat-card.danger .value { color: var(--danger); }
|
|
.stat-card.info .value { color: var(--info); }
|
|
|
|
/* Tables */
|
|
.table-container {
|
|
overflow-x: auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-bottom: 1rem;
|
|
color: var(--text);
|
|
}
|
|
|
|
tr {
|
|
border-bottom: none;
|
|
}
|
|
|
|
th, td {
|
|
padding: 0.75rem;
|
|
text-align: left;
|
|
font-size: 13px;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
border-top: 1px solid var(--border);
|
|
/* line up digits in columns (Inter supports tabular figures) */
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* Cap a long free-text column (e.g. Description) so it truncates with an
|
|
ellipsis instead of widening the row and pushing the Actions column out of
|
|
view. Pair with a title attribute to show the full text on hover. */
|
|
td.cell-truncate {
|
|
max-width: 32rem;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
th {
|
|
font-weight: 600;
|
|
font-size: 11px;
|
|
color: var(--text);
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
padding-top: 0.75rem;
|
|
padding-bottom: 0.75rem;
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
|
|
border-top: none;
|
|
}
|
|
|
|
th.sortable {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
th.sortable:hover {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.sort-arrow {
|
|
margin-left: 0.25rem;
|
|
font-size: 10px;
|
|
}
|
|
|
|
tr:hover {
|
|
background: var(--primary);
|
|
background: rgba(65, 129, 255, 0.1);
|
|
}
|
|
|
|
/* Buttons */
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
padding: 9px 19px;
|
|
border: none;
|
|
border-radius: 0.25rem;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
letter-spacing: 1px;
|
|
text-transform: uppercase;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
vertical-align: middle;
|
|
line-height: 1;
|
|
text-decoration: none;
|
|
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
}
|
|
|
|
.btn:focus {
|
|
box-shadow: none;
|
|
outline: none;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: var(--primary);
|
|
color: white;
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: var(--primary-dark);
|
|
border-color: var(--primary-dark);
|
|
color: white;
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: var(--secondary);
|
|
color: white;
|
|
border-color: var(--secondary);
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: var(--secondary-dark);
|
|
border-color: var(--secondary-dark);
|
|
color: white;
|
|
}
|
|
|
|
.btn-success {
|
|
background: var(--success);
|
|
color: white;
|
|
border-color: var(--success);
|
|
}
|
|
|
|
.btn-success:hover {
|
|
background: var(--success-dark);
|
|
border-color: var(--success-dark);
|
|
}
|
|
|
|
.btn-info {
|
|
background: var(--info);
|
|
color: white;
|
|
border-color: var(--info);
|
|
}
|
|
|
|
.btn-info:hover {
|
|
background: var(--info-dark);
|
|
border-color: var(--info-dark);
|
|
}
|
|
|
|
.btn-warning {
|
|
background: var(--warning);
|
|
color: white;
|
|
border-color: var(--warning);
|
|
}
|
|
|
|
.btn-warning:hover {
|
|
background: var(--warning-dark);
|
|
border-color: var(--warning-dark);
|
|
}
|
|
|
|
.btn-danger {
|
|
background: var(--danger);
|
|
color: white;
|
|
border-color: var(--danger);
|
|
}
|
|
|
|
.btn-danger:hover {
|
|
background: var(--danger-dark);
|
|
border-color: var(--danger-dark);
|
|
}
|
|
|
|
.btn-link {
|
|
color: var(--info);
|
|
background: transparent;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.btn-sm {
|
|
font-size: 10px;
|
|
font-weight: 500;
|
|
padding: 6px 15px;
|
|
}
|
|
|
|
.btn-lg {
|
|
padding: 12px 38px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Forms */
|
|
.form-group {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.form-group label {
|
|
display: block;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
margin-bottom: 0.5rem;
|
|
color: var(--text);
|
|
}
|
|
|
|
.form-control {
|
|
width: 100%;
|
|
padding: 0.625rem 0.875rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 6px;
|
|
font-size: 0.9375rem;
|
|
background: var(--bg-card);
|
|
color: var(--text);
|
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
|
}
|
|
|
|
.form-control:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.15);
|
|
}
|
|
|
|
.form-control::placeholder {
|
|
color: var(--text-light);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
select.form-control {
|
|
background: var(--bg-card);
|
|
cursor: pointer;
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 0.75rem center;
|
|
padding-right: 2.25rem;
|
|
}
|
|
|
|
select.form-control option {
|
|
background: var(--bg-card);
|
|
color: var(--text);
|
|
}
|
|
|
|
/* Textarea styling */
|
|
textarea.form-control {
|
|
min-height: 100px;
|
|
resize: vertical;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
/* Input group for search with icon */
|
|
.input-group {
|
|
display: flex;
|
|
position: relative;
|
|
}
|
|
|
|
.input-group .form-control {
|
|
flex: 1;
|
|
}
|
|
|
|
.input-group-icon {
|
|
position: absolute;
|
|
left: 0.75rem;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: var(--text-light);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.input-group .form-control.has-icon {
|
|
padding-left: 2.5rem;
|
|
}
|
|
|
|
/* Form labels */
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: 0.375rem;
|
|
font-weight: 500;
|
|
color: var(--text);
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
/* Checkbox and radio styling */
|
|
input[type="checkbox"],
|
|
input[type="radio"] {
|
|
width: 1.125rem;
|
|
height: 1.125rem;
|
|
accent-color: var(--primary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Dark mode form adjustments. Scoped to the explicit theme attribute (the
|
|
theme store always stamps it at startup) - a bare prefers-color-scheme
|
|
query here leaks dark widget styles into light mode on dark-OS machines. */
|
|
[data-theme="dark"] .form-control {
|
|
/* background-COLOR, not the shorthand: the shorthand resets a select's
|
|
background-repeat/position and the dropdown arrow tiles across the box. */
|
|
background-color: var(--bg);
|
|
border-color: var(--border);
|
|
}
|
|
|
|
[data-theme="dark"] .form-control:focus {
|
|
background-color: var(--bg);
|
|
box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.2);
|
|
}
|
|
|
|
[data-theme="dark"] select.form-control {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23999' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
|
background-color: var(--bg);
|
|
background-repeat: no-repeat;
|
|
background-position: right 0.75rem center;
|
|
}
|
|
|
|
[data-theme="dark"] select.form-control option {
|
|
background: var(--bg-card-solid);
|
|
}
|
|
|
|
/* Form grid */
|
|
.form-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
/* Badges */
|
|
.badge {
|
|
display: inline-block;
|
|
padding: 0.25em 0.5em;
|
|
border-radius: 0.25rem;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
line-height: 1;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
vertical-align: baseline;
|
|
}
|
|
|
|
.badge-success { background: var(--success); color: #fff; }
|
|
.badge-warning { background: var(--warning); color: #fff; }
|
|
.badge-danger { background: var(--danger); color: #fff; }
|
|
.badge-info { background: var(--info); color: #fff; }
|
|
.badge-primary { background: var(--primary); color: #fff; }
|
|
.badge-secondary { background: var(--secondary); color: #fff; }
|
|
|
|
/* Login page */
|
|
.login-container {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: var(--bg);
|
|
}
|
|
|
|
.login-box {
|
|
background: var(--bg-card);
|
|
padding: 2rem;
|
|
border-radius: 0.25rem;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
width: 100%;
|
|
max-width: 400px;
|
|
}
|
|
|
|
.login-logo {
|
|
display: block;
|
|
width: 160px;
|
|
height: auto;
|
|
margin: 0 auto 1rem;
|
|
}
|
|
|
|
/* Logo is white by default - invert for light mode */
|
|
[data-theme="light"] .login-logo {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.login-box h1 {
|
|
text-align: center;
|
|
margin-bottom: 1.5rem;
|
|
font-size: 24px;
|
|
color: var(--text);
|
|
}
|
|
|
|
.login-box .btn {
|
|
width: 100%;
|
|
justify-content: center;
|
|
padding: 12px;
|
|
}
|
|
|
|
.error-message {
|
|
background: rgba(245, 54, 92, 0.2);
|
|
color: var(--danger);
|
|
padding: 0.75rem 1rem;
|
|
border-radius: 0.25rem;
|
|
margin-bottom: 1rem;
|
|
font-size: 14px;
|
|
border: 1px solid rgba(245, 54, 92, 0.3);
|
|
}
|
|
|
|
/* Modal */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0,0,0,0.7);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1050;
|
|
}
|
|
|
|
.modal {
|
|
background: var(--bg-card-solid);
|
|
border-radius: 0.25rem;
|
|
width: 100%;
|
|
max-width: 500px;
|
|
max-height: 90vh;
|
|
overflow-y: auto;
|
|
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
|
|
color: var(--text);
|
|
}
|
|
|
|
.modal-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 1rem 1.25rem;
|
|
border-bottom: 1px solid var(--border);
|
|
background: transparent;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
margin: 0;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 1.25rem;
|
|
}
|
|
|
|
.modal-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.5rem;
|
|
padding: 1rem 1.25rem;
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
/* Search and filters */
|
|
.filters {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1rem;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
}
|
|
|
|
.filters input[type="text"],
|
|
.filters input.form-control {
|
|
flex: 1 1 auto;
|
|
min-width: 200px;
|
|
max-width: 350px;
|
|
}
|
|
|
|
.filters select,
|
|
.filters select.form-control {
|
|
min-width: 160px;
|
|
max-width: 220px;
|
|
flex: 0 1 auto;
|
|
}
|
|
|
|
/* Filter bar with background */
|
|
.filter-bar {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
padding: 0.75rem 1rem;
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
margin-bottom: 1rem;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
}
|
|
|
|
.filter-bar .form-control {
|
|
background: var(--bg);
|
|
}
|
|
|
|
/* Pagination */
|
|
.pagination-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: 1rem;
|
|
padding-top: 0.75rem;
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.pagination-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.perpage-select {
|
|
padding: 0.375rem 0.5rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.25rem;
|
|
background: var(--bg-card);
|
|
color: var(--text);
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 0.25rem;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.pagination button {
|
|
padding: 0.5rem 0.75rem;
|
|
border: 1px solid var(--border);
|
|
background: transparent;
|
|
border-radius: 0.25rem;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
color: var(--text);
|
|
}
|
|
|
|
.pagination button:hover:not(:disabled):not(.ellipsis) {
|
|
background: var(--bg);
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
.pagination button:disabled {
|
|
opacity: 0.4;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.pagination button.active {
|
|
background: var(--primary);
|
|
color: white;
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
.pagination button.ellipsis {
|
|
border: none;
|
|
cursor: default;
|
|
padding: 0.5rem 0.25rem;
|
|
}
|
|
|
|
/* Loading */
|
|
.loading {
|
|
text-align: center;
|
|
padding: 2rem;
|
|
color: var(--text-light);
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Sidebar footer */
|
|
.sidebar-footer {
|
|
margin-top: auto;
|
|
border-top: 1px solid rgba(255,255,255,0.1);
|
|
}
|
|
|
|
.theme-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
width: 100%;
|
|
padding: 0.75rem 1.25rem;
|
|
background: transparent;
|
|
border: none;
|
|
color: rgba(255,255,255,0.7);
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.theme-toggle:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
color: white;
|
|
}
|
|
|
|
/* User menu */
|
|
.user-menu {
|
|
padding: 1rem 1.25rem;
|
|
border-top: 1px solid rgba(255,255,255,0.1);
|
|
}
|
|
|
|
.user-menu .username {
|
|
font-size: 14px;
|
|
margin-bottom: 0.5rem;
|
|
color: rgba(255,255,255,0.85);
|
|
}
|
|
|
|
.user-menu .btn {
|
|
width: 100%;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Action buttons in tables */
|
|
.actions {
|
|
display: inline-flex;
|
|
gap: 0.25rem;
|
|
align-items: center;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
td.actions {
|
|
/* A td must stay display:table-cell - the .actions inline-flex above pulls
|
|
the cell out of the table's row box, so its bottom border renders ~1px off
|
|
from the other cells. Keep it a cell; space multiple buttons with a margin
|
|
instead of the flex gap. */
|
|
display: table-cell;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
}
|
|
td.actions .btn + .btn {
|
|
margin-left: 0.25rem;
|
|
}
|
|
|
|
/* ============================================
|
|
DETAIL PAGES (shared styles)
|
|
============================================ */
|
|
.detail-page {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
/* Hero Card */
|
|
.hero-card {
|
|
display: flex;
|
|
gap: 2rem;
|
|
background: var(--bg-card);
|
|
border-radius: 0.25rem;
|
|
padding: 1.5rem;
|
|
margin-bottom: 25px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.hero-image {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.hero-image img {
|
|
width: 180px;
|
|
height: 180px;
|
|
object-fit: contain;
|
|
background: var(--bg);
|
|
border-radius: 0.25rem;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.hero-content {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.hero-title {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.hero-title h1 {
|
|
font-size: 30px;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
color: var(--text);
|
|
line-height: 34px;
|
|
}
|
|
|
|
.hero-alias {
|
|
font-size: 18px;
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.hero-meta {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.badge-lg {
|
|
padding: 0.35rem 0.75rem;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
.hero-details {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 2rem;
|
|
margin-top: auto;
|
|
}
|
|
|
|
.hero-detail {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.hero-detail-label {
|
|
font-size: 10px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.hero-detail-value {
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
color: var(--text);
|
|
}
|
|
|
|
.hero-detail-value.mono {
|
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Content Grid */
|
|
/* Balanced two-column card flow. Uses CSS multicol (not a hand-assigned
|
|
grid) so cards distribute by height and the columns stay even no matter
|
|
how many cards land on either side. display:contents flattens the two
|
|
.content-column wrappers so their cards flow directly into the columns,
|
|
which keeps the existing markup unchanged. */
|
|
.content-grid {
|
|
column-count: 2;
|
|
column-gap: 25px;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.content-column {
|
|
display: contents;
|
|
}
|
|
|
|
/* Section Cards */
|
|
.section-card {
|
|
background: var(--bg-card);
|
|
border-radius: 0.25rem;
|
|
padding: 1.25rem;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
/* multicol needs per-card spacing (column-gap is horizontal only) and
|
|
must not split a card across the column break */
|
|
margin-bottom: 25px;
|
|
break-inside: avoid;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
color: var(--text);
|
|
margin: 0 0 1rem 0;
|
|
padding-bottom: 0.75rem;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
/* Settings form controls - shared by the individual settings pages
|
|
(branding, printing, email, integrations, identifiers, search, map...). */
|
|
.setting-group {
|
|
border-top: 1px solid var(--border);
|
|
padding-top: 1rem;
|
|
}
|
|
.setting-group:first-of-type {
|
|
border-top: none;
|
|
padding-top: 0;
|
|
}
|
|
.setting-group h3 {
|
|
margin: 0 0 0.5rem 0;
|
|
font-size: 1rem;
|
|
color: var(--text);
|
|
}
|
|
.setting-description {
|
|
color: var(--text-light);
|
|
font-size: 0.9rem;
|
|
margin: 0 0 1rem 0;
|
|
line-height: 1.5;
|
|
}
|
|
.settings-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.setting-row {
|
|
margin-bottom: 1rem;
|
|
}
|
|
.setting-row.full-width {
|
|
grid-column: 1 / -1;
|
|
}
|
|
.setting-row label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
.setting-row label span {
|
|
color: var(--text);
|
|
font-size: 0.9rem;
|
|
}
|
|
.setting-row input,
|
|
.setting-row select {
|
|
padding: 0.5rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
font-size: 1rem;
|
|
max-width: 400px;
|
|
}
|
|
.setting-row input[type="number"] {
|
|
max-width: 120px;
|
|
}
|
|
.setting-row input:focus,
|
|
.setting-row select:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
}
|
|
.input-hint {
|
|
color: var(--text-light);
|
|
font-size: 0.8rem;
|
|
}
|
|
.toggle-label {
|
|
flex-direction: row !important;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
max-width: 400px;
|
|
}
|
|
.toggle-hint {
|
|
display: block;
|
|
margin-top: -0.5rem;
|
|
margin-left: 0;
|
|
}
|
|
.toggle-btn {
|
|
position: relative;
|
|
width: 50px;
|
|
height: 26px;
|
|
border-radius: 13px;
|
|
border: none;
|
|
background: var(--secondary);
|
|
cursor: pointer;
|
|
transition: background 0.2s;
|
|
}
|
|
.toggle-btn.active {
|
|
background: var(--success);
|
|
}
|
|
.toggle-slider {
|
|
position: absolute;
|
|
top: 3px;
|
|
left: 3px;
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
background: white;
|
|
transition: transform 0.2s;
|
|
}
|
|
.toggle-btn.active .toggle-slider {
|
|
transform: translateX(24px);
|
|
}
|
|
.status-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.75rem;
|
|
background: var(--bg);
|
|
border-radius: 4px;
|
|
font-size: 0.9rem;
|
|
color: var(--text-light);
|
|
max-width: 400px;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.status-dot {
|
|
width: 10px;
|
|
height: 10px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
.status-dot.inactive { background: var(--secondary); }
|
|
.status-dot.warning { background: var(--warning); }
|
|
.status-dot.pending { background: var(--primary); }
|
|
.status-dot.success { background: var(--success); }
|
|
.test-btn {
|
|
padding: 0.5rem 1rem;
|
|
background: var(--primary);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 0.9rem;
|
|
}
|
|
.test-btn:hover:not(:disabled) {
|
|
background: var(--primary-dark);
|
|
}
|
|
.test-btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
.view-logs-link {
|
|
display: inline-block;
|
|
margin-top: 0.5rem;
|
|
color: var(--link);
|
|
text-decoration: none;
|
|
font-size: 0.9rem;
|
|
}
|
|
.view-logs-link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
.identifier-matrix {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
.identifier-matrix th,
|
|
.identifier-matrix td {
|
|
padding: 0.6rem 0.75rem;
|
|
text-align: center;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.identifier-matrix th:first-child,
|
|
.identifier-matrix td.identifier-name {
|
|
text-align: left;
|
|
}
|
|
.identifier-matrix th {
|
|
color: var(--text-light);
|
|
font-weight: 600;
|
|
font-size: 0.9rem;
|
|
}
|
|
.identifier-matrix .identifier-name {
|
|
color: var(--text);
|
|
}
|
|
.color-input-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
}
|
|
.color-input-row input[type="color"] {
|
|
width: 48px;
|
|
height: 34px;
|
|
padding: 2px;
|
|
cursor: pointer;
|
|
}
|
|
.color-input-row input[type="text"] {
|
|
max-width: 160px;
|
|
}
|
|
.map-upload-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
margin-top: 0.4rem;
|
|
}
|
|
.map-thumb {
|
|
height: 40px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
}
|
|
.map-thumb-dark { background: #222; }
|
|
.settings-success {
|
|
margin-top: 1rem;
|
|
padding: 0.75rem;
|
|
background: var(--success);
|
|
color: white;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Info List */
|
|
.info-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 14px;
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.info-value {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text);
|
|
text-align: right;
|
|
}
|
|
|
|
.info-value.mono, .mono {
|
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* Small email/Teams action buttons for support contacts */
|
|
.contact-action {
|
|
display: inline-block;
|
|
margin-left: 0.35rem;
|
|
padding: 0.05rem 0.4rem;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
color: var(--link);
|
|
background: var(--bg);
|
|
text-decoration: none;
|
|
}
|
|
.contact-action:hover {
|
|
border-color: var(--primary);
|
|
color: var(--primary);
|
|
}
|
|
|
|
/* Feature Tags */
|
|
.feature-tag {
|
|
display: inline-block;
|
|
padding: 0.25rem 0.5rem;
|
|
margin-left: 0.25rem;
|
|
font-size: 11px;
|
|
border-radius: 0.25rem;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.feature-tag.active {
|
|
background: rgba(20, 171, 239, 0.2);
|
|
color: var(--info);
|
|
}
|
|
|
|
/* Empty State */
|
|
.empty-message {
|
|
color: var(--text-light);
|
|
font-size: 14px;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Device icon (network detail) */
|
|
.device-icon {
|
|
width: 44px;
|
|
height: 44px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(20, 171, 239, 0.2);
|
|
border-radius: 0.25rem;
|
|
color: var(--info);
|
|
}
|
|
|
|
.device-icon svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
/* Network */
|
|
.network-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.network-item {
|
|
padding: 0.75rem;
|
|
background: var(--bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
.network-primary {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.ip-address {
|
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.primary-badge {
|
|
padding: 0.2rem 0.4rem;
|
|
font-size: 10px;
|
|
text-transform: uppercase;
|
|
background: var(--success);
|
|
color: white;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
.network-secondary {
|
|
margin-top: 0.25rem;
|
|
}
|
|
|
|
.mac-address {
|
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
|
font-size: 13px;
|
|
color: var(--text-light);
|
|
}
|
|
|
|
/* Notes */
|
|
.notes-text {
|
|
margin: 0;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
color: var(--text);
|
|
}
|
|
|
|
/* Audit Footer */
|
|
.audit-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 1rem;
|
|
margin-top: 25px;
|
|
font-size: 13px;
|
|
color: var(--text-light);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
/* Location link */
|
|
.location-link {
|
|
color: var(--info);
|
|
cursor: pointer;
|
|
border-bottom: 1px dashed var(--info);
|
|
}
|
|
|
|
.location-link:hover {
|
|
color: var(--link);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* Badge colors for detail pages */
|
|
.badge-primary {
|
|
background: var(--primary);
|
|
color: white;
|
|
}
|
|
|
|
.badge-printer {
|
|
background: var(--purple);
|
|
color: white;
|
|
}
|
|
|
|
/* Responsive detail pages */
|
|
@media (max-width: 768px) {
|
|
.hero-card {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
}
|
|
|
|
.hero-title {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.hero-details {
|
|
justify-content: center;
|
|
}
|
|
|
|
.content-grid {
|
|
column-count: 1;
|
|
}
|
|
|
|
.audit-footer {
|
|
flex-direction: column;
|
|
gap: 0.375rem;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
FULLCALENDAR DARK THEME OVERRIDES
|
|
============================================ */
|
|
.fc {
|
|
--fc-border-color: var(--border);
|
|
--fc-button-bg-color: var(--primary);
|
|
--fc-button-border-color: var(--primary);
|
|
--fc-button-hover-bg-color: var(--primary-dark);
|
|
--fc-button-hover-border-color: var(--primary-dark);
|
|
--fc-button-active-bg-color: var(--primary-dark);
|
|
--fc-button-active-border-color: var(--primary-dark);
|
|
--fc-page-bg-color: transparent;
|
|
--fc-neutral-bg-color: rgba(0, 0, 0, 0.2);
|
|
--fc-list-event-hover-bg-color: rgba(255, 255, 255, 0.1);
|
|
--fc-today-bg-color: rgba(121, 52, 243, 0.15);
|
|
}
|
|
|
|
.fc .fc-button {
|
|
font-size: 11px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.fc .fc-col-header-cell-cushion,
|
|
.fc .fc-daygrid-day-number {
|
|
color: var(--text);
|
|
}
|
|
|
|
.fc .fc-daygrid-day.fc-day-today {
|
|
background: var(--fc-today-bg-color);
|
|
}
|
|
|
|
.fc-theme-standard .fc-scrollgrid {
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.fc-theme-standard td, .fc-theme-standard th {
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.fc .fc-daygrid-day-top {
|
|
flex-direction: row;
|
|
}
|
|
|
|
.fc-event {
|
|
font-size: 12px;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
.fc .fc-toolbar-title {
|
|
font-size: 18px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.fc .fc-more-link {
|
|
color: var(--info);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.fc .fc-popover {
|
|
background: var(--bg-popover);
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.25rem;
|
|
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
|
|
}
|
|
|
|
.fc .fc-popover-header {
|
|
background: rgba(0, 0, 0, 0.3);
|
|
color: var(--text);
|
|
padding: 0.5rem 0.75rem;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.fc .fc-popover-body {
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.fc .fc-daygrid-more-link {
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.fc-more-tooltip {
|
|
position: fixed;
|
|
background: var(--bg-card-solid);
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.25rem;
|
|
padding: 0.5rem;
|
|
z-index: 9999;
|
|
min-width: 180px;
|
|
max-width: 350px;
|
|
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
|
|
pointer-events: auto;
|
|
color: var(--text);
|
|
}
|
|
|
|
.fc-more-tooltip-event {
|
|
padding: 0.25rem 0.5rem;
|
|
font-size: 12px;
|
|
color: var(--text);
|
|
border-left: 3px solid;
|
|
margin-bottom: 0.25rem;
|
|
background: var(--bg);
|
|
border-radius: 0 0.25rem 0.25rem 0;
|
|
cursor: pointer;
|
|
transition: background 0.15s ease;
|
|
}
|
|
|
|
.fc-more-tooltip-event:hover {
|
|
background: rgba(65, 129, 255, 0.15);
|
|
}
|
|
|
|
.fc-more-tooltip-event:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* ============================================
|
|
LEAFLET DARK THEME OVERRIDES
|
|
============================================ */
|
|
.leaflet-container {
|
|
background: var(--bg-popover);
|
|
}
|
|
|
|
.leaflet-popup-content-wrapper {
|
|
background: var(--bg-popover);
|
|
color: var(--text);
|
|
border-radius: 0.25rem;
|
|
box-shadow: 0 16px 38px -12px rgba(0,0,0,.56), 0 4px 25px 0 rgba(0,0,0,.12), 0 8px 10px -5px rgba(0,0,0,.2);
|
|
}
|
|
|
|
.leaflet-popup-tip {
|
|
background: var(--bg-popover);
|
|
}
|
|
|
|
.leaflet-popup-content {
|
|
margin: 0.75rem 1rem;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.leaflet-popup-content a {
|
|
color: var(--info);
|
|
}
|
|
|
|
.leaflet-control-zoom a {
|
|
background: rgba(0, 0, 0, 0.7) !important;
|
|
color: #fff !important;
|
|
border: none !important;
|
|
}
|
|
|
|
.leaflet-control-zoom a:hover {
|
|
background: rgba(0, 0, 0, 0.9) !important;
|
|
}
|
|
|
|
.leaflet-control-layers {
|
|
background: rgba(0, 0, 0, 0.7);
|
|
color: var(--text);
|
|
border: none;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
/* Notification Banner */
|
|
.notification-banner {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
margin-bottom: 1rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.notification-item {
|
|
flex: 1;
|
|
min-width: 250px;
|
|
padding: 0.625rem 0.875rem;
|
|
border-radius: 6px;
|
|
border-left: 4px solid var(--border);
|
|
background: var(--bg-card);
|
|
}
|
|
|
|
.notification-item.type-incident {
|
|
border-left-color: var(--danger);
|
|
background: rgba(245, 54, 92, 0.06);
|
|
}
|
|
|
|
.notification-item.type-change {
|
|
border-left-color: var(--warning);
|
|
background: rgba(255, 136, 0, 0.06);
|
|
}
|
|
|
|
.notification-item.type-awareness {
|
|
border-left-color: var(--success);
|
|
background: rgba(4, 185, 98, 0.06);
|
|
}
|
|
|
|
.notification-text {
|
|
display: block;
|
|
font-size: 0.85rem;
|
|
font-weight: 500;
|
|
color: var(--text);
|
|
}
|
|
|
|
.notification-meta {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
margin-top: 0.25rem;
|
|
font-size: 0.75rem;
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.notification-ticket {
|
|
color: var(--link);
|
|
text-decoration: none;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.notification-ticket:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
[data-theme="dark"] .notification-item.type-incident {
|
|
background: rgba(245, 54, 92, 0.1);
|
|
}
|
|
[data-theme="dark"] .notification-item.type-change {
|
|
background: rgba(255, 136, 0, 0.1);
|
|
}
|
|
[data-theme="dark"] .notification-item.type-awareness {
|
|
background: rgba(4, 185, 98, 0.1);
|
|
}
|
|
|
|
/* Light mode is now default, dark mode via prefers-color-scheme */
|
|
|
|
/* "Show inactive" toggle in a type-settings page header */
|
|
.show-inactive {
|
|
margin-left: auto;
|
|
margin-right: 0.75rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
font-size: 0.9rem;
|
|
color: var(--text-light);
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Clickable list rows: the whole row navigates to the item detail; interactive
|
|
cells (the actions column, in-row links) stop propagation so they still work
|
|
independently. */
|
|
.clickable-row { cursor: pointer; }
|
|
.clickable-row:hover td { background: var(--bg); }
|