/* ==========================================================
   AI Lab — design system + workspace styles
   ========================================================== */

:root {
  --ailab-bg: #0d0d0f;
  --ailab-surface: #131316;
  --ailab-surface-2: #1a1a1e;
  --ailab-surface-3: #202026;
  --ailab-border: rgba(255,255,255,0.08);
  --ailab-border-strong: rgba(255,255,255,0.14);
  --ailab-text: #e8e8ea;
  --ailab-text-muted: #8a8a9a;
  --ailab-text-dim: #6a6a78;
  --ailab-accent: #4f98a3;
  --ailab-accent-hover: #3d7d87;
  --ailab-accent-soft: rgba(79,152,163,0.18);
  --ailab-positive: #6daa45;
  --ailab-negative: #dd6974;
  --ailab-neutral: #8a8a9a;
  --ailab-dot-color: rgba(255,255,255,0.06);
  --ailab-header-height: 44px;
  --ailab-right-pane-width: 48px;
  --ailab-draw-panel-width: 132px;
  --ailab-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --ailab-mono: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--ailab-bg);
  color: var(--ailab-text);
  font-family: var(--ailab-font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.ailab-page {
  overflow: hidden;
  height: 100vh;
}

/* ===== Root container ===== */
.ailab-root {
  position: relative;
  width: 100%;
  /* Account for unified topbar; topbar height is auto, so use flex column on body */
  height: calc(100vh - 0px);
  background: var(--ailab-bg);
}

/* ===== Mobile blocker ===== */
.ailab-mobile-block {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--ailab-bg);
  z-index: 9000;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
}
.ailab-mobile-block-inner {
  max-width: 320px;
}
.ailab-mobile-block-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 16px;
  border-radius: 12px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ailab-accent);
}
.ailab-mobile-block-icon svg { width: 26px; height: 26px; }
.ailab-mobile-block h2 {
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--ailab-text);
}
.ailab-mobile-block p {
  font-size: 13px;
  color: var(--ailab-text-muted);
  margin: 0;
  line-height: 1.5;
}
@media (max-width: 767px) {
  .ailab-mobile-block { display: flex; }
  .ailab-shell { display: none; }
}

/* ===== Gate (loading / no access) ===== */
.ailab-gate {
  position: fixed;
  inset: 0;
  background: var(--ailab-bg);
  z-index: 8000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.ailab-gate[hidden] { display: none !important; }
.ailab-gate .ailab-btn[hidden] { display: none !important; }
.ailab-gate-inner {
  text-align: center;
  max-width: 360px;
}
.ailab-gate-inner h2 {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--ailab-text);
}
.ailab-gate-inner p {
  font-size: 13px;
  color: var(--ailab-text-muted);
  margin: 0 0 20px;
  line-height: 1.5;
}

/* ===== Application shell ===== */
.ailab-shell {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  /* Topbar sits above; the page's own scroll is hidden because we are full-bleed */
}
.ailab-shell[hidden] { display: none !important; }

/* ===== Header bar ===== */
.ailab-header {
  height: var(--ailab-header-height);
  flex-shrink: 0;
  background: var(--ailab-bg);
  border-bottom: 1px solid var(--ailab-border);
  display: flex;
  align-items: center;
  padding: 0 16px;
  gap: 16px;
  position: relative;
  /* Must sit above the floating draw panel (z-index: 7500 inside the
     workspace) so the Add Widget dropdown isn't covered by the panel. */
  z-index: 8000;
}
.ailab-header-left {
  display: flex;
  align-items: center;
  gap: 5px; /* Iter 12S — halved from 10px to tighten logo → focus icon spacing */
}
.ailab-header-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
}
.ailab-header-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  border-radius: 6px;
  cursor: pointer;
  color: var(--ailab-text-muted);
  transition: background 120ms, color 120ms;
}
.ailab-header-icon-btn:hover { background: var(--ailab-surface); color: var(--ailab-text); }
.ailab-header-icon-btn svg { width: 18px; height: 18px; }
.ailab-header-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ailab-accent);
}

/* Iter 12Q — matrix-mark AI Lab logo (3x3 pixel grid + "AI LAB" wordmark).
   Replaces the burger menu icon and the wordmark. Sized to fit the existing
   44px header height with minimal padding so the header does not need to
   grow. Clicking opens /dashboard?dbtab=watchlists. The SVG's inline
   #1a7a7a wordmark fill is too dim against the dark header bg, so we
   re-tint it via CSS to the brighter accent teal. */
.ailab-header-logo {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 4px;
  margin-left: -4px;
  border-radius: 6px;
  text-decoration: none;
  transition: background 120ms ease, transform 120ms ease, filter 120ms ease;
}
.ailab-header-logo:hover {
  background: var(--ailab-surface);
  filter: brightness(1.15);
}
.ailab-header-logo:active { transform: scale(0.97); }
.ailab-header-logo:focus-visible {
  outline: 2px solid var(--ailab-accent);
  outline-offset: 2px;
}
.ailab-header-logo-svg {
  height: 40px;
  width: auto;
  display: block;
}
/* Re-tint the SVG for the dark theme. Original inline fills:
   #1a7a7a (wordmark text) and #1a9999 (matrix tiles). */
.ailab-header-logo-svg text { fill: var(--ailab-accent); }
.ailab-header-logo-svg rect[fill="#1a9999"] { fill: var(--ailab-accent); }
.ailab-token-counter {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
  padding: 6px 10px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  cursor: help;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.ailab-token-counter:hover,
.ailab-token-counter:focus-visible {
  border-color: var(--ailab-accent);
  outline: none;
}

/* AI Lab — token-counter tooltip ----------------------------------------- */
/* Hidden until the counter is hovered or focused. Shows three rows so the
   user can see at a glance what each cost figure means. */
.ailab-token-tooltip {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 1200;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 220px;
  padding: 10px 12px;
  background: var(--ailab-bg, #14141a);
  color: var(--ailab-text);
  border: 1px solid var(--ailab-border-strong, #2a2a32);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-size: 11.5px;
  line-height: 1.35;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s linear;
  pointer-events: none;
  white-space: nowrap;
}
.ailab-token-counter:hover .ailab-token-tooltip,
.ailab-token-counter:focus-visible .ailab-token-tooltip {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
/* Little caret pointing back up at the counter */
.ailab-token-tooltip::before {
  content: "";
  position: absolute;
  top: -5px;
  right: 18px;
  width: 8px;
  height: 8px;
  background: var(--ailab-bg, #14141a);
  border-top: 1px solid var(--ailab-border-strong, #2a2a32);
  border-left: 1px solid var(--ailab-border-strong, #2a2a32);
  transform: rotate(45deg);
}
.ailab-token-tooltip-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.ailab-token-tooltip-label {
  color: var(--ailab-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ailab-token-tooltip-value {
  color: var(--ailab-text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ailab-token-tooltip-foot {
  margin-top: 2px;
  padding-top: 6px;
  border-top: 1px solid var(--ailab-border, #1f1f26);
  font-size: 10.5px;
  color: var(--ailab-text-dim, #6a6a78);
  font-style: italic;
  text-transform: none;
  letter-spacing: 0;
}
/* AI Lab — token counter: "Token xxxx (today $ / total $)" */
.ailab-token-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ailab-text-muted);
  opacity: 0.75;
}
.ailab-token-num { color: var(--ailab-text); font-weight: 600; }
.ailab-token-cost-group {
  color: var(--ailab-text-muted);
  font-weight: 500;
  margin-left: 2px;
  display: none; /* hidden — backend cost tracking still active */
}
.ailab-token-tooltip-row--cost,
.ailab-token-tooltip-foot--cost { display: none; }
.ailab-token-cost { color: var(--ailab-accent); font-weight: 500; }
.ailab-token-cost-slash {
  color: var(--ailab-border-strong);
  margin: 0 2px;
}
.ailab-token-sep { color: var(--ailab-border-strong); margin: 0 2px; }

/* Quota banner shown when the user hits their monthly cap. */
.ailab-quota-banner {
  position: fixed;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  max-width: 520px;
  padding: 10px 16px;
  background: rgba(220, 38, 38, 0.12);
  border: 1px solid rgba(220, 38, 38, 0.55);
  border-radius: 8px;
  color: #fca5a5;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3);
}
.ailab-quota-banner-close {
  margin-left: auto;
  background: transparent;
  border: 0;
  color: #fca5a5;
  cursor: pointer;
  font-size: 18px;
  padding: 0 4px;
  line-height: 1;
}

/* ===== Buttons ===== */
.ailab-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 120ms, border-color 120ms, color 120ms;
  line-height: 1;
  height: 30px;
}
.ailab-btn-outline {
  background: transparent;
  border-color: var(--ailab-border-strong);
  color: var(--ailab-text);
}
.ailab-btn-outline:hover {
  background: var(--ailab-surface);
  border-color: var(--ailab-text-muted);
}
.ailab-btn-primary {
  background: var(--ailab-accent);
  color: #0d0d0f;
  border-color: var(--ailab-accent);
}
.ailab-btn-primary:hover {
  background: var(--ailab-accent-hover);
  border-color: var(--ailab-accent-hover);
}
.ailab-btn-chev { width: 14px; height: 14px; }
.ailab-btn svg { width: 14px; height: 14px; }

/* ===== Add Widget dropdown — solid dark panel ===== */
.ailab-add-widget-wrap { position: relative; }
.ailab-add-widget-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  /* Solid opaque background — no transparency */
  background: #1a1a1e;
  background-color: #1a1a1e !important;
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: 10px;
  padding: 5px;
  min-width: 210px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.7), 0 4px 16px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04);
  z-index: 8000;
  /* Ensure nothing bleeds through */
  isolation: isolate;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* Section label inside the menu */
.ailab-add-widget-menu-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: rgba(255,255,255,0.35);
  padding: 6px 10px 4px;
}
.ailab-add-widget-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 8px 12px;
  /* Solid background per item — never transparent against page */
  background: transparent;
  border: none;
  border-radius: 7px;
  color: #e8e8ea;
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 100ms, color 100ms;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}
.ailab-add-widget-item:hover {
  background: rgba(255,255,255,0.07);
  color: #ffffff;
}
.ailab-add-widget-item:hover svg {
  color: var(--ailab-accent, #4f98a3);
}
.ailab-add-widget-item svg {
  width: 15px;
  height: 15px;
  color: rgba(255,255,255,0.45);
  flex-shrink: 0;
  transition: color 100ms;
}
.ailab-add-widget-item span {
  flex: 1;
}
/* Divider between groups */
.ailab-add-widget-divider {
  height: 1px;
  background: rgba(255,255,255,0.07);
  margin: 4px 6px;
}

/* ===== Workspace switcher dropdown ===== */
.ailab-ws-switcher { position: relative; }
.ailab-ws-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 220px;
}
.ailab-ws-btn-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 160px;
}
.ailab-ws-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 8px;
  padding: 4px;
  min-width: 240px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.4);
  z-index: 8000;
}
.ailab-ws-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  border-radius: 6px;
  cursor: pointer;
}
.ailab-ws-item:hover { background: var(--ailab-surface-2); }
.ailab-ws-item--active {
  background: var(--ailab-surface-2);
}
.ailab-ws-item--active .ailab-ws-check { color: var(--ailab-accent); }
.ailab-ws-check {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  color: transparent;
}
.ailab-ws-check svg { width: 14px; height: 14px; }
.ailab-ws-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ailab-ws-name-input {
  flex: 1;
  background: var(--ailab-bg);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 4px;
  color: var(--ailab-text);
  font-family: inherit;
  font-size: 13px;
  padding: 4px 6px;
  min-width: 0;
}
.ailab-ws-name-input:focus {
  outline: none;
  border-color: var(--ailab-accent);
}
.ailab-ws-rename-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--ailab-text-muted);
  cursor: pointer;
  padding: 0;
}
.ailab-ws-rename-btn:hover {
  color: var(--ailab-text);
  border-color: var(--ailab-border-strong);
  background: var(--ailab-bg);
}
.ailab-ws-rename-btn svg { width: 12px; height: 12px; }

/* ===== Confirm modal (Reset Workspace, etc.) =================================
   Lightweight in-app dialog that replaces the native window.confirm() prompt.
   Built dynamically by showConfirmModal() so the markup lives entirely in JS
   and doesn't bloat ai-lab.html. Sits above all draw / window content via a
   high z-index. Fade-in driven by the .ailab-confirm--visible toggle so the
   .25s transition runs after the node is appended.
   ============================================================================ */
.ailab-confirm-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 8, 10, 0.6);
  backdrop-filter: blur(4px) saturate(120%);
  -webkit-backdrop-filter: blur(4px) saturate(120%);
  opacity: 0;
  transition: opacity 180ms ease;
  z-index: 9500;
  padding: 24px;
}
.ailab-confirm-overlay.ailab-confirm--visible { opacity: 1; }
.ailab-confirm-dialog {
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 10px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.55);
  padding: 22px 22px 18px;
  transform: translateY(6px) scale(0.98);
  transition: transform 180ms ease;
}
.ailab-confirm-overlay.ailab-confirm--visible .ailab-confirm-dialog {
  transform: translateY(0) scale(1);
}
.ailab-confirm-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ailab-text);
  margin: 0 0 8px;
}
.ailab-confirm-title svg {
  width: 18px;
  height: 18px;
  color: var(--ailab-negative);
  flex: 0 0 18px;
}
.ailab-confirm-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ailab-text-muted);
  margin: 0 0 18px;
}
.ailab-confirm-body strong {
  color: var(--ailab-text);
  font-weight: 600;
}
.ailab-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.ailab-confirm-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  line-height: 1;
  height: 32px;
  border: 1px solid transparent;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.ailab-confirm-btn:focus-visible {
  outline: 2px solid var(--ailab-accent);
  outline-offset: 2px;
}
.ailab-confirm-btn--cancel {
  background: transparent;
  border-color: var(--ailab-border-strong);
  color: var(--ailab-text);
}
.ailab-confirm-btn--cancel:hover {
  background: var(--ailab-surface-2);
  border-color: var(--ailab-text-muted);
}
.ailab-confirm-btn--danger {
  background: var(--ailab-negative);
  border-color: var(--ailab-negative);
  color: #1a0a0c;
  font-weight: 600;
}
.ailab-confirm-btn--danger:hover {
  background: #c95562;
  border-color: #c95562;
}

/* ===== Workspace + canvas ===== */
.ailab-workspace {
  position: relative;
  flex: 1;
  display: flex;
  overflow: hidden;
}
.ailab-canvas {
  flex: 1;
  position: relative;
  background-color: var(--ailab-bg);
  background-image: radial-gradient(circle, var(--ailab-dot-color) 1px, transparent 1px);
  background-size: 24px 24px;
  overflow: hidden;
}
.ailab-canvas.ailab-cursor-crosshair { cursor: crosshair; }

.ailab-empty-state {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.ailab-empty-state-inner {
  text-align: center;
  max-width: 320px;
  color: var(--ailab-text-muted);
}
.ailab-empty-icon {
  width: 56px; height: 56px;
  margin: 0 auto 16px;
  border-radius: 12px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ailab-text-muted);
}
.ailab-empty-icon svg { width: 26px; height: 26px; }
.ailab-empty-state-inner h3 {
  font-size: 14px; font-weight: 600;
  margin: 0 0 6px;
  color: var(--ailab-text);
}
.ailab-empty-state-inner p {
  font-size: 12px;
  margin: 0;
  line-height: 1.5;
}

/* ===== Right icon rail ===== */
/* Iter 12O — z-index bumped from 30 → 9400 so the rail and its tooltip
   pseudo-elements always stack above floating widget windows (which grow
   via state.nextZ, easily reaching the low hundreds with multiple open).
   Tooltip pseudo-element keeps its own 9500 so it sits one notch higher
   than the rail body. Both still sit below the region-capture overlay
   (z=7000) is fine because that overlay covers everything anyway and we
   want the rail visible during capture for the cancel affordance. */
.ailab-rail {
  flex-shrink: 0;
  width: var(--ailab-right-pane-width);
  background: var(--ailab-surface);
  border-left: 1px solid var(--ailab-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px 0;
  gap: 14px;
  position: relative;
  z-index: 9400;
}
.ailab-rail-btn {
  position: relative;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  color: var(--ailab-text-muted);
  transition: background 120ms, color 120ms;
}
.ailab-rail-btn svg { width: 18px; height: 18px; }
.ailab-rail-btn:hover { background: var(--ailab-surface-2); color: var(--ailab-text); }
.ailab-rail-btn.ailab-rail-btn--active {
  background: var(--ailab-accent-soft);
  color: var(--ailab-accent);
}
.ailab-rail-btn--bottom { margin-top: auto; }
.ailab-rail-btn::after {
  content: attr(data-tooltip);
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%) translateX(-4px);
  /* Iter 12O — highlighted teal box. Background uses the project's accent
     gradient over an opaque dark surface so the label reads clearly against
     any underlying widget. Border and box-shadow use the accent token for a
     subtle glow that ties the chip to the brand palette. */
  background: linear-gradient(135deg, var(--ailab-accent) 0%, var(--ailab-accent-hover) 100%);
  color: #ffffff;
  padding: 6px 11px;
  border-radius: 6px;
  border: 1px solid var(--ailab-accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms, transform 120ms;
  box-shadow:
    0 0 0 1px rgba(79,152,163,0.35),
    0 6px 18px rgba(0,0,0,0.55),
    0 0 14px rgba(79,152,163,0.45);
  /* Sit above the draw panel (7500) and widget windows so the tooltip is
     never clipped by overlapping floating UI. */
  z-index: 9500;
}
/* Iter 12O — small triangular tail pointing back toward the rail icon, so
   the chip clearly belongs to the button it sits next to. Coloured with the
   accent so it visually matches the chip body. */
.ailab-rail-btn::before {
  content: "";
  position: absolute;
  right: calc(100% + 5px);
  top: 50%;
  width: 0;
  height: 0;
  transform: translateY(-50%) translateX(-4px);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid var(--ailab-accent);
  opacity: 0;
  transition: opacity 120ms, transform 120ms;
  pointer-events: none;
  z-index: 9500;
}
/* Only show on real hover — prevents tooltips from getting stuck after a
   tap on iPad / touch devices (where :hover lingers until the next tap). */
@media (hover: hover) {
  .ailab-rail-btn:hover::after,
  .ailab-rail-btn:hover::before {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
  }
}

/* ===== Region capture overlay ===== */
.ailab-region-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.25);
  z-index: 7000;
  cursor: crosshair;
  /* iPad / touch: stop the browser from scrolling, zooming, or showing a
     text-selection callout while the user drags out a region. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.ailab-region-hint {
  pointer-events: none;
}
.ailab-region-rect {
  position: absolute;
  border: 1px dashed var(--ailab-accent);
  background: rgba(79,152,163,0.12);
  pointer-events: none;
  display: none;
}
.ailab-region-hint {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  color: var(--ailab-text);
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 6px;
}

/* ============================================================
   Floating windows
   ============================================================ */
.ailab-window {
  position: absolute;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  min-width: 280px;
  min-height: 120px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.4);
  overflow: hidden;
  user-select: none;
}
/* Iter 12BG — Trade windows need overflow:visible so the right-edge
   pull-tab (mounted on the window node) can genuinely overhang the
   panel's outer border. The body and host nodes keep their own
   overflow:hidden so internal content still clips normally; only the
   window-level chrome (the tab) escapes. */
.ailab-window[data-window-type="trade"] {
  overflow: visible;
}
.ailab-window.ailab-window--focused {
  border-color: var(--ailab-border-strong);
  box-shadow: 0 12px 36px rgba(0,0,0,0.55), 0 0 0 1px rgba(79,152,163,0.18);
}
.ailab-window.ailab-window--minimised .ailab-window-search,
.ailab-window.ailab-window--minimised .ailab-window-note,
.ailab-window.ailab-window--minimised .ailab-window-body,
.ailab-window.ailab-window--minimised .ailab-window-resize {
  display: none;
}
.ailab-window.ailab-window--minimised {
  min-height: 32px;
  height: 32px !important;
}

.ailab-window-titlebar {
  height: 32px;
  flex-shrink: 0;
  background: var(--ailab-surface-2);
  border-bottom: 1px solid var(--ailab-border);
  display: flex;
  align-items: center;
  padding: 0 6px 0 8px;
  gap: 6px;
  cursor: move;
  /* Prevent the browser from interpreting drag gestures as page scroll on
     iPad and other touch devices. Required for pointer-event drag. */
  touch-action: none;
}
.ailab-window-grip {
  display: inline-flex; align-items: center;
  color: var(--ailab-text-dim);
  /* Push the grip past the 20x20 top-left resize handle that sits at
     left:0 of the window. Without this padding the resize handle
     overlaps and visually covers the grip icon. */
  padding-left: 9px;
}
.ailab-window-grip svg { width: 14px; height: 14px; }
.ailab-window-type-icon {
  display: inline-flex; align-items: center;
  color: var(--ailab-text-muted);
}
.ailab-window-type-icon svg { width: 12px; height: 12px; }
.ailab-window-title {
  flex: 1;
  font-size: 12px;
  font-weight: 500;
  color: var(--ailab-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: text;
}
.ailab-window-title-input {
  flex: 1;
  background: var(--ailab-bg);
  border: 1px solid var(--ailab-accent);
  color: var(--ailab-text);
  font-size: 12px;
  font-family: inherit;
  padding: 2px 6px;
  border-radius: 4px;
  outline: none;
}
.ailab-window-btn {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--ailab-text-muted);
  border-radius: 4px;
}
/* display: inline-flex above wins over the user-agent [hidden] { display:none } rule
   because of equal specificity but later cascade. Restore hidden behaviour explicitly
   so chart windows correctly hide the search-toggle icon (and any other titlebar btn
   that gets [hidden] applied dynamically). */
.ailab-window-btn[hidden] { display: none; }
.ailab-window-btn:hover { background: var(--ailab-surface-3); color: var(--ailab-text); }
.ailab-window-btn-close:hover { background: var(--ailab-negative); color: #fff; }
.ailab-window-btn svg { width: 12px; height: 12px; }

/* Iter 10g — chart maximise overlay.
   Single shared backdrop sits above the workspace at 50% opacity.
   Maximised window is bumped above the backdrop on a higher z-index
   so it visually 'pops' as a centred modal-style chart. While
   maximised the resize handles are disabled (the user toggles via
   the header button, not by dragging corners).

   Iter 10h — the maximise/restore size change is now animated. We
   only apply the transition while the .ailab-window--animating class
   is set (added by JS during the toggle, removed on transitionend),
   so normal drag and corner-resize stay snappy with no easing lag.
   The chart area's ResizeObserver fires on every paint of the
   transition, so Lightweight Charts grows fluidly in lock-step with
   the window. */
.ailab-window-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 9000;
  cursor: pointer;
  opacity: 0;
  /* Iter 10k — backdrop fade slowed another 40% (470 -> 658ms) to
     stay in proportion with the slower window animation below. */
  transition: opacity 658ms cubic-bezier(0.4, 0, 0.2, 1);
}
.ailab-window-backdrop.is-visible {
  opacity: 1;
}
.ailab-window.ailab-window--animating {
  /* cubic-bezier(0.32, 0.72, 0, 1) is Apple's standard ease-out for
     window-scale transitions — fast initial movement that gently
     decelerates into the target.
     Iter 10k — duration slowed another 40% (550 -> 770ms) per user
     feedback; gives the maximise/restore a more deliberate, cinematic
     feel. */
  transition:
    left   770ms cubic-bezier(0.32, 0.72, 0, 1),
    top    770ms cubic-bezier(0.32, 0.72, 0, 1),
    width  770ms cubic-bezier(0.32, 0.72, 0, 1),
    height 770ms cubic-bezier(0.32, 0.72, 0, 1),
    box-shadow 770ms cubic-bezier(0.32, 0.72, 0, 1);
  /* Promote to its own compositor layer so the transition stays at 60fps
     even with a busy chart underneath. */
  will-change: left, top, width, height;
}
.ailab-window.ailab-window--maximised {
  z-index: 9001 !important;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px var(--ailab-border);
}
.ailab-window.ailab-window--maximised .ailab-window-resize,
.ailab-window.ailab-window--maximised .ailab-window-resize--tl,
.ailab-window.ailab-window--maximised .ailab-window-resize--tr,
.ailab-window.ailab-window--maximised .ailab-window-resize--bl,
.ailab-window.ailab-window--maximised .ailab-window-resize--br {
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms cubic-bezier(0.32, 0.72, 0, 1);
}

