/* Color tokens, fonts, and dark/light switching all come from the shared
   theme.css (linked in index.html before this file) -- the same file
   standalone.html/annotator.html/client.html/admin.html use, so this tool
   matches the rest of NqshLab instead of carrying its own palette. Only
   tokens theme.css doesn't define (layout-only radii) live here. */
:root {
  --radius-lg: 16px;
  --radius-md: 12px;
  --radius-sm: 8px;
}

* { box-sizing: border-box; }

/* An author rule setting `display` (e.g. .tool-btn's flex, below) beats the
   browser's own [hidden]{display:none} regardless of selector specificity
   -- origin wins before specificity is even compared -- so toggling the
   `hidden` property from JS silently did nothing on any element styled
   this way. Restated here at author level so hidden always wins. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  /* .layout's panels scroll internally (overflow-y: auto below); the shell
     itself must never scroll or the fixed-height .topbar -- which is just
     the first item in normal flow, not position:fixed -- gets carried off
     the top of the viewport with it. */
  overflow: hidden;
  background: var(--bg);
  color: var(--fg);
  font-family: 'ThmanyahSans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.fade-in { animation: fadeIn 0.3s ease forwards; }

/* ---------- top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 56px;
  padding: 0 20px;
  background: var(--nav-bg);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-sm);
  position: relative;
  z-index: 10;
}

/* Matches the wordmark + portal-name pattern in annotator.html/client.html's
   DashboardHeader, so this tool reads as the same product mid-navigation. */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
}
.brand-word {
  font-family: 'ThmanyahSans', system-ui, sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--fg);
}
.brand-tag {
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-vl);
  border-left: 1px solid var(--border);
  padding-left: 12px;
}

.slide-picker { display: flex; align-items: center; gap: 8px; color: var(--fg-lo); font-size: 13px; }

.mpp-readout {
  margin-left: auto;
  color: var(--teal);
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  background: var(--teal-surface);
  border: 1px solid var(--teal-brd);
  padding: 4px 10px;
  border-radius: 999px;
  min-height: 14px;
}

select, input[type="text"] {
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border-sm);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  font-family: inherit;
  font-size: 13px;
  transition: border-color .15s, background .15s;
}
select:hover, input[type="text"]:hover { border-color: var(--border); }
select:focus, input[type="text"]:focus { outline: none; border-color: var(--teal-lo); }

.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--fg-lo);
  border: 1px solid var(--border-sm);
  cursor: pointer;
  transition: all .15s;
  flex-shrink: 0;
}
.icon-btn:hover { color: var(--fg); border-color: var(--border); }
.icon-btn svg { width: 15px; height: 15px; }

/* ---------- layout ---------- */
.layout {
  display: grid;
  grid-template-columns: 240px 1fr 260px;
  height: calc(100% - 56px);
}

.panel {
  background: var(--bg);
  border-right: 1px solid var(--border-sm);
  padding: 16px;
  overflow-y: auto;
}
.right-panel { border-right: none; border-left: 1px solid var(--border-sm); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  margin-bottom: 14px;
}

.mono-label {
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal);
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
}
.mono-label::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* ---------- tool grid ---------- */
.tool-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.tool-btn, .wide-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--surface);
  color: var(--fg-lo);
  border: 1px solid var(--border-sm);
  border-radius: var(--radius-md);
  padding: 9px 8px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  transition: all .15s;
}
.tool-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.tool-btn:hover { color: var(--fg); border-color: var(--border); background: var(--surface-hi); }
.tool-btn.active {
  background: var(--teal);
  border-color: var(--teal);
  color: var(--bg);
}
.tool-btn.active:hover { background: var(--teal); opacity: 0.9; }
.tool-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.tool-btn:disabled:hover { color: var(--fg-lo); border-color: var(--border-sm); background: var(--surface); }

/* Not strictly "read-only" any more -- a client can still mark their own
   region-of-interest layer, just never an annotator's -- but the badge
   keeps the class name for the couple of unrelated readonly-mode selectors
   already using it (see .popup-note-save etc. if any get added later). */
body.readonly-mode .topbar::after {
  content: "Client view";
  font-family: 'DM Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--warn, #d9a441);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 3px 10px;
  margin-inline-start: 10px;
}

