/* 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; } /* Full-width alternative to .content-grid, for a tab holding one long list rather than short fact cards. An application inventory or an event feed split into two balanced columns reads as two unrelated lists, and the eye has to hunt for where the first one ended. */ .detail-full { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 25px; } .detail-full > * { min-width: 0; } /* 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); } /* --- Printing from inside the app shell ------------------------------------- * * Core's label pages are full-screen routes precisely so the shell cannot reach * the stock. A tool someone works in for ten minutes wants the navigation * though, so the shell is hidden here instead: the sidebar goes, the content * column gives back the margin it was holding for it, and the notification * banner - which is chrome, not content - goes with them. * * Anything the page itself must keep off the paper marks itself .no-print. */ @media print { .sidebar, .notification-banner, .no-print { display: none !important; } .app-layout { display: block !important; min-height: 0 !important; } .main-content { margin-left: 0 !important; padding: 0 !important; overflow: visible !important; } }