/*
 * Board layout grid.
 *
 * Self-contained so it does not depend on which col-span utilities happen to be
 * compiled into nexus.css (that frozen build omits lg:col-span-6/9/12). Used by
 * the board builder canvas and by rendered board panels on the dashboard.
 */

.board-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.board-grid--tight {
  gap: 1rem;
}

/* Compact board density: shorter charts, tighter tile chrome. Applied on the
 * board grid when Board#density is "compact" (Command Centre default). */
.board-density-compact {
  gap: 0.5rem;
}

.board-chart-wrap {
  height: 320px;
}

.board-chart-wrap--compact {
  height: 120px;
}

/* Viewport-fit: chart band shares the screen instead of a fixed px stack.
 * Used with compact density so three trend tiles don't force page scroll. */
.board-fit-viewport .board-chart-wrap--compact {
  height: min(7.5rem, 16vh);
  max-height: 16vh;
}

/* Water Quality: taller columns beside Alerts (not short stacked strips). */
.board-fit-viewport .widget-water-quality .board-chart-wrap--compact,
.board-density-compact .widget-water-quality .board-chart-wrap--compact {
  height: min(16rem, 32vh);
  max-height: 32vh;
  min-height: 11rem;
}

@media (max-width: 767px) {
  .board-fit-viewport .widget-water-quality .board-chart-wrap--compact,
  .board-density-compact .widget-water-quality .board-chart-wrap--compact {
    height: min(10rem, 22vh);
    max-height: 22vh;
    min-height: 8rem;
  }
}


/* Command Centre bands (docs/design/README.md §Screens).
   Three equal-ish columns: Status and KPIs span all three; WQ spans the
   first two beside a single-column Alerts rail; the band-3 row gives
   Overview (the flow diagram) the extra 0.05fr because its five nodes
   set the floor width. */
@media (min-width: 1024px) {
  /* Qualified with .board-grid deliberately. The generic `.board-grid`
     12-column rule further down this file has the same single-class
     specificity and sits later, so an unqualified selector here loses
     grid-template-columns to it while still winning grid-template-areas —
     a 12-column grid whose named areas cover only the first 3 columns,
     squeezing every band into a quarter of the width. */
  .board-grid.board-grid--command-centre {
    display: grid;
    gap: var(--cc-band-gap, 14px);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr) minmax(0, 1fr);
    grid-template-areas:
      "status status   status"
      "wq     wq       alerts"
      "corr   overview tasks"
      "kpis   kpis     kpis";
    align-items: stretch;
  }

  .board-grid--command-centre > [data-board-area="status"]   { grid-area: status; }
  .board-grid--command-centre > [data-board-area="wq"]       { grid-area: wq; }
  .board-grid--command-centre > [data-board-area="alerts"]   { grid-area: alerts; }
  .board-grid--command-centre > [data-board-area="corr"]     { grid-area: corr; }
  .board-grid--command-centre > [data-board-area="overview"] { grid-area: overview; }
  .board-grid--command-centre > [data-board-area="tasks"]    { grid-area: tasks; }
  .board-grid--command-centre > [data-board-area="kpis"]     { grid-area: kpis; }

  /* Stretch Alerts card to the Water Quality row height — fills the dead zone. */
  .board-grid--command-centre > [data-board-area="alerts"] > .card,
  .board-grid--command-centre > [data-board-area="wq"] > .card {
    height: 100%;
    display: flex;
    flex-direction: column;
  }

  .board-grid--command-centre > [data-board-area="alerts"] .card-body,
  .board-grid--command-centre > [data-board-area="wq"] .card-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .board-grid--command-centre > [data-board-area="wq"] .widget-water-quality {
    flex: 1 1 auto;
  }

  /* Stretch chain: card-body → widget wrapper → turbo-frame → panel → list.
     Every link needs min-height:0 or the scroll container never shrinks. */
  .board-grid--command-centre > [data-board-area="alerts"] .card-body > div:last-child,
  .board-grid--command-centre > [data-board-area="alerts"] turbo-frame,
  .board-grid--command-centre > [data-board-area="alerts"] .widget-alerts-panel {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .board-grid--command-centre > [data-board-area="alerts"] .widget-alerts {
    flex: 1 1 auto;
    max-height: none;
    min-height: 0;
    overflow-y: auto;
  }

  .board-grid--command-centre > [data-board-area="overview"] > .card,
  .board-grid--command-centre > [data-board-area="corr"] > .card,
  .board-grid--command-centre > [data-board-area="tasks"] > .card {
    height: 100%;
  }
}