.wide-btn { width: 100%; margin-top: 8px; }
.wide-btn:hover { color: var(--fg); border-color: var(--border); background: var(--surface-hi); }
.wide-btn.primary {
  background: var(--teal);
  color: var(--bg);
  border: none;
  font-weight: 600;
}
.wide-btn.primary:hover { opacity: 0.88; background: var(--teal); }
.wide-btn.danger {
  background: var(--red-surface);
  color: var(--red);
  border: 1px solid var(--red-border);
}
.wide-btn.danger:hover { opacity: 0.85; }
.wide-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.wide-btn:disabled:hover { border-color: var(--border-sm); background: var(--surface); opacity: 0.35; }

.btn-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.btn-row .wide-btn { margin-top: 0; }

.hint {
  color: var(--fg-lo);
  font-size: 12px;
  line-height: 1.5;
  margin: 10px 0;
}

.status {
  color: var(--fg-lo);
  font-size: 12px;
  min-height: 16px;
  font-family: ui-monospace, "DM Mono", monospace;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
  color: var(--fg-lo);
  font-size: 11.5px;
  letter-spacing: 0.02em;
}
.field select { width: 100%; }

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  color: var(--fg-hi);
  font-size: 13px;
  font-weight: 500;
}
.checkbox-row input[type="checkbox"] {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 5px;
  border: 1px solid var(--border-hi);
  background: var(--surface);
  cursor: pointer;
  position: relative;
  transition: all .15s;
}
.checkbox-row input[type="checkbox"]:checked {
  background: var(--teal);
  border-color: var(--teal);
}
.checkbox-row input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 5px; top: 1.5px;
  width: 4px; height: 8px;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* ---------- range sliders ---------- */
input[type="range"] {
  -webkit-appearance: none;
  width: 100%;
  height: 4px;
  background: var(--surface-hi);
  border-radius: 999px;
  outline: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--teal);
  border: 2px solid var(--bg);
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--teal-brd);
}
input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--teal);
  border: 2px solid var(--bg);
  cursor: pointer;
}

/* ---------- metadata strip ---------- */
.meta-strip {
  display: flex;
  gap: 18px;
  padding: 6px 20px;
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--fg-vl);
  background: var(--bg);
  border-bottom: 1px solid var(--border-sm);
  min-height: 14px;
}
.meta-strip span strong { color: var(--fg-md); font-weight: 500; }

/* ---------- viewer ---------- */
.viewer-area {
  position: relative;
  background: var(--bg-deep);
  height: 100%;
}

.viewer-area.compare-active {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.viewer-pane {
  position: relative;
  height: 100%;
}

#viewer-pane-2 {
  display: none;
  flex-direction: column;
  border-left: 1px solid var(--border-sm);
}
.viewer-area.compare-active #viewer-pane-2 { display: flex; }

.pane-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--border-sm);
  flex-shrink: 0;
}
.pane-toolbar select, .pane-toolbar input[type="range"] { max-width: 110px; }

.osd-wrapper { flex: 1; position: relative; min-height: 0; }
#osd-2 { position: absolute; inset: 0; }

#osd { position: absolute; inset: 0; }

.osd-nav {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 5;
  display: flex;
  gap: 6px;
}

#annotation-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Higher than .osd-nav's z-index:5 -- without this, any shape that
     happens to render underneath that fixed-position button cluster
     (top:12px;left:12px, e.g. after panning, or just because that's
     where someone drew or dropped a region) is permanently unclickable
     at that pan position: the buttons sit on top in the stacking order
     and swallow the click before it ever reaches the shape below, with
     no visual sign anything is wrong. This is what "can't delete an
     annotation/ROI" usually turns out to be. */
  z-index: 6;
}