.ailab-window-search {
  display: flex;
  align-items: center;
  padding: 8px;
  gap: 6px;
  border-bottom: 1px solid var(--ailab-border);
  flex-shrink: 0;
}
/* Charts never show the per-window query row — the ticker / company-name
   editor lives in the titlebar. Defensive rule in case stale JS misses the
   hidden toggle. */
.ailab-window[data-window-type="chart"] .ailab-window-search { display: none; }
/* Heatmap windows have their own header inside the body — the global
   query row is never shown here. Defensive rule mirrors the chart one. */
.ailab-window[data-window-type="heatmap"] .ailab-window-search { display: none; }
/* Watchlist windows never show the search row — the title bar carries a
   list-picker dropdown instead. */
.ailab-window[data-window-type="watchlist"] .ailab-window-search { display: none; }
/* Index Card windows have no search box — header lives inside the body. */
.ailab-window[data-window-type="indexcard"] .ailab-window-search { display: none; }
.ailab-window[data-window-type="fx"] .ailab-window-search { display: none; }
/* Iter 12AT — Treasury Rates and Yield Curve are both pure-display widgets
   with their own internal headers, so the global query row is never used
   here. Defensive rule mirrors the chart/heatmap/indexcard/fx pattern. */
.ailab-window[data-window-type="rates"] .ailab-window-search { display: none; }
.ailab-window[data-window-type="yieldcurve"] .ailab-window-search { display: none; }
/* Iter 12AU — Treasury Rates only has 4 cards, so the inherited
   `.ailab-idxcard-item { flex: 1 1 0 }` rule stretched each card across
   ~25% of the widget width and made them visually much larger than the
   Market Indexes (11 cards) and Currency Pairs (8 cards) tiles. Pin
   rates cards to the same compact basis used by those bars and stop the
   bar from stretching them. */
/* Iter 12AZ — Hide the placeholder AH span on rates cards. FRED daily
   series have no after-hours concept (they publish once per business day
   after the close), so the empty span just steals 13px of vertical room
   and pushes the label off the top of the card. Hidden specifically on
   the rates bar; other index/fx cards still need the span to reserve
   space for SPX/DJI/IXIC/RUT pre-market readouts. */
.ailab-idxcard-bar[data-role="rates-bar"] .ailab-idxcard-ah { display: none; }

/* Iter 12AX — widget-level info button + popover. Used by Treasury Rates
   and Yield Curve to explain the widget and what investors should watch for.
   The button sits inline next to the title; the popover is appended to
   document.body (because .ailab-window has overflow:hidden which would
   clip a panel anchored to the widget) and uses position:fixed with
   left/top set inline by JS from getBoundingClientRect(). */
.ailab-idxcard-header-titlewrap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.ailab-widget-info-btn {
  width: 16px; height: 16px;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.06);
  color: var(--ailab-text, #e6edf3);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: 50%;
  font: 600 10px/1 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
  cursor: pointer;
  flex: 0 0 16px;
  opacity: 0.75;
  transition: opacity 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.ailab-widget-info-btn:hover,
.ailab-widget-info-btn:focus-visible {
  background: rgba(255,255,255,0.14);
  border-color: rgba(255,255,255,0.24);
  opacity: 1;
  outline: none;
}
.ailab-widget-info-panel {
  position: fixed;
  z-index: 9999;
  width: 360px;
  max-width: calc(100vw - 24px);
  max-height: 360px;
  overflow-y: auto;
  padding: 12px 14px;
  background: linear-gradient(180deg, rgba(28,34,46,0.97), rgba(20,25,34,0.97));
  color: var(--ailab-text, #c9d1d9);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.55);
  font: 12px/1.5 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
}
.ailab-widget-info-panel[hidden] { display: none; }
.ailab-widget-info-panel p { margin: 0 0 8px; color: var(--ailab-text-dim, #c2cad6); }
.ailab-widget-info-panel ul { margin: 0 0 4px; padding-left: 16px; }
.ailab-widget-info-panel li { margin-bottom: 5px; color: var(--ailab-text-dim, #c2cad6); }
.ailab-widget-info-panel b { color: var(--ailab-text, #f0f6fc); font-weight: 600; }
.ailab-widget-info-panel::-webkit-scrollbar { width: 6px; }
.ailab-widget-info-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 3px; }
.ailab-widget-info-panel::-webkit-scrollbar-track { background: transparent; }

.ailab-idxcard-bar[data-role="rates-bar"] {
  justify-content: flex-start;
  gap: 8px;
  /* Iter 12AW — Stop the bar's `flex: 1` from stretching the four rate tiles
     vertically to fill the host height. Top-anchor the row so cards stay
     content-sized and visually match the Market Indexes / Currency Pairs
     tiles (where 11/8 tiles naturally pack short because the bar's content
     fills the available vertical space across many rows of text). */
  flex: 0 0 auto;
  align-self: flex-start;
}
.ailab-idxcard-bar[data-role="rates-bar"] .ailab-idxcard-item {
  flex: 0 0 115px;
  min-width: 115px;
  max-width: 115px;
  /* Iter 12AW — Pin card height to match the Market Indexes / Currency Pairs
     rendered tile height so the four rates cards are visually identical to
     their neighbours stacked above them.
     Iter 12AZ — Bumped 76px → 88px and padding-top 8px → 12px to fix the
     header label being clipped at the top on the live AI Lab (Safari).
     The 76px in 12AW was tight against the actual rendered line-box height
     of label (10px font, ~15px line-box) + price (16px font, ~24px line-box)
     + change (12px font, ~18px line-box) + the inherited empty AH span
     min-height (13px) = ~70px content, which combined with 16px vertical
     padding overflowed the 76px ceiling and forced the label to render above
     the padding top. Increasing the height + top padding gives the label
     room to breathe; we also hide the empty AH span on rates cards below
     since FRED data never has after-hours quotes. */
  align-self: flex-start;
  height: 88px;
  padding-top: 12px;
  box-sizing: border-box;
}
.ailab-window-search-input-wrap {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
}
.ailab-window-search-input {
  width: 100%;
  flex: 1;
  background: var(--ailab-bg);
  border: 1px solid var(--ailab-border);
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  padding: 6px 28px 6px 10px;
  border-radius: 6px;
  outline: none;
}
.ailab-window-search-input:focus {
  border-color: var(--ailab-accent);
}
.ailab-window-search-clear {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--ailab-text-dim);
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.ailab-window-search-clear:hover {
  opacity: 1;
  color: var(--ailab-text);
  background: var(--ailab-surface-2, rgba(255,255,255,0.06));
}
.ailab-window-search-clear svg { width: 12px; height: 12px; }
.ailab-window-search-send {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ailab-accent);
  color: #0d0d0f;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.ailab-window-search-send:hover { background: var(--ailab-accent-hover); }
.ailab-window-search-send svg { width: 14px; height: 14px; }
.ailab-window-search-send:disabled { opacity: 0.5; cursor: not-allowed; }

.ailab-window-note {
  padding: 6px 8px;
  border-bottom: 1px solid var(--ailab-border);
  background: var(--ailab-surface-2);
}
.ailab-window-note-input {
  width: 100%;
  background: rgba(79,152,163,0.06);
  border: 1px solid var(--ailab-border);
  border-radius: 4px;
  color: var(--ailab-text);
  font-size: 11px;
  font-family: inherit;
  padding: 4px 6px;
  resize: vertical;
  outline: none;
}

.ailab-window-body {
  flex: 1;
  overflow-y: auto;
  position: relative;
}
.ailab-window-body::-webkit-scrollbar { width: 6px; }
.ailab-window-body::-webkit-scrollbar-thumb { background: var(--ailab-surface-3); border-radius: 3px; }
.ailab-window-body::-webkit-scrollbar-track { background: transparent; }

/* ===================================================================
   Window resize handles
   -------------------------------------------------------------------
   Iter 9c: four invisible corner handles per window — TL, TR, BL, BR.
   No gripper artwork; the OS resize cursor on hover is the only
   visual affordance, matching the convention in standard apps.
   18px square hit area in each corner; touch-action: none prevents
   iPad scroll/zoom while dragging.
   =================================================================== */
.ailab-window-resize {
  position: absolute;
  width: 18px;
  height: 18px;
  touch-action: none;
  z-index: 3;
}

/* Bottom-right handle */
.ailab-window-resize--br {
  right: 0;
  bottom: 0;
  cursor: nwse-resize;
}

/* Top-left handle */
.ailab-window-resize--tl {
  left: 0;
  top: 0;
  cursor: nwse-resize;
}

/* Top-right handle */
.ailab-window-resize--tr {
  right: 0;
  top: 0;
  cursor: nesw-resize;
}

/* Bottom-left handle */
.ailab-window-resize--bl {
  left: 0;
  bottom: 0;
  cursor: nesw-resize;
}

/* Legacy class without modifier — fallback so old DOM (if any) still
   gets a usable hit area at bottom-right. */
.ailab-window-resize:not(.ailab-window-resize--tl):not(.ailab-window-resize--tr):not(.ailab-window-resize--bl):not(.ailab-window-resize--br) {
  right: 0;
  bottom: 0;
  cursor: nwse-resize;
}

/* ===== Stock list rows ===== */
.ailab-stock-list {
  display: flex;
  flex-direction: column;
}
.ailab-stock-row {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid var(--ailab-border);
  cursor: pointer;
  gap: 10px;
  transition: background 100ms;
}
.ailab-stock-row:hover { background: var(--ailab-surface-2); }
.ailab-stock-row:last-child { border-bottom: none; }
.ailab-stock-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.ailab-stock-dot--up { background: var(--ailab-positive); }
.ailab-stock-dot--down { background: var(--ailab-negative); }
.ailab-stock-dot--flat { background: var(--ailab-neutral); }

/* Iter 12L — visible-only Alpaca live-stream indicator for watchlist rows.
   Sits to the right of the price stack as a tiny 6px dot. Admin-only — the
   row only adds [data-live-dot] when the watchlist controller has wired up
   an EventSource and the row is currently in the viewport. States: off (no
   subscription / stream paused), live (tick in last 5s — pulses briefly),
   stale (subscribed but no recent tick), err (stream errored). */
.ailab-stock-live-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--ailab-text-muted, #6b6b73);
  opacity: 0.55;
  margin-left: 6px;
  transition: background 160ms ease, opacity 160ms ease, box-shadow 160ms ease;
}
.ailab-stock-live-dot--off  { background: var(--ailab-text-muted, #6b6b73); opacity: 0.35; }
.ailab-stock-live-dot--live {
  background: var(--ailab-positive, #16a34a);
  opacity: 1;
  box-shadow: 0 0 0 2px rgba(22, 163, 74, 0.18);
  animation: ailab-stock-live-pulse 1.2s ease-out 1;
}
.ailab-stock-live-dot--stale { background: #d1a14a; opacity: 0.85; }
.ailab-stock-live-dot--err   { background: var(--ailab-negative, #dc2626); opacity: 0.85; }
@keyframes ailab-stock-live-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(22, 163, 74, 0.55); }
  100% { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0);    }
}
.ailab-stock-info {
  display: flex; flex-direction: column; flex: 1; min-width: 0;
}
.ailab-stock-symbol {
  font-size: 13px;
  font-weight: 600;
  color: var(--ailab-text);
}
.ailab-stock-name {
  font-size: 11px;
  color: var(--ailab-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}
.ailab-stock-price {
  font-size: 13px;
  font-weight: 600;
  color: var(--ailab-text);
  font-variant-numeric: tabular-nums;
  text-align: right;
  border-radius: 4px;
  padding: 1px 4px;
  margin: -1px -4px;
  transition: background-color 0.5s ease;
}
/* Brief flash on every successful 1s poll where the underlying numeric
   price changed — even when the displayed (2-decimal) price doesn't.
   Direction-tinted so up-ticks pulse green and down-ticks pulse red. */
@keyframes ailab-stock-flash-up {
  0%   { background-color: rgba(38, 166, 154, 0.35); }
  100% { background-color: transparent; }
}
@keyframes ailab-stock-flash-down {
  0%   { background-color: rgba(239, 83, 80, 0.35); }
  100% { background-color: transparent; }
}
.ailab-stock-price.ailab-stock-flash--up {
  animation: ailab-stock-flash-up 0.6s ease-out;
}
.ailab-stock-price.ailab-stock-flash--down {
  animation: ailab-stock-flash-down 0.6s ease-out;
}
/* Same treatment for the chart header price so the chart shows the
   same heartbeat the widgets do. */
.ailab-chart-title-price {
  border-radius: 4px;
  padding: 1px 4px;
  margin: -1px -4px;
  transition: background-color 0.5s ease;
}
.ailab-chart-title-price.ailab-stock-flash--up {
  animation: ailab-stock-flash-up 0.6s ease-out;
}
.ailab-chart-title-price.ailab-stock-flash--down {
  animation: ailab-stock-flash-down 0.6s ease-out;
}
.ailab-stock-change {
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  margin-left: 8px;
  min-width: 60px;
}
.ailab-stock-change--up { color: var(--ailab-positive); }
.ailab-stock-change--down { color: var(--ailab-negative); }
.ailab-stock-change--flat { color: var(--ailab-neutral); }

/* Stacked change block — historical (top) + live quote (sub) */
.ailab-stock-change-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  margin-left: 8px;
  min-width: 64px;
}
.ailab-stock-change-stack .ailab-stock-change {
  margin-left: 0;
  min-width: 0;
}
.ailab-stock-change-sub {
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  opacity: 0.65;
  margin-top: 1px;
}

/* Extended-hours overlay on stock query rows. Mirrors the dashboard
   watchlist row layout: a small price under the regular price and a
   small signed % under the regular % badge, both hidden during the
   regular session and revealed during pre-market / post-market /
   closed (overnight) sessions. */
.ailab-stock-price-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 0;
}
.ailab-stock-price-stack .ailab-stock-price {
  text-align: right;
}
.ailab-stock-ext-price {
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ailab-text-muted);
  text-align: right;
  opacity: 0.7;
  margin-top: 1px;
  white-space: nowrap;
}
.ailab-stock-ext-change {
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  opacity: 0.7;
  margin-top: 1px;
  white-space: nowrap;
}
.ailab-stock-ext-change--up { color: var(--ailab-positive); }
.ailab-stock-ext-change--down { color: var(--ailab-negative); }

/* Watchlist star at the right edge of each stock-query row. Always shown
   at a faint grey so users can spot it without hovering; brightens on row
   hover and turns gold when the ticker is on at least one watchlist. */
.ailab-stock-star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 8px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: rgba(255,255,255,0.28);
  cursor: pointer;
  opacity: 1;
  transition: color 120ms ease, background 120ms ease, transform 120ms ease;
  flex-shrink: 0;
}
.ailab-stock-row:hover .ailab-stock-star {
  color: rgba(255,255,255,0.55);
}
.ailab-stock-star:hover {
  background: rgba(255,255,255,0.06);
  color: var(--ailab-text);
}
.ailab-stock-star:active { transform: scale(0.92); }
.ailab-stock-star--active { color: #f5c542; }
.ailab-stock-star--active svg path {
  fill: #f5c542;
  stroke: #f5c542;
}
.ailab-stock-star:focus-visible {
  outline: 2px solid var(--ailab-accent, #6fbcc9);
  outline-offset: 1px;
}

/* Ranking meta header above stock list */
.ailab-stock-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid var(--ailab-border);
  background: var(--ailab-surface-2);
}
.ailab-stock-meta-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ailab-text);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ailab-stock-meta-period {
  font-size: 11px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ===== Loading shimmer ===== */
.ailab-shimmer {
  display: flex;
  flex-direction: column;
  padding: 12px;
  gap: 10px;
}
.ailab-shimmer-row {
  height: 40px;
  background: linear-gradient(90deg, var(--ailab-surface-2) 25%, var(--ailab-surface-3) 50%, var(--ailab-surface-2) 75%);
  background-size: 200% 100%;
  border-radius: 6px;
  animation: ailab-shimmer 1.4s ease-in-out infinite;
}
@keyframes ailab-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ===== Error message ===== */
.ailab-window-error {
  padding: 16px;
  font-size: 12px;
  color: var(--ailab-negative);
  text-align: center;
  line-height: 1.5;
}
.ailab-window-empty {
  padding: 24px 16px;
  text-align: center;
  font-size: 12px;
  color: var(--ailab-text-muted);
  line-height: 1.5;
}
.ailab-window-empty-icon {
  width: 40px; height: 40px;
  margin: 0 auto 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ailab-text-dim);
}
.ailab-window-empty-icon svg { width: 28px; height: 28px; }
.ailab-window-empty-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ailab-text);
  margin-bottom: 4px;
}
.ailab-window-empty-sub {
  font-size: 12px;
  color: var(--ailab-text-muted);
  margin-bottom: 12px;
}
.ailab-window-empty-note {
  display: inline-block;
  margin: 0 auto 12px;
  padding: 6px 10px;
  border-radius: 6px;
  background: var(--ailab-surface-2, rgba(255,170,0,0.08));
  border: 1px solid var(--ailab-border, rgba(255,170,0,0.25));
  color: var(--ailab-text);
  font-size: 11px;
  line-height: 1.45;
  max-width: 320px;
  text-align: left;
}
.ailab-window-empty-tips {
  margin: 8px auto 0;
  max-width: 340px;
  text-align: left;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--ailab-border);
  background: var(--ailab-surface-2, rgba(255,255,255,0.02));
}
.ailab-window-empty-tips-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ailab-text);
  margin-bottom: 6px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ailab-window-empty-tips ul {
  margin: 0;
  padding-left: 18px;
  font-size: 12px;
  color: var(--ailab-text-muted);
  line-height: 1.55;
}
.ailab-window-empty-tips li { margin: 2px 0; }

/* Ask Claude widget — prose answer body. */
.ailab-ask-body {
  padding: 14px 16px 16px;
  font-size: 13px;
  color: var(--ailab-text);
  line-height: 1.6;
  overflow-y: auto;
}
.ailab-ask-markdown { font-size: 13px; line-height: 1.6; }
.ailab-ask-markdown p { margin: 0 0 10px; }
.ailab-ask-markdown p:last-child { margin-bottom: 0; }
.ailab-ask-markdown h1,
.ailab-ask-markdown h2,
.ailab-ask-markdown h3,
.ailab-ask-markdown h4 {
  margin: 14px 0 6px;
  color: var(--ailab-text);
  font-weight: 600;
  line-height: 1.3;
}
.ailab-ask-markdown h1 { font-size: 16px; }
.ailab-ask-markdown h2 { font-size: 15px; }
.ailab-ask-markdown h3 { font-size: 14px; }
.ailab-ask-markdown h4 { font-size: 13px; }
.ailab-ask-markdown ul,
.ailab-ask-markdown ol { margin: 6px 0 10px; padding-left: 20px; }
.ailab-ask-markdown li { margin: 2px 0; }
.ailab-ask-markdown strong { color: var(--ailab-text); font-weight: 600; }
.ailab-ask-markdown em { font-style: italic; }
.ailab-ask-markdown a {
  color: var(--ailab-accent, #4ea1ff);
  text-decoration: none;
  border-bottom: 1px dotted currentColor;
}
.ailab-ask-markdown a:hover { text-decoration: underline; }
.ailab-ask-markdown blockquote {
  margin: 8px 0;
  padding: 6px 10px;
  border-left: 3px solid var(--ailab-border);
  color: var(--ailab-text-muted);
  background: var(--ailab-surface-2, rgba(255,255,255,0.02));
}
.ailab-ask-markdown code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--ailab-surface-2, rgba(255,255,255,0.06));
  color: var(--ailab-text);
}
.ailab-ask-markdown pre {
  margin: 8px 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--ailab-surface-2, rgba(255,255,255,0.04));
  border: 1px solid var(--ailab-border);
  overflow-x: auto;
}
.ailab-ask-markdown pre code {
  padding: 0;
  background: transparent;
  border-radius: 0;
  font-size: 12px;
  line-height: 1.5;
}
.ailab-ask-foot {
  margin-top: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--ailab-border);
  font-size: 11px;
  color: var(--ailab-text-dim);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  align-items: center;
}

/* ===== Chart window =====
   The chart's symbol / price / change live inside the window titlebar
   (.ailab-window-title--chart) instead of a dedicated header row, so the
   chart body is more compact. The pencil button next to the title opens
   a ticker / company-name editor (see ai-lab.js bindWindow). */
.ailab-window-title--chart {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
  cursor: default;
  /* Iter 8g — anchor for the absolute-positioned ticker picker. */
  position: relative;
}
/* Iter 8g — when the chart picker is mounted, escape title clipping so
   the dropdown can extend below the titlebar. The picker itself sets a
   high z-index to overlay the chart body. */
.ailab-window-title--chart:has(.ailab-chart-symbol-picker),
.ailab-window-title:has(.ailab-chart-symbol-picker) {
  overflow: visible;
}
.ailab-window-title--chart .ailab-stock-dot { width: 6px; height: 6px; }
.ailab-chart-title-symbol {
  font-size: 12px;
  font-weight: 600;
  color: var(--ailab-text);
  letter-spacing: 0.02em;
  /* Iter 8g — clickable ticker pill: hover affordance + tap target. */
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  transition: background 120ms, color 120ms;
}
.ailab-chart-title-symbol:hover {
  background: var(--ailab-surface-2);
  color: var(--ailab-accent);
}
.ailab-chart-title-price {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ailab-text);
}
.ailab-chart-title-change {
  font-size: 11px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ailab-text-muted);
}
.ailab-chart-title-change--up { color: var(--ailab-positive); }
.ailab-chart-title-change--down { color: var(--ailab-negative); }
.ailab-chart-title-change--flat { color: var(--ailab-neutral); }

/* Extended-hours overlay on the chart title row. Mirrors the dashboard
   watchlist chart header (.wl-chart-ext-row): a small dim price + a
   small signed % to the right of the main price+change pair. Hidden
   during regular hours; visible during pre / post / closed sessions. */
