* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --bg: #1a1a2e;
  --bg-raised: #16213e;
  --bg-input: #222;
  --border: #2a2a45;
  --text: #ccc;
  --text-dim: #777;
  --text-bright: #fff;
  --accent: #007BFF;
  --accent-hover: #0069d9;
  --danger: #ff6b6b;
  --success: #28a745;
  --row-hover: #222a40;
  --row-selected: #1e3a5f;
  --row-height: 30px;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  height: 100vh;
  overflow: hidden;
  user-select: none;
  font-size: 14px;
}

/* === LOGIN === */
#loginOverlay {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  background-image: radial-gradient(ellipse at top, var(--bg-raised) 0%, var(--bg) 70%);
  z-index: 1000;
}
#loginBox {
  width: 340px; padding: 36px;
  background: var(--bg-input); border-radius: 14px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.5);
  display: flex; flex-direction: column; align-items: center;
}
#loginLogo { width: 48px; margin-bottom: 10px; }
#loginBox h1 { color: var(--text-bright); font-size: 20px; margin-bottom: 20px; font-weight: 600; }
#loginForm { width: 100%; display: flex; flex-direction: column; gap: 8px; }
#loginForm input {
  padding: 10px 12px; border: 1px solid #444; border-radius: 7px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px; outline: none;
}
#loginForm input:focus { border-color: var(--accent); }
#loginForm input::placeholder { color: var(--text-dim); }
#loginForm .pwField { position: relative; display: flex; }
#loginForm .pwField > input { flex: 1; padding-right: 38px; }
#loginForm .pwToggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; padding: 0;
  background: transparent; border: none; color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; border-radius: 4px; font-weight: normal;
}
#loginForm .pwToggle:hover { color: var(--text-bright); background: rgba(255,255,255,0.06); }
#loginForm .pwToggle:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
#loginForm button {
  padding: 10px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-weight: 600; cursor: pointer;
}
#loginForm button:hover { background: var(--accent-hover); }
/* Hide the login overlay before paint when we already have a session
   cookie — avoids the brief login-form flicker on returning visits.
   The class is set by an inline <script> in <head>; if the cookie is
   stale, app.js removes it once whoami fails. */
html.preauth #loginOverlay { display: none !important; }
html.preauth #loginFooter { display: none !important; }

#loginError { color: var(--danger); font-size: 12px; text-align: center; min-height: 18px; }
#loginError a { color: var(--accent); }
.loginLinks {
  display: flex; justify-content: space-between; margin-top: 6px;
  font-size: 12px;
}
.loginAux {
  color: var(--text-dim);
  text-decoration: none;
}
.loginAux:hover { color: var(--accent); }

/* "or" divider between password and Google sign-in.
   Shown only when /auth/google/status reports enabled; the JS toggles
   display:flex on it. */
.loginOrSep {
  display: flex; align-items: center; gap: 8px;
  margin: 10px 0 6px;
  color: var(--text-dim); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.08em;
}
.loginOrSep::before,
.loginOrSep::after {
  content: "";
  flex: 1;
  border-top: 1px solid #444;
  height: 0;
}

/* Google button — Google's brand guidelines: white surface, dark text,
   their logo. Keeps the look they recommend so users recognise it from
   thousands of other sites. Sized slightly larger than the email-path
   button below it so the visual hierarchy reads: Google first. */
.loginGoogle {
  display: flex; align-items: center; justify-content: center;
  gap: 10px;
  padding: 11px 14px;
  background: #fff;
  color: #1f1f1f;
  border-radius: 7px;
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  font-family: inherit;
  cursor: pointer;
}
.loginGoogle:hover { background: #f4f4f4; }
.loginGoogle svg { display: block; }

/* When the Google button is in play (the .loginOrSep is visible
   beneath it), the email/password Login button steps down to a quieter
   secondary style so the eye stays on Google. .loginSecondary is
   always applied; the rule only kicks in when the form contains the
   visible #loginOrSep — i.e. Google sign-in is configured. Without
   it, the button keeps the original primary-blue style for legacy
   email/password installs. */
#loginForm:has(#loginOrSep:not([style*="none"])) .loginSecondary {
  background: transparent !important;
  color: var(--text-dim) !important;
  border: 1px solid #3a3a4a !important;
  font-weight: 500 !important;
}
#loginForm:has(#loginOrSep:not([style*="none"])) .loginSecondary:hover {
  color: var(--text-bright) !important;
  border-color: var(--accent) !important;
}

.loginNotice {
  background: rgba(31,111,235,0.08);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 8px 0 4px;
  font-size: 12px;
  color: var(--text);
  line-height: 1.45;
}

/* Persistent footer (research-use disclaimer + Licenses link). Lives at
   body level so it stays visible whether or not the user is logged in.
   Sits above the login overlay (z 1000) so the link is clickable on the
   login screen too. Hidden when the workspace is open — its status bar
   already occupies the bottom edge of the viewport. */
#loginFooter {
  position: fixed; left: 0; right: 0; bottom: 12px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 11px; color: var(--text-dim);
  padding: 0 16px;
  z-index: 1100;
  pointer-events: none;
}
#loginFooter > * { pointer-events: auto; }
.loginFooterText { opacity: 0.85; }
.loginFooterLink {
  color: var(--text-dim); text-decoration: underline;
  text-decoration-color: rgba(255,255,255,0.15);
  cursor: pointer;
}
.loginFooterLink:hover { color: var(--text); text-decoration-color: currentColor; }
/* Hide the persistent footer while the user is inside a project workspace
   so it doesn't overlap the table panel's status bar / job icons.
   The body class is toggled by legal.js via a MutationObserver on the
   workspace/home/app elements' style attributes. */
body.medseg-in-workspace #loginFooter { display: none; }

/* Licenses modal: full LICENSE and THIRD_PARTY_NOTICES.md rendered as
   preformatted text with linkified URLs. Two-tab switcher.
   z-index sits above the login overlay (1000) and footer (1100). */