.shape {
  fill: rgba(66,169,230,0.16);
  stroke: var(--teal);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  cursor: pointer;
}
.shape.point { fill: var(--teal); stroke: var(--bg); stroke-width: 1.5; }
.shape.line { fill: none; stroke-width: 2.5; }
.shape.selected { stroke: #fff; stroke-dasharray: 4 3; }

#annotation-svg.mode-select .shape { pointer-events: auto; }

.shape.filter-result {
  fill: rgba(245,197,24,0.15);
  stroke: var(--amber);
  pointer-events: none;
  /* Unlike hand-drawn annotations, a filter can return tens of thousands
     of results (e.g. one per detected nucleus) at wildly varying true
     sizes -- the base .shape's non-scaling-stroke (a constant ~2 screen
     px outline) would then dominate every tiny result the same way
     regardless of its real size, so zoomed out they inflate into a
     crowd of same-ish-looking, overlapping blobs instead of shrinking
     with the tissue like every other shape does. Scaling the stroke
     with the image here lets each result render at its true size. */
  vector-effect: none;
}
/* filter results stay non-interactive in Pan (so they never steal a pan
   drag), but become double-clickable for property inspection in Select */
#annotation-svg.mode-select .shape.filter-result { pointer-events: auto; cursor: zoom-in; }

#annotation-svg.outline-only .shape { fill: none !important; }

.vertex-handle {
  fill: var(--fg);
  stroke: var(--teal);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  cursor: grab;
}
#annotation-svg.mode-select .vertex-handle { pointer-events: auto; }

.in-progress-shape {
  fill: rgba(66,169,230,0.12);
  stroke: var(--teal);
  stroke-dasharray: 5 4;
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

.measure-label {
  fill: var(--fg);
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 11px;
  paint-order: stroke;
  stroke: var(--bg-deep);
  stroke-width: 3px;
  pointer-events: none;
}

/* ---------- OpenSeadragon chrome ---------- */
.openseadragon-container .navigator {
  border-radius: var(--radius-md) !important;
  border: 1px solid var(--border-hi) !important;
  overflow: hidden;
  box-shadow: 0 4px 24px rgba(0,0,0,0.4);
}

/* ---------- property inspector panel ----------
   Docked to the right edge rather than floated near the cursor, so it
   reads as a real panel of the app (matching the 260px right-panel
   column it sits in front of) instead of a tooltip that could appear
   anywhere and get missed. */
#shape-property-popup {
  display: none;
  position: fixed;
  top: 56px;
  right: 0;
  bottom: 0;
  width: 260px;
  overflow-y: auto;
  background: var(--bg);
  border-left: 1px solid var(--border-hi);
  box-shadow: -12px 0 32px rgba(0,0,0,0.35);
  font-size: 12px;
  z-index: 1000;
}
.popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-sm);
  position: sticky;
  top: 0;
  background: var(--bg);
}
.popup-title {
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal);
}
.popup-close {
  background: none;
  border: none;
  color: var(--fg-lo);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 2px 4px;
}
.popup-close:hover { color: var(--fg); }
.popup-table { width: 100%; border-collapse: collapse; }
.popup-table td { padding: 6px 10px; border-bottom: 1px solid var(--border-sm); vertical-align: top; }
.popup-key { color: var(--fg-lo); white-space: nowrap; }
.popup-value { color: var(--fg-hi); text-align: right; word-break: break-word; }
.popup-empty { color: var(--fg-vl); text-align: center; }

.popup-note { padding: 10px; border-top: 1px solid var(--border-sm); }
.popup-note:empty { display: none; padding: 0; border: none; }
.popup-note-label {
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--fg-vl); margin: 0 0 6px;
}
.popup-note-text { color: var(--fg-hi); white-space: pre-wrap; word-break: break-word; margin: 0; }
.popup-note-textarea {
  width: 100%; resize: vertical; background: var(--surface); color: var(--fg);
  border: 1px solid var(--border-sm); border-radius: var(--radius-sm);
  padding: 8px; font-family: inherit; font-size: 12px; line-height: 1.4;
}
.popup-note-textarea:focus { outline: none; border-color: var(--teal-lo); }
.popup-class-row { display: flex; gap: 8px; align-items: stretch; }
.popup-class-row input[type="color"] {
  flex-shrink: 0; width: 36px; padding: 2px; border: 1px solid var(--border-sm);
  border-radius: var(--radius-sm); background: var(--surface); cursor: pointer;
}
.popup-class-combo { position: relative; flex: 1; }
.popup-class-combo .popup-note-textarea { width: 100%; }
.popup-class-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 1001;
  background: var(--surface); border: 1px solid var(--border-sm); border-radius: var(--radius-sm);
  box-shadow: 0 8px 20px rgba(0,0,0,0.3); overflow: hidden;
}
.popup-class-option { padding: 7px 8px; font-size: 12px; color: var(--fg); cursor: pointer; }
.popup-class-option:hover { background: var(--teal-lo); color: var(--bg); }
.popup-note-save {
  margin-top: 8px; width: 100%; background: var(--teal); color: var(--bg);
  border: none; border-radius: var(--radius-sm); padding: 7px 8px;
  font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.popup-note-save:hover { opacity: 0.88; }

/* ---------- label toggle / color rows (filter results) ---------- */
.label-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 12.5px;
  color: var(--fg-hi);
}
.label-row input[type="color"] {
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--border-sm);
  border-radius: 6px;
  background: none;
  cursor: pointer;
}
.label-row .label-name { flex: 1; }
.label-row .label-count { color: var(--fg-vl); font-family: ui-monospace, "DM Mono", monospace; font-size: 11px; }