.ailab-chart-title-ext-price {
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ailab-text-muted);
  opacity: 0.75;
  margin-left: 2px;
  white-space: nowrap;
}
.ailab-chart-title-ext-change {
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ailab-chart-title-ext-change--up { color: var(--ailab-positive); }
.ailab-chart-title-ext-change--down { color: var(--ailab-negative); }

/* Watchlist star button next to the chart's ticker symbol. Hollow by
   default; filled gold when the ticker is in any of the user's lists. */
.ailab-chart-title-star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  margin: 0 2px;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--ailab-text-muted);
  cursor: pointer;
  transition: color 120ms ease, background 120ms ease, transform 120ms ease;
  flex-shrink: 0;
}
.ailab-chart-title-star:hover {
  background: rgba(255,255,255,0.06);
  color: var(--ailab-text);
}
.ailab-chart-title-star:active { transform: scale(0.92); }
.ailab-chart-title-star--active {
  color: #f5c542;
}
.ailab-chart-title-star--active svg path {
  fill: #f5c542;
  stroke: #f5c542;
}
.ailab-chart-title-star:focus-visible {
  outline: 2px solid var(--ailab-accent, #6fbcc9);
  outline-offset: 1px;
}

/* Watchlist popover anchored to the star button. Floats above all
   chart windows (z-index above the max window z-index of 9999). */
.ailab-watchlist-popover {
  position: fixed;
  z-index: 11000;
  min-width: 220px;
  max-width: 280px;
  background: rgba(18, 22, 30, 0.96);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.5);
  backdrop-filter: blur(8px) saturate(140%);
  color: var(--ailab-text);
  font-size: 12px;
  overflow: hidden;
  animation: ailab-wl-pop-in 140ms ease;
}
@keyframes ailab-wl-pop-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.ailab-watchlist-popover-header {
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.ailab-watchlist-popover-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ailab-text-muted);
}
.ailab-watchlist-popover-body {
  max-height: 280px;
  overflow-y: auto;
  padding: 4px 0;
}
.ailab-watchlist-popover-loading,
.ailab-watchlist-popover-empty {
  padding: 16px 12px;
  font-size: 12px;
  color: var(--ailab-text-muted);
  text-align: center;
  line-height: 1.5;
}
.ailab-watchlist-popover-link {
  color: var(--ailab-accent, #6fbcc9);
  text-decoration: none;
}
.ailab-watchlist-popover-link:hover { text-decoration: underline; }
.ailab-watchlist-popover-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  user-select: none;
  transition: background 100ms ease;
}
.ailab-watchlist-popover-row:hover { background: rgba(255,255,255,0.05); }
.ailab-watchlist-popover-row input[type="checkbox"] {
  margin: 0;
  width: 14px;
  height: 14px;
  accent-color: #f5c542;
  cursor: pointer;
  flex-shrink: 0;
}
.ailab-watchlist-popover-name {
  flex: 1;
  font-size: 12px;
  color: var(--ailab-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-watchlist-popover-count {
  font-size: 10px;
  font-weight: 500;
  color: var(--ailab-text-muted);
  background: rgba(255,255,255,0.06);
  padding: 2px 6px;
  border-radius: 8px;
  font-variant-numeric: tabular-nums;
}
.ailab-chart-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--ailab-border);
  flex-shrink: 0;
}
.ailab-chart-tab {
  background: transparent;
  border: none;
  color: var(--ailab-text-muted);
  font-size: 11px;
  font-weight: 500;
  font-family: inherit;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.ailab-chart-tab:hover { color: var(--ailab-text); background: var(--ailab-surface-2); }
.ailab-chart-tab.ailab-chart-tab--active {
  color: var(--ailab-accent);
  background: var(--ailab-accent-soft);
}
.ailab-chart-area {
  flex: 1;
  position: relative;
  overflow: hidden;
}
.ailab-chart-canvas-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
}
.ailab-chart-canvas-overlay.ailab-chart-canvas-overlay--active {
  pointer-events: auto;
  cursor: crosshair;
  /* Required so iPad/touch devices don't intercept the drag for scroll/zoom
     while the user is drawing. */
  touch-action: none;
}
/* Anchored drawings layer sits above the raster overlay but below the
   active interaction overlay. It is always pointer-events:none — input
   is captured by the overlay above it and the chart below it. */
.ailab-chart-canvas-anchor {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
}
/* Anchored tools are visually distinguished from raster tools so users
   know these stick to the chart. */
.ailab-draw-tool.ailab-draw-tool--anchored {
  position: relative;
}
.ailab-draw-tool.ailab-draw-tool--anchored::after {
  content: '';
  position: absolute;
  top: 3px;
  right: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #4f98a3;
  opacity: 0.7;
}
.ailab-draw-tool[data-draw-tool="magnet"].ailab-draw-tool--magnet-on {
  background: rgba(243, 183, 63, 0.18);
  color: #f3b73f;
}
.ailab-chart-footer {
  padding: 6px 10px;
  border-top: 1px solid var(--ailab-border);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 11px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.ailab-chart-footer-item span { color: var(--ailab-text); margin-left: 4px; }

/* ===== News window =====
   Top of the panel shows the first 2 articles as a side-by-side hero pair
   with a larger image. The remaining articles render as compact rows with
   the thumbnail on the right. Each article carries a sentiment badge
   (POSITIVE / NEGATIVE / NEUTRAL) supplied by the server. */
.ailab-news-list {
  display: flex;
  flex-direction: column;
}

.ailab-news-hero-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-news-hero-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  cursor: pointer;
  border-radius: 8px;
  padding: 4px;
  transition: background 120ms;
  min-width: 0;
}
.ailab-news-hero-card:hover { background: var(--ailab-surface-2); }
.ailab-news-hero-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.ailab-news-row {
  display: flex;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--ailab-border);
  cursor: pointer;
  transition: background 100ms;
  align-items: flex-start;
}
.ailab-news-row:hover { background: var(--ailab-surface-2); }
.ailab-news-row:last-child { border-bottom: none; }

.ailab-news-thumb {
  border-radius: 6px;
  background: var(--ailab-surface-3);
  flex-shrink: 0;
  object-fit: cover;
}
/* Hero card image — large, fills card width, ~16:10 aspect. */
.ailab-news-thumb--hero {
  width: 100%;
  aspect-ratio: 16 / 10;
  height: auto;
}
/* Compact row image — sits on the right of the row. */
.ailab-news-thumb--row {
  width: 72px;
  height: 72px;
}
.ailab-news-thumb-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ailab-text-dim);
}
.ailab-news-thumb-fallback svg { width: 22px; height: 22px; }

.ailab-news-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ailab-news-badges { display: flex; gap: 6px; flex-wrap: wrap; }
.ailab-news-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ailab-text);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ailab-news-title--hero {
  font-size: 13px;
  -webkit-line-clamp: 3;
}
.ailab-news-meta {
  font-size: 11px;
  color: var(--ailab-text-muted);
}
.ailab-news-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 3px;
  align-self: flex-start;
  line-height: 1;
}
.ailab-news-badge-arrow { font-size: 11px; line-height: 1; }
.ailab-news-badge--positive { background: rgba(109,170,69,0.16); color: var(--ailab-positive); }
.ailab-news-badge--negative { background: rgba(221,105,116,0.16); color: var(--ailab-negative); }
.ailab-news-badge--neutral { background: rgba(138,138,154,0.16); color: var(--ailab-neutral); }

/* Narrow news panels (< ~360px wide): collapse hero pair to a single column
   so titles don't get squashed. */
@media (max-width: 380px) {
  .ailab-news-hero-grid { grid-template-columns: 1fr; }
}

/* ===== Floating drawing panel ===== */
.ailab-draw-panel {
  position: absolute;
  top: 24px;
  right: 80px;
  width: var(--ailab-draw-panel-width);
  background: #ffffff;
  color: #1a1a1e;
  border-radius: 10px;
  box-shadow: 0 10px 32px rgba(0,0,0,0.55);
  display: flex;
  flex-direction: column;
  z-index: 7500;
  user-select: none;
}
/* Required because the rule above sets display: flex which would otherwise
   override the user-agent [hidden] { display: none } default and leave
   the panel visible after the close button toggles the hidden attribute. */
.ailab-draw-panel[hidden] { display: none; }
.ailab-draw-handle {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #f3f3f5;
  padding: 6px 8px;
  border-radius: 10px 10px 0 0;
  border-bottom: 1px solid rgba(0,0,0,0.08);
  cursor: move;
  /* Prevent the browser from interpreting drag gestures as page scroll / zoom
     on iPad and other touch devices. Required for pointer-event drag. */
  touch-action: none;
}
.ailab-draw-handle-grip {
  width: 16px; height: 6px;
  background-image: radial-gradient(circle, rgba(0,0,0,0.35) 1px, transparent 1px);
  background-size: 4px 4px;
}
.ailab-draw-handle-label {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #1a1a1e;
  margin-left: 2px;
  flex: 1;
}
.ailab-draw-close {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  color: #1a1a1e;
  border-radius: 4px;
  /* Re-enable normal touch handling so the close button reliably fires
     a tap on iPad even though the parent .ailab-draw-handle uses
     touch-action: none for drag. */
  touch-action: auto;
  /* Pull the button out of the parent's stacking flow so its hit area
     can't be covered by the grip / label. */
  position: relative;
  z-index: 1;
}
.ailab-draw-close * { pointer-events: none; }
.ailab-draw-close:hover { background: rgba(0,0,0,0.08); }
.ailab-draw-close svg { width: 12px; height: 12px; }

.ailab-draw-section {
  padding: 8px 10px;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}
.ailab-draw-section:last-child { border-bottom: none; }
.ailab-draw-section-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #6a6a78;
  margin-bottom: 6px;
}
.ailab-draw-swatch {
  display: block;
  width: 100%;
  height: 28px;
  border-radius: 6px;
  border: 1px solid rgba(0,0,0,0.1);
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.ailab-draw-swatch input[type="color"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.ailab-draw-swatch-fill {
  display: block;
  width: 100%; height: 100%;
  background: #b8e066;
}
.ailab-draw-tools {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.ailab-draw-tool {
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #f3f3f5;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  color: #1a1a1e;
  transition: background 120ms, border-color 120ms;
}
.ailab-draw-tool:hover { background: #e6e6ea; }
.ailab-draw-tool.ailab-draw-tool--active {
  background: rgba(79,152,163,0.16);
  border-color: var(--ailab-accent);
  color: var(--ailab-accent);
}
.ailab-draw-tool svg { width: 16px; height: 16px; }
.ailab-draw-sizes {
  display: flex;
  align-items: center;
  justify-content: space-around;
  gap: 8px;
}
.ailab-draw-size {
  background: transparent;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
}
.ailab-draw-size span {
  display: inline-block;
  border-radius: 50%;
  background: #c0c0c8;
  transition: background 120ms;
}
.ailab-draw-size--sm span { width: 6px; height: 6px; }
.ailab-draw-size--md span { width: 10px; height: 10px; }
.ailab-draw-size--lg span { width: 16px; height: 16px; }
.ailab-draw-size--active span { background: var(--ailab-accent); }

/* ===== Tokens summary toast ===== */
.ailab-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  color: var(--ailab-text);
  font-size: 12px;
  padding: 10px 16px;
  border-radius: 8px;
  z-index: 9000;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms;
}
.ailab-toast.ailab-toast--visible { opacity: 1; }

/* ===== AI Lab board (stub) ===== */
.ailab-board-page {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 24px;
  text-align: center;
}
.ailab-board-card {
  max-width: 420px;
}
.ailab-board-card h1 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ailab-accent);
  margin: 0 0 12px;
}
.ailab-board-card p {
  font-size: 14px;
  color: var(--ailab-text-muted);
  line-height: 1.6;
  margin: 0 0 24px;
}

/* ===== Focus / Zen mode =====
   In focus mode the unified Marketinsight topbar (brand row + main nav) is
   hidden so the canvas reaches the very top of the viewport. The in-app AI Lab
   header (AI LAB title, credits, Reset Workspace, Add Widget) stays visible so
   the user keeps full control of the toolbar. The icon next to AI LAB doubles
   as the toggle: it swaps between maximize-2 and minimize-2 in JS. */
body.ailab-zen .mi-topbar { display: none !important; }
/* Clear the topbar reservation padding the mi-nav-host class adds, otherwise
   the AI Lab header would still sit ~144px down and the canvas below it would
   be cut off the bottom of the viewport. */
body.ailab-page.mi-nav-host.ailab-zen { padding-top: 0 !important; scroll-padding-top: 0 !important; }

/* ===== Chart toolbar extras =====
   The chart toolbar is a single flex row: period tabs on the left, then a
   spacer, then a chart-type icon group (line / candle), then an Indicators
   dropdown on the far right. The dropdown menu is absolutely positioned
   beneath the button. Sub-panes (RSI, MACD) stack vertically below the main
   price pane and use a fixed height while the main pane flexes to fill. */
.ailab-chart-tabs-spacer { flex: 1; }

.ailab-chart-typegroup {
  display: flex;
  gap: 2px;
  margin-right: 4px;
}
.ailab-chart-typebtn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--ailab-text-muted);
  padding: 3px 6px;
  border-radius: 4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.ailab-chart-typebtn i { width: 14px; height: 14px; }
.ailab-chart-typebtn:hover { color: var(--ailab-text); background: var(--ailab-surface-2); }
.ailab-chart-typebtn.ailab-chart-typebtn--active {
  color: var(--ailab-accent);
  background: var(--ailab-accent-soft);
  border-color: var(--ailab-accent-soft);
}

.ailab-chart-indwrap { position: relative; }
.ailab-chart-indbtn {
  background: transparent;
  border: 1px solid var(--ailab-border);
  color: var(--ailab-text-muted);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  line-height: 1;
}
.ailab-chart-indbtn:hover { color: var(--ailab-text); background: var(--ailab-surface-2); }
.ailab-chart-indbtn i { width: 12px; height: 12px; }
.ailab-chart-indbadge {
  background: var(--ailab-accent-soft);
  color: var(--ailab-accent);
  font-size: 10px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 8px;
  line-height: 1.4;
}
.ailab-chart-indmenu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 180px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 4px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.ailab-chart-indmenu[hidden] { display: none; }
.ailab-chart-inditem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  font-size: 12px;
  color: var(--ailab-text);
  border-radius: 4px;
  cursor: pointer;
  user-select: none;
}
.ailab-chart-inditem:hover { background: var(--ailab-surface-2); }
.ailab-chart-inditem input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
  accent-color: var(--ailab-accent);
}

/* Structural Leg Profiler settings sub-row inside the indicators menu.
   Indents under the SLP checkbox and stacks the four fields vertically
   so the menu doesn't grow too wide. */
.ailab-chart-inditem-sub.ailab-slp-settings {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px 8px 8px 28px;
  margin: 0 0 2px 0;
  border-bottom: 1px solid var(--ailab-border);
  background: rgba(255, 255, 255, 0.02);
}
.ailab-slp-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
  color: var(--ailab-text-muted, #8a8a9a);
}
.ailab-slp-field span { white-space: nowrap; }
.ailab-slp-field select {
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  color: var(--ailab-text);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 11px;
  cursor: pointer;
  min-width: 80px;
}
.ailab-slp-field-check {
  cursor: pointer;
  user-select: none;
  justify-content: flex-start;
}
.ailab-slp-field-check input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
  accent-color: var(--ailab-accent);
}

/* SLP overlay canvas: positioned absolutely over the chart area. The
   inline styles set in lib/structural-leg-renderer.js win, but this
   keeps a sane fallback if the JS file is delayed. */
.mi-slp-canvas {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
}

.ailab-chart-stack {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.ailab-chart-area--main { flex: 1; min-height: 0; }
.ailab-chart-area--sub {
  /* Iter 7q: height + flex-basis are mutated inline by the sub-pane
     resizer; min-height stays at the agreed floor (60px) so the user
     can shrink the pane more than the previous 100px lower bound. */
  flex: 0 0 100px;
  height: 100px;
  min-height: 60px;
  border-top: 1px solid var(--ailab-border);
  position: relative;
}
/* Iter 7q — draggable divider above each indicator sub-pane. The strip
   sits in the flex stack between the main chart and the sub-pane it
   resizes; height is intentionally small (4px hit-target, 6px hover) so
   it never steals chart real-estate at rest. */
.ailab-chart-resizer {
  flex: 0 0 4px;
  height: 4px;
  width: 100%;
  cursor: row-resize;
  background: transparent;
  position: relative;
  z-index: 4;
  touch-action: none;
  user-select: none;
  outline: none;
}
.ailab-chart-resizer::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 36px;
  height: 2px;
  border-radius: 2px;
  background: var(--ailab-border, rgba(255,255,255,0.10));
  transition: background 0.15s ease, height 0.15s ease;
}
.ailab-chart-resizer:hover::before,
.ailab-chart-resizer.is-dragging::before,
.ailab-chart-resizer:focus-visible::before {
  background: var(--ailab-accent, #b8e066);
  height: 3px;
}
.ailab-chart-resizer:focus-visible {
  box-shadow: inset 0 0 0 1px var(--ailab-accent, #b8e066);
}
.ailab-chart-pane-label {
  position: absolute;
  top: 4px;
  left: 8px;
  font-size: 10px;
  color: var(--ailab-text-muted);
  z-index: 2;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* AI Lab — search-toggle button (news / blank windows after first query). */
.ailab-window-btn-search-toggle svg { width: 12px; height: 12px; }
.ailab-window-btn-search-toggle.ailab-window-btn--active {
  color: var(--ailab-accent);
  background: rgba(184, 224, 102, 0.10);
}

/* AI Lab — Help window content -------------------------------------------- */
.ailab-help-body {
  padding: 14px 16px 16px 16px;
  color: var(--ailab-text);
  font-size: 12.5px;
  line-height: 1.55;
  overflow-y: auto;
  height: 100%;
  box-sizing: border-box;
}
.ailab-help-intro {
  color: var(--ailab-text);
  margin-bottom: 14px;
}
.ailab-help-section {
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-help-section:last-of-type {
  border-bottom: none;
  padding-bottom: 4px;
  margin-bottom: 8px;
}
.ailab-help-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ailab-accent);
  margin-bottom: 8px;
}
.ailab-help-section-title i {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
}
.ailab-help-list {
  margin: 0;
  padding-left: 18px;
  color: var(--ailab-text);
}
.ailab-help-list li {
  margin: 4px 0;
}
.ailab-help-list ul {
  margin: 4px 0 4px 0;
  padding-left: 18px;
  color: var(--ailab-text-muted);
}
.ailab-help-list ul li { margin: 2px 0; }
.ailab-help-list b { color: var(--ailab-text); font-weight: 600; }
.ailab-help-list i { color: var(--ailab-text-muted); font-style: italic; }
.ailab-help-foot {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--ailab-text-muted);
  font-style: italic;
}

/* =========================================================================
 * Sector heatmap window
 * Fixed header (title + market + metric toggles) sits above a stage that
 * fills the remaining body and hosts the squarify treemap. The canvas
 * itself absolutely-positions tiles and reflows on smooth resize via a
 * per-window ResizeObserver.
 * ========================================================================= */
.ailab-window-body.ailab-heatmap-host {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}
.ailab-heatmap-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  background: var(--ailab-surface-2);
  border-bottom: 1px solid var(--ailab-border);
  position: sticky;
  top: 0;
  z-index: 2;
  flex-wrap: wrap;
}
.ailab-heatmap-title {
  font-family: 'Inter', sans-serif;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ailab-text);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
}
.ailab-heatmap-toggles {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}
.ailab-heatmap-switch {
  display: inline-flex;
  background: var(--ailab-surface-3);
  border: 1px solid var(--ailab-border);
  border-radius: 4px;
  overflow: hidden;
}
.ailab-heatmap-switch-btn {
  background: transparent;
  border: 0;
  /* Iter 10d — brighter inactive label for higher contrast on the dark
     header strip. The previous --ailab-text-muted (#8a8a9a) was washing
     out next to the active white pill, especially on the metric group
     (Day % / Week % / YTD %). Bumped to a near-text neutral so all three
     options stay legible at a glance. */
  color: #c8c8d2;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  padding: 4px 9px;
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: color 0.12s ease, background 0.12s ease;
}
.ailab-heatmap-switch-btn + .ailab-heatmap-switch-btn {
  border-left: 1px solid var(--ailab-border);
}
.ailab-heatmap-switch-btn:hover {
  color: var(--ailab-text);
  background: rgba(255, 255, 255, 0.06);
}
.ailab-heatmap-switch-btn.is-active {
  background: var(--ailab-text);
  color: var(--ailab-bg);
}
/* Iter 9q: watchlist-source select sits between source and metric toggles.
   Hidden via the [hidden] attribute when source !== 'watchlist'. */
.ailab-heatmap-watchlist-select {
  background: var(--ailab-surface-3);
  border: 1px solid var(--ailab-border);
  border-radius: 4px;
  color: var(--ailab-text);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 3px 22px 3px 8px;
  cursor: pointer;
  max-width: 160px;
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ailab-text-muted) 50%), linear-gradient(135deg, var(--ailab-text-muted) 50%, transparent 50%);
  background-position: calc(100% - 11px) 50%, calc(100% - 7px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}
.ailab-heatmap-watchlist-select:hover { color: var(--ailab-text); border-color: var(--ailab-text-muted); }
.ailab-heatmap-watchlist-select:focus { outline: none; border-color: var(--ailab-text); }
.ailab-heatmap-watchlist-select[hidden] { display: none; }
.ailab-heatmap-watchlist-select option { background: var(--ailab-surface-3); color: var(--ailab-text); }
.ailab-heatmap-stage {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  background: #0e0e11;
  overflow: hidden;
}
.ailab-heatmap-canvas {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.ailab-heatmap-status {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 12px;
  color: var(--ailab-text-muted);
  padding: 16px;
}

/* Treemap tile primitives — self-scoped (ailab- prefix) so they don't
 * collide with the dashboard's index.html .tm-* rules. */
.ailab-tm-sector {
  position: absolute;
  box-sizing: border-box;
  border: 2px solid #000;
  overflow: hidden;
}
.ailab-tm-sector-label {
  position: absolute;
  top: 0; left: 0;
  z-index: 2;
  padding: 2px 5px;
  font-family: 'Inter', sans-serif;
  font-size: 9px;
  font-weight: 800;
  color: #fff;
  letter-spacing: 0.07em;
  background: rgba(0,0,0,0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  line-height: 18px;
  height: 18px;
  width: 100%;
  box-sizing: border-box;
}
.ailab-tm-industry {
  position: absolute;
  box-sizing: border-box;
  border: 1px solid rgba(0,0,0,0.5);
  overflow: hidden;
}
.ailab-tm-industry-label {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 14px;
  line-height: 14px;
  padding: 0 3px;
  font-family: 'Inter', sans-serif;
  font-size: 7.5px;
  font-weight: 700;
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.05em;
  background: rgba(0,0,0,0.3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  box-sizing: border-box;
}
.ailab-tm-tile {
  position: absolute;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 0.5px solid rgba(0,0,0,0.2);
  cursor: pointer;
  transition: filter 0.1s;
}
.ailab-tm-tile:hover {
  filter: brightness(1.18);
  z-index: 10;
}
.ailab-tm-tile-ticker {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.7);
  line-height: 1.1;
  text-align: center;
  pointer-events: none;
}
.ailab-tm-tile-pct {
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  color: rgba(255,255,255,0.88);
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  line-height: 1.1;
  text-align: center;
  pointer-events: none;
}
/* Iter 12CY — Company logo on AI Lab heatmap tiles (medium+ tiles only,
   gated in ai-lab.js _heatmapDraw() by tw>=60 && th>=60). Mirrors the
   .tm-tile-logo styling shipped in Iter 12CX for /markets sector map.
   Transparent PNG placed directly on the tile background; drop-shadow
   lifts it over the red/green colour. Pointer-events disabled so the
   tile keeps the click target for hover tooltip / dblclick handlers. */
.ailab-tm-tile-logo {
  display: block;
  object-fit: contain;
  margin-bottom: 4px;
  pointer-events: none;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.45));
  -webkit-user-drag: none;
  user-select: none;
}

/* Floating tooltip used by the heatmap window. Positioned at body root
 * so it is never clipped by the window's overflow:hidden. */