#licensesModal {
  position: fixed; inset: 0; z-index: 1500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#licensesModalContent {
  position: relative;
  width: 760px; max-width: 92vw;
  height: 80vh; max-height: 720px;
  display: flex; flex-direction: column;
  padding: 24px 0 0; /* tabs + body fill the rest; padding handled inside */
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#licensesModalContent h2 {
  color: var(--text-bright); font-size: 16px; margin: 0 24px 12px;
}
#licensesTabs {
  display: flex; gap: 4px; padding: 0 24px;
  border-bottom: 1px solid var(--border);
}
.licensesTab {
  background: transparent; border: none;
  color: var(--text-dim); font-size: 13px;
  padding: 8px 12px; cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.licensesTab:hover { color: var(--text); }
.licensesTab.active { color: var(--text-bright); border-bottom-color: var(--accent); }
#licensesBody {
  flex: 1; overflow: auto;
  padding: 16px 24px 24px;
}
#licensesContent {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap; word-wrap: break-word;
  margin: 0;
}
#licensesContent a { color: var(--accent); text-decoration: underline; }
#licensesContent a:hover { color: var(--accent-hover); }

/* === TOP BAR === */
#topBar {
  height: 44px; background: var(--bg-raised);
  display: flex; align-items: center; padding: 0 12px; gap: 10px;
  border-bottom: 1px solid var(--border); flex-shrink: 0;
  /* iOS: push content below the notch / Safari address bar overlay */
  padding-top: env(safe-area-inset-top);
  box-sizing: content-box;
}
#userInfo { color: var(--text-dim); font-size: 12px; white-space: nowrap; }
#userLabel {
  color: var(--text-dim);
  text-decoration: none;
}
#userLabel:hover { color: var(--accent); }
.topBarLink {
  padding: 5px 12px;
  border: 1px solid #3a3a5a;
  border-radius: 5px;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.topBarLink:hover { color: var(--accent); border-color: var(--accent); }
.projectGroup { display: flex; align-items: center; gap: 4px; }
#projectDropdown {
  padding: 5px 14px; border-radius: 5px; font-size: 13px;
  cursor: pointer; white-space: nowrap; color: #fff;
  background: var(--accent); border: none; font-weight: 600;
  max-width: 200px; overflow: hidden; text-overflow: ellipsis;
}
#projectDropdown:hover { background: var(--accent-hover); }
.dropArrow { font-size: 10px; opacity: 0.7; }
#projectSettings {
  padding: 4px 9px; border-radius: 5px; font-size: 16px; line-height: 1;
  background: transparent; border: 1px solid #3a3a5a; color: #aaa;
  cursor: pointer; height: 28px;
}
#projectSettings:hover:not(:disabled) { background: #333; color: #fff; border-color: #666; }
#projectSettings:disabled { opacity: 0.3; cursor: default; }
#topActions { display: flex; gap: 4px; margin-left: auto; }
#topActions button {
  padding: 5px 12px; border: 1px solid #3a3a5a; border-radius: 5px;
  background: transparent; color: #999; font-size: 12px; cursor: pointer;
}
#topActions button:hover { background: #333; color: #fff; border-color: #666; }
#btnDeleteSeg {
  padding: 6px 10px; border: none; border-radius: 7px;
  background: transparent; color: #777; font-size: 11px;
  cursor: pointer;
}
#btnDeleteSeg:hover { color: var(--danger); background: rgba(255,0,0,0.08); }

#app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh; /* dynamic viewport — handles iOS address bar show/hide */
  overflow: hidden;
}

/* === WORKSPACE === */
#workspace {
  display: flex; flex: 1; min-height: 0; overflow: hidden;
}

/* === TABLE === */
#tablePanel { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }

#tableHeader {
  display: flex; background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
  height: 26px; align-items: center; flex-shrink: 0;
  position: relative; overflow: hidden;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.thCell {
  height: 100%; display: flex; align-items: center; padding: 0 8px;
  cursor: pointer; white-space: nowrap; font-size: 12px;
  font-weight: 600; color: var(--text-dim); position: relative;
}
.thCell:hover { color: var(--text); }
.thCell.sorted { color: var(--accent); }
.thCell .sortIcon { margin-left: 3px; font-size: 9px; }
.thResize {
  position: absolute; top: 0; right: -3px; width: 6px; height: 100%;
  cursor: col-resize; z-index: 10;
  border-right: 1px solid #333;
  pointer-events: auto;
}
.thResize:hover, .thResize.dragging { border-right: 2px solid var(--accent); }

#tableBody { flex: 1; overflow-y: auto; outline: none; position: relative; }
#tableBody::-webkit-scrollbar { width: 6px; }
#tableBody::-webkit-scrollbar-track { background: transparent; }
#tableBody::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }

.row {
  display: flex; height: var(--row-height); align-items: center;
  border-bottom: 1px solid rgba(42,42,69,0.3); cursor: default;
  position: relative;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  --rs-focus: 0 0 0 0 transparent; --rs-new: 0 0 0 0 transparent; --rs-train: 0 0 0 0 transparent;
  box-shadow: inset var(--rs-focus), inset var(--rs-new), inset var(--rs-train);
}
.row:hover { background: var(--row-hover); }

/* Hover-revealed row-actions button. Solid background masks any text in
   the rightmost cell (e.g. a long comment) so the icon stays readable. */
