/* Dashboard styles. Dash auto-loads any *.css in dashboard/assets/. */

/* Page root */
.dash-root {
  font-family: sans-serif;
  padding: 16px;
  overflow-x: hidden;
  box-sizing: border-box;
}

.dash-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.dash-header h2 {
  margin: 0;
}

.dash-add-graph-row {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 8px;
}

.btn {
  padding: 6px 12px;
  cursor: pointer;
}

.btn-flex {
  padding: 6px 0;
  cursor: pointer;
  flex: 1;
}

.btn-retry {
  padding: 4px 10px;
  cursor: pointer;
  font-size: 0.85em;
  white-space: nowrap;
}

/* Graph grid */
.graph-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 500px), 1fr));
  gap: 12px;
}

/* Graph cell */
.graph-cell {
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px;
  background-color: #fafafa;
}

.graph-cell-header {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 4px;
}

.graph-cell .max-bins-wrapper {
  display: flex;
  gap: 4px;
  align-items: center;
}

.graph-cell .max-bins-wrapper.hidden {
  display: none;
}

.graph-cell .max-bins-label {
  font-size: 0.8em;
  color: #555;
  white-space: nowrap;
}

.graph-cell .max-bins-input {
  width: 52px;
  padding: 2px 4px;
}

.graph-cell .label-mode-wrapper {
  display: flex;
  align-items: center;
}

.graph-cell .label-mode-wrapper.hidden {
  display: none;
}

.graph-cell .label-mode-input {
  width: 120px;
  font-size: 0.8em;
}

.graph-cell .btn-remove {
  background: none;
  border: 1px solid #ccc;
  border-radius: 3px;
  cursor: pointer;
  font-size: 1em;
  padding: 2px 6px;
  color: #888;
  line-height: 1;
}

.graph-cell .selector {
  flex: 1;
}

.graph-cell .figure {
  height: 400px;
}

/* Config panel */
.config-panel {
  border: 1px solid #aaa;
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 16px;
  background-color: #f5f7fa;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Dropdown (fills the row) + New button beside it */
.config-selector-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.config-selector-wrap {
  flex: 1;
  min-width: 0;
}

.config-selector-wrap .config-selector {
  width: 100%;
}

/* Right-edge action buttons share a width so they form a tidy column */
.config-selector-row .btn,
.config-runs-wrap .btn-retry {
  min-width: 92px;
  text-align: center;
  flex: 0 0 auto;
}

/* Rename + Retry Parse + Delete row at the bottom of the card */
.config-bottom-row {
  margin-top: 4px;
  justify-content: flex-end;
}

.config-panel-row {
  display: flex;
  gap: 24px;
  align-items: stretch;
}

.config-card {
  flex: 1;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 10px 12px;
  background-color: #fff;
}

.config-card-heading {
  display: block;
  font-weight: bold;
  margin-bottom: 12px;
  font-size: 0.85em;
  color: #333;
}

.config-row {
  display: flex;
  gap: 6px;
  align-items: center;
}

.config-row.spaced {
  margin-top: 8px;
}

.config-row-label {
  font-size: 0.85em;
  color: #555;
  white-space: nowrap;
  width: 92px;
  text-align: left;
}

.config-input {
  flex: 1;
  padding: 4px 6px;
  box-sizing: border-box;
}

input.config-input[type="number"]::-webkit-inner-spin-button,
input.config-input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none !important;
  appearance: none !important;
  margin: 0 !important;
  display: none !important;
}

input.config-input[type="number"] {
  -moz-appearance: textfield !important;
  appearance: textfield !important;
}

.config-name-hint {
  font-size: 0.78em;
  color: #c00;
  margin-top: 2px;
}

.config-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex: 1;
}

.config-status {
  font-size: 0.85em;
  color: #555;
  flex: 1;
}

.config-selector {
  font-size: 0.9em;
}

.config-button-row {
  display: flex;
  gap: 8px;
  margin-top: 6px;
}

.config-runs-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
}

.config-runs-display {
  flex: 1;
  font-size: 1.15em;
  font-weight: 700;
  color: #1a3b6e;
  font-family: monospace;
  background: #eef3fb;
  border: 1px solid #d4e0f0;
  border-radius: 4px;
  padding: 6px 10px;
}

/* Primary action button (modal Save) */
.btn-primary {
  background-color: #1a73e8;
  color: #fff;
  border: 1px solid #1669c1;
  border-radius: 3px;
}

.btn-primary:hover {
  background-color: #1669c1;
}

/* Modal editor */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-card {
  background: #fff;
  border-radius: 6px;
  padding: 18px 20px;
  width: 440px;
  max-width: 90vw;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
}

.modal-title {
  font-weight: bold;
  font-size: 1.05em;
  margin-bottom: 14px;
  color: #222;
}

.modal-card .config-row-label {
  width: 60px;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}

.recent-runs {
  margin-top: 10px;
}