.board-fit-viewport .widget-scatter-placeholder {
  height: min(4rem, 10vh);
}

/* Proportional board scale (CSS zoom). Fixed scales set --board-scale server-side;
 * Fit mode starts at 1 and board-viewer overwrites --board-scale from viewport math. */
.board-scale-85,
.board-scale-75,
.board-scale-fit {
  zoom: var(--board-scale, 1);
}

.board-scale-fit {
  --board-scale: 1;
  overflow: hidden;
}

/* Fit isn't holding everything on one screen — either it hit the legibility
 * floor (MIN_FIT_SCALE) or the viewport is too narrow to zoom at all. Stop
 * clipping; the page scrolls. */
.board-scale-fit.board-scale-fit--scrolls {
  overflow: visible;
}


.board-panel__body--compact {
  padding: 0.5rem 0.75rem !important;
  gap: 0;
}

.board-panel--compact .card-body > .flex {
  gap: 0.35rem;
}

.board-density-compact .widget-status-tile {
  min-height: 0;
  padding: 0.35rem 0.5rem;
}

.board-density-compact .widget-status-tile__label {
  font-size: 0.65rem;
}

.board-density-compact .widget-status-tile__value {
  font-size: 0.9375rem;
  margin-top: 0.1rem;
  line-height: 1.2;
}

.board-density-compact .widget-status-tile__meta {
  margin-top: 0.1rem;
  font-size: 0.65rem;
}

.board-density-compact .widget-status-strip {
  gap: 0.35rem;
}

.board-density-compact .widget-alert-row {
  padding: 0.25rem 0.4rem;
  gap: 0.4rem;
}

.board-density-compact .widget-alert-row__message {
  font-size: 0.75rem;
}

/* Fits COMPACT_LIMIT rows at the field-ready 40px ack target (54px pitch),
   so the 5th alert isn't hidden exactly when every row needs acknowledging. */
.board-density-compact .widget-alerts {
  gap: 0.25rem;
  max-height: 17.5rem;
  overflow-y: auto;
}

.board-density-compact .widget-flow-stage {
  padding: 0.35rem 0.5rem;
  min-width: 5.5rem;
  flex-basis: 5.5rem;
}

.board-density-compact .widget-flow-stages {
  gap: 0.25rem;
}

.board-density-compact .widget-kpi-strip,
.board-density-compact .widget-metrics-grid,
.board-density-compact .widget-correlation-grid {
  gap: 0.35rem;
}

.board-density-compact .widget-scatter-placeholder {
  height: 5rem;
}

@media (min-width: 1024px) {
  .board-grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }

  .board-span-full       { grid-column: span 12 / span 12; }
  .board-span-two-thirds { grid-column: span 8 / span 8; }
  .board-span-half       { grid-column: span 6 / span 6; }
  .board-span-third      { grid-column: span 4 / span 4; }
  .board-span-quarter    { grid-column: span 3 / span 3; }

  .board-builder-main   { grid-column: span 9 / span 9; }
  .board-builder-drawer { grid-column: span 3 / span 3; }
}

/* Keep each tile's content from forcing the grid track wider than its share. */
.board-grid > * {
  min-width: 0;
}

/* ── Builder: workspace, tiles, drawer (boards/_form.html.erb) ───────────── */

/* Secondary text. Slightly toward ink from the app's 60% habit so 14px prose
 * still clears the contrast bar, while staying clearly muted under primary text. */
.board-muted {
  color: color-mix(in oklch, var(--color-base-content) 68%, transparent);
}

/* Template picker modal — avoid Tailwind flex-1 (missing from nexus.css). */
.board-template-picker__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1.25rem 1.25rem 1rem;
}

.board-template-picker__copy {
  min-width: 0;
  flex: 1 1 auto;
}

.board-template-picker__close {
  flex: 0 0 auto;
  margin: -0.25rem -0.25rem 0 0;
}

.board-template-picker__list {
  border-top: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
  max-height: min(24rem, 60vh);
  overflow-y: auto;
}

.board-template-picker__row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
}

.board-template-picker__list > .board-template-picker__row:first-child {
  border-top: 0;
}

.board-template-picker__icon {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.5rem;
  background-color: var(--color-base-200);
  display: flex;
  align-items: center;
  justify-content: center;
}

.board-template-picker__action {
  flex: 0 0 auto;
}