.rowKebab {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  background: var(--row-hover); border: 1px solid transparent;
  color: #aaa; font-size: 16px; line-height: 1;
  padding: 2px 8px; border-radius: 4px; cursor: pointer;
  opacity: 0; transition: background 0.12s ease, color 0.12s ease;
  z-index: 2;
}
.row:hover .rowKebab,
.rowKebab:focus { opacity: 1; }
.row.selected .rowKebab { background: var(--row-selected); }
.rowKebab:hover { background: #2a3550; color: #fff; border-color: #3a3a5a; }
/* On touch devices hover doesn't exist — keep the kebab visible. */
@media (pointer: coarse) {
  .rowKebab { opacity: 1; }
}
.rubberBand {
  position: absolute; background: rgba(0,123,255,0.12);
  border: 1px solid rgba(0,123,255,0.35); pointer-events: none; z-index: 10;
  border-radius: 2px;
}
.row.selected { background: var(--row-selected); }
.row.focused { --rs-focus: 0 0 0 1px var(--accent); }
.row.hasNew { --rs-new: 0 0 0 1px #FFA726; }
.row.hasTrain { --rs-train: 0 0 0 0 transparent; }

.td {
  height: 100%; display: flex; align-items: center; padding: 0 8px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 13px; background: transparent;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

/* Status indicators. The dot itself stays small for visual minimalism,
   but its click target is the surrounding .statusHit wrapper so users
   don't need pixel-perfect aim. Hover affordance is a thin dim rim
   around the dot — scaled to the 8px dot, not a halo on the 22px hit
   area which would read as oversized. No transitions — snappy. */
.statusHit {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  cursor: pointer;
}
.statusHit:hover .statusDot {
  box-shadow: 0 0 0 2px rgba(255,255,255,0.35);
}
.statusDot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.statusDot.none { background: #444; }
.statusDot.inprogress { background: #f0ad4e; }
.statusDot.complete { background: var(--success); }
.statusDot.flagged { background: var(--danger); }

/* Center the dot in the body cell only — the header keeps the default
   left-aligned label so it lines up with the other column headers. */
.td.statusCell { justify-content: center; padding: 0; }

/* Training badge in table */
.trainBadge {
  display: inline-block; font-size: 9px; font-weight: 700;
  margin-left: 4px; flex-shrink: 0; cursor: pointer;
  color: #555; padding: 1px 3px; border-radius: 2px;
}
.trainBadge:hover { background: rgba(255,255,255,0.08); }
.trainBadge.active { color: var(--success); }
.trainBadge.otherMask { color: var(--success); opacity: 0.4; }
.row.hasTrain { background: rgba(76,175,80,0.12); }
.row.hasTrain:hover { background: #1a3a2a; }
.row.hasTrain.selected { background: #1a4535; }
.row.hasTrain.selected:hover { background: #1f4f3f; }

/* Per-row inference indicator. Left-edge accent bar so users can see at a
   glance which case has an inference job running or queued, without
   reshuffling columns. Bar is a real div (not ::before) so it can host
   its own hover tooltip — CSS-only, no JS delay. */
.rowInfBar {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 5px;
  z-index: 3;
  display: none;
}
.row.infRunning .rowInfBar,
.row.infQueued  .rowInfBar { display: block; }
/* Fill via ::before so the pulse animates only the coloured bar, not the
   child tooltip element (which would inherit the parent's opacity). */
.rowInfBar::before {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
}
.row.infRunning .rowInfBar::before {
  background: var(--success, #4caf50);
  animation: rowInfPulse 1.2s ease-in-out infinite;
}
.row.infQueued .rowInfBar::before {
  background: #f0ad4e;
}
@keyframes rowInfPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* Instant styled tooltip on bar hover — matches the .siTooltip pattern
   from the bottom-bar icons. Display flips on :hover with no transition. */
.rowInfTip {
  display: none;
  position: absolute;
  left: 100%; top: 50%; transform: translateY(-50%);
  margin-left: 6px;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 10px; white-space: nowrap;
  font-size: 12px; color: var(--text);
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  pointer-events: none;
  z-index: 220;
}
.rowInfBar:hover .rowInfTip { display: block; }

/* Seg cell in table — only the badges/name are interactive; cell
   padding falls through to row select like any other column.
   segNameWrap absorbs the flex:1 stretch so the inner segActiveName
   is sized to its text content; hovering / clicking the empty area
   inside the wrap doesn't hit the name. */
.segCell { gap: 4px; }
.segNameWrap {
  flex: 1; min-width: 0;
  display: flex; align-items: center;
  overflow: hidden;
}
.segActiveName {
  flex: 0 1 auto; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; color: var(--accent);
  cursor: pointer;
}
.segActiveName:hover { font-weight: 600; }
.segNone { color: #555; font-size: 12px; }
.segBadge {
  font-size: 10px; color: #888; white-space: nowrap; flex-shrink: 0;
  padding: 1px 4px; border-radius: 3px; background: rgba(255,255,255,0.06);
  cursor: pointer;
}
.segBadge:hover { color: var(--accent); background: rgba(0,123,255,0.12); }

/* === DETAIL RESIZE HANDLE === */
#detailResize {
  width: 15px; cursor: col-resize; flex-shrink: 0;
  position: relative;
}
#detailResize::after {
  content: ''; position: absolute; top: 0; bottom: 0;
  left: 5px; width: 3px; background: #333;
}
#detailResize:hover::after, #detailResize.dragging::after { background: var(--accent); }

/* === DETAIL PANEL === */
#detailPanel {
  width: 280px; min-width: 180px; max-width: 60vw;
  background: var(--bg-raised);
  display: flex; flex-direction: column; overflow: hidden;
}
#detailPreview {
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  flex-shrink: 0;
}
#detailPreview .previewMain {
  width: 100%; aspect-ratio: 1; object-fit: contain;
  background: #0e0e1a; border-radius: 3px; display: block;
}
#previewSmall { display: flex; gap: 4px; }
#previewSmall img {
  flex: 1; min-width: 0; aspect-ratio: 1; object-fit: contain;
  background: #0e0e1a; border-radius: 3px; display: block;
}
/* The thumbnail whose plane matches the volume's stored slice axis (the
   affine-detected in-plane view) gets a subtle lighter-blue outline.
   Outline (not border) so it doesn't shift flex layout, and offset inwards
   so it sits on top of the radius. */
#detailPreview img.nativePlane {
  outline: 1.5px solid #4da3ff;
  outline-offset: -1.5px;
}
#detailActions {
  padding: 6px; flex-shrink: 0; display: flex; gap: 4px;
}
#btnOpen {
  flex: 1; padding: 9px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#btnOpen:hover { background: var(--accent-hover); }
#btnOpen:disabled { background: #333; color: #666; cursor: default; }
#btnOpenVR {
  padding: 9px 12px; border: none; border-radius: 7px;
  background: #7c3aed; color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#btnOpenVR:hover { background: #6d28d9; }
.btnSecondary {
  padding: 9px 12px; border: 1px solid #444; border-radius: 7px;
  background: transparent; color: #aaa; font-size: 12px;
  cursor: pointer;
}
.btnSecondary:hover { background: #333; color: #fff; border-color: #666; }
#detailInfo {
  flex: 1; overflow-y: auto; overflow-x: hidden; padding: 10px; font-size: 12px;
  line-height: 1.7; color: var(--text-dim); min-height: 0;
}
#detailInfo::-webkit-scrollbar { width: 4px; }
#detailInfo::-webkit-scrollbar-thumb { background: #333; border-radius: 2px; }
#detailInfo .detailTitle {
  color: var(--text-bright); font-weight: 600; font-size: 13px;
  margin-bottom: 6px; word-break: break-word;
}
#btnNextMask {
  flex-shrink: 0; margin-left: 6px; padding: 4px 10px;
  border: 1px solid #444; border-radius: 5px;
  background: transparent; color: var(--accent); font-size: 11px;
  font-weight: 600; cursor: pointer; white-space: nowrap;
}
#btnNextMask:hover { background: #222; border-color: var(--accent); }
#detailInfo .detailSection {
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border);
}
#detailInfo .detailSection h4 {
  font-size: 11px; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.5px; margin-bottom: 4px;
}
.detailRow { display: flex; gap: 6px; }
.detailKey { color: #555; min-width: 70px; flex-shrink: 0; }

/* Track 2: segmentation version history pip + collapsible list.
   Only renders when version > 1, so single-save segs see nothing. */
.segHistoryPip {
  background: transparent; border: 1px solid #3a3a5a; color: var(--text-dim);
  font-size: 11px; padding: 3px 8px; border-radius: 12px;
  cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
}
.segHistoryPip:hover { color: var(--accent); border-color: var(--accent); }
.segHistoryPip[aria-expanded="true"] { color: var(--text); border-color: #555; }
.segHistoryList {
  margin-top: 6px; padding: 6px 4px;
  font-size: 11px; color: var(--text-dim);
  border-left: 2px solid #2a2a3a;
  max-height: 180px; overflow-y: auto;
}
.segHistoryRow {
  display: grid;
  grid-template-columns: 28px 1fr auto auto;
  gap: 6px; align-items: baseline;
  padding: 2px 6px;
}
.segHistoryV { color: #888; font-variant-numeric: tabular-nums; }
.segHistoryWhen { color: #666; }
.segHistoryWho { color: #777; font-style: italic; }
.segHistoryState { color: #555; font-size: 10px; text-transform: uppercase; letter-spacing: 0.3px; }
.segHistoryState strong { color: var(--accent); font-weight: 600; }

/* Track 2: comments thread on the segmentation in detail panel.
   Pip shows count or "+ comment". Panel collapses to keep panel quiet. */
.commentsPip {
  background: transparent; border: 1px solid #3a3a5a; color: var(--text-dim);
  font-size: 11px; padding: 3px 10px; border-radius: 12px;
  cursor: pointer; display: inline-flex; align-items: center;
}
.commentsPip:hover { color: var(--accent); border-color: var(--accent); }
.commentsPip[aria-expanded="true"] { color: var(--text); border-color: #555; }
.commentsPipEmpty { color: #555; }
.commentsPanel {
  margin-top: 6px; padding: 6px 4px;
  font-size: 11px; color: var(--text-dim);
  border-left: 2px solid #2a2a3a;
  max-height: 260px; overflow-y: auto;
}
.commentsEmpty { color: #555; padding: 4px 6px; font-style: italic; }
.commentRow { padding: 6px; border-bottom: 1px solid #1f1f2c; }
.commentRow:last-of-type { border-bottom: none; }
.commentMeta {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; color: #666; margin-bottom: 2px;
}
.commentAuthor { color: #999; font-weight: 600; }
.commentWhen { color: #555; flex: 1; }
.commentResolved { color: #4d6c4d; font-size: 9px; text-transform: uppercase; }
.commentResolveBtn {
  background: transparent; border: 1px solid #2a2a3a;
  color: #555; cursor: pointer; padding: 0 5px; border-radius: 3px;
  font-size: 11px; line-height: 1.4;
}
.commentResolveBtn:hover { color: #6aa86a; border-color: #6aa86a; }
.commentResolveBtn:disabled { opacity: 0.4; cursor: default; }
.commentBody {
  color: #aaa; line-height: 1.4; white-space: pre-wrap; word-break: break-word;
}
.commentForm {
  display: flex; flex-direction: column; gap: 4px;
  padding: 6px; border-top: 1px solid #1f1f2c; margin-top: 4px;
}
.commentInput {
  background: #15151c; color: var(--text); border: 1px solid #2a2a3a;
  border-radius: 4px; font-size: 11px; padding: 5px 7px; resize: vertical;
  min-height: 28px; font-family: inherit;
}
.commentInput:focus { border-color: var(--accent); outline: none; }
.commentFormActions { display: flex; justify-content: flex-end; }
.commentSubmitBtn {
  background: var(--accent); color: #fff; border: none;
  border-radius: 4px; padding: 3px 12px; font-size: 11px; cursor: pointer;
}
.commentSubmitBtn:hover { background: var(--accent-hover); }
.commentSubmitBtn:disabled { opacity: 0.5; cursor: default; }
#btnLogout { color: #888 !important; }
#btnLogout:hover { color: var(--danger) !important; border-color: var(--danger) !important; }

/* === STATUS BAR === */
#statusBar {
  height: 22px; background: var(--bg-raised); border-top: 1px solid var(--border);
  display: flex; align-items: center; padding: 0 10px; font-size: 11px;
  color: #555; justify-content: space-between; flex-shrink: 0; gap: 8px;
}

/* Multi-select / selection action bar — sits between the table body and the
   status bar. Visible whenever ≥1 row is selected; surfaces the bulk verbs
   so the user doesn't have to discover the right-click / kebab menu. */
#selBar {
  height: 38px; background: #1e2745; border-top: 1px solid #2a3a5a;
  display: flex; align-items: center; padding: 0 8px; gap: 6px;
  flex-shrink: 0;
}
.selBarBtn {
  background: #2a3550; border: 1px solid #3a4565; color: #ddd;
  padding: 4px 12px; font-size: 12px; border-radius: 4px; cursor: pointer;
  line-height: 1;
}
.selBarBtn:hover { background: #354060; border-color: #4a5575; color: #fff; }
.selBarBtn.selBarDanger { color: #f55; border-color: #4a3050; }
.selBarBtn.selBarDanger:hover { background: rgba(255,80,80,0.15); border-color: #6a3050; color: #fff; }
.selBarSpacer { flex: 1; }
.selBarClose {
  background: transparent; border: none; color: #888; font-size: 18px;
  line-height: 1; cursor: pointer; padding: 2px 8px; border-radius: 4px;
}
.selBarClose:hover { color: #fff; background: rgba(255,255,255,0.06); }
.statusSummary {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 10px;
}

/* === CONTEXT MENU === */
.ctxMenu {
  position: fixed; background: var(--bg-input); border: 1px solid #444;
  border-radius: 7px; padding: 3px 0; min-width: 170px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.45); z-index: 600;
}
.ctxItem {
  padding: 5px 14px; cursor: pointer; color: var(--text);
  font-size: 12px;
}
.ctxItem:hover { background: #333; color: var(--text-bright); }
.ctxItem.danger { color: var(--danger); }
.ctxItem.disabled { color: #555; pointer-events: none; }
.ctxItem.hasSecondary { display: flex; align-items: center; }
.ctxItem.hasSecondary:not(.ctxCheck) > span:first-child { flex: 1; }
.ctxSecondary {
  margin-left: auto; padding: 0 4px; font-size: 13px; color: #666; cursor: pointer; border-radius: 3px;
}
.ctxSecondary:hover { color: var(--danger, #f44336); background: rgba(244,67,54,0.1); }
.ctxSecondaryActive { color: var(--success) !important; font-weight: 700; }
.ctxSecondaryActive:hover { color: var(--success) !important; background: rgba(76,175,80,0.15); }
.ctxSep { height: 1px; background: #3a3a5a; margin: 3px 0; }
.ctxLabel { padding: 4px 14px; font-size: 10px; color: #555; text-transform: uppercase; letter-spacing: 0.5px; }
.ctxCheck {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; color: var(--text);
  padding: 7px 14px; letter-spacing: 0.2px;
}
.ctxCheck:hover { background: rgba(0,123,255,0.12); color: #fff; }
.ctxChecked { color: var(--accent); font-weight: 600; background: rgba(0,123,255,0.08); }
.ctxTick { width: 18px; text-align: center; font-size: 14px; color: var(--accent); flex-shrink: 0; }

/* === COMMENT COLUMN ===
   Only the visible text / "Add comment" placeholder is interactive;
   the surrounding cell padding falls through to row select. */
.commentPlaceholder {
  color: var(--text-dim); font-size: 12px; opacity: 0.5;
  cursor: pointer;
}
.commentPlaceholder:hover { opacity: 1; }
.commentText {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; color: var(--text);
  cursor: pointer;
}
.commentText:hover { color: var(--text-bright); }

/* === COMMENT MODAL === */
#commentModal {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#commentModalContent {
  width: 380px; padding: 24px;
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#commentModalContent h2 { color: var(--text-bright); font-size: 16px; margin-bottom: 14px; }
#commentText {
  display: block; width: 100%; padding: 10px 12px;
  border: 1px solid #444; border-radius: 6px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px;
  font-family: inherit; resize: vertical; outline: none;
}
#commentText:focus { border-color: var(--accent); }
#commentActions { display: flex; gap: 8px; margin-top: 16px; }
#commentSave {
  flex: 1; padding: 9px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#commentSave:hover { background: var(--accent-hover); }
#commentDelete:hover { border-color: var(--danger); color: var(--danger); }
#commentActions .btnSecondary { padding: 9px 14px; }

/* === MERGE MASKS MODAL === */
#mergeModal {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#mergeModalContent {
  position: relative;
  width: 380px; max-width: 92vw; padding: 24px;
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#mergeModalContent h2 { color: var(--text-bright); font-size: 16px; margin-bottom: 14px; }
#mergeModalContent label {
  display: block; margin-bottom: 10px;
  color: var(--text-dim); font-size: 12px;
}
#mergeModalContent select,
#mergeModalContent input[type="text"] {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  border: 1px solid #444; border-radius: 6px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px;
  font-family: inherit; outline: none;
}
#mergeModalContent select:focus,
#mergeModalContent input[type="text"]:focus { border-color: var(--accent); }
#mergeActions { display: flex; gap: 8px; margin-top: 16px; }
#mergeStartBtn {
  flex: 1; padding: 9px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#mergeStartBtn:hover { background: var(--accent-hover); }
#mergeStartBtn:disabled { opacity: 0.5; cursor: not-allowed; }
#mergeActions .btnSecondary { padding: 9px 14px; }
#mergeStatus {
  margin-top: 12px; padding: 8px 10px; border-radius: 6px;
  font-size: 12px; text-align: center;
}
#mergeStatus.success { background: rgba(34,197,94,0.15); color: #22c55e; }
#mergeStatus.error { background: rgba(239,68,68,0.15); color: #ef4444; }

/* === DICOM EXPORT MODAL === */
#dicomModal {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#dicomModalContent {
  position: relative;
  width: 560px; max-width: 94vw; max-height: 90vh; overflow-y: auto;
  padding: 24px;
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#dicomModalContent h2 { color: var(--text-bright); font-size: 16px; margin-bottom: 10px; }
#dicomBlurb {
  color: var(--text-dim); font-size: 12px;
  margin: 0 0 16px; line-height: 1.5;
}
#dicomBlurb code { font-family: monospace; font-size: 11px; color: var(--text); }

/* Description text input */
#dicomModalContent label.dicomTextRow {
  display: block; margin-bottom: 16px;
  color: var(--text-dim); font-size: 12px;
}
#dicomModalContent input[type="text"] {
  display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
  border: 1px solid #444; border-radius: 6px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px;
  font-family: inherit; outline: none; box-sizing: border-box;
}
#dicomModalContent input[type="text"]:focus { border-color: var(--accent); }

/* "What to include" header */
.dicomFormatsHeader {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-dim); margin-bottom: 8px; font-weight: 600;
}
#dicomFormats { display: flex; flex-direction: column; gap: 4px; }

/* Each format row: checkbox on the left, name + description on the right.
   Higher specificity than `#dicomModalContent label` (block) so flex sticks. */
#dicomModalContent label.dicomFormatRow {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; border-radius: 8px;
  background: rgba(255,255,255,0.02); border: 1px solid transparent;
  cursor: pointer; margin: 0;
}
#dicomModalContent label.dicomFormatRow:hover {
  background: rgba(255,255,255,0.04); border-color: #333;
}
#dicomModalContent label.dicomFormatRow input[type="checkbox"] {
  margin: 3px 0 0 0; flex-shrink: 0;
}
.dicomFormatInfo { flex: 1; min-width: 0; }
.dicomFormatName {
  color: var(--text-bright); font-size: 13px; font-weight: 600;
  margin-bottom: 2px;
}
.dicomFormatDesc {
  color: var(--text-dim); font-size: 11px; line-height: 1.45;
}
.dicomFormatDesc code {
  font-family: monospace; font-size: 10px; color: var(--text);
  background: rgba(255,255,255,0.06); padding: 0 4px; border-radius: 3px;
}

/* Sub-checkbox indented under a parent format row (the "burn volumes"
   toggle nested under RGB). */
.dicomSubCheck {
  display: flex !important; gap: 6px; align-items: flex-start;
  margin: 8px 0 0 0; padding-top: 6px;
  border-top: 1px dashed rgba(255,255,255,0.06);
  font-size: 11px; color: var(--text-dim);
  cursor: pointer;
}
.dicomSubCheck input[type="checkbox"] { margin: 1px 0 0 0; }

#dicomActions { display: flex; gap: 8px; margin-top: 18px; }
#dicomStartBtn {
  flex: 1; padding: 10px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#dicomStartBtn:hover { background: var(--accent-hover); }
#dicomStartBtn:disabled { opacity: 0.5; cursor: not-allowed; }
#dicomActions .btnSecondary { padding: 10px 16px; }
#dicomStatus {
  margin-top: 12px; padding: 8px 10px; border-radius: 6px;
  font-size: 12px; text-align: center;
}
#dicomStatus.success { background: rgba(34,197,94,0.15); color: #22c55e; }
#dicomStatus.error { background: rgba(239,68,68,0.15); color: #ef4444; }

/* === VOLUME-ANALYSIS (REPORT) MODAL === */
#reportModal {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#reportModalContent {
  position: relative;
  width: 420px; max-width: 92vw;
  max-height: 88vh; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 24px;
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}

/* Generic small X-in-the-corner close button. Reusable across modals. */
.modalCloseX {
  position: absolute; top: 10px; right: 12px;
  width: 28px; height: 28px; padding: 0;
  border: none; background: transparent;
  color: var(--text-dim); font-size: 22px; line-height: 1;
  cursor: pointer; border-radius: 5px;
}
.modalCloseX:hover { background: rgba(255,255,255,0.08); color: var(--text-bright); }
/* Expand the modal for the results view — the table needs more space. */
#reportModalContent:has(#reportModalResults:not([style*="display:none"])),
#reportModalContent:has(#reportModalResults[style=""]) {
  width: 92vw;
  max-width: 1200px;
}
#reportModalContent h2 { color: var(--text-bright); font-size: 16px; margin-bottom: 10px; }
.reportSummary { font-size: 12px; color: var(--text-dim); margin-bottom: 16px; }
#reportModalOptions label {
  display: block; font-size: 13px; color: var(--text); margin-bottom: 10px; cursor: pointer;
}
#reportModalOptions .radioRow { margin-top: 4px; }
#reportModalProgress {
  margin: 4px 0 12px;
  padding: 12px; background: #222; border-radius: 8px;
}
.reportProgressLabel { font-size: 12px; color: var(--text-dim); margin-bottom: 8px; }
.reportProgressBar { width: 100%; height: 6px; accent-color: var(--accent); }
#reportModalActions { display: flex; gap: 8px; margin-top: 8px; }
#reportStartBtn {
  flex: 1; padding: 9px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#reportStartBtn:hover { background: var(--accent-hover); }
#reportStartBtn:disabled { opacity: 0.6; cursor: not-allowed; }
#reportModalActions .btnSecondary { padding: 9px 14px; }

/* Results view inside the report modal */
#reportModalResults {
  display: flex; flex-direction: column;
  gap: 10px; min-height: 0; flex: 1;
}
.reportResultsStats {
  font-size: 11px; color: var(--text-dim);
}
#reportResultsTableWrap {
  flex: 1; min-height: 0; overflow: auto;
  border: 1px solid #2a2a3a; border-radius: 6px;
  background: #18182a;
}
#reportResultsTable {
  width: 100%; border-collapse: collapse; font-size: 12px;
  color: var(--text);
}
#reportResultsTable th,
#reportResultsTable td {
  padding: 5px 8px; text-align: left;
  border-bottom: 1px solid #24243a;
  white-space: nowrap;
  max-width: 240px; overflow: hidden; text-overflow: ellipsis;
}
#reportResultsTable th {
  position: sticky; top: 0; z-index: 1;
  background: #22223a; color: var(--text-bright);
  cursor: pointer; user-select: none;
  font-weight: 600; font-size: 11px;
  letter-spacing: 0.02em;
}
#reportResultsTable th:hover { background: #2a2a45; }
#reportResultsTable tbody tr { cursor: pointer; }
#reportResultsTable tbody tr:hover { background: #20203a; }
#reportResultsTable tbody tr.rrSelected,
#reportResultsTable tbody tr.rrSelected:hover {
  background: #2a3a66;
  outline: 1px solid var(--accent, #4a7cff);
  outline-offset: -1px;
}
#reportResultsTable td.rrEmpty { color: #555; font-style: italic; }
#reportResultsTable td.rrOutlier { color: #ff8b7c; font-weight: 600; }

#reportResultsDownloads {
  display: flex; gap: 8px; align-items: center;
  padding-top: 8px; font-size: 12px; color: var(--text-dim);
  border-top: 1px solid #24243a;
}
.reportDlLabel { margin-right: 4px; }
.reportDlBtn {
  padding: 6px 12px; border: 1px solid #3a3a55; border-radius: 6px;
  background: transparent; color: var(--text); font-size: 12px; cursor: pointer;
}
.reportDlBtn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.reportDlBtn:disabled { opacity: 0.5; cursor: not-allowed; }