.recent-runs-title {
  font-size: 0.85em;
  font-weight: 600;
  color: #555;
  margin-bottom: 3px;
}

.recent-runs-row {
  display: flex;
  gap: 6px;
  font-size: 0.85em;
  line-height: 1.5;
}

.recent-runs-board {
  min-width: 56px;
  font-weight: 600;
  color: #444;
}

.recent-runs-runs {
  color: #555;
}

.recent-runs-empty {
  color: #999;
  font-style: italic;
}

.overlap-warning {
  background: #fdecea;
  border: 1px solid #d32f2f;
  color: #a32d00;
  padding: 8px 14px;
  margin: 6px 12px;
  border-radius: 4px;
  font-size: 0.9em;
  font-weight: 600;
}

.scatter-panel {
  margin: 6px 12px;
}

.scatter-error {
  background: #fdecea;
  border: 1px solid #d32f2f;
  color: #a32d00;
  padding: 8px 14px;
  margin-bottom: 8px;
  border-radius: 4px;
  font-size: 0.9em;
}

.scatter-error ul {
  margin: 4px 0 0;
  padding-left: 20px;
}

.scatter-scale-options {
  margin-bottom: 6px;
  display: flex;
  gap: 16px;
  font-size: 0.9em;
}

.scatter-controls {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.scatter-control {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.9em;
}

.scatter-control-label {
  font-weight: 600;
  color: #444;
}

.scatter-axis-dropdown {
  min-width: 140px;
  font-size: 0.9em;
}

.scatter-controls .scatter-scale-options {
  margin-bottom: 0;
}

.graphs-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.graphs-empty {
  padding: 24px;
  text-align: center;
  color: #777;
  background: #fafafa;
  border: 1px dashed #ccc;
  border-radius: 8px;
}

.graph-card {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 10px 12px;
  background: #fff;
}

.graph-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;          /* actions drop to their own line on narrow cards */
  gap: 4px 12px;
  margin-bottom: 6px;
}

/* Title items flow as inline text (wrapping between items, never inside
   them) instead of shrinking into narrow flex columns. */
.graph-card-title {
  display: block;
  min-width: 0;
  line-height: 1.6;
}

/* inline-block: Dash emits the spans with no whitespace between them, and
   line breaks are allowed between atomic inline boxes but not inside them. */
.graph-card-title > span {
  display: inline-block;
  white-space: nowrap;
}

/* Uniform "·" separators between every item after the graph name. */
.graph-card-title > span + span::before {
  content: "·";
  color: #999;
  margin: 0 8px;
}

.graph-card-name {
  font-weight: 600;
  font-size: 1.05em;
}

/* Everything after the graph name shares one quiet style; only the status
   glyph (✓ / !) is coloured. */
.graph-card-type,
.graph-card-runs,
.graph-card-status,
.graph-card-meta {
  color: #555;
  font-size: 0.85em;
  font-weight: normal;
}

.graph-card-side {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  margin-left: auto;
}

.graph-card-side .btn {
  padding: 2px 8px;
  font-size: 0.8em;
}

.btn-danger {
  background: #fbe9e7;
  border-color: #e0b4ac;
  color: #a32d00;
}

.scatter-panel .figure {
  height: 520px;
}

/* ---- Collapsible configuration sidebar ---- */
.app-body {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.main-content {
  flex: 1;
  min-width: 0;
}

.config-sidebar {
  flex: 0 0 240px;
  width: 240px;
  border: 1px solid #ccc;
  border-radius: 6px;
  background-color: #fff;
  align-self: stretch;
  transition: flex-basis 0.15s ease, width 0.15s ease;
}

.config-sidebar.collapsed {
  flex-basis: 38px;
  width: 38px;
}

.config-sidebar.collapsed .config-sidebar-body,
.config-sidebar.collapsed .config-sidebar-title {
  display: none;
}

.config-sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  border-bottom: 1px solid #eee;
}

.config-sidebar.collapsed .config-sidebar-header {
  justify-content: center;
  padding: 8px 4px;
}

.config-sidebar-title {
  font-weight: bold;
  font-size: 0.9em;
  color: #333;
}

.sidebar-toggle {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 1.2em;
  line-height: 1;
  padding: 2px 6px;
  color: #555;
}

.sidebar-toggle:hover {
  color: #000;
}

