/* CHANGE-016 Spec-AC-010: highlight currently selected variant rows in the
 * Optimization Results stats table. The className `por-stats-row--selected` is
 * applied server-side for the initial (top) row and toggled by the checkbox
 * clientside callback (see src/pages/planner_optimization.py). */

tr.por-stats-row--selected {
  background: rgba(64, 176, 135, 0.10);
  outline: 1px solid var(--mantine-color-feramat-green-6, #40b087);
}

tr.por-stats-row--selected > td {
  background: transparent;
}

/* CHANGE-016 (revised 2026-04-22): "loading" state for the stats table and
 * graphs container. Applied as a className on POR_STATS / POR_GRAPHS by the
 * clientside callbacks in src/pages/planner_optimization.py while the server
 * recomputes. The server's Stats.update() / Graphs.update() clears the class
 * when they set new children, so the dim state ends automatically when content
 * arrives.
 *
 * Design: hide existing content completely (user preference: "blank and
 * empty" while loading, not a dimmed ghost of stale content) and show a
 * centered spinner on the container itself via a ::after pseudo-element.
 * Children get opacity: 0 instead of visibility: hidden so they still
 * contribute to layout — the container keeps its size, and the spinner lands
 * in the visual center of where content used to be.
 */
.por-loading {
  position: relative;
  pointer-events: none;
  min-height: 120px;
}

.por-loading > * {
  opacity: 0;
  transition: opacity 0.08s ease-out;
}

.por-loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 42px;
  height: 42px;
  margin: -21px 0 0 -21px;
  border: 3px solid var(--mantine-color-feramat-green-6, #40b087);
  border-top-color: transparent;
  border-radius: 50%;
  animation: por-loading-spin 0.8s linear infinite;
  pointer-events: none;
}

@keyframes por-loading-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Checkbox-specific graph loading states.
 * - add-top / add-bottom: keep current graph(s) visible and show a loader
 *   where the NEW graph will appear
 * - slot-top / slot-bottom: hide the existing slot that is being removed or
 *   replaced and show the loader in its place
 */
.por-loading-add-top,
.por-loading-add-bottom,
.por-loading-slot-top,
.por-loading-slot-bottom {
  position: relative;
  pointer-events: none;
}

.por-loading-slot-top .por-graph-slot--top,
.por-loading-slot-bottom .por-graph-slot--bottom {
  position: relative;
}

.por-loading-slot-top .por-graph-slot--top > *,
.por-loading-slot-bottom .por-graph-slot--bottom > * {
  opacity: 0;
  transition: opacity 0.08s ease-out;
}

.por-loading-add-top::after,
.por-loading-add-bottom::after,
.por-loading-slot-top .por-graph-slot--top::after,
.por-loading-slot-bottom .por-graph-slot--bottom::after {
  content: '';
  position: absolute;
  left: 50%;
  width: 42px;
  height: 42px;
  border: 3px solid var(--mantine-color-feramat-green-6, #40b087);
  border-top-color: transparent;
  border-radius: 50%;
  animation: por-loading-spin 0.8s linear infinite;
  z-index: 2;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 0 0 8px rgba(255, 255, 255, 0.92);
  pointer-events: none;
}

.por-loading-add-top::after {
  top: 25%;
  margin: -21px 0 0 -21px;
}

.por-loading-add-bottom::after {
  top: 75%;
  margin: -21px 0 0 -21px;
}

.por-loading-slot-top .por-graph-slot--top::after,
.por-loading-slot-bottom .por-graph-slot--bottom::after {
  top: 50%;
  margin: -21px 0 0 -21px;
}

.por-graph-slot {
  min-height: 460px;
  position: relative;
}

.por-graph-slot--top,
.por-graph-slot--bottom {
  transition: opacity 0.08s ease-out;
}
