/* app.css – Device Hub */

/* ── Layout shell ───────────────────────────────────────────────────────────── */
html, body, #root { height: 100%; margin: 0; }

#app-shell { display: flex; height: 100%; position: relative; }

/* ── Sidebar ────────────────────────────────────────────────────────────────── */
#sidebar {
  width: 220px; min-width: 220px;
  background: #1a1f2e; color: #c8d0e0;
  display: flex; flex-direction: column;
  z-index: 100;
  transition: margin-left .2s ease;
}
/* Collapsed: slide off-screen, reveal the pull-out handle. */
#app-shell.sidebar-collapsed #sidebar { margin-left: -221px; }

#sidebar-handle {
  display: none;
  position: fixed; left: 0; top: 50%; transform: translateY(-50%);
  z-index: 200; border: none;
  background: #1a1f2e; color: #c8d0e0;
  border-radius: 0 .5rem .5rem 0; padding: .7rem .45rem;
  box-shadow: 1px 0 6px rgba(0,0,0,.2);
}
#app-shell.sidebar-collapsed #sidebar-handle { display: block; }

#sidebar-brand {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.25rem 1.25rem 1rem;
  font-size: 1.05rem; font-weight: 700; color: #fff;
  border-bottom: 1px solid rgba(255,255,255,.08);
  letter-spacing: .02em;
}
#sidebar-brand i { color: #6ea8fe; }
#sidebar-brand .brand-logo { display: block; }
#sidebar-brand .brand-sub { font-size: .7rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: #6ea8fe; margin-top: .35rem; }
/* Customer selector, between brand and navigation (corporate design: group-switcher).
   One group -> a static name; several -> a Select2 that has to look at home in a dark
   sidebar, which is the only reason for the overrides below. */
#sidebar-tenant {
  padding: .5rem 1.25rem; margin: 0; border-bottom: 1px solid rgba(255,255,255,.08);
}
#sidebar-tenant .sidebar-group {
  font-size: .82rem; font-weight: 600; color: #fff;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#sidebar-tenant .sidebar-group i { color: #6c7a93; margin-right: .5rem; font-size: .75rem; }
#sidebar-tenant .select2-container { width: 100% !important; }
#sidebar-tenant .select2-selection--single {
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12);
  border-radius: .35rem; height: auto; padding: .15rem .1rem;
}
#sidebar-tenant .select2-selection__rendered { color: #fff; font-size: .82rem; font-weight: 600; line-height: 1.6; }
#sidebar-tenant .select2-selection__arrow { top: 50%; transform: translateY(-50%); }
#sidebar-tenant .select2-selection__arrow b { border-color: #8b97ab transparent transparent transparent; }
/* Dropdown is appended inside the sidebar, so it must clear the collapsed rail. */
.tenant-switcher-dropdown { z-index: 1060; }
#sidebar-collapse-btn { background: none; opacity: .7; }
#sidebar-collapse-btn:hover { opacity: 1; color: #fff; }
#app-copyright { margin-top: .6rem; font-size: .68rem; color: #5b6679; line-height: 1.3; }

/* Status dot (devices table) */
.status-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; vertical-align: middle; }

/* Editable cells (devices table, "Label bearbeiten" toggle on) */
#devTable.labels-editable .asset-cell { background: #fff3cd; cursor: pointer; outline: 1px dashed #e0a800; outline-offset: -2px; }
#devTable.labels-editable .asset-cell:hover { background: #ffe69c; }
#devPropFilters .select2-container { font-size: .85rem; }

#nav-menu { flex: 1; padding: .5rem 0; }
#nav-menu .nav-link {
  display: flex; align-items: center;
  padding: .6rem 1.25rem; color: #9ba8bb; font-size: .9rem;
  transition: background .15s, color .15s;
}
#nav-menu .nav-link i { width: 1.4rem; text-align: center; }
#nav-menu .nav-link:hover { background: rgba(255,255,255,.06); color: #fff; }
#nav-menu .nav-link.active {
  background: rgba(110,168,254,.15); color: #6ea8fe;
  border-left: 3px solid #6ea8fe;
}

#sidebar-footer {
  padding: .75rem 1.25rem; border-top: 1px solid rgba(255,255,255,.08);
  font-size: .82rem; color: #6c7a93;
}
#sidebar-footer .user-email {
  color: #9ba8bb; font-size: .8rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Main content ───────────────────────────────────────────────────────────── */