.config-sidebar-body {
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sidebar-new {
  width: 100%;
}

.config-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.config-item {
  text-align: left;
  background-color: #f5f7fa;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  padding: 6px 8px;
  cursor: pointer;
  font-size: 0.85em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.config-item:hover {
  background-color: #eef3fb;
}

.config-item.active {
  background-color: #1a73e8;
  color: #fff;
  border-color: #1669c1;
  font-weight: 600;
}

.config-list-empty {
  color: #999;
  font-size: 0.85em;
  font-style: italic;
  padding: 4px;
}

/* Config toolbar (active config name + actions) */
.config-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.active-config-label {
  font-weight: bold;
  font-size: 1.4em;
  color: #222;
  margin-right: auto;
}

/* Per-graph parse status badge in the card header */
.graph-card-status.muted {
  color: #999;
}

.status-glyph-ok {
  color: #137333;
  font-weight: 600;
}

.status-glyph-warn {
  color: #a32d00;
  font-weight: 600;
}

/* Recent runs pinned at the bottom of the sidebar */
.sidebar-recent {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid #eee;
}

.sidebar-recent-title {
  font-size: 0.8em;
  font-weight: 600;
  color: #666;
  margin-bottom: 4px;
}

/* Board/dose summary in the graph card header (after the parse status). */
.graph-card-meta {
}

/* Graph modal: consistent vertical rhythm and a shared-graph edit warning. */
.modal-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 4px;
}

.modal-form .config-row,
.modal-form .scatter-controls,
.modal-form .scatter-scale-options {
  margin: 0;
}

.modal-options {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.graph-edit-warning:empty {
  display: none;
}

.graph-edit-warning {
  background: #fff8e1;
  border: 1px solid #f0d27a;
  color: #7a5b00;
  border-radius: 4px;
  padding: 6px 10px;
  font-size: 0.85em;
  margin-bottom: 10px;
}

/* --- graph modal: type selector and per-type option blocks ------------- */
.graph-type-dropdown {
  flex: 1;
  min-width: 220px;
}

.type-options {
  border-top: 1px dashed #ddd;
  padding-top: 8px;
  margin-top: 4px;
}

.modal-form .type-options .scatter-controls {
  margin-bottom: 6px;
}


/* --- graph grid: rows of side-by-side cards + move buttons ------------- */
.graph-row {
  display: flex;
  gap: 16px;
  align-items: stretch;
}

.graph-row > .graph-card {
  flex: 1 1 0;
  min-width: 0;
}

.graph-move-group {
  display: inline-flex;
  gap: 2px;
  margin-right: 8px;
}

.graph-card-side .btn-move {
  padding: 1px 5px;
  font-size: 0.7em;
  line-height: 1.4;
}

.btn-move:disabled {
  opacity: 0.35;
  cursor: default;
}

/* Responsive plots fill their container, so the card must give them a height. */
.graph-card .figure {
  height: 420px;
  width: 100%;
}

/* Uniform 26px-high action buttons; icon buttons draw an SVG via CSS so the
   glyph metrics don't depend on the system emoji font. */
.graph-card-side .btn,
.graph-card-side .btn-move {
  height: 26px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Flat look. Without this a button carrying a background-image loses the
     native appearance and falls back to a bevelled 3D border. */
  appearance: none;
  -webkit-appearance: none;
  background-color: #fff;
  border: 1px solid #bbb;
  border-radius: 3px;
  color: #333;
}

.graph-card-side .btn:hover:not(:disabled) {
  background-color: #eef3fb;
  border-color: #9fb8dd;
}

.graph-card-side .btn:disabled {
  color: #bbb;
  background-color: #f7f7f7;
}

.graph-card-side .btn-icon {
  width: 30px;
  padding: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 15px 15px;
}

.graph-card-side .icon-copy {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='9' width='13' height='13' rx='2'/><path d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1'/></svg>");
}

.graph-card-side .icon-edit {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M17 3a2.83 2.83 0 0 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'/></svg>");
}

.graph-card-side .icon-trash {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='3 6 5 6 21 6'/><path d='M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6'/><path d='M10 11v6M14 11v6'/><path d='M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2'/></svg>");
}

.graph-card-side .icon-trash:hover {
  background-color: #fbe9e7;
  border-color: #e0b4ac;
}

/* --- card layout: main column + vertical control column on the right ---- */
.graph-card {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.graph-card-main {
  flex: 1 1 0;
  min-width: 0;
}

.graph-card-side {
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-left: 0;
  padding-top: 2px;
}

.graph-card-side .btn-icon {
  width: 30px;
}

/* Move arrows stacked vertically below the icon buttons. */
.graph-arrows {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
}

.graph-card-side .graph-arrows .btn-move {
  width: 30px;
  height: 24px;
  padding: 0;
  font-size: 0.65em;
}

.hist-max-bins {
  flex: 0 0 80px;
  width: 80px;
  max-width: 90px;
}

.hist-max-bins-row {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.hist-max-bins-row .hist-max-bins-hint {
  flex: 1;
  min-width: 0;
}

.hist-max-bins-hint {
  font-size: 0.8em;
  color: #777;
}

/* Live status of the newest run (sidebar). */
.live-status {
  margin-bottom: 8px;
  font-size: 0.85em;
  line-height: 1.5;
}

.live-dot {
  color: #bbb;
}

.live-dot.active {
  color: #137333;
}

.live-meta {
  color: #555;
}