/* === TRAINING MODAL === */
#trainModal {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.6);
}
#trainModalContent {
  width: 380px; padding: 24px;
  background: var(--bg-input); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#trainModalContent h2 { color: var(--text-bright); font-size: 16px; margin-bottom: 14px; }
#trainInfo { font-size: 12px; color: var(--text-dim); margin-bottom: 14px; line-height: 1.6; }
#trainInfo .trainWarn { color: var(--danger); }
#trainInfo .trainSubtle { color: var(--text-dim); }
#trainBasic label, #trainAdvanced label {
  display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 10px;
}
#trainBasic input[type="text"], #trainAdvanced input[type="number"] {
  display: block; width: 100%; margin-top: 4px; padding: 7px 10px;
  border: 1px solid #444; border-radius: 6px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px; outline: none;
}
#trainBasic input:focus, #trainAdvanced input:focus { border-color: var(--accent); }
.sliderRow { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.sliderRow input[type="range"] { flex: 1; accent-color: var(--accent); }
#trainDurationLabel { font-size: 13px; color: var(--text-bright); min-width: 55px; }
.radioRow { display: flex; gap: 14px; margin-top: 4px; }
.radioRow label { display: flex; align-items: center; gap: 4px; color: var(--text); font-size: 13px; cursor: pointer; }
#trainAdvancedToggle {
  margin: 10px 0; font-size: 11px; color: var(--accent); cursor: pointer;
}
#trainAdvancedToggle:hover { text-decoration: underline; }
#trainAdvanced { border-top: 1px solid var(--border); padding-top: 10px; margin-bottom: 6px; }
#trainAdvanced label { cursor: pointer; }
#trainTransferModel {
  width: 100%; padding: 6px 8px; margin-top: 4px;
  border: 1px solid #444; border-radius: 6px;
  background: #2a2a2a; color: var(--text-bright); font-size: 13px;
}
#trainActions { display: flex; gap: 8px; margin-top: 16px; }
#trainStart {
  flex: 1; padding: 9px; border: none; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  font-weight: 600; cursor: pointer;
}
#trainStart:hover { background: var(--accent-hover); }
#trainStart:disabled { background: #333; color: #666; cursor: default; }
#trainActions .btnSecondary { padding: 9px 14px; }


