/* dashboard-grid.css — standalone. Sole owner of `.dg-*`.
 *
 * Ported from redpash-rust-pwa `origin/lean`,
 * frontend/framework/dashboard-grid/dashboard-grid.css, with every
 * redpash framework token (--rp-*) replaced by a locally-defined --dg-*
 * custom property so this file stands on its own.
 *
 * Knobs (all overridable on `.dg` or any ancestor):
 *   --dg-cols / --dg-rows   canvas size in cells (JS sets these inline)
 *   --dg-cell-size          row height; also the width a cell reaches at
 *                           the canvas's max-width, making cells square
 *   --dg-gap                gutter between cells
 *   --dg-surface --dg-border --dg-text --dg-text-mute
 *   --dg-accent --dg-danger --dg-radius --dg-radius-sm
 */

.dg {
  --dg-cols: 15;
  --dg-rows: 10;
  --dg-cell-size: 56px;
  --dg-gap: 6px;
  --dg-radius: 10px;
  --dg-radius-sm: 6px;
  --dg-surface: #ffffff;
  --dg-surface-2: #f6f7f9;
  --dg-border: #d7dbe0;
  --dg-text: #1b1f24;
  --dg-text-mute: #6b7280;
  --dg-accent: #6366f1;
  --dg-danger: #c62a2f;
  --dg-danger-bg: #fdf1f1;
  --dg-danger-border: #f0c2c3;
  --dg-glass: rgba(255, 255, 255, 0.86);

  display: grid;
  grid-template-columns: repeat(var(--dg-cols), minmax(0, 1fr));
  grid-template-rows: repeat(var(--dg-rows), var(--dg-cell-size));
  gap: var(--dg-gap);
  width: 100%;
  max-width: calc(var(--dg-cols) * (var(--dg-cell-size) + var(--dg-gap)));
  color: var(--dg-text);
  font: 13px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Lean's original sizing: rows as fractions of a fixed aspect box, so
   cols:rows = 3:2 gives square cells at any width. Opt in with `dg--aspect`. */
.dg.dg--aspect {
  grid-template-rows: repeat(var(--dg-rows), minmax(0, 1fr));
  aspect-ratio: var(--dg-cols) / var(--dg-rows);
  max-width: none;
  max-height: 80vh;
}

@media (prefers-color-scheme: dark) {
  .dg {
    --dg-surface: #191c20;
    --dg-surface-2: #23272d;
    --dg-border: #3a4048;
    --dg-text: #e8eaed;
    --dg-text-mute: #9aa3ad;
    --dg-danger: #ff8b8e;
    --dg-danger-bg: #2b1b1c;
    --dg-danger-border: #5c3234;
    --dg-glass: rgba(25, 28, 32, 0.86);
  }
}

/* Editable: a faint cell-grid backdrop so placement reads clearly. */
.dg.is-editable {
  background-image:
    linear-gradient(to right, var(--dg-border) 1px, transparent 1px),
    linear-gradient(to bottom, var(--dg-border) 1px, transparent 1px);
  background-size:
    calc((100% + var(--dg-gap)) / var(--dg-cols))
    calc(var(--dg-cell-size) + var(--dg-gap));
  border: 1px solid var(--dg-border);
  border-radius: var(--dg-radius);
  padding: 1px;
}
.dg.dg--aspect.is-editable {
  background-size:
    calc((100% + var(--dg-gap)) / var(--dg-cols))
    calc((100% + var(--dg-gap)) / var(--dg-rows));
}

.dg-cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  background: var(--dg-surface);
  border: 1px solid var(--dg-border);
  border-radius: var(--dg-radius-sm);
  overflow: hidden;
}

.dg-cell-body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/* Edit chrome — a slim top bar (grip + title + remove) revealed on hover,
   plus an SE resize handle. */
.dg-cell-bar {
  position: absolute;
  inset: 0 0 auto 0;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  height: 1.5rem;
  padding: 0 0.4rem;
  background: var(--dg-glass);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--dg-border);
  opacity: 0;
  transition: opacity 0.12s;
}
.dg-cell:hover .dg-cell-bar,
.dg-cell:focus-within .dg-cell-bar,
.dg-cell.is-dragging .dg-cell-bar,
.dg-cell.is-resizing .dg-cell-bar { opacity: 1; }

.dg-grip {
  height: 100%;
  cursor: move;
  display: flex;
  align-items: center;
  flex: none;
}
.dg-grip::before {
  content: "\22EE\22EE";        /* ⋮⋮ */
  color: var(--dg-text-mute);
  font-size: 0.75rem;
  letter-spacing: -0.15em;
}

/* The title shares the grip's drag surface — the whole bar is the handle. */
.dg-cell-title {
  flex: 1;
  min-width: 0;
  cursor: move;
  color: var(--dg-text-mute);
  font-size: 0.7rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dg-del {
  border: 0;
  background: transparent;
  color: var(--dg-text-mute);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.2rem;
  flex: none;
}
.dg-del:hover { color: var(--dg-danger); }

.dg-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 1rem;
  height: 1rem;
  cursor: se-resize;
  opacity: 0;
}
.dg-cell:hover .dg-resize,
.dg-cell.is-resizing .dg-resize { opacity: 1; }
.dg-resize::after {
  content: "";
  position: absolute;
  right: 0.2rem;
  bottom: 0.2rem;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--dg-text-mute);
  border-bottom: 2px solid var(--dg-text-mute);
}

.dg-cell.is-dragging,
.dg-cell.is-resizing {
  outline: 2px solid var(--dg-accent);
  z-index: 2;
}

/* ── the isolated error tile ─────────────────────────────────────────
   A failed mount is contained here: the cell keeps its placement and its
   edit chrome, so it stays movable and removable. */
.dg-cell.is-error {
  background: var(--dg-danger-bg);
  border-color: var(--dg-danger-border);
}

.dg-error {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.15rem;
  width: 100%;
  height: 100%;
  padding: 0.5rem 0.6rem;
  color: var(--dg-danger);
  overflow: auto;
}
.dg-error-icon { font-size: 1rem; line-height: 1; }
.dg-error-title { font-weight: 600; font-size: 0.78rem; }
.dg-error-msg {
  font-size: 0.7rem;
  line-height: 1.35;
  opacity: 0.9;
  overflow-wrap: anywhere;
}