.ailab-heatmap-tooltip {
  position: fixed;
  pointer-events: none;
  z-index: 9999;
  display: none;
  background: #1c1c20;
  border: 1px solid #2a2a30;
  border-radius: 6px;
  padding: 10px 14px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  color: #cdccca;
  box-shadow: 0 4px 20px rgba(0,0,0,0.6);
  min-width: 160px;
  max-width: 220px;
}
.ailab-heatmap-tt-sym {
  font-weight: 700;
  font-size: 13px;
  color: #fff;
  margin-bottom: 4px;
}
.ailab-heatmap-tt-name {
  color: #797876;
  font-size: 11px;
  margin-bottom: 6px;
}
.ailab-heatmap-tt-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
}
.ailab-heatmap-tt-row span:first-child { color: #797876; }
.ailab-heatmap-tt-row span:last-child  { color: #cdccca; }
.ailab-heatmap-tt-row span.is-up   { color: #0eb35b; font-weight: 600; }
.ailab-heatmap-tt-row span.is-down { color: #C24A4A; font-weight: 600; }

/* =========================================================================
 * Watchlist window
 *
 * Title bar carries a dropdown trigger that lets the user switch which of
 * their saved watchlists is shown. The dropdown menu itself is rendered
 * at <body> root (so it can escape the window's overflow:hidden) and
 * positioned in JS just below the trigger.
 * ========================================================================= */
.ailab-window-title--watchlist {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
  /* The trigger button supplies its own font / colour treatment so the
     surrounding span just acts as a flex parent. */
  padding: 0;
}
.ailab-watchlist-title-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--ailab-text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  cursor: pointer;
  max-width: 100%;
  min-width: 0;
  text-align: left;
}
.ailab-watchlist-title-btn:hover {
  background: var(--ailab-surface-2);
  border-color: var(--ailab-border-strong);
}
.ailab-watchlist-title-btn[aria-expanded="true"] {
  background: var(--ailab-surface-2);
  border-color: var(--ailab-border-strong);
}
.ailab-watchlist-title-btn:focus-visible {
  outline: 2px solid var(--ailab-accent);
  outline-offset: 1px;
}
.ailab-watchlist-title-btn svg {
  flex: 0 0 12px;
  color: var(--ailab-text-muted);
}
.ailab-watchlist-title-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* Watchlist switcher dropdown — rendered at body root with absolute
   positioning. Visual treatment mirrors the workspace switcher menu so
   the AI Lab feels visually consistent. */
.ailab-watchlist-menu {
  position: fixed;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 8px;
  padding: 4px;
  min-width: 240px;
  max-width: 320px;
  max-height: 360px;
  overflow-y: auto;
  box-shadow: 0 12px 32px rgba(0,0,0,0.4);
  z-index: 9000;
}
.ailab-watchlist-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  border-radius: 6px;
  cursor: pointer;
}
.ailab-watchlist-menu-item:hover {
  background: var(--ailab-surface-2);
}
.ailab-watchlist-menu-item--active {
  background: var(--ailab-surface-2);
}
.ailab-watchlist-menu-item--active .ailab-watchlist-menu-check {
  color: var(--ailab-accent);
}
.ailab-watchlist-menu-check {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  color: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ailab-watchlist-menu-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.ailab-watchlist-menu-count {
  flex: 0 0 auto;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  padding: 1px 6px;
  background: var(--ailab-bg);
  border-radius: 10px;
  border: 1px solid var(--ailab-border);
}

/* Empty-state link inside watchlist widget body. */
.ailab-window-empty-link {
  color: var(--ailab-accent);
  text-decoration: none;
  font-weight: 600;
}
.ailab-window-empty-link:hover { text-decoration: underline; }

/* ============================================================
   Trading Notes panel
   ============================================================
   Slide-in from the right edge. Two-pane layout: scrollable list
   on the left (~300px), structured editor on the right. Editor
   has Trade Card and Free Notes tabs.
*/
.ailab-notes-panel {
  position: absolute;
  top: 0;
  right: var(--ailab-right-pane-width);
  bottom: 0;
  width: 720px;
  max-width: calc(100vw - 80px);
  background: var(--ailab-surface);
  border-left: 1px solid var(--ailab-border);
  box-shadow: -8px 0 32px rgba(0,0,0,0.45);
  display: flex;
  flex-direction: column;
  /* Must sit above all chart widgets/floating windows (max z-index 9999)
     so notes opens in front when toggled, like the right rail. */
  z-index: 11000;
  font-family: 'Inter', sans-serif;
  color: var(--ailab-text);
  /* Slide-in / slide-out animation. Starts off-screen to the right and
     glides into place when .ailab-notes-panel--open is added; reverses
     on close. The transform-based animation is GPU-accelerated and
     stays smooth on iPad. */
  transform: translateX(100%);
  opacity: 0;
  transition: transform 945ms cubic-bezier(0.22, 0.61, 0.36, 1),
              opacity 740ms ease-out;
  will-change: transform, opacity;
  pointer-events: none;
}
.ailab-notes-panel--open {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}
.ailab-notes-panel[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .ailab-notes-panel { transition: opacity 120ms ease-out; transform: none; }
  .ailab-notes-panel--open { transform: none; }
}
/* While a region capture is in progress the notes panel must not
   intercept taps or drags — critical on iPad where a faded panel still
   absorbs touches. We fade it visually and disable pointer events. */
.ailab-notes-panel--capturing {
  opacity: 0.12;
  pointer-events: none;
  touch-action: none;
  transition: opacity 120ms;
}

.ailab-notes-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-notes-head-left {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ailab-text);
}
.ailab-notes-head-left svg { width: 18px; height: 18px; color: var(--ailab-accent); }
.ailab-notes-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.ailab-notes-head-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ailab-notes-newbtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--ailab-accent);
  color: #0d1114;
  border: none;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms;
}
.ailab-notes-newbtn:hover { background: var(--ailab-accent-hover); }
.ailab-notes-newbtn svg { width: 14px; height: 14px; }
.ailab-notes-iconbtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--ailab-surface-2);
  color: var(--ailab-text-muted);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.ailab-notes-iconbtn:hover { background: var(--ailab-surface-3); color: var(--ailab-text); }