#main-content { flex: 1; overflow-y: auto; background: #f4f6fb; padding: 1.75rem 2rem; }

/* The dashboard page fills the content area; 42px right gutter keeps content
   (toolbar buttons, chart fullscreen button) clear of the fixed 38px TECH bar. */
#main-content.dashboard-page { padding: 0 42px 0 0; overflow: hidden; display: flex; flex-direction: column; height: 100%; }
.dash-toolbar { padding: .6rem 1rem; border-bottom: 1px solid #dee2e6; background: #fff; }
.dash-body { flex: 1; display: flex; overflow: hidden; }
.dash-left { width: 300px; min-width: 300px; padding: 0 .75rem; background: #fff; }
.dash-right { flex: 1; padding: .5rem; }

/* Selected device in the Data list: Bootstrap paints the row blue. A customised
   label carries .text-primary (blue) and the meta lines .text-muted — force them
   readable on the blue background. */
.list-group-item.active .text-primary,
.list-group-item.active .fa-tag { color: #fff !important; }
.list-group-item.active .text-muted { color: rgba(255, 255, 255, .8) !important; }

/* ── Charts ─────────────────────────────────────────────────────────────────── */
.chart-widget { position: relative; height: 100%; }
.chart-widget canvas { height: 100% !important; width: 100% !important; }
.h-66 { height: 66.67% !important; }
.h-33 { height: 33.33% !important; }

/* ── Widget host (Data page): panes are sized by flex, not by a fixed height ──── */
.widget-host { min-height: 0; }
.widget-host > .widget-pane { min-height: 0; height: auto; border-bottom: 1px solid #dee2e6; }
.widget-host > .widget-pane:last-child { border-bottom: 0; }
.detected-bar { background: #f8f9fa; }

/* ── Device comparison ──────────────────────────────────────────────────────── */
.compare-swatch {
  display: inline-block; width: .7rem; height: .7rem; border-radius: 2px;
  margin-right: .35rem; vertical-align: -1px;
}
.list-group-item.compare-selected { background: #e7f1ff; }
/* The chart must be allowed to shrink (min-height:0) — otherwise the canvas at height:100%
   claims the whole pane and squeezes the stats table to nothing. */
.compare-chart { flex: 1 1 0; min-height: 0; }
/* The stats table keeps its natural height under the chart, and scrolls when long. */
.compare-stats { flex: 0 0 auto; max-height: 34%; overflow-y: auto; border-top: 1px solid #dee2e6; background: #fff; }
.compare-stats table { margin-bottom: 0; }
.compare-stats thead th { position: sticky; top: 0; background: #f8f9fa; z-index: 1; }

/* ── Map widget ─────────────────────────────────────────────────────────────── */
/* Leaflet stacks its own layers up to z-index 1000 (panes 400, controls 800, the
   control corners 1000). Without a stacking context of its own those numbers compete
   with the rest of the page: on mobile the zoom/layer controls painted straight over the
   device-list drawer (z-index 20). `isolation` confines them to this widget, so the map
   can never cover anything outside it — no matter what Leaflet does internally. */
.map-widget { isolation: isolate; }
.map-widget .leaflet-container { height: 100%; width: 100%; background: #eef1f4; }
.map-badge { position: absolute; left: 50%; transform: translateX(-50%); bottom: .5rem; z-index: 500; pointer-events: none; }
.map-pick-btn a,
.map-fs-btn a { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; color: #333; }
.map-pick-btn.active a { background: #0d6efd; color: #fff; }

/* ── Toast container ────────────────────────────────────────────────────────── */
#toast-container {
  position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 9999;
  display: flex; flex-direction: column; gap: .5rem;
}

/* ── Spinner overlay ────────────────────────────────────────────────────────── */
.page-spinner { display: flex; align-items: center; justify-content: center; padding: 4rem 0; }

/* ── Blocking loading overlay (bars spinner) ──────────────────────────────────── */
#app-loader {
  position: fixed; inset: 0; z-index: 3000;
  display: none; align-items: center; justify-content: center;
  background: rgba(255,255,255,.6);
}
#app-loader.show { display: flex; }
.loader-bars { display: flex; align-items: center; gap: 6px; height: 44px; }
.loader-bars span {
  display: block; width: 7px; height: 100%;
  background: #6ea8fe; border-radius: 2px;
  transform: scaleY(.3); transform-origin: center;
  animation: loader-bars 1s ease-in-out infinite;
}
.loader-bars span:nth-child(1) { animation-delay: -.9s; }
.loader-bars span:nth-child(2) { animation-delay: -.8s; }
.loader-bars span:nth-child(3) { animation-delay: -.7s; }
.loader-bars span:nth-child(4) { animation-delay: -.6s; }
.loader-bars span:nth-child(5) { animation-delay: -.5s; }
@keyframes loader-bars { 0%, 100% { transform: scaleY(.3); } 50% { transform: scaleY(1); } }

/* ── Mobile chrome (hidden on desktop) ────────────────────────────────────────── */
#mobile-topbar { display: none; }
#sidebar-backdrop { display: none; }
.mobile-brand { font-weight: 700; }

/* ── Mobile layout (≤768px). Desktop is unaffected. ───────────────────────────── */
@media (max-width: 768px) {
  /* Fixed top bar with hamburger */
  #mobile-topbar {
    display: flex; align-items: center; gap: .5rem;
    position: fixed; top: 0; left: 0; right: 0; height: 48px; z-index: 1035;
    background: #1a1f2e; color: #fff; padding: 0 .75rem;
  }
  #mobile-topbar .btn { color: #fff; font-size: 1.15rem; padding: .2rem .5rem; }
  #mobile-topbar .mobile-brand i { color: #6ea8fe; }

  /* Sidebar becomes a slide-in overlay (full nav, not the mini rail) */
  #sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 1050;
    width: 250px; min-width: 250px; margin-left: 0 !important;
    transform: translateX(-100%); transition: transform .2s ease;
  }
  body.sidebar-open #sidebar { transform: translateX(0); }
  #sidebar-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 1045; }
  body.sidebar-open #sidebar-backdrop { display: block; }
  #sidebar-handle, #sidebar-collapse-btn { display: none !important; }

  /* Content clears the fixed top bar */
  #main-content { padding: 48px .75rem .75rem; }
  #main-content.dashboard-page { padding: 48px 42px 0 0; }

  /* Data page: device list as a slide-in overlay over the chart */
  .dash-body { position: relative; }
  .dash-left {
    position: absolute; z-index: 20; top: 0; bottom: 0; left: 0;
    width: 86%; max-width: 320px; background: #fff;
    transform: translateX(-105%); transition: transform .2s ease;
    box-shadow: 2px 0 10px rgba(0,0,0,.25);
  }
  .dash-body.show-list .dash-left { transform: translateX(0); }
}

/* ── Mini map: "where is this device" affordance in device lists ──────────────
   The floating hover card carries its critical geometry inline (see
   dashboard/miniMap.js) so it is usable even before this file loads; what is
   here is the polish. */
.mini-map-icon {
  color: #6c757d;
  line-height: 1;
  text-decoration: none;
}
.mini-map-icon:hover,
.mini-map-icon:focus-visible { color: #0d6efd; }

.mini-map-hover {
  /* Above the Data page's device-list overlay (z-index 20) and Bootstrap's
     offcanvas backdrop, below a modal — a hover card must never cover a dialog. */
  box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .18);
}
.mini-map-hover-foot {
  font-size: .75rem;
  padding: .2rem .4rem;
  color: #6c757d;
  border-top: 1px solid #dee2e6;
  display: flex; gap: .4rem; justify-content: space-between; align-items: center;
}
.mini-map-hover .leaflet-container { background: #f8f9fa; }

/* Source badge in the devices table (loriot / teltonika / …) — muted on purpose:
   it is provenance, not a headline. */
.dev-source-badge { font-size: .7rem; }

/* A sensor's map is a reference, not a measurement: it renders as a ~200px strip (see
   widgets/host.js). At that height Leaflet's default chrome eats a noticeable share of
   the map, so it steps back — the controls stay usable, they just stop shouting. */
.widget-compact .leaflet-control-attribution { font-size: .62rem; opacity: .75; }
.widget-compact .leaflet-control-zoom a { width: 22px; height: 22px; line-height: 22px; }