/* The canvas is a workspace surface, not a card — tiles are the cards on it. */
.board-canvas {
  background-color: var(--color-base-200);
  background-image: radial-gradient(
    color-mix(in oklch, var(--color-base-content) 8%, transparent) 1px,
    transparent 1px
  );
  background-size: 18px 18px;
  background-position: -9px -9px;
  border: 1px solid var(--color-base-300);
  border-radius: var(--radius-box, 1rem);
  padding: 1.25rem;
  min-height: 18rem;
}

.board-canvas-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 3rem 1rem;
  text-align: center;
}

.board-tile {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  background-color: var(--color-base-100);
  border: 1px solid var(--color-base-300);
  border-radius: var(--radius-box, 0.75rem);
  padding: 0.75rem 0.875rem;
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.06);
  transition: box-shadow 160ms ease, border-color 160ms ease;
}

.board-tile:hover {
  border-color: color-mix(in oklch, var(--color-base-content) 22%, transparent);
  box-shadow: 0 6px 16px rgb(0 0 0 / 0.14);
}

.board-drawer {
  background-color: var(--color-base-200);
  border: 1px solid var(--color-base-300);
  border-radius: var(--radius-box, 1rem);
  padding: 1rem;
}

.board-drawer-list {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  max-height: 30rem;
  overflow-y: auto;
}

.board-drawer-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem;
  border-radius: var(--radius-field, 0.5rem);
  transition: background-color 140ms ease;
}

.board-drawer-row:hover {
  background-color: var(--color-base-300);
}

.board-drawer-row[data-added="true"] {
  opacity: 0.4;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .board-tile,
  .board-drawer-row {
    transition: none;
  }
}

/* Graph/widget panel states: skeleton (loading), empty-with-action (no data
 * in window). Theme-agnostic baseline — Command Centre re-tints these same
 * classes under [data-theme="command-centre"] in command_centre_widgets.css
 * (higher specificity there wins on that theme); everywhere else, including
 * the flag off, this is what renders. Without this, unflagged pages lose all
 * empty-state styling the moment the flagged markup replaced the old
 * inline-Tailwind-utility overlay it used to carry its own look. */
/* :not(.hidden) is required: this file is unlayered, so display:flex here
 * beats Tailwind's layered `.hidden { display: none }` even at equal
 * specificity. graph-viewer toggles visibility by adding `.hidden`; without
 * the gate, the empty copy stays on screen under a populated chart. */
/* position: absolute; inset: 0 restores what the inline-Tailwind overlay this
 * replaced carried (`absolute inset-0 flex items-center justify-center`).
 * Without it .cc-empty/.cc-skeleton are ordinary in-flow siblings of the
 * canvas inside a fixed-height .board-chart-wrap (320px, 120px compact) —
 * nothing collapses the canvas, so an empty/loading chart renders a
 * full-height canvas PLUS this block stacked below it, overflowing the wrap
 * (worse on the 120px compact height, which the block alone can exceed). */
.cc-empty:not(.hidden) {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 12px;
  font-size: 0.8125rem;
  color: color-mix(in oklch, var(--color-base-content) 68%, transparent);
  text-align: center;
}
.cc-empty__action {
  font-size: 0.75rem;
  border: 1px solid color-mix(in oklch, var(--color-primary) 40%, transparent);
  color: var(--color-primary);
  border-radius: var(--radius-field, 0.5rem);
  padding: 4px 10px;
  background: transparent;
  cursor: pointer;
  min-height: 2rem;
}

/* Same absolute-overlay restoration as .cc-empty above, and for the same
 * reason: without it the skeleton is an in-flow block stacked under the
 * full-height canvas during connect -> first payload, not an overlay on it. */
.cc-skeleton:not(.hidden) { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px; padding: 8px 0; }
.cc-skeleton span {
  display: block;
  height: 10px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--color-base-200), var(--color-base-300), var(--color-base-200));
  background-size: 200% 100%;
  animation: cc-shimmer 1.4s linear infinite;
}
.cc-skeleton span:nth-child(2) { width: 70%; }
.cc-skeleton span:nth-child(3) { width: 45%; }

/* Global by nature — @keyframes are never scoped by an ancestor selector, so
 * this single definition already serves both the baseline skeleton above and
 * Command Centre's re-tinted one (command_centre_widgets.css references the
 * same name rather than redefining it). */
@keyframes cc-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cc-skeleton span { animation: none; }
}