/* Train button active state */
#btnTrain.training { color: #FFA726 !important; border-color: #FFA726 !important; animation: pulse 2s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.6; } }

/* === TOTALSEGMENTATOR MODAL === */
.tsOverlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 500; }
.tsModal {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: 540px; max-height: 85vh; overflow-y: auto;
  background: var(--bg-input); color: var(--text); border-radius: 12px;
  padding: 20px 20px 0; box-shadow: 0 12px 40px rgba(0,0,0,0.5); z-index: 501;
}
.tsExplainer {
  font-size: 12px; color: #aaa; line-height: 1.55;
  background: rgba(255,255,255,0.03); border-left: 2px solid var(--accent);
  padding: 8px 12px; border-radius: 4px; margin: 4px 0 14px;
}
.tsExplainer b { color: #ddd; }
.tsModal::-webkit-scrollbar { width: 6px; }
.tsModal::-webkit-scrollbar-thumb { background: #444; border-radius: 3px; }
.tsTitle { font-size: 17px; font-weight: 600; color: var(--text-bright); margin-bottom: 4px; }
.tsSubtitle { font-size: 11px; color: var(--text-dim); margin-bottom: 14px; }
.tsSectionHeader { font-size: 14px; font-weight: 600; color: var(--text-bright); margin-top: 14px; margin-bottom: 6px; border-bottom: 2px solid var(--accent); padding-bottom: 4px; }
.tsTaskRow {
  display: flex; justify-content: space-between; align-items: center;
  padding: 5px 4px; cursor: pointer; border-radius: 4px; margin-top: 3px;
}
.tsTaskRow:hover { background: rgba(255,255,255,0.04); }
.tsTaskLabel { font-size: 13px; font-weight: 600; color: #bbb; }
.tsCount { color: var(--text-dim); font-size: 11px; font-weight: 400; }
.tsSelectAll { font-size: 11px; color: var(--accent); cursor: pointer; padding: 2px 6px; border-radius: 3px; }
.tsSelectAll:hover { background: rgba(255,255,255,0.06); }
.tsContent { padding-left: 8px; border-left: 2px solid #444; margin-left: 6px; margin-bottom: 4px; }
.tsSubgroupHeader { display: flex; justify-content: space-between; align-items: center; margin-top: 6px; margin-bottom: 2px; border-bottom: 1px solid #3a3a5a; padding-bottom: 2px; }
.tsSubgroupHeader span:first-child { font-size: 12px; font-weight: 600; color: #999; }
.tsStructRow { display: flex; align-items: center; padding: 2px 12px; cursor: pointer; border-radius: 3px; font-size: 11px; gap: 8px; }
.tsStructRow:hover { background: rgba(255,255,255,0.04); }
.tsStructRow input { flex-shrink: 0; }
.tsBtnRow {
  display: flex; justify-content: flex-end; gap: 10px;
  position: sticky; bottom: 0;
  margin: 16px -20px 0; padding: 12px 20px;
  background: var(--bg-input); border-top: 1px solid #2a2a45;
}
.tsRunBtn {
  padding: 8px 24px; background: var(--accent); color: #fff; border: none;
  border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.tsRunBtn:hover { background: var(--accent-hover); }
.tsRunBtn:disabled { background: #2a2a3a; color: #777; cursor: not-allowed; }
.tsRunBtn:disabled:hover { background: #2a2a3a; }

/* Status icons */
#statusIcons { display: flex; gap: 6px; align-items: center; }
.statusIcon {
  display: flex; align-items: center; gap: 4px; padding: 4px 8px;
  border-radius: 6px; cursor: pointer; font-size: 11px; color: var(--text-dim);
  position: relative;
}
.statusIcon:hover { background: rgba(255,255,255,0.06); color: var(--text-bright); }
.statusIcon svg { opacity: 0.6; }
.statusIcon:hover svg { opacity: 1; }
.siLabel { user-select: none; }
.siDot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
  background: #555; transition: background 0.3s;
}
.statusIcon.running .siDot { background: #4caf50; animation: pulse 1.5s infinite; }
.statusIcon.pulse { animation: iconPulse 0.4s ease-out; }
@keyframes iconPulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } }
.statusIcon.queued .siDot { background: #ff9800; }
.statusIcon.idle .siDot { background: #555; }

/* Active states get a coloured chip so first-time users notice the icon
   without hunting for the 6-px dot. */
.statusIcon.running {
  background: rgba(76,175,80,0.14);
  color: var(--text-bright);
  box-shadow: 0 0 0 1px rgba(76,175,80,0.35);
}
.statusIcon.running:hover { background: rgba(76,175,80,0.22); }
.statusIcon.queued {
  background: rgba(255,152,0,0.12);
  color: var(--text-bright);
  box-shadow: 0 0 0 1px rgba(255,152,0,0.30);
}
.statusIcon.queued:hover { background: rgba(255,152,0,0.20); }

/* Small queue-count badge next to the label. Hidden by default; JS reveals
   when count > 0. */
.siCount {
  font-size: 10px; font-weight: 700; line-height: 1;
  padding: 2px 5px; border-radius: 8px;
  background: rgba(255,152,0,0.85); color: #1a1a1a;
  margin-left: 2px;
}
.statusIcon.running .siCount { background: rgba(76,175,80,0.85); }
.siCount[hidden] { display: none; }
.siTooltip {
  display: none; position: absolute; bottom: 100%; left: 0; margin-bottom: 6px;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; min-width: 220px; max-width: 320px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.5); z-index: 210;
  font-size: 12px; color: var(--text); white-space: normal;
}
.statusIcon:hover .siTooltip { display: block; }
.statusIcon.panelOpen .siTooltip { display: none !important; }
.siTooltip b { color: var(--text-bright); }
.siTooltipMetrics { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 4px; font-size: 11px; color: var(--text-dim); }
.siTooltipQueue { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--border); font-size: 11px; color: var(--text-dim); }
#jobPanel {
  position: fixed; bottom: 28px; width: 440px; max-width: calc(100vw - 16px); max-height: 60vh;
  background: #1e1e1e; border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.5); z-index: 200; overflow: hidden;
  display: flex; flex-direction: column;
}
#jobPanelHeader {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-weight: 600; font-size: 13px; color: var(--text-bright);
}
#jobPanelClose { cursor: pointer; font-size: 18px; color: var(--text-dim); }
#jobPanelClose:hover { color: var(--text-bright); }
#jobPanelContent { overflow-y: auto; padding: 8px 0; max-height: calc(70vh - 42px); }
.jobSection { padding: 4px 14px 8px; }
.jobSectionTitle { font-size: 10px; text-transform: uppercase; color: var(--text-dim); letter-spacing: 0.5px; margin-bottom: 6px; }
.jobItem { padding: 6px 0; font-size: 12px; color: var(--text); display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.jobItem + .jobItem { border-top: 1px solid rgba(255,255,255,0.04); }
.jobItemHeader { display: flex; align-items: center; gap: 6px; width: 100%; }
.jobElapsed { margin-left: auto; font-size: 11px; color: var(--text-dim); }
.jobStatus {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.jobStatus.running { background: #4caf50; animation: pulse 1.5s infinite; }
.jobStatus.queued { background: #ff9800; }
.jobStatus.done { background: #4caf50; }
.jobStatus.failed { background: #f44336; }
.jobStatus.cancelled { background: #888; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
.jobProgress { width: 100%; height: 4px; background: rgba(255,255,255,0.08); border-radius: 2px; margin: 4px 0; }
.jobProgressBar { height: 100%; background: var(--accent); border-radius: 2px; transition: width 0.5s; }
.jobMetrics { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--text-dim); width: 100%; }
.jobMetrics span { white-space: nowrap; }
.jobActions { display: flex; gap: 6px; width: 100%; margin-top: 4px; }
.jobBtn {
  padding: 3px 10px; border: 1px solid var(--border); border-radius: 4px;
  background: transparent; color: var(--text); font-size: 11px; cursor: pointer;
}
.jobBtn:hover { background: rgba(255,255,255,0.06); }
.jobBtnAbort { border-color: #f44336; color: #f44336; }
.jobBtnAbort:hover { background: rgba(244,67,54,0.1); }
.jobBtnCancel { border-color: #ff9800; color: #ff9800; }
.jobBtnCancel:hover { background: rgba(255,152,0,0.1); }
/* Save snapshot is the safest action — pure copy, no side effects on
 * the running training. Green. Stop & Save interrupts the run so it
 * gets the warning tone (yellow). Abort stays red. */
.jobBtnSave { border-color: #4caf50; color: #4caf50; }
.jobBtnSave:hover { background: rgba(76,175,80,0.1); }
.jobBtnStop { border-color: #ffc107; color: #ffc107; }
.jobBtnStop:hover { background: rgba(255,193,7,0.1); }
.jobEmpty { font-size: 11px; color: var(--text-dim); padding: 4px 0; }
.jobDetail { font-size: 11px; color: var(--text-dim); width: 100%; }
.jobError { color: var(--text-dim); font-size: 11px; }
.jobRecent { opacity: 0.7; }