/* ---------- source styles: tell layers apart when shown merged ---------- */
.shape.src-model { stroke-dasharray: 7 4; }
.shape.src-upload { stroke-dasharray: 2 3; }
.shape.selected.src-model,
.shape.selected.src-upload { stroke-dasharray: 4 3; }

/* ---------- layers panel ---------- */
.seg {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 2px;
  background: var(--bg-deep);
  border: 1px solid var(--border-sm);
  border-radius: var(--radius-md);
}
.seg button {
  background: none;
  border: none;
  border-radius: calc(var(--radius-md) - 2px);
  padding: 6px 4px;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--fg-lo);
  cursor: pointer;
}
.seg button:hover { color: var(--fg); }
.seg button.active { background: var(--surface-hi); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,0.08); }

.layer-group { padding: 6px 0; border-bottom: 1px solid var(--border-sm); }
.layer-group:last-child { border-bottom: none; }
.layer-head, .class-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--fg-hi);
  padding: 3px 0;
}
.layer-head { font-weight: 600; }
.class-row { padding-left: 22px; }
.layer-head .label-name, .class-row .label-name { flex: 1; min-width: 0; overflow-wrap: break-word; }
.label-name.sub { color: var(--fg-md); font-weight: 400; }
.label-count { color: var(--fg-vl); font-family: ui-monospace, "DM Mono", monospace; font-size: 11px; }
.layer-check { margin: 0; }

.swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
  background: var(--swatch, transparent);
  border: 2px solid var(--swatch, var(--fg-md));
}
.swatch.src-solid { border-style: solid; background: none; }
.swatch.src-model { border-style: dashed; background: none; }
.swatch.src-upload { border-style: dotted; background: none; }

.tag {
  font-family: ui-monospace, "DM Mono", monospace;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal-link);
  border: 1px solid var(--teal-brd);
  border-radius: 999px;
  padding: 1px 6px;
}

.badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 600;
  border-radius: 999px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  color: var(--fg-lo);
  background: var(--surface);
  white-space: nowrap;
}
.badge.confirmed { color: var(--ok); background: var(--ok-surface); border-color: var(--ok-border); }
.badge.changes { color: var(--warn); background: var(--warn-surface); border-color: var(--warn-border); }
.badge-btn { cursor: pointer; font-family: inherit; }
.badge-btn:hover { border-color: var(--border-hi); }

.class-review, .class-review-line { padding: 2px 0 6px 42px; display: flex; flex-wrap: wrap; gap: 4px; }
.review-form { width: 100%; margin-top: 6px; }
.review-form .popup-note-textarea { width: 100%; box-sizing: border-box; }
.review-form .btn-row { margin-top: 8px; }

.merged-legend { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 10px; font-size: 12px; color: var(--fg-md); }
.legend-item { display: inline-flex; align-items: center; gap: 6px; }

/* ---------- review card ---------- */
.progress { height: 6px; border-radius: 999px; background: var(--bg-deep); overflow: hidden; margin-top: 6px; }
.progress-fill { height: 100%; background: var(--ok); transition: width .2s; }
.review-item { padding: 8px 0; border-bottom: 1px solid var(--border-sm); }
.review-item:last-child { border-bottom: none; }
.review-title { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--fg-hi); }
.review-meta { display: flex; align-items: center; gap: 8px; margin: 4px 0 0 20px; }
.review-who { font-size: 12px; color: var(--fg-md); }
.review-edits { margin: 4px 0 0 20px; font-size: 11.5px; color: var(--info); font-family: ui-monospace, "DM Mono", monospace; }
.review-note { margin: 4px 0 0 20px; font-size: 12px; color: var(--fg-hi); white-space: pre-wrap; }

/* ---------- uploads card ---------- */
.upload-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-sm); }
.upload-info { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 12.5px; color: var(--fg-hi); }
.upload-info .label-count { overflow-wrap: anywhere; }
.upload-row .icon-btn { width: auto; min-width: 32px; padding: 0 8px; font-family: inherit; font-size: 11.5px; }

/* ---------- client model runs (background job) ---------- */
.model-job { margin-top: 10px; padding: 10px; border: 1px solid var(--border-sm); border-radius: 8px; background: var(--bg-deep); }
.model-job .progress { background: var(--border-sm); }
.model-job-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; font-weight: 500; }
.link-btn { background: none; border: none; padding: 2px 4px; font: inherit; font-size: 12px; color: var(--red); cursor: pointer; }
.link-btn:disabled { opacity: .45; cursor: default; }
.link-btn:not(:disabled):hover { text-decoration: underline; }