.ailab-notes-iconbtn svg { width: 14px; height: 14px; }
.ailab-notes-iconbtn--danger { color: #d97a7a; }
.ailab-notes-iconbtn--danger:hover { background: rgba(194,74,74,0.16); color: #ff8a8a; }

.ailab-notes-body {
  flex: 1 1 auto;
  display: flex;
  min-height: 0;
}

/* List pane ------------------------------------------------ */
.ailab-notes-list {
  flex-shrink: 0;
  width: 300px;
  border-right: 1px solid var(--ailab-border);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.ailab-notes-search {
  position: relative;
  padding: 10px 12px 6px;
}
.ailab-notes-search svg {
  position: absolute;
  left: 22px;
  top: 50%;
  transform: translateY(-25%);
  width: 14px;
  height: 14px;
  color: var(--ailab-text-dim);
  pointer-events: none;
}
.ailab-notes-search input {
  box-sizing: border-box;
  width: 100%;
  padding: 7px 10px 7px 32px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  color: var(--ailab-text);
  font-size: 12px;
  font-family: inherit;
  outline: none;
}
.ailab-notes-search input:focus { border-color: var(--ailab-accent); }

.ailab-notes-filterbar {
  display: flex;
  gap: 6px;
  padding: 4px 12px 8px;
  flex-wrap: wrap;
}
.ailab-notes-filterchip {
  padding: 4px 10px;
  background: transparent;
  border: 1px solid var(--ailab-border);
  border-radius: 999px;
  color: var(--ailab-text-muted);
  font-size: 11px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.ailab-notes-filterchip:hover { background: var(--ailab-surface-2); color: var(--ailab-text); }
.ailab-notes-filterchip--active {
  background: var(--ailab-accent-soft);
  border-color: var(--ailab-accent);
  color: var(--ailab-accent);
}

.ailab-notes-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 6px 12px 10px;
  border-bottom: 1px solid var(--ailab-border);
  font-size: 10px;
  color: var(--ailab-text-dim);
  letter-spacing: 0.02em;
}
.ailab-notes-stat { white-space: nowrap; }

.ailab-notes-rows {
  list-style: none;
  margin: 0;
  padding: 6px 0;
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}
.ailab-notes-row {
  position: relative;
  padding: 10px 12px;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background 120ms, border-color 120ms;
}
.ailab-notes-row:hover { background: var(--ailab-surface-2); }
.ailab-notes-row--active {
  background: var(--ailab-surface-2);
  border-left-color: var(--ailab-accent);
}
.ailab-notes-row-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.ailab-notes-row-ticker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: 13px;
  color: var(--ailab-text);
  letter-spacing: 0.02em;
}
.ailab-notes-row-dir {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
}
.ailab-notes-row-dir--long { background: rgba(14,179,91,0.15); color: #0eb35b; }
.ailab-notes-row-dir--short { background: rgba(194,74,74,0.15); color: #ff6b6b; }
.ailab-notes-row-outcome {
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 4px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ailab-notes-row-outcome--win { background: rgba(14,179,91,0.18); color: #0eb35b; }
.ailab-notes-row-outcome--loss { background: rgba(194,74,74,0.18); color: #ff6b6b; }
.ailab-notes-row-outcome--be { background: rgba(255,255,255,0.08); color: var(--ailab-text-muted); }
.ailab-notes-row-outcome--open { background: rgba(255,193,7,0.16); color: #f5c84b; }
.ailab-notes-row-mid {
  font-size: 12px;
  color: var(--ailab-text-muted);
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ailab-notes-row-bot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.ailab-notes-row-date {
  font-size: 11px;
  color: var(--ailab-text-dim);
}
.ailab-notes-row-shot {
  font-size: 11px;
  color: var(--ailab-accent);
}
.ailab-notes-row-del {
  background: transparent;
  border: none;
  color: var(--ailab-text-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  opacity: 0;
  transition: opacity 120ms, background 120ms, color 120ms;
}
.ailab-notes-row:hover .ailab-notes-row-del { opacity: 1; }
.ailab-notes-row-del:hover { background: rgba(194,74,74,0.18); color: #ff6b6b; }

.ailab-notes-empty {
  padding: 24px 16px;
  text-align: center;
  color: var(--ailab-text-dim);
  font-size: 12px;
  line-height: 1.5;
}
.ailab-notes-empty b { color: var(--ailab-text); }

/* Editor pane ---------------------------------------------- */
.ailab-notes-editor {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.ailab-notes-editor[hidden] { display: none; }

.ailab-notes-edit-tabs {
  flex-shrink: 0;
  display: flex;
  gap: 4px;
  padding: 10px 16px 0;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-notes-edit-tab {
  padding: 8px 14px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--ailab-text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: color 120ms, border-color 120ms;
  font-family: inherit;
}
.ailab-notes-edit-tab:hover { color: var(--ailab-text); }
.ailab-notes-edit-tab--active {
  color: var(--ailab-accent);
  border-bottom-color: var(--ailab-accent);
}
.ailab-notes-edit-body {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Lock horizontal scroll inside the trade card / free notes panes —
     only vertical scrolling is allowed. */
  overflow-x: hidden;
  min-width: 0;
  min-height: 0;
}
.ailab-notes-pane {
  padding: 14px 18px;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}
.ailab-notes-pane[hidden] { display: none; }

.ailab-notes-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px 12px;
  margin-bottom: 14px;
}
.ailab-notes-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--ailab-text-dim);
  letter-spacing: 0.02em;
}
.ailab-notes-field > span {
  text-transform: uppercase;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.ailab-notes-field input,
.ailab-notes-field select,
.ailab-notes-field textarea {
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 7px 9px;
  color: var(--ailab-text);
  font-size: 12px;
  font-family: inherit;
  outline: none;
  transition: border-color 120ms;
}
.ailab-notes-field input:focus,
.ailab-notes-field select:focus,
.ailab-notes-field textarea:focus {
  border-color: var(--ailab-accent);
}
.ailab-notes-field--ticker input { font-weight: 700; letter-spacing: 0.04em; }
.ailab-notes-field--wide { grid-column: span 4; }
.ailab-notes-hint {
  display: block;
  font-size: 10px;
  color: var(--ailab-text-dim);
  font-style: normal;
  margin-top: 2px;
}

.ailab-notes-section {
  margin-bottom: 14px;
}
.ailab-notes-section-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ailab-text-dim);
  margin-bottom: 6px;
}
.ailab-notes-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ailab-notes-chip {
  padding: 4px 10px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 999px;
  color: var(--ailab-text-muted);
  font-size: 11px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
  font-family: inherit;
}
.ailab-notes-chip:hover { background: var(--ailab-surface-3); color: var(--ailab-text); }
.ailab-notes-chip--active {
  background: var(--ailab-accent-soft);
  border-color: var(--ailab-accent);
  color: var(--ailab-accent);
}
.ailab-notes-chip--mistake-on {
  background: rgba(194,74,74,0.18);
  border-color: rgba(194,74,74,0.45);
  color: #ff6b6b;
}

.ailab-notes-section textarea {
  width: 100%;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--ailab-text);
  font-size: 12px;
  font-family: inherit;
  resize: vertical;
  outline: none;
  min-height: 56px;
}
.ailab-notes-section textarea:focus { border-color: var(--ailab-accent); }

.ailab-notes-shot {
  position: relative;
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
  background: var(--ailab-surface-2);
  padding: 6px;
  max-width: 100%;
}
.ailab-notes-shot img {
  display: block;
  max-width: 100%;
  max-height: 240px;
  border-radius: 4px;
  margin: 0 auto;
}
.ailab-notes-shot--empty {
  text-align: center;
  padding: 20px;
  color: var(--ailab-text-dim);
  font-size: 12px;
}
.ailab-notes-shot--empty b { color: var(--ailab-text); }
.ailab-notes-shot-clear {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  background: rgba(0,0,0,0.6);
  border: 1px solid var(--ailab-border);
  border-radius: 50%;
  color: var(--ailab-text);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.ailab-notes-shot-clear:hover { background: rgba(194,74,74,0.6); }

.ailab-notes-freebody {
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  min-height: 320px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 10px 12px;
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  line-height: 1.55;
  /* Vertical-only resize, and break long unbroken strings (URLs, hashes)
     so the textarea never forces horizontal scroll on the pane. */
  resize: vertical;
  overflow-wrap: anywhere;
  word-break: break-word;
  outline: none;
}
.ailab-notes-freebody:focus { border-color: var(--ailab-accent); }

/* Editor footer -------------------------------------------- */
.ailab-notes-edit-foot {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-top: 1px solid var(--ailab-border);
  background: var(--ailab-surface);
}
.ailab-notes-spacer { flex: 1 1 auto; }
.ailab-notes-savedot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ailab-text-dim);
}
.ailab-notes-savedot--dirty  { background: #f5c84b; }
.ailab-notes-savedot--saving { background: var(--ailab-accent); }
.ailab-notes-savedot--saved  { background: #0eb35b; }
.ailab-notes-savedot--error  { background: #C24A4A; }
.ailab-notes-savetxt {
  font-size: 11px;
  color: var(--ailab-text-dim);
}

/* Explicit Save button --------------------------------------
   Lives in the editor footer next to Capture / Delete. Mirrors the
   New-note button colour scheme so it reads as a primary action when
   there are unsaved changes, and dims to a muted state once saved. */
.ailab-notes-savebtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--ailab-border);
  background: var(--ailab-surface-2);
  color: var(--ailab-text-dim);
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.ailab-notes-savebtn svg { width: 14px; height: 14px; }
.ailab-notes-savebtn[disabled] { cursor: default; }
.ailab-notes-savebtn--dirty {
  background: var(--ailab-accent);
  border-color: var(--ailab-accent);
  color: #fff;
}
.ailab-notes-savebtn--dirty:hover { background: var(--ailab-accent-hover); border-color: var(--ailab-accent-hover); }
.ailab-notes-savebtn--saving {
  background: var(--ailab-surface-3);
  border-color: var(--ailab-border);
  color: var(--ailab-text-dim);
}
.ailab-notes-savebtn--saved {
  background: rgba(14,179,91,0.12);
  border-color: rgba(14,179,91,0.45);
  color: #0eb35b;
}
.ailab-notes-savebtn--error {
  background: rgba(194,74,74,0.12);
  border-color: rgba(194,74,74,0.55);
  color: #ff7a7a;
}
.ailab-notes-savebtn--error:hover { background: rgba(194,74,74,0.22); }

/* EDITING pill on the active row of the list pane --------
   Makes it unambiguous which existing note the editor is mutating, so
   typing into the editor never feels like it's creating a new note. */
.ailab-notes-row-editing {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  border-radius: 3px;
  background: rgba(79,152,163,0.18);
  color: var(--ailab-accent);
  border: 1px solid rgba(79,152,163,0.4);
  vertical-align: middle;
}

/* Chart-title notes badge ---------------------------------- */
.ailab-chart-title-notes {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 6px;
  padding: 2px 6px;
  background: transparent;
  border: 1px solid var(--ailab-border);
  border-radius: 4px;
  color: var(--ailab-text-dim);
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.ailab-chart-title-notes:hover {
  background: var(--ailab-surface-2);
  color: var(--ailab-text);
  border-color: var(--ailab-border-strong);
}
.ailab-chart-title-notes--has-notes {
  background: var(--ailab-accent-soft);
  border-color: var(--ailab-accent);
  color: var(--ailab-accent);
}
.ailab-chart-title-notes svg { width: 12px; height: 12px; }
.ailab-chart-title-notes-count {
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}
.ailab-chart-title-notes-count:empty { display: none; }

@media (max-width: 900px) {
  .ailab-notes-panel { width: 100%; right: 0; }
  .ailab-notes-list { width: 200px; }
  .ailab-notes-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ailab-notes-field--wide { grid-column: span 2; }
}

/* Ticker section (dedicated, full-width above the trade-card grid).
   One unified card. Empty state: just the search input. Selected state:
   a compact chip above the search showing symbol + company + clear. */
.ailab-notes-tickerbox {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
}
.ailab-notes-tickerbox-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}
.ailab-notes-tickerbox-current {
  display: flex;
  align-items: center;
  min-height: 0;
}
.ailab-notes-tickerbox-current:empty { display: none; }
.ailab-notes-tickerbox-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 6px 12px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 999px;
  max-width: 100%;
}
.ailab-notes-tickerbox-sym {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ailab-accent);
}
.ailab-notes-tickerbox-name {
  font-size: 12px;
  color: var(--ailab-text-muted);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.ailab-notes-tickerbox-search {
  position: relative;
  width: 100%;
}
.ailab-notes-tickerbox-search > svg {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  color: var(--ailab-text-dim);
  pointer-events: none;
}
.ailab-notes-tickerbox-search input {
  box-sizing: border-box;
  width: 100%;
  padding: 9px 12px 9px 32px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  outline: none;
  transition: border-color 120ms;
}
.ailab-notes-tickerbox-search input:focus { border-color: var(--ailab-accent); }
.ailab-notes-tickerbox-clear {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  background: transparent;
  border: none;
  color: var(--ailab-text-dim);
  font-size: 16px;
  line-height: 1;
  border-radius: 50%;
  cursor: pointer;
  transition: background 120ms, color 120ms;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ailab-notes-tickerbox-clear:hover { background: rgba(194,74,74,0.18); color: #ff6b6b; }

.ailab-notes-tickerbox-suggest {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  z-index: 50;
  max-height: 280px;
  overflow-y: auto;
}
.ailab-notes-tickerbox-suggest[hidden] { display: none; }
.ailab-notes-tickerbox-suggest-row {
  display: grid;
  grid-template-columns: 70px 1fr auto;
  align-items: baseline;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-notes-tickerbox-suggest-row:last-child { border-bottom: none; }
.ailab-notes-tickerbox-suggest-row:hover,
.ailab-notes-tickerbox-suggest-row--active {
  background: var(--ailab-surface-2);
}
.ailab-notes-tickerbox-suggest-sym {
  font-size: 13px;
  font-weight: 700;
  color: var(--ailab-accent);
  letter-spacing: 0.02em;
}
.ailab-notes-tickerbox-suggest-name {
  font-size: 12px;
  color: var(--ailab-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ailab-notes-tickerbox-suggest-ex {
  font-size: 10px;
  color: var(--ailab-text-dim);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ailab-notes-tickerbox-empty-row {
  padding: 10px 12px;
  font-size: 12px;
  color: var(--ailab-text-dim);
  text-align: center;
}

/* Reflow the trade-card grid to 3 columns now that Ticker is its own
   section. Direction / Outcome / Date land on the first row, then
   Strategy / Size / R-multiple, and so on. Tags stays full-width. */
.ailab-notes-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ailab-notes-field--wide { grid-column: span 3; }
@media (max-width: 900px) {
  .ailab-notes-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ailab-notes-field--wide { grid-column: span 2; }
}

/* =====================================================================
 * AI Lab: chart-style toggle (Coloured / Neutral) + SLP info popover
 * (added 29 Apr 2026 — slp4)
 * ===================================================================== */

/* Chart style toggle — single 3D pill, matches .wl-style-toggle on dashboard.
   Grey = neutral candles (off), muted red = coloured candles (on). */
.ailab-chart-style-toggle {
  height: 22px;
  width: 22px;
  padding: 0;
  margin-left: 6px;
  border-radius: 5px;
  border: 1px solid rgba(0,0,0,0.6);
  cursor: pointer;
  user-select: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex-shrink: 0;
  background: linear-gradient(180deg, #5a5f66 0%, #3a3e44 55%, #2a2d31 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.22),
    inset 0 -1px 0 rgba(0,0,0,0.45),
    0 1px 2px rgba(0,0,0,0.55),
    0 2px 3px rgba(0,0,0,0.35);
  transition: transform 0.08s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.ailab-chart-style-toggle::after {
  content: "";
  position: absolute;
  inset: 1px 1px auto 1px;
  height: 45%;
  border-radius: 4px 4px 2px 2px;
  background: linear-gradient(180deg, rgba(255,255,255,0.30) 0%, rgba(255,255,255,0.04) 100%);
  pointer-events: none;
}
.ailab-chart-style-toggle:hover { filter: brightness(1.08); }
.ailab-chart-style-toggle:active {
  transform: translateY(1px);
  box-shadow:
    inset 0 1px 2px rgba(0,0,0,0.55),
    inset 0 -1px 0 rgba(255,255,255,0.10),
    0 1px 1px rgba(0,0,0,0.40);
}
.ailab-chart-style-toggle.is-on {
  border-color: rgba(120,40,40,0.75);
  background: linear-gradient(180deg, #c24a4a 0%, #a33a3a 55%, #7a2828 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.22),
    inset 0 -1px 0 rgba(0,0,0,0.55),
    0 1px 2px rgba(0,0,0,0.55),
    0 2px 6px rgba(194,74,74,0.30),
    0 0 8px rgba(194,74,74,0.18);
}
.ailab-chart-style-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(79,152,163,0.55);
}
.ailab-chart-style-toggle .sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* Indicator row with a help icon: align checkbox / label / '?' on one line. */
.ailab-chart-inditem--slp,
.ailab-chart-inditem--has-info { display: flex; align-items: center; gap: 6px; }
.ailab-chart-inditem--slp > span,
.ailab-chart-inditem--has-info > span { flex: 1; }

/* Touch-device discovery hint at the top of the Indicators dropdown.
   Hidden on mouse-driven systems (where hover-preview already makes the
   '?' icons self-explanatory) and shown on iPads / phones / hybrid
   tablets where hover doesn't fire. */
.ailab-chart-indhint {
  display: none;
  margin: 4px 8px 8px;
  padding: 6px 8px;
  background: rgba(79,152,163,0.10);
  border: 1px solid rgba(79,152,163,0.22);
  border-radius: 5px;
  color: var(--ailab-text-dim, #c2cad6);
  font: 500 11px/1.35 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
  letter-spacing: 0.01em;
}
.ailab-chart-indhint-q {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px; height: 14px;
  margin: 0 1px;
  border-radius: 50%;
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.18);
  color: var(--ailab-text, #f0f6fc);
  font: 700 10px/1 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
}
@media (hover: none) and (pointer: coarse) {
  .ailab-chart-indhint { display: block; }
}

/* Display-options separator at the bottom of the Indicators dropdown. */
.ailab-chart-indsep {
  height: 1px;
  margin: 6px 8px;
  background: rgba(255, 255, 255, 0.08);
}

.ailab-slp-info-btn {
  width: 18px; height: 18px;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.06);
  color: var(--ailab-text, #e6edf3);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 50%;
  font: 600 11px/1 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
  cursor: pointer;
}
.ailab-slp-info-btn:hover {
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.20);
}

.ailab-slp-info-panel {
  margin: 6px 10px 8px;
  padding: 12px 14px;
  background: linear-gradient(180deg, rgba(28,34,46,0.96), rgba(20,25,34,0.96));
  color: var(--ailab-text, #c9d1d9);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  font: 12px/1.5 var(--ailab-font, system-ui, -apple-system, "Segoe UI", sans-serif);
  width: 360px;
  max-width: 360px;
  max-height: 420px;
  overflow-y: auto;
}
.ailab-slp-info-panel[hidden] { display: none; }
.ailab-slp-info-title {
  font-weight: 700;
  color: var(--ailab-text, #f0f6fc);
  margin: 0 0 4px;
  font-size: 13px;
  letter-spacing: 0.01em;
}
.ailab-slp-info-h {
  font-weight: 700;
  color: #4f98a3;
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.06em;
  margin: 12px 0 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(79,152,163,0.18);
}
.ailab-slp-info-panel p { margin: 0 0 8px; color: var(--ailab-text-dim, #c2cad6); }
.ailab-slp-info-panel ul { margin: 0 0 4px; padding-left: 16px; }
.ailab-slp-info-panel li { margin-bottom: 5px; color: var(--ailab-text-dim, #c2cad6); }
.ailab-slp-info-panel b { color: var(--ailab-text, #f0f6fc); font-weight: 600; }
/* Custom scrollbar inside the popover so it doesn't draw the system bar. */
.ailab-slp-info-panel::-webkit-scrollbar { width: 6px; }
.ailab-slp-info-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 3px; }
.ailab-slp-info-panel::-webkit-scrollbar-track { background: transparent; }

/* ===================================================================
   Iter 8g — Chart-widget ticker picker
   ===================================================================
   Clickable autocomplete dropdown anchored to a chart window's title
   span. Mirrors the notes-tickerbox UX (debounced /api/stock/search,
   keyboard nav, hover/active row highlight) but rendered as a floating
   panel that overlays the chart body.
   ------------------------------------------------------------------- */
.ailab-chart-symbol-picker {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 280px;
  max-width: calc(100vw - 24px);
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.55);
  padding: 8px;
  z-index: 60;
}
.ailab-chart-symbol-picker-search {
  position: relative;
  width: 100%;
}
.ailab-chart-symbol-picker-search > svg {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  color: var(--ailab-text-dim);
  pointer-events: none;
}
.ailab-chart-symbol-picker-input {
  box-sizing: border-box;
  width: 100%;
  /* Iter 8h — right padding bumped to 30px to leave room for the
     inline clear (×) button without text running under it. */
  padding: 8px 30px 8px 32px;
  background: var(--ailab-bg);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  color: var(--ailab-text);
  font-size: 13px;
  font-family: inherit;
  outline: none;
  transition: border-color 120ms;
}
.ailab-chart-symbol-picker-input:focus { border-color: var(--ailab-accent); }
/* Iter 8h — inline clear (×) button anchored to the right edge of the
   search row. Hidden via the [hidden] attribute when the input is empty;
   visible state matches the notes-tickerbox-clear hover treatment. */
.ailab-chart-symbol-picker-clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--ailab-text-dim);
  font-size: 16px;
  line-height: 1;
  border-radius: 50%;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms, color 120ms;
}
.ailab-chart-symbol-picker-clear[hidden] { display: none; }
.ailab-chart-symbol-picker-clear:hover {
  background: rgba(194,74,74,0.18);
  color: #ff6b6b;
}
.ailab-chart-symbol-picker-suggest {
  margin-top: 6px;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  max-height: 280px;
  overflow-y: auto;
}
.ailab-chart-symbol-picker-suggest[hidden] { display: none; }
.ailab-chart-symbol-picker-row {
  display: grid;
  grid-template-columns: 70px 1fr auto;
  align-items: baseline;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--ailab-border);
}
.ailab-chart-symbol-picker-row:last-child { border-bottom: none; }
.ailab-chart-symbol-picker-row:hover,
.ailab-chart-symbol-picker-row--active {
  background: var(--ailab-surface-2);
}
.ailab-chart-symbol-picker-sym {
  font-size: 13px;
  font-weight: 700;
  color: var(--ailab-accent);
  letter-spacing: 0.02em;
}
.ailab-chart-symbol-picker-name {
  font-size: 12px;
  color: var(--ailab-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ailab-chart-symbol-picker-ex {
  font-size: 10px;
  color: var(--ailab-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ailab-chart-symbol-picker-empty {
  padding: 12px;
  text-align: center;
  color: var(--ailab-text-dim);
  font-size: 12px;
}

/* ============================================================
   Index Card widget (Iter 9x)
   Real-time index ticker bar inside an AI Lab window.
   Mirrors the watchlist page's .idx-bar look-and-feel but
   scoped under .ailab-idxcard-* so the two are decoupled.
   ============================================================ */
.ailab-idxcard-host {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px 14px;
  overflow: hidden;
}

.ailab-idxcard-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.ailab-idxcard-title {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ailab-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ailab-idxcard-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  flex: 1;
  min-height: 0;
}

.ailab-idxcard-item {
  flex: 1 1 0;
  min-width: 80px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
  padding: 8px 12px;
  transition: background 0.2s ease;
  display: flex;
  flex-direction: column;
  /* Iter 9p — pin rows to the top so label/price/change/AH align
     horizontally across all tiles regardless of whether AH is filled. */
  justify-content: flex-start;
}

.ailab-idxcard-item:hover {
  background: var(--ailab-surface-3);
}

.ailab-idxcard-label {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 600;
  color: var(--ailab-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: block;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ailab-idxcard-price {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 16px;
  font-weight: 500;
  color: var(--ailab-text);
  font-variant-numeric: tabular-nums lining-nums;
  display: block;
}

.ailab-idxcard-change {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 12px;
  font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums;
  margin-top: 2px;
  display: block;
  color: var(--ailab-text-muted);
}

.ailab-idxcard-change.up { color: var(--ailab-positive); }
.ailab-idxcard-change.down { color: var(--ailab-negative); }

.ailab-idxcard-ah {
  display: flex;
  align-items: center;
  gap: 3px;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
  margin-top: 1px;
  opacity: 0.85;
}

/* Iter 9p — keep empty AH spans in flow so all tiles reserve the same
   vertical space; otherwise rows shift up and break horizontal alignment
   between AH-bearing tiles (SPX/DJI/IXIC/RUT) and the rest. */
.ailab-idxcard-ah:empty { min-height: 13px; }
.ailab-idxcard-ah.up { color: var(--ailab-positive); }
.ailab-idxcard-ah.down { color: var(--ailab-negative); }
.ailab-idxcard-ah svg { flex-shrink: 0; opacity: 0.7; }

/* Crypto label accent — BTC orange / ETH blue (matches dashboard) */
.ailab-idxcard-item--crypto[data-key="BTCUSD"] .ailab-idxcard-label { color: #f7931a; }
.ailab-idxcard-item--crypto[data-key="ETHUSD"] .ailab-idxcard-label { color: #627eea; }

/* Flash on price update */
@keyframes ailab-idxcard-flash-green {
  0% { background: rgba(109, 170, 69, 0.18); }
  100% { background: var(--ailab-surface-2); }
}
@keyframes ailab-idxcard-flash-red {
  0% { background: rgba(221, 105, 116, 0.18); }
  100% { background: var(--ailab-surface-2); }
}
.ailab-idxcard-item.flash-up { animation: ailab-idxcard-flash-green 0.6s ease; }
.ailab-idxcard-item.flash-down { animation: ailab-idxcard-flash-red 0.6s ease; }

/* Narrow widget — let cards shrink down then wrap to two rows of four. */
.ailab-idxcard-item {
  /* Allow flex shrink without busting min-width on slightly-resized
     windows; the wrap rule below handles truly narrow widgets. */
  min-width: 0;
}
@media (max-width: 720px) {
  .ailab-idxcard-bar { flex-wrap: wrap; }
  .ailab-idxcard-item { flex: 1 1 calc(25% - 6px); min-width: 70px; }
}

/* ============================================================
   Iter 12AS — Yield Curve widget
   Plot canvas + inversion badge + spread strip. Reuses
   .ailab-idxcard-host / -header / -title from the Index Card
   block above so the header chrome matches Treasury Rates exactly;
   only the bits unique to a chart (SVG container, badge pill,
   spread strip) live here.
   ============================================================ */
.ailab-ycurve-plot {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
  padding: 6px 8px;
  overflow: hidden;
}
.ailab-ycurve-svg {
  width: 100%;
  height: 100%;
  display: block;
}
.ailab-ycurve-loading {
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  color: var(--ailab-text-muted);
}

/* Inversion badge — lives in the header row, right-aligned against
   the title. Pill shape with state-driven colour. Width is
   content-sized; minimum padding keeps single-word labels comfortable. */
.ailab-ycurve-badge {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 10px;
  border: 1px solid var(--ailab-border);
  color: var(--ailab-text-muted);
  background: var(--ailab-surface-2);
  white-space: nowrap;
}
.ailab-ycurve-badge--normal {
  color: var(--ailab-positive);
  border-color: rgba(109, 170, 69, 0.45);
  background: rgba(109, 170, 69, 0.12);
}
.ailab-ycurve-badge--flat {
  color: #d4a04c;
  border-color: rgba(212, 160, 76, 0.45);
  background: rgba(212, 160, 76, 0.12);
}
.ailab-ycurve-badge--inverted {
  color: var(--ailab-negative);
  border-color: rgba(221, 105, 116, 0.45);
  background: rgba(221, 105, 116, 0.14);
}

/* Spread strip below the chart — three compact tiles showing
   2s10s / 2s30s / 10s30s in bps. */
.ailab-ycurve-spreads {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.ailab-ycurve-spread {
  flex: 1 1 0;
  min-width: 0;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 6px 10px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.ailab-ycurve-spread-label {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 600;
  color: var(--ailab-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.ailab-ycurve-spread-value {
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: var(--ailab-text);
  font-variant-numeric: tabular-nums lining-nums;
}
.ailab-ycurve-spread-value.up   { color: var(--ailab-positive); }
.ailab-ycurve-spread-value.down { color: var(--ailab-negative); }

/* ============================================================
   Currency Pairs widget (Iter 9z)
   FX live ticker bar inside an AI Lab window. Mirrors the Index
   Card visual language but scoped under .ailab-fxcard-* so the
   two are decoupled.
   ============================================================ */
.ailab-fxcard-host {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px 14px;
  overflow: hidden;
}

.ailab-fxcard-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

.ailab-fxcard-title {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ailab-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ailab-fxcard-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  flex: 1;
  min-height: 0;
}

.ailab-fxcard-item {
  flex: 1 1 0;
  min-width: 80px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 8px;
  padding: 8px 12px;
  transition: background 0.2s ease;
  display: flex;
  flex-direction: column;
  /* Iter 9p — pin rows to top for consistent horizontal alignment. */
  justify-content: flex-start;
  /* Iter 12BT — anchor for the absolute-positioned delete (×) button. */
  position: relative;
}

.ailab-fxcard-item:hover {
  background: var(--ailab-surface-3);
}

.ailab-fxcard-label {
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 600;
  color: var(--ailab-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: block;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ailab-fxcard-price {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 16px;
  font-weight: 500;
  color: var(--ailab-text);
  font-variant-numeric: tabular-nums lining-nums;
  display: block;
}

.ailab-fxcard-change {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 12px;
  font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums;
  margin-top: 2px;
  display: block;
  color: var(--ailab-text-muted);
}

.ailab-fxcard-change.up { color: var(--ailab-positive); }
.ailab-fxcard-change.down { color: var(--ailab-negative); }

/* DXY accent — gold-ish to set it apart from the FX pairs. */
.ailab-fxcard-item--dxy .ailab-fxcard-label { color: #d4a017; }

/* Flash on price update */
@keyframes ailab-fxcard-flash-green {
  0% { background: rgba(109, 170, 69, 0.18); }
  100% { background: var(--ailab-surface-2); }
}
@keyframes ailab-fxcard-flash-red {
  0% { background: rgba(221, 105, 116, 0.18); }
  100% { background: var(--ailab-surface-2); }
}
.ailab-fxcard-item.flash-up { animation: ailab-fxcard-flash-green 0.6s ease; }
.ailab-fxcard-item.flash-down { animation: ailab-fxcard-flash-red 0.6s ease; }

/* Narrow widget — let cards shrink down then wrap to two rows of four. */
.ailab-fxcard-item {
  min-width: 0;
}
@media (max-width: 720px) {
  .ailab-fxcard-bar { flex-wrap: wrap; }
  .ailab-fxcard-item { flex: 1 1 calc(25% - 6px); min-width: 70px; }
}

/* ============================================================
 * Iter 12BT — Add/Delete controls for the Currency Pairs widget.
 * Header search box + dropdown + per-card delete (×) overlay.
 * Cards are flex 1 1 0 so removing/adding pairs reflows the bar
 * naturally without manual width recompute.
 * ============================================================ */
.ailab-fxcard-add {
  position: relative;
  display: flex;
  align-items: center;
  margin-left: 12px;
  margin-right: 10px;
  flex: 1 1 auto;
  max-width: 200px;
}

.ailab-fxcard-add-input {
  width: 100%;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  padding: 4px 8px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  color: var(--ailab-text);
  outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.ailab-fxcard-add-input::placeholder {
  color: var(--ailab-text-muted);
  opacity: 0.85;
}
.ailab-fxcard-add-input:focus {
  border-color: var(--ailab-border-strong);
  background: var(--ailab-surface-3);
}

.ailab-fxcard-add-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 220px;
  max-height: 280px;
  overflow-y: auto;
  background: var(--ailab-surface);
  border: 1px solid var(--ailab-border-strong);
  border-radius: 8px;
  padding: 4px 0;
  z-index: 100;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}
.ailab-fxcard-add-menu[hidden] { display: none; }

/* Iter 12BU — floating variant: dropdown is reparented to document.body
   and positioned with position:fixed so the host window's overflow:hidden
   never clips it. The JS sets top/left/width inline each open.
   Iter 12CA — removed the previous `top: 0; right: 0` defaults from this
   class. The class itself no longer asserts any inline coordinates so a
   freshly-attached menu can't briefly flash at the top-right corner before
   positionMenu() runs, and stale class defaults can't fight inline values.
   The JS now sets every positioning prop (top/right/bottom/left) inline. */
.ailab-fxcard-add-menu--floating {
  position: fixed;
  z-index: 10000;
}

.ailab-fxcard-add-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  cursor: pointer;
  transition: background 0.12s ease;
}
.ailab-fxcard-add-item:hover,
.ailab-fxcard-add-item.is-active {
  background: var(--ailab-surface-2);
}
.ailab-fxcard-add-item-main {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1 1 auto;
  min-width: 0;
}
.ailab-fxcard-add-item-label {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ailab-text);
  letter-spacing: 0.04em;
}
.ailab-fxcard-add-item-name {
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  color: var(--ailab-text-muted);
}
.ailab-fxcard-add-item-tag {
  font-family: 'Inter', sans-serif;
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ailab-text-muted);
  background: var(--ailab-surface-3);
  border: 1px solid var(--ailab-border);
  border-radius: 4px;
  padding: 2px 6px;
  flex-shrink: 0;
}
.ailab-fxcard-add-item.is-added {
  cursor: not-allowed;
  opacity: 0.55;
}
.ailab-fxcard-add-item.is-added:hover {
  background: transparent;
}
.ailab-fxcard-add-empty {
  padding: 8px 10px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-style: italic;
  color: var(--ailab-text-muted);
}

/* Per-card delete overlay — hidden until card hover. tabindex=-1 in JS
   so it doesn't steal keyboard focus from the card itself. */
.ailab-fxcard-del {
  position: absolute;
  top: 3px;
  right: 4px;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 3px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  line-height: 1;
  color: var(--ailab-text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.ailab-fxcard-item:hover .ailab-fxcard-del {
  opacity: 1;
}
.ailab-fxcard-del:hover {
  color: var(--ailab-text);
  background: rgba(255, 255, 255, 0.06);
}

@media (max-width: 720px) {
  .ailab-fxcard-add { max-width: 150px; margin-left: 8px; }
  .ailab-fxcard-add-menu { min-width: 200px; }
  /* On narrow widget, expose delete buttons full-time since hover is unreliable on touch. */
  .ailab-fxcard-del { opacity: 0.6; }
}

/* ============================================================
 * Iter 11b — Earnings Calendar widget
 * ============================================================ */
.ailab-earnings-host {
  padding: 6px 0 0;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--ailab-surface);
}
/* Cap the inner row/header content to its natural column-sum width so no
   empty space is reserved to the right of the Imp/Time column when the
   widget is wider than the grid (~632px). Left-aligned (no auto margin)
   so the rows pin to the left edge and any extra widget width is empty
   to the right — but the widget default size now matches this width. */
.ailab-earnings-row,
.ailab-earnings-day,
.ailab-earnings-empty,
.ailab-earnings-headers {
  max-width: 632px;
  width: 100%;
  box-sizing: border-box;
}
.ailab-earnings-section {
  margin-bottom: 6px;
}
.ailab-earnings-day {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  background: var(--ailab-surface);
  border-bottom: 1px solid var(--ailab-border);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ailab-text-muted);
  text-transform: uppercase;
}
.ailab-earnings-day-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--ailab-surface-2);
  color: var(--ailab-text-muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
}
/* Iter 11x earnings refresh: every event is a SINGLE-LINE row that never
   wraps. Layout columns:
     [ticker | company name (flex, ellipsis) | EPS A/E | Rev A/E | tags]
   The company name column flexes/ellipsises so narrow widget widths
   still keep all stats visible on one line. */
/* v3 row grid: identity (logo + ticker stack) | EPS-A | EPS-E | Rev-A | Rev-E | tags.
   Identity flexes; numeric columns are fixed-width and centre-aligned so the
   header label sits exactly above the value cell beneath it. The tags column
   pins to the right edge so impact / time chips never drift between rows. */
.ailab-earnings-row,
.ailab-earnings-headers {
  display: grid;
  /* Identity column is fixed-width so the numeric block hugs the company
     name closely (identity → EPS A gap effectively zero). The trailing
     spacer column is capped to a small fixed width so the gap between
     Rev E and Imp/Time stays tight (~70% smaller than the previous 1fr
     spacer that absorbed all extra space). Numeric columns use a halved
     inline padding (1.5px) to keep the EPS/Rev block compact. */
  grid-template-columns:
    minmax(140px, 180px) /* identity (logo + ticker + name) — tight cap so name hugs EPS A */
    68px                 /* EPS A */
    68px                 /* EPS E */
    84px                 /* Rev A */
    84px                 /* Rev E */
    minmax(0, 24px)      /* small fixed spacer (was 1fr) — Rev E→tags gap */
    96px;                /* Imp / Time tags */
  align-items: center;
  column-gap: 0;
  padding: 6px 14px;
  white-space: nowrap;
}
.ailab-earnings-row {
  cursor: pointer;
  transition: background 80ms ease;
  border-bottom: 1px solid var(--ailab-border-subtle, rgba(255,255,255,0.04));
  padding: 8px 14px;
}
.ailab-earnings-row:hover { background: var(--ailab-surface-2); }
.ailab-earnings-row:focus-visible {
  outline: 2px solid var(--ailab-accent, #5fa7ff);
  outline-offset: -2px;
}
/* Column-header row: small uppercase muted labels, centred under their values.
   Right-padding is 0 so the sticky-header background ends flush with the
   IMP/TIME column, matching the implicit (transparent) right edge of the
   data rows below. */
.ailab-earnings-headers {
  padding: 8px 0 6px 14px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ailab-text-muted);
  border-bottom: 1px solid var(--ailab-border-subtle, rgba(255,255,255,0.06));
  background: var(--ailab-surface-1, transparent);
}
/* Sticky variant — the single column header pinned to the top of the
   widget body so it stays visible while users scroll the day sections. */
.ailab-earnings-headers--sticky {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--ailab-surface-1, var(--ailab-bg, #0e1117));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.ailab-earnings-h-ticker { text-align: left; }
.ailab-earnings-h-num    { text-align: center; }
.ailab-earnings-h-tags   { text-align: center; }
/* Identity cell: small logo + stacked ticker / company name. */
.ailab-earnings-id {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.ailab-earnings-logo {
  width: 18px;
  height: 18px;
  border-radius: 3px;
  object-fit: contain;
  background: var(--ailab-surface-2);
  flex-shrink: 0;
}
.ailab-earnings-logo--placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--ailab-text-muted);
  letter-spacing: 0.02em;
}
.ailab-earnings-id-text {
  display: inline-flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
}
.ailab-earnings-symbol {
  font-size: 13px;
  font-weight: 700;
  color: var(--ailab-text);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.ailab-earnings-name {
  font-size: 11px;
  color: var(--ailab-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  margin-top: 1px;
}
/* Centre-aligned numeric cells, one per Actual/Estimate column. The fixed
   column width above keeps the value visually centred under its header.
   Tiny inline padding controls the gap between adjacent numeric columns
   without affecting the identity→EPS A boundary. */
.ailab-earnings-num {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
  padding: 0 1.5px;
}
.ailab-earnings-h-num { padding: 0 1.5px; }
.ailab-earnings-num--actual {
  font-weight: 700;
  color: var(--ailab-text);
}
.ailab-earnings-num--est {
  font-weight: 500;
  color: var(--ailab-text-muted);
}
.ailab-earnings-tags {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex-shrink: 0;
}
/* Importance pill (L / M / H). Colours mirror the reference design:
   high = solid red, medium = amber outline, low = grey outline. */
.ailab-earnings-impact {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 20px;
  padding: 0 7px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
  background: var(--ailab-surface-2);
  color: var(--ailab-text-muted);
}
.ailab-earnings-impact--high {
  background: #d04a4a;
  color: #fff;
  border-color: #d04a4a;
}
.ailab-earnings-impact--medium {
  background: rgba(212, 160, 23, 0.16);
  color: #d4a017;
  border-color: rgba(212, 160, 23, 0.55);
}
.ailab-earnings-impact--low {
  background: transparent;
  color: var(--ailab-text-muted);
  border-color: var(--ailab-border);
}
.ailab-earnings-impact--none {
  background: transparent;
  color: var(--ailab-text-muted);
  border-color: var(--ailab-border-subtle, rgba(255,255,255,0.08));
}
/* Time icon chip — colour-coded by session, no text label. */
.ailab-earnings-time {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 20px;
  border-radius: 4px;
  background: var(--ailab-surface-2);
  color: var(--ailab-text-muted);
}
.ailab-earnings-time i {
  width: 13px;
  height: 13px;
}
.ailab-earnings-time--bmo {
  background: rgba(109, 170, 69, 0.18);
  color: var(--ailab-positive, #6daa45);
}
.ailab-earnings-time--amc {
  background: rgba(95, 167, 255, 0.18);
  color: var(--ailab-accent, #5fa7ff);
}
.ailab-earnings-time--dmh {
  background: rgba(212, 160, 23, 0.18);
  color: #d4a017;
}
.ailab-earnings-time--tbd {
  background: var(--ailab-surface-2);
  color: var(--ailab-text-muted);
}
/* Inline EPS / Revenue stat: "<Label> <Actual> / <Estimate>" — sits
   inline as one of the row's grid columns. */
.ailab-earnings-stat {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ailab-earnings-stat-label {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ailab-text-muted);
  margin-right: 2px;
}
.ailab-earnings-stat-actual {
  font-size: 12px;
  font-weight: 700;
  color: var(--ailab-text);
}
.ailab-earnings-stat-sep {
  font-size: 11px;
  color: var(--ailab-text-muted);
  opacity: 0.7;
}
.ailab-earnings-stat-est {
  font-size: 11px;
  font-weight: 500;
  color: var(--ailab-text-muted);
}
.ailab-earnings-empty {
  padding: 10px 12px 12px;
  font-size: 11px;
  color: var(--ailab-text-muted);
  font-style: italic;
}
.ailab-earnings-foot {
  padding: 10px 12px 14px;
  font-size: 10px;
  color: var(--ailab-text-muted);
  text-align: center;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Menu separator (used in the earnings filter dropdown). */
.ailab-watchlist-menu-sep {
  height: 1px;
  margin: 4px 8px;
  background: var(--ailab-border);
}

/* Earnings widget hides the search row (it's data-driven, not query-driven). */
.ailab-window[data-window-type="earnings"] .ailab-window-search { display: none; }

/* ============================================================
 * Iter 11c — Value at Risk widget
 * ============================================================ */
.ailab-window-title--var {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}
.ailab-window-title--var .ailab-watchlist-title-btn {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 140px;
}
.ailab-var-titlebar-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex-shrink: 0;
}
.ailab-var-weight-toggle {
  display: inline-flex;
  height: 22px;
  padding: 2px;
  border-radius: 6px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
}
.ailab-var-weight-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 18px;
  min-width: 24px;
  padding: 0 6px;
  border: 0;
  background: transparent;
  color: var(--ailab-text-muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 4px;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.ailab-var-weight-btn:hover { color: var(--ailab-text); }
.ailab-var-weight-btn--active {
  background: var(--ailab-accent, #5fa7ff);
  color: #fff;
}
.ailab-var-notional {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 6px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  font-size: 11px;
  color: var(--ailab-text);
  cursor: text;
}
.ailab-var-notional-prefix {
  color: var(--ailab-text-muted);
  margin-right: 2px;
  font-weight: 600;
}
.ailab-var-notional-input {
  width: 60px;
  border: 0;
  background: transparent;
  color: var(--ailab-text);
  font: inherit;
  font-variant-numeric: tabular-nums;
  outline: none;
  padding: 0;
}
.ailab-var-notional:focus-within {
  border-color: var(--ailab-accent, #5fa7ff);
}

/* Body */
.ailab-var-host {
  display: flex;
  flex-direction: column;
  padding: 10px;
  gap: 10px;
  background: var(--ailab-surface);
}
.ailab-var-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
}
.ailab-var-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 6px;
  padding: 10px;
  border-radius: 8px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
  min-height: 88px;
  transition: border-color 150ms ease, background 150ms ease;
}
.ailab-var-tile-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ailab-text-muted);
  text-transform: uppercase;
}
.ailab-var-tile-sub {
  display: inline-block;
  margin-left: 4px;
  font-size: 9px;
  font-weight: 500;
  color: var(--ailab-text-muted);
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.7;
}
.ailab-var-tile-value {
  font-size: 20px;
  font-weight: 700;
  color: var(--ailab-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.ailab-var-tile-foot {
  font-size: 10px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
}
/* Heat ramp on the headline 95% VaR magnitude. */
.ailab-var-tile--low    { border-color: rgba(109, 170, 69, 0.35); }
.ailab-var-tile--low    .ailab-var-tile-value { color: #6daa45; }
.ailab-var-tile--mid    { border-color: rgba(212, 160, 23, 0.35); }
.ailab-var-tile--mid    .ailab-var-tile-value { color: #d4a017; }
.ailab-var-tile--high   { border-color: rgba(232, 92, 92, 0.45); }
.ailab-var-tile--high   .ailab-var-tile-value { color: #e85c5c; }
.ailab-var-tile--xhigh  { border-color: rgba(232, 92, 92, 0.7); background: rgba(232, 92, 92, 0.06); }
.ailab-var-tile--xhigh  .ailab-var-tile-value { color: #ff5c5c; }
.ailab-var-tile--neutral .ailab-var-tile-value { color: var(--ailab-text-muted); }

.ailab-var-sparkrow {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px 8px;
  border-radius: 8px;
  background: var(--ailab-surface-2);
  border: 1px solid var(--ailab-border);
}
.ailab-var-spark-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ailab-text-muted);
  text-transform: uppercase;
}
.ailab-var-spark {
  width: 100%;
  height: 36px;
  color: #e85c5c;
}
.ailab-var-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px 2px;
}
.ailab-var-pct-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  border: 1px solid var(--ailab-border);
  background: var(--ailab-surface-2);
  color: var(--ailab-text);
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
}
.ailab-var-pct-toggle:hover { background: var(--ailab-surface); }
.ailab-var-foot-meta {
  font-size: 10px;
  color: var(--ailab-text-muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-window[data-window-type="var"] .ailab-window-search { display: none; }

/* === Iter 11d — Correlation Matrix === */
.ailab-window[data-window-type="correlation"] .ailab-window-search { display: none; }
.ailab-corr-host {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 10px;
  gap: 10px;
  box-sizing: border-box;
  overflow: hidden;
}
.ailab-corr-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  flex-shrink: 0;
}
.ailab-corr-summary-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  background: var(--ailab-surface-2);
  min-width: 0;
}
.ailab-corr-summary-label {
  font-size: 10px;
  color: var(--ailab-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-corr-summary-value {
  font-size: 13px;
  font-weight: 600;
  color: var(--ailab-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-corr-canvas-wrap {
  flex: 1 1 auto;
  min-height: 320px;
  overflow: auto;
  border: 1px solid var(--ailab-border);
  border-radius: 6px;
  background: var(--ailab-surface);
  padding: 8px;
  box-sizing: border-box;
}
.ailab-corr-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--ailab-text-muted);
  font-size: 12px;
  text-align: center;
  padding: 16px;
}
.ailab-corr-svg {
  display: block;
  width: 100%;
  height: auto;
}
.ailab-corr-cell {
  cursor: pointer;
  transition: stroke 0.1s ease;
  stroke: transparent;
  stroke-width: 1;
}
.ailab-corr-cell:hover {
  stroke: var(--ailab-text);
  stroke-width: 1.5;
}
.ailab-corr-axis-label {
  fill: var(--ailab-text-muted);
  font-size: 10px;
  font-family: inherit;
}
.ailab-corr-cell-text {
  font-size: 10px;
  font-weight: 600;
  font-family: inherit;
  pointer-events: none;
}
.ailab-corr-foot {
  flex-shrink: 0;
  font-size: 11px;
  color: var(--ailab-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 2px;
}

/* ─────────────────────────────────────────────────────────────────────
 * Iter 12a/12b — Trade (Paper) widget — Alpaca paper-trading.
 * Three-pane grid: Account (top-left) · Positions (bottom-left) ·
 * Order Ticket (full right column, stub until Iter 12c).
 * ───────────────────────────────────────────────────────────────────── */
/* Iter 12a-fix — Trade widget never shows the per-window stock query row;
   the Order Ticket pane carries its own symbol input (Iter 12c). */
.ailab-window[data-window-type="trade"] .ailab-window-search { display: none; }
.ailab-window[data-window-type="trade"] .ailab-window-btn-search-toggle { display: none; }
.ailab-trade-host {
  padding: 0;
  overflow: hidden;
  background: var(--ailab-surface-0);
  color: var(--ailab-text-1);
}
.ailab-trade-grid {
  /* Iter 12AL.1 — IB color palette (tightened to match reference screenshot) */
  --ib-bg:          #000000;
  --ib-surface:     #0d0e10;
  --ib-surface-2:   #15171b;
  --ib-surface-3:   #1b1e23;
  --ib-input-bg:    #0a0b0d;
  --ib-border:      #1f232a;
  --ib-border-2:    #2a2f37;
  --ib-divider:     rgba(255,255,255,0.04);
  --ib-text:        #d9dce1;
  --ib-text-strong: #ffffff;
  --ib-text-dim:    #8e94a0;
  --ib-text-muted:  #6a6f7a;
  --ib-text-label:  #b0b5be;
  --ib-blue:        #2962ff;
  --ib-blue-hov:    #1e4fd9;
  --ib-green:       #00c853;
  --ib-red:         #ef4444;
  --ib-cyan:        #29b6f6;
  --ib-pink:        #ec407a;
  --ib-amber:       #ffa726;
  --ib-radius:      2px;

  /* Inter-family typography (IB-like; system fallback) */
  font-family: "Inter", "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-feature-settings: "tnum" 1, "cv02" 1, "cv11" 1;
  letter-spacing: 0;

  /* Iter 12AL.1 — KPI strip row + two-column body */
  display: grid;
  grid-template-rows: auto 1fr;
  grid-template-columns: 1fr;
  gap: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  background: var(--ib-bg);
  color: var(--ib-text);

  /* No rounded corners > 2px within the trade window */
  border-radius: 0;
}
/* Tabular numerics utility */
.ailab-trade-grid .num,
.ailab-trade-grid .tnum,
.ailab-trade-grid [data-numeric] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Override any 6px/8px radius that may cascade in */
.ailab-trade-grid *,
.ailab-trade-grid *::before,
.ailab-trade-grid *::after {
  border-radius: var(--ib-radius) !important;
}
/* ── Two-column body ───────────────────────────────────────────────── */
.ailab-trade-body {
  display: grid;
  /* Iter 12AL.7 — right pane minimum bumped from 320 → 460 so the
     Order Ticket form (Limit/Stop/Trail labels and Time-in-Force /
     Order Class controls) renders without ellipsis truncation. */
  grid-template-columns: minmax(0, 2.1fr) minmax(460px, 1fr);
  gap: 0;
  min-height: 0;
  overflow: hidden;
}
/* ── Left pane (tabbed) ───────────────────────────────────────────── */
.ailab-trade-left-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--ib-border);
  overflow: hidden;
  background: var(--ib-bg);
}
/* ── Right pane (detail card + order ticket) ─────────────────────── */
.ailab-trade-right-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  background: var(--ib-surface);
}
/* ─────────────────────────────────────────────────────────────────── */
/* KPI STRIP                                                           */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-kpi-strip {
  display: flex;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 0;
  height: 48px;
  background: var(--ib-surface);
  border-bottom: 1px solid var(--ib-border);
  overflow-x: auto;
  overflow-y: hidden;
  flex-shrink: 0;
  /* Hide scrollbar */
  scrollbar-width: none;
}
.ailab-trade-kpi-strip::-webkit-scrollbar { display: none; }
.ailab-trade-kpi-cell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 12px;
  min-width: 88px;
  flex: 1 1 88px;
  border-right: 1px solid var(--ib-border);
  flex-shrink: 0;
}
.ailab-trade-kpi-cell--right {
  margin-left: auto;
  flex: 0 0 auto;
  min-width: auto;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
}
.ailab-trade-kpi-label {
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ib-text-label);
  margin-bottom: 2px;
  white-space: nowrap;
}
.ailab-trade-kpi-val {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text-strong);
  white-space: nowrap;
}
.ailab-trade-kpi-val.pos { color: var(--ib-green); }
.ailab-trade-kpi-val.neg { color: var(--ib-red); }
/* Clock in KPI strip */
.ailab-trade-clock {
  font-size: 11px;
  color: var(--ib-text-dim);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
/* Env badge in KPI strip */
.ailab-trade-kpi-env {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--ib-radius);
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--ib-border-2);
  color: var(--ib-text-dim);
}
/* ─────────────────────────────────────────────────────────────────── */
/* TAB BAR                                                             */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-tab-bar {
  display: flex;
  align-items: stretch;
  background: var(--ib-surface);
  border-bottom: 1px solid var(--ib-border);
  flex-shrink: 0;
  height: 34px;
  overflow: hidden;
}
.ailab-trade-tab {
  padding: 0 14px;
  border: none;
  background: transparent;
  color: var(--ib-text-dim);
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 100ms ease, border-color 100ms ease;
  white-space: nowrap;
  flex-shrink: 0;
}
.ailab-trade-tab:hover { color: var(--ib-text); }
.ailab-trade-tab.is-active {
  color: var(--ib-text-strong);
  border-bottom-color: var(--ib-blue);
}
/* Decorative chrome (Portfolio View / Sort By — static, non-functional) */
.ailab-trade-tab-chrome {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  flex-shrink: 0;
}
.ailab-trade-tab-chrome-label {
  font-size: 11px;
  color: var(--ib-text-muted);
}
.ailab-trade-tab-chrome-sep {
  font-size: 10px;
  color: var(--ib-text-muted);
}
/* ─────────────────────────────────────────────────────────────────── */
/* TAB BODIES                                                          */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-tab-body {
  display: none;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  flex-direction: column;
}
.ailab-trade-tab-body.is-active {
  display: flex;
}
/* ─────────────────────────────────────────────────────────────────── */
/* POSITIONS TABLE                                                     */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-positions-body {
  padding: 0;
  flex: 1 1 auto;
  overflow: auto;
  min-height: 0;
}
.ailab-trade-positions-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-positions-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--ib-surface);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 10px;
  color: var(--ib-text-label);
  padding: 7px 10px 5px;
  border-bottom: 1px solid var(--ib-border);
  text-align: right;
  white-space: nowrap;
}
.ailab-trade-positions-table thead .ailab-trade-th-sym { text-align: left; }
.ailab-trade-positions-table thead .ailab-trade-th-name { text-align: left; min-width: 100px; }
.ailab-trade-positions-table tbody td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--ib-divider);
  white-space: nowrap;
  color: var(--ib-text);
  font-size: 12px;
}
.ailab-trade-td-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-td-name {
  color: var(--ib-text-dim);
  font-size: 11px;
  min-width: 80px;
}
.ailab-trade-td-pct {
  font-weight: 500;
  opacity: 0.85;
  font-size: 11px;
  margin-left: 2px;
}
.ailab-trade-td-sym {
  display: flex;
  align-items: center;
  gap: 6px;
}
.ailab-trade-sym {
  font-weight: 700;
  font-size: 13px;
  color: var(--ib-text-strong);
  letter-spacing: 0.02em;
}
.ailab-trade-side-pill {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: var(--ib-radius);
  background: rgba(244, 63, 94, 0.15);
  color: #fca5a5;
  letter-spacing: 0.06em;
}
.ailab-trade-position-row { cursor: pointer; }
.ailab-trade-position-row:hover td { background: var(--ib-surface-2); }
.ailab-trade-position-row.is-selected td {
  background: var(--ib-surface-3);
}
.ailab-trade-position-row.is-selected td:first-child {
  border-left: 2px solid var(--ib-blue);
}
.ailab-trade-position-row.short .ailab-trade-sym { color: #fca5a5; }
.ailab-trade-position-row .pos { color: var(--ib-green); }
.ailab-trade-position-row .neg { color: var(--ib-red); }
/* ─────────────────────────────────────────────────────────────────── */
/* DETAIL CARD (right pane)                                            */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-detail-card {
  background: var(--ib-surface);
  border-bottom: 1px solid var(--ib-border);
  padding: 12px;
  flex-shrink: 0;
}
.ailab-trade-detail-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
}
.ailab-trade-detail-sym {
  font-size: 14px;
  font-weight: 700;
  color: var(--ib-text-strong);
  letter-spacing: 0.04em;
}
.ailab-trade-detail-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--ib-text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}
.ailab-trade-detail-price-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}
.ailab-trade-detail-last {
  font-size: 28px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text-strong);
  line-height: 1;
}
.ailab-trade-detail-last.pos { color: var(--ib-green); }
.ailab-trade-detail-last.neg { color: var(--ib-red); }
.ailab-trade-detail-chg {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text-dim);
}
.ailab-trade-detail-bidask-row {
  display: flex;
  gap: 16px;
  margin-bottom: 8px;
}
.ailab-trade-detail-ask {
  font-size: 12px;
  font-weight: 600;
  color: var(--ib-pink);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-detail-bid {
  font-size: 12px;
  font-weight: 600;
  color: var(--ib-cyan);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-detail-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.ailab-trade-detail-btn {
  flex: 1 1 0;
  height: 34px;
  border: none;
  border-radius: var(--ib-radius);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.03em;
  cursor: pointer;
  font-family: inherit;
  color: #fff;
  transition: filter 120ms ease;
}
.ailab-trade-detail-btn--buy  { background: var(--ib-blue); }
.ailab-trade-detail-btn--sell { background: var(--ib-red); }
.ailab-trade-detail-btn:hover { filter: brightness(1.1); }
/* Position sub-card */
.ailab-trade-detail-pos {
  border-top: 1px solid var(--ib-border);
  padding-top: 10px;
  margin-top: 2px;
}
.ailab-trade-detail-pos-head {
  font-size: 11px;
  font-weight: 600;
  color: var(--ib-text-strong);
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ailab-trade-detail-pos-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px 6px;
  margin-bottom: 10px;
}
.ailab-trade-detail-pos-cell { min-width: 0; }
.ailab-trade-detail-pos-k {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ib-text-label);
  margin-bottom: 2px;
}
.ailab-trade-detail-pos-v {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-trade-detail-pos-v.pos { color: var(--ib-green); }
.ailab-trade-detail-pos-v.neg { color: var(--ib-red); }
.ailab-trade-detail-pos-actions {
  display: flex;
  gap: 6px;
}
.ailab-trade-detail-close-btn {
  height: 30px;
  padding: 0 14px;
  border: none;
  border-radius: var(--ib-radius);
  background: var(--ib-blue);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  flex: 0 0 auto;
}
.ailab-trade-detail-close-btn:hover { filter: brightness(1.1); }
/* ─────────────────────────────────────────────────────────────────── */
/* ORDER TICKET WRAP (right pane bottom)                               */
/* ─────────────────────────────────────────────────────────────────── */
.ailab-trade-ticket-wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
.ailab-trade-pane {
  display: flex;
  flex-direction: column;
  background: var(--ib-surface);
  border: 1px solid var(--ib-border);
  border-radius: var(--ib-radius);
  overflow: hidden;
  min-height: 0;
}
.ailab-trade-pane-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  height: 32px;
  border-bottom: 1px solid var(--ib-border);
  font-size: 11px;
  flex-shrink: 0;
  background: var(--ib-surface-2);
}
.ailab-trade-pane-head i { width: 14px; height: 14px; opacity: 0.75; color: var(--ib-text-dim); }
.ailab-trade-pane-title {
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ib-text-dim);
  font-size: 11px;
}
.ailab-trade-pane-meta,
.ailab-trade-clock {
  margin-left: auto;
  font-size: 11px;
  color: var(--ib-text-muted);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.ailab-trade-pane-body {
  padding: 10px 12px;
  overflow: auto;
  flex: 1 1 auto;
  min-height: 0;
  color: var(--ib-text);
}
.ailab-trade-empty {
  font-size: 12px;
  color: var(--ib-text-dim);
  padding: 14px 0;
  text-align: center;
}
.ailab-trade-error {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 10px 12px;
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.4);
  border-radius: 6px;
  font-size: 12px;
  color: #fecaca;
}
.ailab-trade-error i { width: 16px; height: 16px; flex-shrink: 0; color: #f87171; margin-top: 1px; }
.ailab-trade-error span { color: var(--ailab-text-muted); font-size: 11px; }

/* Account pane */
.ailab-trade-account-row--equity {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}
.ailab-trade-account-equity {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-account-daypl {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-account-daypl span { font-weight: 500; opacity: 0.85; margin-left: 2px; }
.ailab-trade-account-daypl.pos { color: var(--ib-green); }
.ailab-trade-account-daypl.neg { color: var(--ib-red); }
.ailab-trade-account-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 14px;
}
.ailab-trade-account-cell { min-width: 0; }
.ailab-trade-account-k {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ailab-text-muted);
  margin-bottom: 2px;
}
.ailab-trade-account-v {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-account-status.ok   { color: var(--ib-green); }
.ailab-trade-account-status.warn { color: #f59e0b; }
.ailab-trade-account-flags {
  margin-top: 8px;
  font-size: 11px;
  color: #f59e0b;
}
.ailab-trade-account-foot {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--ailab-border-1);
  font-size: 10px;
  color: var(--ailab-text-muted);
  letter-spacing: 0.02em;
}
.ailab-trade-account-foot .ok   { color: #22c55e; }
.ailab-trade-account-foot .warn { color: #f59e0b; }

/* Positions table */
/* Iter 12AL.1 — positions table styles moved to new layout block above */

/* Market clock dot */
.ailab-trade-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ailab-text-muted);
}
.ailab-trade-dot.ok   { background: #22c55e; box-shadow: 0 0 6px rgba(34, 197, 94, 0.6); }
.ailab-trade-dot.warn { background: #f59e0b; }

/* Iter 12c-ui: Order ticket form (replaces 12a stub) */
/* Iter 12AL.1: IB-style ticket body */
.ailab-trade-ticket-body {
  display: flex;
  flex-direction: column;
  padding: 10px 12px 12px;
  gap: 8px;
  overflow-y: auto;
  background: var(--ib-surface);
}
.ailab-trade-ticket-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ailab-trade-ticket-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
}
.ailab-trade-ticket-row--symbol { align-items: flex-end; }
.ailab-trade-ticket-row--side   { align-items: stretch; }
.ailab-trade-ticket-row--size   { align-items: flex-end; }
.ailab-trade-ticket-row--type   { align-items: stretch; }
.ailab-trade-ticket-row--tif    { align-items: flex-end; }
.ailab-trade-ticket-row--prices { align-items: flex-end; }
.ailab-trade-ticket-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 0;
  min-width: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ib-text-muted);
}
.ailab-trade-ticket-label--qty  { flex: 1 1 55%; }
.ailab-trade-ticket-label--unit { flex: 0 0 auto; }
.ailab-trade-input {
  width: 100%;
  height: 28px;
  padding: 0 8px;
  border-radius: var(--ib-radius);
  border: 1px solid var(--ib-border-2);
  background: var(--ib-input-bg);
  color: var(--ib-text);
  font-size: 13px;
  font-family: inherit;
  box-sizing: border-box;
  outline: none;
  transition: border-color 120ms ease;
}
.ailab-trade-input:focus {
  border-color: var(--ib-blue);
  box-shadow: none;
}
.ailab-trade-input--sym {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}

/* Iter 12AL.4 — Symbol input wrap + autocomplete dropdown + company name
   caption above the input. The wrap is position:relative so the absolute
   suggest list overlays the form below. */
.ailab-trade-ticket-label--sym { gap: 2px; }
.ailab-trade-ticket-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-height: 12px;
}
.ailab-trade-ticket-label-key {
  flex: 0 0 auto;
}
.ailab-trade-company-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ib-text);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-trade-company-name[hidden] { display: none; }

.ailab-trade-sym-wrap {
  position: relative;
  width: 100%;
}
.ailab-trade-sym-suggest {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 250;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  max-height: 260px;
  overflow-y: auto;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border);
  border-radius: var(--ib-radius);
  box-shadow: 0 6px 18px rgba(0,0,0,0.7);
}
.ailab-trade-sym-suggest[hidden] { display: none; }
.ailab-trade-sym-suggest-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12px;
  color: var(--ib-text);
  transition: background 80ms ease, color 80ms ease;
}
.ailab-trade-sym-suggest-row:hover,
.ailab-trade-sym-suggest-row.is-active {
  background: rgba(41,98,255,0.15);
  color: var(--ib-text-strong);
}
.ailab-trade-sym-suggest-sym {
  flex: 0 0 auto;
  min-width: 56px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ib-blue);
}
.ailab-trade-sym-suggest-row.is-active .ailab-trade-sym-suggest-sym,
.ailab-trade-sym-suggest-row:hover .ailab-trade-sym-suggest-sym {
  color: var(--ib-text-strong);
}
.ailab-trade-sym-suggest-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 11px;
  color: var(--ib-text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-trade-sym-suggest-ex {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ib-text-muted);
  background: var(--ib-surface-3);
  border-radius: var(--ib-radius);
  padding: 1px 6px;
}
.ailab-trade-sym-suggest-empty {
  padding: 8px 10px;
  font-size: 11px;
  color: var(--ib-text-muted);
  font-style: italic;
}
.ailab-trade-input--qty {
  font-variant-numeric: tabular-nums;
}
select.ailab-trade-input {
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%238a8a9a'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 24px;
}
/* Hide native number spinners — replaced by .ailab-trade-stepper */
.ailab-trade-input[type="number"]::-webkit-outer-spin-button,
.ailab-trade-input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.ailab-trade-input[type="number"] { -moz-appearance: textfield; }
/* Number inputs use tabular monospace for alignment */
.ailab-trade-input[type="number"] { font-variant-numeric: tabular-nums; }

/* Iter 12AL.1: IB-style quote chip */
.ailab-trade-quote {
  flex: 0 0 auto;
  min-width: 86px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  border-radius: var(--ib-radius);
  border: 1px solid var(--ib-border-2);
  background: var(--ib-input-bg);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text);
  white-space: nowrap;
}
.ailab-trade-quote.warn {
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.3);
}

/* Iter 12AL.1: IB-style segmented controls */
.ailab-trade-segctl {
  display: flex;
  width: 100%;
  border-radius: var(--ib-radius);
  background: var(--ib-surface-2);
  border: none;
  padding: 0;
  gap: 0;
}
.ailab-trade-seg {
  flex: 1 1 0;
  height: 32px;
  border: none;
  background: transparent;
  color: var(--ib-text-dim);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: var(--ib-radius);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
  font-family: inherit;
  position: relative;
}
.ailab-trade-seg:hover { color: var(--ib-text); background: rgba(255,255,255,0.04); }
/* Buy active: IB blue */
.ailab-trade-seg--buy.is-active {
  background: var(--ib-blue);
  color: #fff;
}
/* Sell active: IB red */
.ailab-trade-seg--sell.is-active {
  background: var(--ib-red);
  color: #fff;
}
/* Type segmented active (Market/Limit/Stop): surface-3 + top blue border */
.ailab-trade-seg--type.is-active {
  background: var(--ib-surface-3);
  color: #fff;
  box-shadow: inset 0 2px 0 var(--ib-blue);
}
/* Shares/USD unit segmented */
.ailab-trade-seg--shares.is-active,
.ailab-trade-seg--usd.is-active {
  background: var(--ib-surface-3);
  color: var(--ib-blue);
  box-shadow: inset 0 2px 0 var(--ib-blue);
}
.ailab-trade-segctl--unit .ailab-trade-seg { height: 28px; font-size: 11px; }
.ailab-trade-segctl--type .ailab-trade-seg { height: 28px; }

/* Stop button caret */
.ailab-trade-type-caret {
  display: inline-block;
  margin-left: 4px;
  font-size: 9px;
  opacity: 0.7;
  pointer-events: auto;
  vertical-align: middle;
}

/* Iter 12AL.3 — Inline Stop subtype row (replaces .ailab-trade-type-popover
   which was absolute-positioned and anchored to the wrong segment). The row
   sits directly below the order-type segmented control. Hidden whenever a
   non-stop variant is selected. */
.ailab-trade-stop-subtypes {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 4px 0 0;
  padding: 4px 0 0;
}
.ailab-trade-stop-subtypes[hidden] { display: none; }
.ailab-trade-stop-subtype {
  flex: 0 0 auto;
  padding: 4px 10px;
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border-2);
  border-radius: var(--ib-radius);
  color: var(--ib-text-dim);
  font-size: 11px;
  font-family: inherit;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
}
.ailab-trade-stop-subtype:hover {
  background: var(--ib-surface-3);
  color: var(--ib-text);
}
.ailab-trade-stop-subtype.is-active {
  background: rgba(41,98,255,0.15);
  border-color: var(--ib-blue);
  color: var(--ib-blue);
  font-weight: 600;
}

/* Section headers (IB ⊖ QUANTITY / DESCRIPTION / TIME IN FORCE) */
.ailab-trade-section-head {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ib-text-muted);
  padding: 6px 0 2px;
  border-bottom: 1px solid var(--ib-border);
  margin-bottom: 2px;
}

/* Iter 12AL.1 — ailab-trade-account-mini removed; data moved to KPI strip.
   Selector kept as empty no-op to avoid stale-selector warnings. */
.ailab-trade-account-mini { display: none; }
.ailab-trade-account-mini-cell,
.ailab-trade-account-mini-k,
.ailab-trade-account-mini-v { display: none; }

/* Input row with adjacent stepper */
.ailab-trade-input-row {
  display: flex;
  align-items: stretch;
  gap: 0;
}
.ailab-trade-input-row .ailab-trade-input {
  flex: 1 1 auto;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: none;
}

/* Iter 12AL.1: ▲▼ stepper buttons */
.ailab-trade-stepper {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  width: 20px;
  border: 1px solid var(--ib-border-2);
  border-radius: 0 var(--ib-radius) var(--ib-radius) 0;
  overflow: hidden;
  background: var(--ib-surface-2);
}
.ailab-trade-stepper-btn {
  flex: 1 1 0;
  border: none;
  background: transparent;
  color: var(--ib-text-dim);
  font-size: 8px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 80ms ease, color 80ms ease;
  font-family: inherit;
}
.ailab-trade-stepper-btn:hover {
  background: var(--ib-surface-3);
  color: var(--ib-blue);
}
.ailab-trade-stepper-btn:active { background: rgba(41,98,255,0.15); }
.ailab-trade-stepper-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.ailab-trade-stepper-btn + .ailab-trade-stepper-btn {
  border-top: 1px solid var(--ib-border-2);
}

/* Iter 12AL.3 — Permanent Ask/Bid row at the top of the order ticket.
   Replaces the old single-line hint that lived under the limit input and was
   gated on order type. Two stacked rows: each has an uppercase label on the
   left and a right-aligned mono "<qty> x <price>" value. */
.ailab-trade-bidask {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  margin: 0 0 4px;
  background: var(--ib-surface-2);
  border-top: 1px solid var(--ib-border);
  border-bottom: 1px solid var(--ib-border);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-bidask[hidden] { display: none; }
.ailab-trade-bidask-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ailab-trade-bidask-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ib-text-muted);
}
.ailab-trade-bidask-val {
  font-size: 12px;
  font-weight: 600;
  font-family: "Roboto Mono", ui-monospace, Menlo, Consolas, monospace;
  text-align: right;
}
.ailab-trade-bidask-val.ib-ask { color: var(--ib-pink); }
.ailab-trade-bidask-val.ib-bid { color: var(--ib-cyan); }

/* Notional toggle (RTH checkbox — now labelled "Fill outside RTH") */
.ailab-trade-ticket-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding-bottom: 4px;
  font-size: 11px;
  color: var(--ib-text-muted);
  cursor: pointer;
  user-select: none;
}
.ailab-trade-ticket-toggle input[type="checkbox"] {
  width: 13px;
  height: 13px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--ib-blue);
}

/* Estimated cost line */
.ailab-trade-ticket-est {
  font-size: 11px;
  color: var(--ib-text-dim);
  padding: 5px 8px;
  border-radius: var(--ib-radius);
  background: var(--ib-surface-2);
  border: 1px solid var(--ib-border);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-ticket-est.warn {
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.3);
  background: rgba(245, 158, 11, 0.06);
}

/* Submit button — IB-style: full-width, sharp corners, IB blue/red */
.ailab-trade-ticket-actions {
  display: flex;
  margin-top: 4px;
}
.ailab-trade-submit {
  flex: 1 1 auto;
  height: 40px;
  border: none;
  border-radius: var(--ib-radius);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.03em;
  cursor: pointer;
  font-family: inherit;
  transition: filter 120ms ease, transform 80ms ease;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.ailab-trade-submit:hover { filter: brightness(1.1); }
.ailab-trade-submit:active { transform: translateY(1px); }
.ailab-trade-submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
  transform: none;
}
.ailab-trade-submit--buy  { background: var(--ib-blue); }
.ailab-trade-submit--sell { background: var(--ib-red); }
.ailab-trade-submit--buy:hover  { background: var(--ib-blue-hov); filter: none; }
.ailab-trade-submit--sell:hover { background: #d93030; filter: none; }

/* Confirm modal — order payload preview */
.ailab-trade-confirm-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
  color: var(--ailab-text-1);
}
.ailab-trade-confirm-summary .ailab-trade-side-pill {
  font-size: 10px;
  letter-spacing: 0.06em;
}
.ailab-trade-confirm-est {
  display: block;
  font-size: 12px;
  color: var(--ailab-text-muted);
  margin-bottom: 10px;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-confirm-payload-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ailab-text-muted);
  margin-bottom: 4px;
}
.ailab-trade-confirm-payload {
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 6px;
  background: rgba(0,0,0,0.35);
  border: 1px solid var(--ailab-border, rgba(255,255,255,0.08));
  color: var(--ailab-text-1);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 11px;
  line-height: 1.45;
  max-height: 220px;
  overflow: auto;
  white-space: pre;
}
.ailab-trade-confirm-foot {
  font-size: 11px;
  color: var(--ailab-text-muted);
  line-height: 1.5;
}
.ailab-trade-confirm-foot code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 11px;
  padding: 1px 5px;
  background: rgba(255,255,255,0.06);
  border-radius: 3px;
}

/* Open Orders mini-list */
.ailab-trade-orders {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border-top: 1px solid var(--ailab-border, rgba(255,255,255,0.06));
  padding-top: 8px;
  margin-top: 4px;
}
.ailab-trade-orders-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0 2px 4px;
}
.ailab-trade-orders-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ailab-text-muted);
}
.ailab-trade-orders-meta {
  font-size: 10px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-orders-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 160px;
  overflow-y: auto;
}
.ailab-trade-order-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-radius: 6px;
  background: rgba(255,255,255,0.02);
  border: 1px solid rgba(255,255,255,0.05);
}
.ailab-trade-order-cell {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 12px;
}
.ailab-trade-order-sym {
  font-weight: 600;
  color: var(--ailab-text-1);
  letter-spacing: 0.04em;
}
.ailab-trade-order-qty {
  font-variant-numeric: tabular-nums;
  color: var(--ailab-text-1);
}
.ailab-trade-order-type {
  font-size: 11px;
  color: var(--ailab-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 auto;
}
.ailab-trade-order-cancel {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgba(255,255,255,0.08);
  background: transparent;
  border-radius: 4px;
  color: var(--ailab-text-muted);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.ailab-trade-order-cancel:hover {
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.4);
  background: rgba(239, 68, 68, 0.08);
}
.ailab-trade-order-cancel i { width: 12px; height: 12px; }

/* Side pill (used in open orders + confirm summary) */
.ailab-trade-side-pill.buy {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
  border-color: rgba(34, 197, 94, 0.3);
}
.ailab-trade-side-pill.sell {
  background: rgba(239, 68, 68, 0.15);
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.3);
}

/* Iter 12d: bracket / OTO / OCO leg block + trailing-stop row + class pill */
.ailab-trade-ticket-row--class { align-items: flex-end; }
.ailab-trade-ticket-row--trail { align-items: flex-end; }
.ailab-trade-ticket-legs {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: var(--ib-radius);
  background: rgba(41, 98, 255, 0.05);
  border: 1px solid rgba(41, 98, 255, 0.20);
}
.ailab-trade-ticket-legs-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ib-blue);
}
.ailab-trade-ticket-legs-hint {
  font-size: 11px;
  line-height: 1.4;
  color: var(--ib-text-muted);
}
.ailab-trade-ticket-legs .ailab-trade-ticket-row { gap: 8px; }

/* Confirm modal: order class pill + legs line */
.ailab-trade-class-pill {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(99, 179, 237, 0.15);
  border: 1px solid rgba(99, 179, 237, 0.35);
  color: #9bd1ff;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  vertical-align: 1px;
}
.ailab-trade-confirm-legs {
  width: 100%;
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px dashed rgba(255,255,255,0.08);
  font-size: 11px;
  color: var(--ailab-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Per-position Close button (Actions column in positions table) */
.ailab-trade-th-act { text-align: right; width: 60px; }
.ailab-trade-td-act { text-align: right; }
.ailab-trade-pos-close {
  height: 22px;
  padding: 0 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: var(--ib-radius);
  border: 1px solid rgba(239, 68, 68, 0.3);
  background: rgba(239, 68, 68, 0.08);
  color: #ef4444;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease, border-color 120ms ease;
}
.ailab-trade-pos-close:hover {
  background: rgba(239, 68, 68, 0.16);
  border-color: rgba(239, 68, 68, 0.5);
}
.ailab-trade-pos-close:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Iter 12e — Asset metadata badges (tradable / shortable / fractionable / status) */
.ailab-trade-asset-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 4px;
  margin-top: 2px;
}
.ailab-trade-asset-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid transparent;
  line-height: 1.4;
  white-space: nowrap;
}
.ailab-trade-asset-badge--ok {
  color: #16a34a;
  background: rgba(22, 163, 74, 0.10);
  border-color: rgba(22, 163, 74, 0.30);
}
.ailab-trade-asset-badge--err {
  color: #dc2626;
  background: rgba(220, 38, 38, 0.10);
  border-color: rgba(220, 38, 38, 0.35);
}
.ailab-trade-asset-badge--warn {
  color: #b45309;
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.35);
}
.ailab-trade-asset-badge--info {
  color: #1d4ed8;
  background: rgba(59, 130, 246, 0.10);
  border-color: rgba(59, 130, 246, 0.30);
}
.ailab-trade-asset-badge--mute {
  color: #4b5563;
  background: rgba(107, 114, 128, 0.10);
  border-color: rgba(107, 114, 128, 0.25);
}
@media (prefers-color-scheme: dark) {
  .ailab-trade-asset-badge--ok {
    color: #4ade80;
    background: rgba(22, 163, 74, 0.18);
    border-color: rgba(74, 222, 128, 0.35);
  }
  .ailab-trade-asset-badge--err {
    color: #f87171;
    background: rgba(220, 38, 38, 0.18);
    border-color: rgba(248, 113, 113, 0.40);
  }
  .ailab-trade-asset-badge--warn {
    color: #fbbf24;
    background: rgba(245, 158, 11, 0.18);
    border-color: rgba(251, 191, 36, 0.40);
  }
  .ailab-trade-asset-badge--info {
    color: #93c5fd;
    background: rgba(59, 130, 246, 0.18);
    border-color: rgba(147, 197, 253, 0.35);
  }
  .ailab-trade-asset-badge--mute {
    color: #d1d5db;
    background: rgba(156, 163, 175, 0.15);
    border-color: rgba(209, 213, 219, 0.25);
  }
}
/* Iter 12e — Disabled state for segmented controls (Buy/Sell, Qty/Notional) when gated by asset metadata */
.ailab-trade-seg.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
  filter: grayscale(0.4);
}
.ailab-trade-seg.is-disabled:hover {
  background: inherit;
  border-color: inherit;
}

/* Iter 12f — Quote chip pieces (last + bid/ask + age) */
.ailab-trade-quote-last {
  font-weight: 700;
  color: var(--ailab-text-1, #111827);
  font-variant-numeric: tabular-nums;
}
.ailab-trade-quote-spread {
  color: var(--ailab-text-2, #6b7280);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.ailab-trade-quote-sep {
  color: var(--ailab-text-3, #9ca3af);
  margin: 0 1px;
}
.ailab-trade-quote-age {
  font-size: 10px;
  color: var(--ailab-text-3, #9ca3af);
  font-variant-numeric: tabular-nums;
  padding: 1px 5px;
  border-radius: 3px;
  background: rgba(107, 114, 128, 0.10);
}
.ailab-trade-quote-age--stale {
  color: #b45309;
  background: rgba(245, 158, 11, 0.15);
}
@media (prefers-color-scheme: dark) {
  .ailab-trade-quote-last { color: #f3f4f6; }
  .ailab-trade-quote-spread { color: #9ca3af; }
  .ailab-trade-quote-sep { color: #6b7280; }
  .ailab-trade-quote-age {
    color: #d1d5db;
    background: rgba(156, 163, 175, 0.18);
  }
  .ailab-trade-quote-age--stale {
    color: #fbbf24;
    background: rgba(245, 158, 11, 0.22);
  }
}

/* Iter 12f — Limit / stop price quick-fill helpers (bid / mid / ask / last) */
.ailab-trade-input-with-helpers {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ailab-trade-helpers {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ailab-trade-helper {
  appearance: none;
  -webkit-appearance: none;
  background: rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.25);
  color: #1d4ed8;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px 6px;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  line-height: 1.4;
  white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease;
}
.ailab-trade-helper:hover:not(:disabled) {
  background: rgba(59, 130, 246, 0.16);
  border-color: rgba(59, 130, 246, 0.45);
}
.ailab-trade-helper:active:not(:disabled) {
  background: rgba(59, 130, 246, 0.24);
}
.ailab-trade-helper:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  background: rgba(107, 114, 128, 0.08);
  color: #6b7280;
  border-color: rgba(107, 114, 128, 0.20);
}
@media (prefers-color-scheme: dark) {
  .ailab-trade-helper {
    background: rgba(59, 130, 246, 0.18);
    border-color: rgba(147, 197, 253, 0.30);
    color: #93c5fd;
  }
  .ailab-trade-helper:hover:not(:disabled) {
    background: rgba(59, 130, 246, 0.28);
    border-color: rgba(147, 197, 253, 0.50);
  }
  .ailab-trade-helper:disabled {
    background: rgba(156, 163, 175, 0.14);
    color: #9ca3af;
    border-color: rgba(156, 163, 175, 0.22);
  }
}

/* Iter 12g — streaming-quote connection status dot (live / stale / off / err) */
.ailab-trade-quote-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ailab-trade-quote-stream-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: #9ca3af;
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
  transition: background 120ms ease, box-shadow 200ms ease;
}
.ailab-trade-quote-stream-dot--live {
  background: #16a34a;
  animation: ailab-trade-stream-pulse 1.6s ease-out infinite;
}
.ailab-trade-quote-stream-dot--stale {
  background: #f59e0b;
}
.ailab-trade-quote-stream-dot--off {
  background: #9ca3af;
}
.ailab-trade-quote-stream-dot--err {
  background: #dc2626;
  animation: ailab-trade-stream-blink 0.8s steps(2, start) infinite;
}
@keyframes ailab-trade-stream-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0); }
  100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}
@keyframes ailab-trade-stream-blink {
  0%   { opacity: 1;   }
  50%  { opacity: 0.4; }
  100% { opacity: 1;   }
}
@media (prefers-reduced-motion: reduce) {
  .ailab-trade-quote-stream-dot--live,
  .ailab-trade-quote-stream-dot--err {
    animation: none;
  }
}
@media (prefers-color-scheme: dark) {
  .ailab-trade-quote-stream-dot--live  { background: #4ade80; }
  .ailab-trade-quote-stream-dot--stale { background: #fbbf24; }
  .ailab-trade-quote-stream-dot--off   { background: #6b7280; }
  .ailab-trade-quote-stream-dot--err   { background: #f87171; }
  @keyframes ailab-trade-stream-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.55); }
    70%  { box-shadow: 0 0 0 6px rgba(74, 222, 128, 0); }
    100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
  }
}

/* Iter 12h — Order History pane styles. Lives in row 3 of the trade grid,
   spans both columns. Collapsed state hides body+filter-bar but keeps the
   header click-target visible so the pane can be re-opened. Filter bar is a
   responsive flex row that wraps on narrow widgets. Table reuses the same
   sticky-header / monospace numerics convention as the positions table. */
.ailab-trade-history-head { cursor: pointer; user-select: none; }
.ailab-trade-history-toggle {
  margin-left: 6px; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 4px; border: none; background: transparent;
  color: var(--ailab-text-2); cursor: pointer;
}
.ailab-trade-history-toggle:hover { background: var(--ailab-surface-2); color: var(--ailab-text-1); }
.ailab-trade-history-toggle i { width: 14px; height: 14px; }
.ailab-trade-history[data-collapsed="true"] .ailab-trade-pane-body { display: none; }
.ailab-trade-history[data-collapsed="true"] .ailab-trade-history-toggle i.ailab-icon-chev-up { display: none; }
.ailab-trade-history:not([data-collapsed="true"]) .ailab-trade-history-toggle i.ailab-icon-chev-down { display: none; }

.ailab-trade-history-filterbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--ailab-border-1);
  background: var(--ailab-surface-1);
  font-size: 11px;
}
.ailab-trade-history-filter {
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
}
.ailab-trade-history-filter > label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ailab-text-muted); font-weight: 600;
}
.ailab-trade-history-filter > select,
.ailab-trade-history-filter > input {
  padding: 5px 8px; border: 1px solid var(--ailab-border-1); border-radius: 5px;
  background: var(--ailab-surface-0); color: var(--ailab-text-1); font-size: 12px;
  min-width: 0; box-sizing: border-box;
}
.ailab-trade-history-filter--symbols > input { width: 140px; }
.ailab-trade-history-filter--date    > input { width: 130px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.ailab-trade-history-filter--limit   > select { width: 80px; }
.ailab-trade-history-actions { margin-left: auto; display: inline-flex; gap: 6px; }
.ailab-trade-history-btn {
  padding: 6px 10px; border: 1px solid var(--ailab-border-1); border-radius: 5px;
  background: var(--ailab-surface-2); color: var(--ailab-text-1); font-size: 11px;
  font-weight: 600; cursor: pointer;
}
.ailab-trade-history-btn:hover { background: var(--ailab-surface-3, var(--ailab-surface-2)); }
.ailab-trade-history-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.ailab-trade-history-btn--primary {
  background: var(--ailab-accent, #2563eb); color: #fff; border-color: transparent;
}
.ailab-trade-history-btn--primary:hover { filter: brightness(1.08); }

.ailab-trade-history-table-wrap { overflow: auto; max-height: 280px; }
.ailab-trade-history-table {
  width: 100%; border-collapse: collapse; font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.ailab-trade-history-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--ailab-surface-1); color: var(--ailab-text-2);
  text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--ailab-border-1);
  font-weight: 600; font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
}
.ailab-trade-history-table tbody td {
  padding: 5px 8px; border-bottom: 1px solid var(--ailab-border-1);
  white-space: nowrap;
}
.ailab-trade-history-table tbody tr:hover td { background: var(--ailab-surface-2); }
.ailab-trade-history-table .num    { text-align: right; }
.ailab-trade-history-table .muted  { color: var(--ailab-text-muted); }
.ailab-trade-history-table .status-pill {
  display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 10px;
  font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase;
  background: var(--ailab-surface-2); color: var(--ailab-text-2);
}
.ailab-trade-history-table .status-pill.filled    { background: rgba(22, 163, 74, 0.18); color: #16a34a; }
.ailab-trade-history-table .status-pill.canceled,
.ailab-trade-history-table .status-pill.expired,
.ailab-trade-history-table .status-pill.rejected { background: rgba(220, 38, 38, 0.15); color: #dc2626; }
.ailab-trade-history-table .status-pill.partially_filled,
.ailab-trade-history-table .status-pill.pending_cancel,
.ailab-trade-history-table .status-pill.pending_replace { background: rgba(245, 158, 11, 0.18); color: #b45309; }
.ailab-trade-history-table .status-pill.new,
.ailab-trade-history-table .status-pill.accepted,
.ailab-trade-history-table .status-pill.pending_new { background: rgba(37, 99, 235, 0.16); color: #2563eb; }

.ailab-trade-history-row-cancel {
  background: transparent; border: 1px solid var(--ailab-border-1); border-radius: 4px;
  padding: 2px 6px; font-size: 10px; color: var(--ailab-text-2); cursor: pointer;
}
.ailab-trade-history-row-cancel:hover { background: rgba(220, 38, 38, 0.12); color: #dc2626; border-color: #dc2626; }
.ailab-trade-history-row-cancel[disabled] { opacity: 0.35; cursor: default; }

.ailab-trade-history-meta-extra {
  margin-left: 8px; color: var(--ailab-text-muted); font-size: 10px;
}

@media (prefers-color-scheme: dark) {
  .ailab-trade-history-table .status-pill.filled            { background: rgba(74, 222, 128, 0.18); color: #4ade80; }
  .ailab-trade-history-table .status-pill.canceled,
  .ailab-trade-history-table .status-pill.expired,
  .ailab-trade-history-table .status-pill.rejected          { background: rgba(248, 113, 113, 0.18); color: #f87171; }
  .ailab-trade-history-table .status-pill.partially_filled,
  .ailab-trade-history-table .status-pill.pending_cancel,
  .ailab-trade-history-table .status-pill.pending_replace   { background: rgba(251, 191, 36, 0.18); color: #fbbf24; }
  .ailab-trade-history-table .status-pill.new,
  .ailab-trade-history-table .status-pill.accepted,
  .ailab-trade-history-table .status-pill.pending_new       { background: rgba(96, 165, 250, 0.18); color: #60a5fa; }
}

/* Iter 12i — Watchlist quick-buy context menu. Floats over the workspace at
   pointer coordinates; closed by outside click, Esc, or selecting an item.
   Iter 12i-fix: the original draft used --ailab-surface-1 / --ailab-border-1 /
   --ailab-text-1, none of which are defined in this stylesheet, so the
   floating menu rendered translucent and unreadable. Switched to the actual
   defined vars (--ailab-surface, --ailab-surface-2, --ailab-border, --ailab-text)
   with hex fallbacks matched to :root so the menu is always solid even when
   the cascade misses. backdrop-filter is explicitly disabled to defeat any
   inherited blur from parent surfaces. */
.ailab-quicktrade-menu {
  position: fixed;
  z-index: 10000;
  min-width: 220px;
  background: var(--ailab-surface, #131316); /* solid */
  background-color: var(--ailab-surface, #131316);
  color: var(--ailab-text, #e8e8ea);
  border: 1px solid var(--ailab-border-strong, rgba(255,255,255,0.14));
  border-radius: 8px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.55);
  padding: 6px 0;
  font-size: 12px;
  overflow: hidden;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  opacity: 1;
}
.ailab-quicktrade-menu-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 6px 12px 8px;
  border-bottom: 1px solid var(--ailab-border, rgba(255,255,255,0.08));
  color: var(--ailab-text, #e8e8ea);
  font-size: 12px;
}
.ailab-quicktrade-menu-head strong { font-size: 13px; letter-spacing: 0.02em; }
.ailab-quicktrade-menu-name {
  color: var(--ailab-text-muted, #8a8a9a); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px;
}
.ailab-quicktrade-menu-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; box-sizing: border-box;
  padding: 8px 12px;
  background: transparent; border: none; color: var(--ailab-text, #e8e8ea);
  font: inherit; text-align: left; cursor: pointer;
}
.ailab-quicktrade-menu-item:hover,
.ailab-quicktrade-menu-item:focus-visible { background: var(--ailab-surface-2, #1a1a1e); outline: none; }
.ailab-quicktrade-menu-item i { width: 14px; height: 14px; opacity: 0.8; }
.ailab-quicktrade-menu-pill {
  display: inline-block; min-width: 36px; text-align: center;
  padding: 1px 6px; border-radius: 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
}
.ailab-quicktrade-menu-pill.buy  { background: rgba(109,170,69,0.22); color: var(--ailab-positive, #6daa45); }
.ailab-quicktrade-menu-pill.sell { background: rgba(221,105,116,0.22); color: var(--ailab-negative, #dd6974); }
.ailab-quicktrade-menu-sub { color: var(--ailab-text-muted, #8a8a9a); font-size: 11px; margin-left: auto; }
.ailab-quicktrade-menu-sep { height: 1px; background: var(--ailab-border, rgba(255,255,255,0.08)); margin: 4px 0; }

.ailab-quicktrade-confirm-name { color: var(--ailab-text-muted, #8a8a9a); }

/* Iter 12k — position-aware quick-menu: position summary row + new actions. */
.ailab-quicktrade-menu-pos {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--ailab-border, rgba(255,255,255,0.08));
  background: var(--ailab-surface-2, #1a1a1e);
}
.ailab-quicktrade-menu-pos-qty {
  font-size: 11px; color: var(--ailab-text-muted, #8a8a9a); letter-spacing: 0.02em;
}
/* CLOSE / divide pills inherit from .ailab-quicktrade-menu-pill base. The
   buy/sell color modifiers above already cover the dynamic side coloring,
   so a long position close uses the .sell pill (red, opposite-side fill)
   and a short close uses the .buy pill (green). */

/* ----- Iter 12M: Trade widget Paper/Live account selector ------------ */
/* The trade widget's titlebar hosts a Paper / Live <select> on the
   right side of the title slot and an equity readout span next to it.
   When data-trade-env="live" is set on the window, the titlebar gets a
   subtle red banner so the user is constantly reminded that orders
   placed from this widget will hit a real-money account. The pencil
   rename icon is hidden via JS (bindWindow). */
.ailab-window-title--trade {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.ailab-trade-env-select {
  appearance: none;
  -webkit-appearance: none;
  background: var(--ailab-surface-2, #1a1a1e);
  color: var(--ailab-text, #e6e6ee);
  border: 1px solid var(--ailab-border, rgba(255,255,255,0.12));
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 22px 4px 8px;
  line-height: 1.2;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 9l6 6 6-6' fill='none' stroke='%238a8a9a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 12px 12px;
}
.ailab-trade-env-select:hover { border-color: rgba(255,255,255,0.24); }
.ailab-trade-env-select:focus-visible { outline: 2px solid #4a8cff; outline-offset: 1px; }
.ailab-trade-env-equity {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ailab-text-muted, #8a8a9a);
  padding: 3px 8px;
  border-radius: 5px;
  background: rgba(255,255,255,0.04);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Live mode: red banner across the entire titlebar + warning-tinted
   equity chip. Background is layered over the existing titlebar so
   focused / unfocused window states still read correctly. */
.ailab-window[data-trade-env="live"] .ailab-window-titlebar {
  background: linear-gradient(180deg, rgba(220, 38, 38, 0.18), rgba(220, 38, 38, 0.08));
  border-bottom: 1px solid rgba(220, 38, 38, 0.55);
  box-shadow: inset 0 -2px 0 0 rgba(220, 38, 38, 0.65);
}
.ailab-window[data-trade-env="live"] .ailab-trade-env-select {
  border-color: rgba(220, 38, 38, 0.7);
  color: #ffd9d9;
  background-color: rgba(220, 38, 38, 0.18);
}
.ailab-window[data-trade-env="live"] .ailab-trade-env-equity {
  background: rgba(220, 38, 38, 0.22);
  color: #ffe4e4;
  border: 1px solid rgba(220, 38, 38, 0.45);
}

/* ============================================================
   Iter 12D — AI Lab widget outline colour test (2026-05-12)
   ------------------------------------------------------------
   Lighter, more visible grey outline on every widget window on
   the AI Lab page. Default outline brightened from
   rgba(255,255,255,0.08) -> rgba(255,255,255,0.16). The focused
   border (active window) is brightened in step so the focus
   distinction stays clear -- 0.16 default -> 0.30 focused (was
   var(--ailab-border-strong) which is 0.14).

   Applies to every widget type: Stocks, Chart, News, Heatmap,
   Index card, FX, Watchlist, Earnings, Trade, VaR, Correlation,
   Blank. All use the same .ailab-window container.

   To revert: delete this entire block + bump the ai-lab.css
   cache-bust on ai-lab.html. No other CSS changed.
   ============================================================ */
.ailab-window {
  border-color: rgba(255,255,255,0.16);
}
.ailab-window.ailab-window--focused {
  border-color: rgba(255,255,255,0.30);
}

/* ============================================================
   Iter 12H — Index + FX card colour test (2026-05-12)
   ------------------------------------------------------------
   Mirrors the Iter 12C dashboard.css scoping but targets the
   AI Lab Index Card and Currency Pair widgets. Card background
   moves from var(--ailab-surface-2) -> #2b2f3a so the AI Lab
   versions match the Watchlists-tab idx-item tiles.

   Companion overrides:
     - flash-up / flash-down keyframes settle to #2b2f3a so a
       price tick doesn't snap back to the old colour.
     - :hover bumped to #353a47 so hover stays distinct.
     - cursor: pointer hints click-to-chart (handlers attached
       in ai-lab.js renderIndexCardBody / renderFxBody).

   Price-text colours (.ailab-*-change up/down) are unchanged --
   var(--ailab-positive) / var(--ailab-negative) read fine on
   the new base.

   To revert: delete this entire block + bump the ai-lab.css
   cache-bust on ai-lab.html. No other CSS changed.
   ============================================================ */
.ailab-idxcard-item,
.ailab-fxcard-item {
  background: #2b2f3a;
  cursor: pointer;
}
.ailab-idxcard-item:hover,
.ailab-fxcard-item:hover {
  background: #353a47;
}

/* Flash keyframes settle on the new card colour so a tick doesn't
   snap back to the old var(--ailab-surface-2). Named -12h so they
   don't collide with the original keyframes (still defined). */
@keyframes ailab-idxcard-flash-green-12h {
  0% { background: rgba(109, 170, 69, 0.18); }
  100% { background: #2b2f3a; }
}
@keyframes ailab-idxcard-flash-red-12h {
  0% { background: rgba(221, 105, 116, 0.18); }
  100% { background: #2b2f3a; }
}
@keyframes ailab-fxcard-flash-green-12h {
  0% { background: rgba(109, 170, 69, 0.18); }
  100% { background: #2b2f3a; }
}
@keyframes ailab-fxcard-flash-red-12h {
  0% { background: rgba(221, 105, 116, 0.18); }
  100% { background: #2b2f3a; }
}
.ailab-idxcard-item.flash-up   { animation: ailab-idxcard-flash-green-12h 0.6s ease; }
.ailab-idxcard-item.flash-down { animation: ailab-idxcard-flash-red-12h   0.6s ease; }
.ailab-fxcard-item.flash-up    { animation: ailab-fxcard-flash-green-12h 0.6s ease; }
.ailab-fxcard-item.flash-down  { animation: ailab-fxcard-flash-red-12h   0.6s ease; }

/* ─────────────────────────────────────────────────────────────────────
 * Iter 12BF — Trade widget compact mode redesigned.
 * The Iter 12BC full-height left rail (book icon + rotated mini ticker) is
 * replaced by a small chevron edge-tab that hangs off the panel's right
 * edge in BOTH compact and expanded modes. The compact body now stacks a
 * top KPI strip (5 account tiles: Daily P&L, Unrealized, Net Liq, Available,
 * Buying Power) + content column (header + inline sym/price/change row +
 * prominent company-name block + Order Ticket form). Compact width is
 * tightened to 500px; the compact KPI strip uses smaller padding and
 * typography so all 5 tiles fit at that width without horizontal scroll.
 * ───────────────────────────────────────────────────────────────────── */
.ailab-trade-grid--compact {
  /* Single column at root: the compact KPI strip and content column stack
     vertically. The edge-tab is positioned absolutely against this grid
     (see .ailab-trade-edge-tab) so it floats over the right edge. */
  grid-template-rows: auto 1fr;
  grid-template-columns: 1fr;
  position: relative;
}
.ailab-trade-compact-col {
  display: grid;
  grid-template-rows: auto 1fr;
  grid-template-columns: 1fr;
  min-width: 0;
  min-height: 0;
}
/* Iter 12BF — The expanded grid also gets the edge-tab; make it
   position:relative so the absolute-positioned tab lands on its right
   edge instead of escaping to the nearest positioned ancestor. */
.ailab-trade-grid { position: relative; }
/* Iter 12BF — Compact KPI strip variant: tighter padding and slightly
   smaller typography so 5 tiles fit comfortably across a 500px panel
   without horizontal scroll. Each tile gets a minimum width that keeps
   the longest formatted value (e.g. "+$22,807.80") readable; if a value
   ever exceeds the tile, native overflow-x scroll on the parent kicks
   in as a graceful fallback. */
.ailab-trade-kpi-strip--compact {
  height: 44px;
}
.ailab-trade-kpi-strip--compact .ailab-trade-kpi-cell {
  padding: 0 8px;
  min-width: 0;
  flex: 1 1 0;
}
.ailab-trade-kpi-strip--compact .ailab-trade-kpi-label {
  font-size: 9px;
  letter-spacing: 0.04em;
}
.ailab-trade-kpi-strip--compact .ailab-trade-kpi-val {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Iter 12BF — Inline symbol/last/change row above the Order Ticket form.
   Replaces the rotated rail mini-ticker. Horizontal three-cell layout:
   symbol on the left, last price prominent in the middle, day-change
   percent on the right with up/down/flat color states. Hidden until
   _renderTradeRailMini reveals it once a symbol + quote land. */
.ailab-trade-syminfo {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 12px 4px;
  border-bottom: 1px solid var(--ib-border);
  background: var(--ib-surface-2);
  flex-shrink: 0;
}
.ailab-trade-syminfo[hidden] { display: none; }
.ailab-trade-syminfo-sym {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ib-text-strong);
}
.ailab-trade-syminfo-last {
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ib-text-strong);
}
.ailab-trade-syminfo-change {
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-left: auto;
  color: var(--ib-text-dim);
}
.ailab-trade-syminfo-change.up   { color: var(--ib-green, #6daa45); }
.ailab-trade-syminfo-change.down { color: var(--ib-red, #dd6974); }
.ailab-trade-syminfo-change.flat { color: var(--ib-text-dim); }
.ailab-trade-syminfo-change[hidden] { display: none; }
/* Iter 12BF — Edge-tab toggle. Iter 12BG — the tab is now mounted on
   the .ailab-window node directly (sibling of .ailab-window-body) and
   genuinely overhangs the panel's outer right border via right: -16px.
   The .ailab-window[data-window-type="trade"] override above flips the
   window-level overflow to visible so the tab can escape; the body and
   host nodes still clip their own internal content. The pill is shaped
   as a full pill (rounded on both sides) with an all-around border and
   omnidirectional shadow so it reads as a distinct floating handle. In
   compact mode the chevron points right (›) to invite expand; in
   expanded mode the window carries data-trade-expanded="1" and the
   chevron flips 180° to point left (‹) for collapse. The pill respects
   the same surface-3/blue hover colors as other chrome controls. */
.ailab-trade-edge-tab {
  position: absolute;
  top: 50%;
  right: -16px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--ib-border);
  border-radius: 14px;
  background: var(--ib-surface-3, var(--ib-surface-2));
  color: var(--ib-text-dim);
  cursor: pointer;
  z-index: 4;
  box-shadow: 0 2px 8px rgba(0,0,0,0.4);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.ailab-trade-edge-tab:hover {
  background: var(--ib-blue, #2b6cb0);
  color: #fff;
  border-color: var(--ib-blue, #2b6cb0);
}
.ailab-trade-edge-tab:focus-visible {
  outline: 1px solid var(--ib-blue);
  outline-offset: 2px;
}
.ailab-trade-edge-tab-icon {
  pointer-events: none;
  flex-shrink: 0;
  transition: transform 0.18s ease;
}
/* Iter 12BG — Flip the chevron based on the data-trade-expanded marker
   set by _mountTradeEdgeTab on the window node. The tab is no longer
   inside .ailab-trade-host so the previous host-class selector cannot
   reach it. */
.ailab-window[data-trade-expanded="1"] .ailab-trade-edge-tab-icon {
  transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .ailab-trade-edge-tab,
  .ailab-trade-edge-tab-icon { transition: none; }
}
/* Left rail — mirrors .wl-insight-tab from dashboard.css L533-555. Slim
   vertical button spanning the full window height, with the book SVG at
   the top and the Iter 12BD mini quote ticker (symbol + last + day
   change) stacked below it, rotated -90deg so the values read bottom-to-
   top (same idiom as .wl-insight-tab's vertical label). Click anywhere
   on the rail animates window grow to expanded mode. */
.ailab-trade-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  width: 36px;
  height: 100%;
  padding: 10px 0 12px;
  background: var(--ib-surface-2);
  border: 0;
  border-right: 1px solid var(--ib-border);
  color: var(--ib-text-dim);
  cursor: pointer;
  flex-shrink: 0;
  overflow: hidden;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.ailab-trade-rail:hover {
  background: var(--ib-surface-3);
  color: var(--ib-text-strong);
  border-right-color: var(--ib-blue);
}
.ailab-trade-rail:focus-visible {
  outline: 1px solid var(--ib-blue);
  outline-offset: -1px;
}
.ailab-trade-rail-icon {
  width: 20px;
  height: 20px;
  pointer-events: none;
  flex-shrink: 0;
}
/* Iter 12BD — mini quote ticker stacked below the book icon. Each row is
   rotated -90deg (writing-mode vertical-rl with text upright via
   transform) so values read bottom-to-top inside the 36px-wide rail. The
   stack is flex-column with small gaps; values are tabular numbers so
   ticks update without column-width shimmer. Wrapper is hidden by JS
   until a symbol is selected and a quote with `last` lands. */
.ailab-trade-rail-mini {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  pointer-events: none; /* clicks pass through to the rail button */
}
.ailab-trade-rail-mini[hidden] { display: none; }
.ailab-trade-rail-mini-sym,
.ailab-trade-rail-mini-last,
.ailab-trade-rail-mini-change {
  /* Rotate text -90deg so it reads bottom-to-top. Use writing-mode +
     text-orientation rather than transform: rotate so layout reserves the
     correct height inside the flex column. */
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.ailab-trade-rail-mini-sym {
  font-size: 11px;
  font-weight: 600;
  color: var(--ib-text-strong);
  letter-spacing: 0.06em;
}
.ailab-trade-rail-mini-last {
  font-size: 12px;
  font-weight: 700;
  color: var(--ib-text-strong);
}
.ailab-trade-rail-mini-change {
  font-size: 10px;
  font-weight: 600;
  color: var(--ib-text-dim);
}
.ailab-trade-rail-mini-change.up   { color: var(--ib-green, #6daa45); }
.ailab-trade-rail-mini-change.down { color: var(--ib-red, #dd6974); }
.ailab-trade-rail-mini-change.flat { color: var(--ib-text-dim); }
.ailab-trade-rail-mini-change[hidden] { display: none; }
/* Animate the trade window only while the toggle handler has tagged it
   with data-trade-anim="1". This avoids fighting the drag/resize paths,
   which also write width/height/left every frame and would otherwise feel
   laggy if a transition was always-on. The handler sets the attribute,
   triggers the geometry change on the next frame, and removes the
   attribute on transitionend (or after a fallback timeout). Duration
   matches the watchlist .wl-insight-col open animation feel (~240ms). */
.ailab-window[data-window-type="trade"][data-trade-anim="1"] {
  transition: width 240ms ease, height 240ms ease, left 240ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .ailab-window[data-window-type="trade"][data-trade-anim="1"] { transition: none; }
  .ailab-trade-rail { transition: none; }
}
.ailab-trade-compact-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 32px;
  border-bottom: 1px solid var(--ib-border);
  background: var(--ib-surface-2);
  flex-shrink: 0;
}
.ailab-trade-compact-head i[data-lucide="send"] {
  width: 14px;
  height: 14px;
  opacity: 0.75;
  color: var(--ib-text-dim);
}
.ailab-trade-compact-head .ailab-trade-pane-title {
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ib-text-dim);
  font-size: 11px;
}
.ailab-trade-compact-head .ailab-trade-clock {
  margin-left: auto;
  font-size: 11px;
  color: var(--ib-text-muted);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.ailab-trade-compact-head .ailab-trade-kpi-env {
  /* Match the env-chip styling used in the KPI strip in expanded mode. */
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px 6px;
  border: 1px solid var(--ib-border-2);
  color: var(--ib-text-dim);
  background: var(--ib-input-bg);
}
.ailab-trade-compact-body {
  overflow-y: auto;
  min-height: 0;
  padding: 0;
  background: var(--ib-surface);
}
/* Prominent company-name display — large headline above the ticket form
   in compact mode. Hidden until a ticker resolves. */
.ailab-trade-prominent {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px 10px 16px;
  border-bottom: 1px solid var(--ib-border);
  background: var(--ib-surface);
}
.ailab-trade-prominent[hidden] { display: none; }
.ailab-trade-prominent-name {
  font-size: 19px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ib-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ailab-trade-prominent-sym {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ib-text-dim);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
/* Expand / collapse toggle button — used in both compact head and
   expanded right-pane Order Ticket head. Compact head right-aligns the
   button via margin-left:0 (clock already pushed left); in expanded mode
   the pane-head also right-aligns via its own ml:auto rule on meta. */
.ailab-trade-expand-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--ib-border-2);
  background: var(--ib-input-bg);
  color: var(--ib-text-dim);
  cursor: pointer;
  flex-shrink: 0;
}
.ailab-trade-expand-toggle:hover {
  color: var(--ib-text-strong);
  background: var(--ib-surface-3);
  border-color: var(--ib-text-dim);
}
.ailab-trade-expand-toggle:focus-visible {
  outline: 1px solid var(--ib-blue);
  outline-offset: 1px;
}
.ailab-trade-expand-toggle i {
  width: 14px;
  height: 14px;
  pointer-events: none;
}
/* In the expanded right-pane Order Ticket head, push the collapse-toggle
   to the right edge of the pane head. */
.ailab-trade-pane-head .ailab-trade-expand-toggle--collapse {
  margin-left: auto;
}
/* In compact mode the symbol's small inline company-name caption is
   redundant (the prominent block above shows the same info, larger).
   Keep the slot but hide the duplicate text to declutter. */
.ailab-trade-host--compact .ailab-trade-company-name { display: none !important; }

/* Iter 12BW — Treasury Rates widget stale-hint UX. When a rate card's
   data-stale-days attribute is > 1 (i.e. the as-of date is older than
   the previous business day) the JS adds the .is-stale class. The CSS
   dims the value glyph to 0.6 opacity so the card still renders but
   reads visually as "this number is not today's". The label and ± bps
   change are left at full opacity so the structural framing of the
   card is still legible at a glance — only the headline number is
   visually de-emphasised. */
.ailab-idxcard-item.is-stale [data-role="price"],
.ailab-idxcard-item.is-stale [data-role="change"] {
  opacity: 0.6;
}
