/* ============================================================
   Page: Operator Dashboard — 360eDash
   Styles for pages/operator/operator-dashboard.html.
   Reuses the shared design tokens (--primary, --border, --surface,
   --ink, --muted, --page-bg) already defined globally by
   css/admin-view.css and swapped for dark mode by
   css/dark-mode-v8.css, and the .pm-tabs tab-bar component from
   css/project-monitoring.css so this page matches Project
   Monitoring's look.
============================================================= */

.opd-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-family: 'Poppins', sans-serif;
  color: var(--ink, #25343F);
}
.opd-page * { box-sizing: border-box; }

/* Title left, search + "Add Graph" right, aligned on the same row.
   This was missing its layout rule (elements were falling back to
   default block stacking), which is why the search bar / "Add
   Graph" button appeared to "disappear" from their intended spot
   next to the title. */
.opd-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.opd-head-text {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.opd-head-text .opd-title {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink, #25343F);
}

/* ---------- Today's date badge (next to the "Dashboard" title) ---------- */
.opd-date-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border: 1px solid var(--border, #e7edee);
  border-radius: 10px;
  background: var(--surface, #fff);
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  font-size: 13px;
  font-weight: 500;
  color: var(--muted, #7c8b8d);
  white-space: nowrap;
}
.opd-date-badge i {
  color: var(--primary, #0f6a71);
  font-size: 13px;
}

/* ---------- Environmental Impact — compact variant ----------
   Shrinks the text (title, labels, captions) and tightens spacing so
   the colored icon becomes the strongest visual element in each
   mini-card, instead of the numbers/copy competing for attention.
   Scoped to this page only (.opd-env-compact) so the Project
   Overview admin card, which reuses the same .pd-env-* classes,
   keeps its original size. */
.opd-env-compact {
  padding: 14px 16px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e7edee);
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
}
.opd-env-compact .pd-card-head {
  margin-bottom: 8px;
}
.opd-env-compact .pd-card-head h2 {
  font-size: 12.5px;
  gap: 6px;
  color: var(--ink, #25343f);
}
.opd-env-compact .pd-card-head h2 i {
  font-size: 11px;
  color: var(--primary, #0f6a71);
}
.opd-env-compact .pd-card-head p {
  font-size: 10.5px;
  margin-top: 1px;
  color: var(--muted, #7c8b8d);
}
.opd-env-compact .pd-env-grid {
  gap: 10px;
  margin-top: 0;
}
.opd-env-compact .pd-env-card {
  padding: 10px 8px;
  border-radius: 10px;
}
.opd-env-compact .pd-env-icon {
  width: 32px;
  height: 32px;
  margin: 0 auto 8px;
  font-size: 14px;
}
.opd-env-compact .pd-env-value {
  font-size: 16px;
}
.opd-env-compact .pd-env-value small {
  font-size: 10px;
}
.opd-env-compact .pd-env-label {
  font-size: 10px;
  margin-top: 2px;
}
.opd-env-compact .pd-env-sub {
  font-size: 9px;
  margin-top: 2px;
}
.opd-env-compact .pd-env-arrow {
  font-size: 12px;
  color: var(--border, #e7edee);
}

/* Mini-cards now keep their per-type tint (amber/blue/green — see
   css/project-detail.css .pd-env-card.is-*) against a plain white
   outer card, instead of a single flat teal tone against a solid
   teal card. Text stays the app's normal ink/muted tokens since the
   background is light now, not a dark teal that needed light text. */
.opd-env-compact .pd-env-value {
  color: var(--ink, #25343f);
}
.opd-env-compact .pd-env-value small {
  color: var(--muted, #7c8b8d);
}
.opd-env-compact .pd-env-label {
  color: var(--ink, #25343f);
}
.opd-env-compact .pd-env-sub {
  color: var(--muted, #7c8b8d);
}

/* ---------- Fullscreen toggle (page content only, no header/sidebar) ----------
   Icon-only, pinned bottom-right, filled with the app's primary
   teal so it reads as an action button. Targets `.edash-content` —
   the scrollable main-content region, a sibling of #header-root and
   outside #sidebar-root — with the native Fullscreen API (see
   js/operator/operator-dashboard.js), so both the header and the
   sidebar are naturally excluded. Rounded-square, not a circle. */
.opd-fullscreen-fab {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 46px;
  height: 46px;
  border: none;
  border-radius: 12px;
  background: var(--primary, #0f6a71);
  color: #fff;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(15, 106, 113, 0.35);
  z-index: 40;
  transition: background 0.15s ease;
}
.opd-fullscreen-fab:hover {
  background: var(--primary-dark, #0b4f54);
}

/* While `.edash-content` is the fullscreen element, keep the page
   background instead of the browser's default black backdrop. */
.edash-content:fullscreen {
  background: var(--page-bg, #f4f7f7);
  padding: 24px;
}
html[data-theme="dark"] .edash-content:fullscreen {
  background: #101b1f;
}

/* ---------- Search bar ----------
   No outer card: the pill itself carries the border/background and
   stretches to fill the row, pushing "Add Graph" to the far right
   edge on the same line. */
.opd-search-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  flex: 1 1 420px;
  max-width: 520px;
  margin-left: auto;
}
.opd-search {
  position: relative;
  flex: 1 1 auto;
  min-width: 180px;
}
.opd-search i {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 13px;
  color: var(--muted, #7c8b8d);
  pointer-events: none;
}
.opd-search input {
  width: 100%;
  font-family: inherit;
  border: 1px solid var(--border, #e7edee);
  border-radius: 999px;
  padding: 10px 16px 10px 36px;
  font-size: 13.5px;
  color: var(--ink, #25343F);
  background: var(--surface, #fff);
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  outline: none;
}
.opd-search input:focus {
  border-color: var(--primary, #0f6a71);
  box-shadow: 0 0 0 3px var(--primary-soft, #e4f1f1);
}

/* ---------- Shared button ---------- */
.opd-btn {
  border: none;
  border-radius: 999px;
  padding: 10px 18px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.15s ease;
}
.opd-btn-primary {
  background: var(--primary, #0f6a71);
  color: #fff;
}
.opd-btn-primary:hover {
  background: var(--primary-dark, #0b4f54);
}

/* ---------- Card grid ----------
   Flex-wrap instead of a fixed-column grid: cards keep a consistent
   size and simply wrap to a new row once the current row runs out
   of space, exactly like the wireframe. */
.opd-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.opd-card,
.opd-card-add {
  width: 220px;
  height: 150px;
  border-radius: 14px;
  flex-shrink: 0;
}

.opd-card {
  position: relative;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e7edee);
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  padding: 12px;
}
.opd-card-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted, #7c8b8d);
}
.opd-card-remove {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 7px;
  background: var(--page-bg, #f4f7f7);
  color: var(--muted, #7c8b8d);
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.opd-card:hover .opd-card-remove {
  opacity: 1;
}
.opd-card-remove:hover {
  background: var(--danger-soft, #fbe9e9);
  color: var(--danger, #d64545);
}

/* Empty add-card tile: dashed border, centered + icon */
.opd-card-add {
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1.5px dashed var(--border, #e7edee);
  color: var(--muted, #7c8b8d);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.opd-card-add i {
  font-size: 20px;
}
.opd-card-add:hover {
  background: var(--primary-soft, #e4f1f1);
  border-color: var(--primary, #0f6a71);
  color: var(--primary-dark, #0b4f54);
}

/* ---------- Chart cards ----------
   Sized so exactly 3 fit per row (grid gap is 16px, so each card
   takes up the remaining space after 2 gaps, divided by 3). Taller
   than the blank/add tiles too, so the Chart.js canvas has real
   room to render in. Falls back to 2-per-row then 1-per-row on
   narrower screens (see media queries below). */
.opd-card-chart {
  width: calc((100% - 32px) / 3);
  min-width: 300px;
  height: 430px;
  display: flex;
  flex-direction: column;
}
.opd-card-chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-right: 26px; /* keep clear of the remove (x) button */
}
.opd-card-chart-head .opd-card-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink, #25343F);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.opd-card-chart-meta {
  font-size: 11px;
  color: var(--muted, #7c8b8d);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.opd-card-chart-body {
  flex: 1;
  position: relative;
  margin-top: 8px;
  min-height: 0;
}
.opd-card-chart-body canvas {
  width: 100% !important;
  height: 100% !important;
}
.opd-card-chart-legend {
  margin-top: 8px;
}

/* Period toggle (24 Hours / 7 Days / 30 Days / Custom) + refresh,
   date-range fields and compact stat chips for saved chart cards —
   mirrors the equivalent System Information chart widget (see
   css/system-information.css .si-chart-toggle etc.) but sized to fit
   inside the smaller dashboard card. */
.opd-card-period-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 8px;
}
.opd-card-period-toggle {
  display: flex;
  flex-wrap: wrap;
  background: var(--page-bg, #f4f7f7);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
  min-width: 0;
}
.opd-card-period-toggle button {
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  padding: 4px 6px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--muted, #7c8b8d);
  cursor: pointer;
  transition: all 0.15s ease;
  white-space: nowrap;
}
.opd-card-period-toggle button.is-active {
  background: var(--surface, #fff);
  color: var(--primary-dark, #0b4f54);
  box-shadow: 0 1px 4px rgba(15,106,113,0.18);
}
.opd-card-period-toggle button i {
  margin-right: 2px;
}
.opd-card-refresh-btn {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border, #e7edee);
  background: var(--surface, #fff);
  color: var(--muted, #7c8b8d);
  border-radius: 7px;
  cursor: pointer;
  font-size: 11px;
}
.opd-card-refresh-btn:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.opd-card-refresh-btn:not(:disabled):hover {
  border-color: var(--primary, #0f6a71);
  color: var(--primary, #0f6a71);
}

.opd-card-daterange {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.opd-card-daterange-field {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.opd-card-daterange-field label {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--muted, #7c8b8d);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.opd-card-daterange-field input[type="date"] {
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink, #25343f);
  border: 1px solid var(--border, #e7edee);
  border-radius: 7px;
  padding: 4px 6px;
  background: var(--surface, #fff);
  width: 100%;
  box-sizing: border-box;
}

.opd-card-stats-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
  min-height: 0;
}
.opd-card-stat-chip {
  display: flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--border, #e7edee);
  background: var(--surface, #fff);
  border-radius: 8px;
  padding: 3px 7px;
  max-width: 100%;
  overflow: hidden;
}
.opd-card-stat-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.opd-card-stat-label {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--ink, #25343f);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.opd-card-stat-minmax {
  font-size: 9.5px;
  color: var(--muted, #7c8b8d);
  white-space: nowrap;
}
.opd-card-stat-empty {
  font-size: 10.5px;
  color: var(--muted, #7c8b8d);
}

.opd-grid-empty-hint {
  font-size: 12.5px;
  color: var(--muted, #7c8b8d);
  padding: 4px 2px;
}

@media (max-width: 480px) {
  .opd-search {
    flex: 1 1 100%;
  }
  .opd-btn {
    flex: 1 1 100%;
  }
}

@media (max-width: 980px) {
  .opd-card-chart {
    width: calc((100% - 16px) / 2);
    min-width: 260px;
    height: 430px;
  }
}
@media (max-width: 620px) {
  .opd-card-chart {
    width: 100%;
    min-width: 0;
    height: 380px;
  }
  .opd-card-period-toggle button {
    font-size: 9px;
    padding: 4px 5px;
  }
}

/* ============================================================
   "Buat grafik" modal (Add Graph)
   Reuses the shared .modal-backdrop / .modal-card / .modal-btn /
   .modal-input components from css/alert.css — only the two-pane
   variable-picker + chart-builder layout below is page-specific.
   All classes are prefixed .opd-graph- so nothing here leaks onto
   other pages' cards/fields/buttons.
============================================================= */
.opd-graph-modal .modal-card {
  max-width: 1120px;
}
.opd-graph-modal-scroll {
  display: flex;
  flex-direction: column;
}

.opd-graph-subtitle {
  margin: 2px 0 0;
  font-size: 11.5px;
  color: var(--muted, #7c8b8d);
}

.opd-graph-device-switch {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}
.opd-graph-device-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted, #7c8b8d);
}
.opd-graph-divider {
  height: 1px;
  background: var(--border, #e7edee);
  margin: 14px 0 16px;
}

.opd-graph-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  align-items: start;
  gap: 22px;
}

/* ---- left: variable picker ----
   Height is set inline (in JS, via syncVarPanelHeight) to match the
   right column's actual rendered height — title through the caption
   under the chart — every time that height changes (variables
   toggled, chart type switched, device group changed). That keeps
   the two panels flush with no blank gap at the bottom of either
   side. align-items:start on the grid (instead of stretch) is what
   lets the left column stop short at that JS-set height rather than
   being pulled down to match the taller natural content of its own
   long variable list. overflow-y:auto gives it its own independent
   scrollbar for whatever doesn't fit — separate from the outer
   .modal-scroll — so scrolling the list never scrolls the whole
   modal. The px value below is just a same-as-before fallback for
   the instant before JS runs. */
.opd-graph-var-panel {
  max-height: 460px;
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
  padding-right: 8px;
}
.opd-graph-var-category {
  margin-bottom: 16px;
}
.opd-graph-cat-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted, #7c8b8d);
  margin: 0 0 8px 2px;
}
.opd-graph-var-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border, #e7edee);
  border-radius: 10px;
  padding: 8px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  user-select: none;
}
.opd-graph-var-row:hover {
  border-color: var(--primary-header, #6dc3bb);
}
.opd-graph-var-row.is-checked {
  border-color: var(--primary, #0f6a71);
  background: var(--primary-soft, #e4f1f1);
}
.opd-graph-var-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--primary, #0f6a71);
  flex-shrink: 0;
  cursor: pointer;
}
.opd-graph-var-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.opd-graph-var-label {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink, #25343f);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.opd-graph-var-unit {
  font-size: 11.5px;
  color: var(--muted, #7c8b8d);
  white-space: nowrap;
}

/* ---- right: chart builder ---- */
.opd-graph-chart-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.opd-graph-field-row {
  display: flex;
  gap: 16px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.opd-graph-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.opd-graph-field-title {
  flex: 1;
  min-width: 0;
}
.opd-graph-field label {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink, #25343f);
}
.opd-graph-field-chart-type {
  flex: 0 0 auto;
}

.opd-graph-segmented {
  display: inline-flex;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border, #e7edee);
}
.opd-graph-seg-btn {
  border: none;
  background: var(--surface, #fff);
  padding: 8px 16px;
  font-size: 13.5px;
  font-weight: 500;
  font-family: inherit;
  color: var(--muted, #7c8b8d);
  cursor: pointer;
}
.opd-graph-seg-btn.is-active {
  background: var(--primary, #0f6a71);
  color: #fff;
  font-weight: 600;
}

.opd-graph-preview-label {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink, #25343f);
  margin: 18px 0 8px;
}

.opd-graph-stats-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 0;
}
.opd-graph-stat-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border, #e7edee);
  background: var(--surface, #fff);
  border-radius: 10px;
  padding: 6px 10px;
}
.opd-graph-stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.opd-graph-stat-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted, #7c8b8d);
  white-space: nowrap;
}
.opd-graph-stat-now {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink, #25343f);
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: 20px;
}
.opd-graph-stat-minmax {
  font-size: 10.5px;
  color: var(--muted, #7c8b8d);
  white-space: nowrap;
  border-left: 1px solid var(--border, #e7edee);
  padding-left: 7px;
  margin-left: 1px;
}

.opd-graph-preview-box {
  border: 1px solid var(--border, #e7edee);
  border-radius: 14px;
  padding: 18px 14px 10px;
  min-height: 280px;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface, #fff);
  position: relative;
  margin-top: 10px;
}
.opd-graph-preview-box canvas {
  width: 100% !important;
  height: 270px !important;
}

.opd-graph-empty-state {
  text-align: center;
  max-width: 340px;
  width: 100%;
  box-sizing: border-box;
  margin: 0 auto;
  color: var(--muted, #7c8b8d);
  padding: 10px;
}
.opd-graph-empty-icon {
  font-size: 30px;
  margin-bottom: 6px;
  opacity: 0.6;
}
.opd-graph-empty-state p {
  margin: 4px 0;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink, #25343f);
}
.opd-graph-empty-sub {
  font-size: 11.5px;
  font-weight: 400;
  color: var(--muted, #7c8b8d);
  line-height: 1.6;
}

.opd-graph-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  margin-top: 10px;
  min-height: 18px;
}
.opd-graph-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink, #25343f);
}
.opd-graph-legend-item .opd-graph-legend-ring {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 2.5px solid;
  background: var(--surface, #fff);
}

.opd-graph-preview-caption {
  font-size: 11.5px;
  color: var(--muted, #7c8b8d);
  text-align: center;
  margin: 10px 0 0;
  line-height: 1.6;
}

.opd-graph-actions {
  border-top: 1px solid var(--border, #e7edee);
  padding-top: 14px;
}

.opd-graph-var-panel::-webkit-scrollbar {
  width: 7px;
}
.opd-graph-var-panel::-webkit-scrollbar-thumb {
  background: var(--border, #e7edee);
  border-radius: 10px;
}

@media (max-width: 760px) {
  .opd-graph-body {
    grid-template-columns: minmax(0, 1fr);
  }
  .opd-graph-var-panel {
    max-height: 220px;
}
}